about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--Cargo.lock14
-rw-r--r--README.md39
-rw-r--r--compiler/rustc_ast/src/ast.rs13
-rw-r--r--compiler/rustc_ast/src/ptr.rs16
-rw-r--r--compiler/rustc_ast/src/token.rs2
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs2
-rw-r--r--compiler/rustc_ast/src/util/parser.rs7
-rw-r--r--compiler/rustc_ast_lowering/src/index.rs15
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs8
-rw-r--r--compiler/rustc_ast_passes/messages.ftl2
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs29
-rw-r--r--compiler/rustc_ast_passes/src/errors.rs3
-rw-r--r--compiler/rustc_borrowck/src/borrow_set.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/.cirrus.yml3
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml2
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/main.yml68
-rw-r--r--compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml2
-rw-r--r--compiler/rustc_codegen_cranelift/Readme.md22
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_backend.rs16
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/main.rs13
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/prepare.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/tests.rs17
-rw-r--r--compiler/rustc_codegen_cranelift/build_system/utils.rs18
-rw-r--r--compiler/rustc_codegen_cranelift/docs/rustc_testing.md23
-rw-r--r--compiler/rustc_codegen_cranelift/example/mini_core.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/rust-toolchain2
-rwxr-xr-xcompiler/rustc_codegen_cranelift/scripts/filter_profile.rs9
-rw-r--r--compiler/rustc_codegen_cranelift/src/base.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/num.rs2
-rw-r--r--compiler/rustc_codegen_cranelift/src/vtable.rs2
-rw-r--r--compiler/rustc_codegen_gcc/Cargo.lock10
-rw-r--r--compiler/rustc_codegen_gcc/Cargo.toml2
-rw-r--r--compiler/rustc_codegen_llvm/src/abi.rs120
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs29
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/declare.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs8
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/block.rs32
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs6
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/check_consts/check.rs2
-rw-r--r--compiler/rustc_const_eval/src/transform/validate.rs2
-rw-r--r--compiler/rustc_data_structures/src/graph/dominators/mod.rs8
-rw-r--r--compiler/rustc_errors/src/lib.rs37
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs2
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir/src/def.rs3
-rw-r--r--compiler/rustc_hir/src/definitions.rs9
-rw-r--r--compiler/rustc_hir/src/hir.rs7
-rw-r--r--compiler/rustc_hir/src/hir_id.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs44
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl2
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/check.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/closure.rs32
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs26
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs313
-rw-r--r--compiler/rustc_hir_typeck/src/intrinsicck.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/pat.rs91
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs55
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs9
-rw-r--r--compiler/rustc_incremental/src/persist/load.rs3
-rw-r--r--compiler/rustc_incremental/src/persist/save.rs3
-rw-r--r--compiler/rustc_index/src/bit_set.rs2
-rw-r--r--compiler/rustc_index_macros/src/newtype.rs3
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs10
-rw-r--r--compiler/rustc_infer/src/lib.rs2
-rw-r--r--compiler/rustc_infer/src/traits/mod.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs3
-rw-r--r--compiler/rustc_interface/src/tests.rs1
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs207
-rw-r--r--compiler/rustc_lint_defs/src/builtin.rs6
-rw-r--r--compiler/rustc_llvm/build.rs28
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp53
-rw-r--r--compiler/rustc_middle/src/arena.rs1
-rw-r--r--compiler/rustc_middle/src/dep_graph/dep_node.rs14
-rw-r--r--compiler/rustc_middle/src/hir/map/mod.rs5
-rw-r--r--compiler/rustc_middle/src/hir/mod.rs8
-rw-r--r--compiler/rustc_middle/src/infer/canonical.rs2
-rw-r--r--compiler/rustc_middle/src/mir/consts.rs2
-rw-r--r--compiler/rustc_middle/src/mir/coverage.rs8
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs2
-rw-r--r--compiler/rustc_middle/src/mir/interpret/value.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs17
-rw-r--r--compiler/rustc_middle/src/mir/query.rs65
-rw-r--r--compiler/rustc_middle/src/mir/statement.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs6
-rw-r--r--compiler/rustc_middle/src/mir/tcx.rs2
-rw-r--r--compiler/rustc_middle/src/mir/visit.rs2
-rw-r--r--compiler/rustc_middle/src/query/mod.rs6
-rw-r--r--compiler/rustc_middle/src/query/on_disk_cache.rs7
-rw-r--r--compiler/rustc_middle/src/query/plumbing.rs4
-rw-r--r--compiler/rustc_middle/src/thir.rs8
-rw-r--r--compiler/rustc_middle/src/traits/mod.rs2
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect.rs7
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect/format.rs8
-rw-r--r--compiler/rustc_middle/src/ty/cast.rs2
-rw-r--r--compiler/rustc_middle/src/ty/codec.rs1
-rw-r--r--compiler/rustc_middle/src/ty/consts.rs2
-rw-r--r--compiler/rustc_middle/src/ty/consts/kind.rs4
-rw-r--r--compiler/rustc_middle/src/ty/context.rs127
-rw-r--r--compiler/rustc_middle/src/ty/instance.rs66
-rw-r--r--compiler/rustc_middle/src/ty/mod.rs6
-rw-r--r--compiler/rustc_middle/src/ty/normalize_erasing_regions.rs4
-rw-r--r--compiler/rustc_middle/src/ty/print/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/ty/structural_impls.rs1
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs36
-rw-r--r--compiler/rustc_middle/src/ty/typeck_results.rs60
-rw-r--r--compiler/rustc_mir_build/src/build/block.rs45
-rw-r--r--compiler/rustc_mir_build/src/build/custom/mod.rs5
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs17
-rw-r--r--compiler/rustc_mir_build/src/build/expr/into.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs108
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs52
-rw-r--r--compiler/rustc_mir_build/src/build/scope.rs20
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs5
-rw-r--r--compiler/rustc_mir_build/src/errors.rs23
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs57
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs9
-rw-r--r--compiler/rustc_mir_dataflow/src/elaborate_drops.rs10
-rw-r--r--compiler/rustc_mir_transform/messages.ftl49
-rw-r--r--compiler/rustc_mir_transform/src/check_unsafety.rs615
-rw-r--r--compiler/rustc_mir_transform/src/coroutine.rs10
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs159
-rw-r--r--compiler/rustc_mir_transform/src/coverage/query.rs2
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs12
-rw-r--r--compiler/rustc_mir_transform/src/errors.rs171
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs2
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs4
-rw-r--r--compiler/rustc_mir_transform/src/inline/cycle.rs20
-rw-r--r--compiler/rustc_mir_transform/src/known_panics_lint.rs12
-rw-r--r--compiler/rustc_mir_transform/src/lib.rs7
-rw-r--r--compiler/rustc_mir_transform/src/promote_consts.rs2
-rw-r--r--compiler/rustc_mir_transform/src/shim.rs4
-rw-r--r--compiler/rustc_mir_transform/src/simplify.rs2
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/attr_wrapper.rs2
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs1
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse_format/src/lib.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/constructor.rs29
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs2
-rw-r--r--compiler/rustc_pattern_analysis/src/usefulness.rs49
-rw-r--r--compiler/rustc_query_system/src/dep_graph/graph.rs24
-rw-r--r--compiler/rustc_query_system/src/dep_graph/serialized.rs200
-rw-r--r--compiler/rustc_resolve/src/ident.rs2
-rw-r--r--compiler/rustc_resolve/src/imports.rs6
-rw-r--r--compiler/rustc_session/src/config.rs348
-rw-r--r--compiler/rustc_session/src/config/cfg.rs373
-rw-r--r--compiler/rustc_session/src/options.rs2
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/mir.rs2
-rw-r--r--compiler/rustc_span/src/def_id.rs2
-rw-r--r--compiler/rustc_span/src/hygiene.rs4
-rw-r--r--compiler/rustc_span/src/source_map/tests.rs2
-rw-r--r--compiler/rustc_span/src/symbol.rs3
-rw-r--r--compiler/rustc_symbol_mangling/src/legacy.rs12
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid.rs29
-rw-r--r--compiler/rustc_symbol_mangling/src/typeid/typeid_itanium_cxx_abi.rs424
-rw-r--r--compiler/rustc_symbol_mangling/src/v0.rs8
-rw-r--r--compiler/rustc_target/src/abi/call/mod.rs27
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs24
-rw-r--r--compiler/rustc_target/src/spec/base/apple/tests.rs12
-rw-r--r--compiler/rustc_target/src/spec/base/msvc.rs1
-rw-r--r--compiler/rustc_target/src/spec/mod.rs3
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs27
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs27
-rw-r--r--compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs13
-rw-r--r--compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs3
-rw-r--r--compiler/rustc_trait_selection/src/lib.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/alias_relate.rs159
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs13
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs2
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs47
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs91
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs12
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/build.rs27
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalize.rs4
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs69
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs6
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs24
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs10
-rw-r--r--compiler/rustc_trait_selection/src/traits/fulfill.rs19
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs7
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs93
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/mod.rs16
-rw-r--r--compiler/rustc_trait_selection/src/traits/util.rs42
-rw-r--r--compiler/rustc_trait_selection/src/traits/wf.rs26
-rw-r--r--compiler/rustc_ty_utils/src/layout.rs44
-rw-r--r--compiler/rustc_ty_utils/src/opaque_types.rs3
-rw-r--r--compiler/rustc_ty_utils/src/sig_types.rs11
-rw-r--r--compiler/rustc_type_ir/src/flags.rs6
-rw-r--r--compiler/rustc_type_ir/src/lib.rs2
-rw-r--r--compiler/rustc_type_ir/src/visit.rs4
-rw-r--r--compiler/stable_mir/src/mir/body.rs1
-rw-r--r--library/alloc/benches/vec_deque_append.rs5
-rw-r--r--library/alloc/src/lib.miri.rs4
-rw-r--r--library/core/src/clone.rs5
-rw-r--r--library/core/src/cmp.rs10
-rw-r--r--library/core/src/fmt/mod.rs4
-rw-r--r--library/core/src/intrinsics/simd.rs6
-rw-r--r--library/core/src/lib.miri.rs4
-rw-r--r--library/core/src/lib.rs4
-rw-r--r--library/core/src/marker.rs8
-rw-r--r--library/core/src/ptr/const_ptr.rs10
-rw-r--r--library/core/src/ptr/metadata.rs3
-rw-r--r--library/core/src/ptr/mod.rs14
-rw-r--r--library/core/src/ptr/mut_ptr.rs11
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--library/core/tests/ptr.rs3
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs10
-rw-r--r--library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs10
-rw-r--r--library/portable-simd/crates/core_simd/tests/pointers.rs6
-rw-r--r--library/proc_macro/src/lib.rs4
-rw-r--r--library/std/build.rs1
-rw-r--r--library/std/src/fs.rs4
-rw-r--r--library/std/src/fs/tests.rs17
-rw-r--r--library/std/src/lib.miri.rs4
-rw-r--r--library/std/src/os/mod.rs2
-rw-r--r--library/std/src/os/unix/mod.rs2
-rw-r--r--library/std/src/os/unix/net/mod.rs2
-rw-r--r--library/std/src/os/unix/net/stream.rs2
-rw-r--r--library/std/src/os/unix/net/ucred.rs16
-rw-r--r--library/std/src/os/unix/net/ucred/tests.rs2
-rw-r--r--library/std/src/os/visionos/fs.rs160
-rw-r--r--library/std/src/os/visionos/mod.rs6
-rw-r--r--library/std/src/os/visionos/raw.rs83
-rw-r--r--library/std/src/rt.rs4
-rw-r--r--library/std/src/sys/pal/hermit/thread.rs8
-rw-r--r--library/std/src/sys/pal/itron/thread.rs8
-rw-r--r--library/std/src/sys/pal/mod.rs6
-rw-r--r--library/std/src/sys/pal/sgx/thread.rs6
-rw-r--r--library/std/src/sys/pal/teeos/thread.rs6
-rw-r--r--library/std/src/sys/pal/uefi/thread.rs6
-rw-r--r--library/std/src/sys/pal/unix/args.rs15
-rw-r--r--library/std/src/sys/pal/unix/env.rs11
-rw-r--r--library/std/src/sys/pal/unix/fd.rs2
-rw-r--r--library/std/src/sys/pal/unix/fs.rs38
-rw-r--r--library/std/src/sys/pal/unix/mod.rs3
-rw-r--r--library/std/src/sys/pal/unix/os.rs13
-rw-r--r--library/std/src/sys/pal/unix/process/process_unix.rs1
-rw-r--r--library/std/src/sys/pal/unix/rand.rs21
-rw-r--r--library/std/src/sys/pal/unix/thread.rs83
-rw-r--r--library/std/src/sys/pal/unix/thread_local_dtor.rs8
-rw-r--r--library/std/src/sys/pal/unix/thread_parking/mod.rs1
-rw-r--r--library/std/src/sys/pal/unix/thread_parking/pthread.rs3
-rw-r--r--library/std/src/sys/pal/unix/time.rs5
-rw-r--r--library/std/src/sys/pal/unsupported/thread.rs6
-rw-r--r--library/std/src/sys/pal/wasi/thread.rs6
-rw-r--r--library/std/src/sys/pal/wasip2/cabi_realloc.rs65
-rw-r--r--library/std/src/sys/pal/wasip2/mod.rs8
-rw-r--r--library/std/src/sys/pal/wasm/atomics/thread.rs4
-rw-r--r--library/std/src/sys/pal/windows/stack_overflow.rs30
-rw-r--r--library/std/src/sys/pal/windows/stack_overflow_uwp.rs9
-rw-r--r--library/std/src/sys/pal/windows/thread.rs29
-rw-r--r--library/std/src/sys/pal/xous/thread.rs6
-rw-r--r--library/std/src/sys/personality/gcc.rs2
-rw-r--r--library/std/src/sys/sync/condvar/pthread.rs3
-rw-r--r--library/std/src/sys_common/net.rs2
-rw-r--r--library/std/src/thread/mod.rs33
-rw-r--r--library/std/src/thread/tests.rs23
-rw-r--r--library/unwind/src/libunwind.rs2
-rw-r--r--src/bootstrap/bootstrap.py1
-rw-r--r--src/bootstrap/src/core/build_steps/dist.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs3
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs79
-rw-r--r--src/bootstrap/src/core/builder.rs45
-rw-r--r--src/bootstrap/src/core/builder/tests.rs2
-rw-r--r--src/bootstrap/src/core/config/config.rs7
-rw-r--r--src/bootstrap/src/core/config/flags.rs31
-rw-r--r--src/bootstrap/src/lib.rs3
-rw-r--r--src/bootstrap/src/utils/render_tests.rs12
-rw-r--r--src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version2
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh5
-rwxr-xr-xsrc/ci/scripts/upload-artifacts.sh14
-rw-r--r--src/doc/rustc/src/SUMMARY.md1
-rw-r--r--src/doc/rustc/src/platform-support.md2
-rw-r--r--src/doc/rustc/src/platform-support/apple-visionos.md53
-rw-r--r--src/doc/rustc/src/platform-support/netbsd.md8
-rw-r--r--src/doc/rustdoc/src/what-is-rustdoc.md11
-rw-r--r--src/doc/unstable-book/src/compiler-flags/external-clangrt.md6
-rw-r--r--src/doc/unstable-book/src/compiler-flags/sanitizer.md15
-rw-r--r--src/etc/completions/x.py.fish42
-rw-r--r--src/etc/completions/x.py.ps149
-rw-r--r--src/etc/completions/x.py.sh133
-rw-r--r--src/etc/completions/x.py.zsh56
-rw-r--r--src/librustdoc/clean/blanket_impl.rs2
-rw-r--r--src/librustdoc/clean/cfg.rs1
-rw-r--r--src/librustdoc/html/static/css/noscript.css4
-rw-r--r--src/librustdoc/html/static/css/rustdoc.css8
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/.gitignore3
-rw-r--r--src/tools/clippy/CHANGELOG.md2
-rw-r--r--src/tools/clippy/Cargo.toml1
-rw-r--r--src/tools/clippy/book/src/SUMMARY.md1
-rw-r--r--src/tools/clippy/book/src/development/defining_lints.md9
-rw-r--r--src/tools/clippy/book/src/development/lint_passes.md2
-rw-r--r--src/tools/clippy/book/src/development/the_team.md130
-rw-r--r--src/tools/clippy/book/src/lint_configuration.md1
-rw-r--r--src/tools/clippy/clippy_config/src/conf.rs7
-rw-r--r--src/tools/clippy/clippy_config/src/lib.rs8
-rw-r--r--src/tools/clippy/clippy_config/src/msrvs.rs2
-rw-r--r--src/tools/clippy/clippy_dev/src/lib.rs9
-rw-r--r--src/tools/clippy/clippy_dev/src/lint.rs4
-rw-r--r--src/tools/clippy/clippy_dev/src/update_lints.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/approx_const.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/asm_syntax.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/assertions_on_constants.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/assigning_clones.rs30
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/inline_always.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs85
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/mod.rs20
-rw-r--r--src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/await_holding_invalid.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/booleans.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/box_default.rs55
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/feature_name.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/cargo/wildcard_dependencies.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_nan_to_int.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_truncation.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/cognitive_complexity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/collection_is_never_read.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/declared_lints.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/default_union_representation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derivable_impls.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/derive.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_macros.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_methods.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_names.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/disallowed_types.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/drop_forget_ref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/duplicate_mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/endian_bytes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/entry.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/eta_reduction.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/excessive_bools.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/exhaustive_items.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/explicit_write.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/extra_unused_type_parameters.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/float_literal.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/format_args.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/format_impl.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/formatting.rs17
-rw-r--r--src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/must_use.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/result.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/implicit_hasher.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/incompatible_msrv.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/inherent_to_string.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/instant_subtraction.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/item_name_repetitions.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_futures.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_include_file.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_arrays.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/large_stack_frames.rs106
-rw-r--r--src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs293
-rw-r--r--src/tools/clippy/clippy_lints/src/len_zero.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/lib.rs15
-rw-r--r--src/tools/clippy/clippy_lints/src/lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/literal_representation.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/never_loop.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/same_item_push.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/main_recursion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_assert.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_bits.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_clamp.rs38
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_strip.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs33
-rw-r--r--src/tools/clippy/clippy_lints/src/map_unit_fn.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/match_result_ok.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/mod.rs32
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/mem_replace.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs5
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/drain_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/expect_fun_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map.rs53
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs18
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/get_first.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/is_empty.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_cloned_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_count.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_filter.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_nth.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_clone.rs9
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_flatten.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/map_identity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs51
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/needless_collect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/open_options.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/search_is_some.rs12
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/str_splitn.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs62
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unnecessary_to_owned.rs19
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/useless_asref.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/utils.rs11
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/wrong_self_convention.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/min_ident_chars.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/builtin_type_shadow.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/mod.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_doc.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_inline.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/missing_trait_methods.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/module_style.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mut_reference.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/mutex_atomic.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_bool.rs28
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_borrows_for_generic_args.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_continue.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/needless_question_mark.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/new_without_default.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/no_effect.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_copy_const.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/non_expressive_names.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/octal_escapes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/bit_mask.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/eq_op.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/operators/self_assignment.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/option_if_let_else.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/question_mark.rs36
-rw-r--r--src/tools/clippy/clippy_lints/src/ranges.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_closure_call.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_locals.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/regex.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/returns.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/self_named_constructors.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/serde_api.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/shadow.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/std_instead_of_core.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/strings.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/swap.rs182
-rw-r--r--src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/trailing_empty_array.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/trait_bounds.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/crosspointer_transmute.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs87
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs34
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_bool.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs10
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/wrong_transmute.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/types/box_collection.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unconditional_recursion.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs22
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/let_unit_value.rs44
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_io_amount.rs24
-rw-r--r--src/tools/clippy/clippy_lints/src/unused_rounding.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/unwrap_in_result.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/use_self.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/useless_conversion.rs14
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/lint_without_lint_pass.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/metadata_collector.rs16
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/msrv_attr_impl.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/internal_lints/unnecessary_def_path.rs13
-rw-r--r--src/tools/clippy/clippy_lints/src/visibility.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/write.rs8
-rw-r--r--src/tools/clippy/clippy_lints/src/zero_div_zero.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs20
-rw-r--r--src/tools/clippy/clippy_utils/src/attrs.rs32
-rw-r--r--src/tools/clippy/clippy_utils/src/check_proc_macro.rs12
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs10
-rw-r--r--src/tools/clippy/clippy_utils/src/diagnostics.rs55
-rw-r--r--src/tools/clippy/clippy_utils/src/higher.rs54
-rw-r--r--src/tools/clippy/clippy_utils/src/hir_utils.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/lib.rs76
-rw-r--r--src/tools/clippy/clippy_utils/src/macros.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/mir/mod.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs79
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs42
-rw-r--r--src/tools/clippy/clippy_utils/src/usage.rs18
-rw-r--r--src/tools/clippy/clippy_utils/src/visitors.rs28
-rw-r--r--src/tools/clippy/lintcheck/src/main.rs41
-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/absolute_paths/absolute_paths.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.rs2
-rw-r--r--src/tools/clippy/tests/ui-toml/large_stack_frames/large_stack_frames.stderr17
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.fixed13
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.rs13
-rw-r--r--src/tools/clippy/tests/ui/assigning_clones.stderr12
-rw-r--r--src/tools/clippy/tests/ui/author/issue_3849.rs2
-rw-r--r--src/tools/clippy/tests/ui/auxiliary/macro_rules.rs7
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.fixed7
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.rs7
-rw-r--r--src/tools/clippy/tests/ui/blocks_in_conditions.stderr8
-rw-r--r--src/tools/clippy/tests/ui/box_default.fixed85
-rw-r--r--src/tools/clippy/tests/ui/box_default.rs75
-rw-r--r--src/tools/clippy/tests/ui/box_default.stderr104
-rw-r--r--src/tools/clippy/tests/ui/cast.rs12
-rw-r--r--src/tools/clippy/tests/ui/cast.stderr190
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.fixed1
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.rs1
-rw-r--r--src/tools/clippy/tests/ui/checked_conversions.stderr34
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-12616.fixed7
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-12616.rs7
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-12616.stderr19
-rw-r--r--src/tools/clippy/tests/ui/crashes/ice-1782.rs2
-rw-r--r--src/tools/clippy/tests/ui/duplicated_attributes.rs13
-rw-r--r--src/tools/clippy/tests/ui/duplicated_attributes.stderr94
-rw-r--r--src/tools/clippy/tests/ui/eager_transmute.fixed2
-rw-r--r--src/tools/clippy/tests/ui/eager_transmute.rs2
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.fixed86
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.rs86
-rw-r--r--src/tools/clippy/tests/ui/filter_map_identity.stderr134
-rw-r--r--src/tools/clippy/tests/ui/large_stack_frames.rs17
-rw-r--r--src/tools/clippy/tests/ui/large_stack_frames.stderr64
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants.fixed117
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants.rs117
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants.stderr184
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.rs78
-rw-r--r--src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.stderr83
-rw-r--r--src/tools/clippy/tests/ui/len_zero.fixed37
-rw-r--r--src/tools/clippy/tests/ui/len_zero.rs37
-rw-r--r--src/tools/clippy/tests/ui/len_zero.stderr20
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.fixed7
-rw-r--r--src/tools/clippy/tests/ui/let_and_return.rs7
-rw-r--r--src/tools/clippy/tests/ui/let_unit.fixed18
-rw-r--r--src/tools/clippy/tests/ui/let_unit.rs18
-rw-r--r--src/tools/clippy/tests/ui/let_unit.stderr21
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2018.fixed8
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2018.stderr11
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2021.fixed8
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.edition2021.stderr11
-rw-r--r--src/tools/clippy/tests/ui/manual_assert.rs10
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.fixed279
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.rs333
-rw-r--r--src/tools/clippy/tests/ui/manual_clamp.stderr188
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed2
-rw-r--r--src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs2
-rw-r--r--src/tools/clippy/tests/ui/manual_swap_auto_fix.fixed57
-rw-r--r--src/tools/clippy/tests/ui/manual_swap_auto_fix.rs72
-rw-r--r--src/tools/clippy/tests/ui/manual_swap_auto_fix.stderr88
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed45
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or_default.rs48
-rw-r--r--src/tools/clippy/tests/ui/manual_unwrap_or_default.stderr12
-rw-r--r--src/tools/clippy/tests/ui/map_clone.fixed24
-rw-r--r--src/tools/clippy/tests/ui/map_clone.rs24
-rw-r--r--src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs2
-rw-r--r--src/tools/clippy/tests/ui/missing_transmute_annotations.fixed78
-rw-r--r--src/tools/clippy/tests/ui/missing_transmute_annotations.rs78
-rw-r--r--src/tools/clippy/tests/ui/missing_transmute_annotations.stderr76
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.rs60
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style.stderr41
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style/auxiliary/submodule.rs9
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style/global_allow.rs7
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.rs3
-rw-r--r--src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.stderr14
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.fixed7
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.rs7
-rw-r--r--src/tools/clippy/tests/ui/ptr_cast_constness.stderr14
-rw-r--r--src/tools/clippy/tests/ui/question_mark.fixed34
-rw-r--r--src/tools/clippy/tests/ui/question_mark.rs36
-rw-r--r--src/tools/clippy/tests/ui/question_mark.stderr10
-rw-r--r--src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs1
-rw-r--r--src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr18
-rw-r--r--src/tools/clippy/tests/ui/suspicious_else_formatting.rs28
-rw-r--r--src/tools/clippy/tests/ui/transmute.rs7
-rw-r--r--src/tools/clippy/tests/ui/transmute.stderr72
-rw-r--r--src/tools/clippy/tests/ui/transmute_collection.rs1
-rw-r--r--src/tools/clippy/tests/ui/transmute_collection.stderr36
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.fixed1
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.rs1
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.stderr12
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char.fixed1
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char.rs1
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char.stderr4
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed1
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs1
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr4
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed1
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs1
-rw-r--r--src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr20
-rw-r--r--src/tools/clippy/tests/ui/transmute_null_to_fn.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed6
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs6
-rw-r--r--src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr44
-rw-r--r--src/tools/clippy/tests/ui/transmute_ref_to_ref.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmute_undefined_repr.rs7
-rw-r--r--src/tools/clippy/tests/ui/transmute_undefined_repr.stderr24
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed2
-rw-r--r--src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs2
-rw-r--r--src/tools/clippy/tests/ui/transmuting_null.rs2
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box.fixed24
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box.rs24
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box.stderr33
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs31
-rw-r--r--src/tools/clippy/tests/ui/type_id_on_box_unfixable.stderr22
-rw-r--r--src/tools/clippy/tests/ui/uninhabited_references.rs1
-rw-r--r--src/tools/clippy/tests/ui/uninhabited_references.stderr8
-rw-r--r--src/tools/clippy/tests/ui/use_self.fixed3
-rw-r--r--src/tools/clippy/tests/ui/use_self.rs3
-rw-r--r--src/tools/clippy/tests/ui/use_self.stderr86
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.fixed18
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.rs18
-rw-r--r--src/tools/clippy/tests/ui/useless_asref.stderr36
-rw-r--r--src/tools/clippy/triagebot.toml2
-rw-r--r--src/tools/compiletest/src/raise_fd_limit.rs2
-rw-r--r--src/tools/compiletest/src/runtest.rs14
-rw-r--r--src/tools/miri/README.md2
-rw-r--r--src/tools/miri/cargo-miri/src/phases.rs53
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs4
-rw-r--r--src/tools/miri/src/helpers.rs69
-rw-r--r--src/tools/miri/src/shims/intrinsics/simd.rs6
-rw-r--r--src/tools/miri/tests/fail/provenance/ptr_invalid.rs2
-rw-r--r--src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs2
-rw-r--r--src/tools/miri/tests/pass/async-closure-captures.rs125
-rw-r--r--src/tools/miri/tests/pass/async-closure-captures.stdout14
-rw-r--r--src/tools/miri/tests/pass/portable-simd-ptrs.rs2
-rw-r--r--src/tools/miri/tests/pass/ptr_int_from_exposed.rs10
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs4
-rw-r--r--src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs2
-rw-r--r--src/tools/run-make-support/src/cc.rs202
-rw-r--r--src/tools/run-make-support/src/lib.rs89
-rw-r--r--src/tools/run-make-support/src/run.rs21
-rw-r--r--src/tools/tidy/src/allowed_run_make_makefiles.txt3
-rw-r--r--src/tools/tidy/src/deps.rs5
-rw-r--r--src/tools/tidy/src/issues.txt19
-rw-r--r--src/tools/tidy/src/rustdoc_css_themes.rs7
-rw-r--r--src/tools/tidy/src/ui_tests.rs2
-rw-r--r--tests/assembly/targets/targets-macho.rs8
-rw-r--r--tests/auxiliary/rust_test_helpers.c24
-rw-r--r--tests/codegen/cast-target-abi.rs280
-rw-r--r--tests/codegen/cffi/ffi-out-of-bounds-loads.rs28
-rw-r--r--tests/codegen/no-redundant-item-monomorphization.rs33
-rw-r--r--tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs18
-rw-r--r--tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs24
-rw-r--r--tests/incremental/hashes/function_interfaces.rs6
-rw-r--r--tests/incremental/hashes/inherent_impls.rs8
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir2
-rw-r--r--tests/mir-opt/box_expr.main.ElaborateDrops.diff2
-rw-r--r--tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir8
-rw-r--r--tests/mir-opt/building/match/match_false_edges.main.built.after.mir2
-rw-r--r--tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir8
-rw-r--r--tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir6
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir6
-rw-r--r--tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir6
-rw-r--r--tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff2
-rw-r--r--tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff6
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff6
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff6
-rw-r--r--tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff6
-rw-r--r--tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff2
-rw-r--r--tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff2
-rw-r--r--tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/invalid_constant.main.GVN.diff12
-rw-r--r--tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff12
-rw-r--r--tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff (renamed from tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff)2
-rw-r--r--tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff (renamed from tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff)2
-rw-r--r--tests/mir-opt/const_prop/pointer_expose_provenance.rs (renamed from tests/mir-opt/const_prop/pointer_expose_address.rs)4
-rw-r--r--tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff2
-rw-r--r--tests/mir-opt/const_prop/reify_fn_ptr.rs2
-rw-r--r--tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff2
-rw-r--r--tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff2
-rw-r--r--tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff4
-rw-r--r--tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff4
-rw-r--r--tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff4
-rw-r--r--tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff4
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff38
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff8
-rw-r--r--tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff8
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff2
-rw-r--r--tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff2
-rw-r--r--tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff4
-rw-r--r--tests/mir-opt/dead-store-elimination/provenance_soundness.rs4
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff6
-rw-r--r--tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff10
-rw-r--r--tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff10
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/gvn.slices.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff12
-rw-r--r--tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff12
-rw-r--r--tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff6
-rw-r--r--tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff6
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff4
-rw-r--r--tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff4
-rw-r--r--tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff8
-rw-r--r--tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff8
-rw-r--r--tests/mir-opt/inline/inline_instruction_set.default.Inline.diff2
-rw-r--r--tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff20
-rw-r--r--tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff12
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff14
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff14
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir10
-rw-r--r--tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir10
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff24
-rw-r--r--tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff24
-rw-r--r--tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff28
-rw-r--r--tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir8
-rw-r--r--tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir8
-rw-r--r--tests/mir-opt/issue_72181.main.built.after.mir2
-rw-r--r--tests/mir-opt/issue_72181_1.main.built.after.mir2
-rw-r--r--tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff6
-rw-r--r--tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff2
-rw-r--r--tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff2
-rw-r--r--tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff2
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff8
-rw-r--r--tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff8
-rw-r--r--tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir10
-rw-r--r--tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir6
-rw-r--r--tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir4
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir20
-rw-r--r--tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir20
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir2
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir48
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir48
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir44
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir44
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir4
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir4
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir50
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir50
-rw-r--r--tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff2
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff258
-rw-r--r--tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff232
-rw-r--r--tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff4
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir10
-rw-r--r--tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir10
-rw-r--r--tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff (renamed from tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff)8
-rw-r--r--tests/mir-opt/simplify_locals.rs6
-rw-r--r--tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff2
-rw-r--r--tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff2
-rw-r--r--tests/mir-opt/tls_access.main.PreCodegen.after.mir6
-rw-r--r--tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir2
-rw-r--r--tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir2
-rw-r--r--tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir2
-rw-r--r--tests/run-make/arguments-non-c-like-enum/Makefile8
-rw-r--r--tests/run-make/arguments-non-c-like-enum/rmake.rs20
-rw-r--r--tests/run-make/hir-tree/Makefile8
-rw-r--r--tests/run-make/hir-tree/input.rs3
-rw-r--r--tests/run-make/issue-7349/Makefile11
-rw-r--r--tests/run-make/issue-7349/foo.rs22
-rw-r--r--tests/rustdoc-gui/anchors.goml6
-rw-r--r--tests/rustdoc-gui/code-color.goml6
-rw-r--r--tests/rustdoc-gui/codeblock-tooltip.goml5
-rw-r--r--tests/rustdoc-gui/docblock-code-block-line-number.goml13
-rw-r--r--tests/rustdoc-gui/docblock-details.goml4
-rw-r--r--tests/rustdoc-gui/docblock-table.goml4
-rw-r--r--tests/rustdoc-gui/headers-color.goml5
-rw-r--r--tests/rustdoc-gui/headings.goml8
-rw-r--r--tests/rustdoc-gui/help-page.goml6
-rw-r--r--tests/rustdoc-gui/highlight-colors.goml4
-rw-r--r--tests/rustdoc-gui/item-decl-colors.goml6
-rw-r--r--tests/rustdoc-gui/item-decl-comment-highlighting.goml4
-rw-r--r--tests/rustdoc-gui/javascript-disabled.goml14
-rw-r--r--tests/rustdoc-gui/jump-to-def-background.goml6
-rw-r--r--tests/rustdoc-gui/links-color.goml7
-rw-r--r--tests/rustdoc-gui/notable-trait.goml6
-rw-r--r--tests/rustdoc-gui/pocket-menu.goml7
-rw-r--r--tests/rustdoc-gui/run-on-hover.goml4
-rw-r--r--tests/rustdoc-gui/rust-logo.goml7
-rw-r--r--tests/rustdoc-gui/scrape-examples-color.goml7
-rw-r--r--tests/rustdoc-gui/scrape-examples-toggle.goml4
-rw-r--r--tests/rustdoc-gui/search-error.goml7
-rw-r--r--tests/rustdoc-gui/search-filter.goml4
-rw-r--r--tests/rustdoc-gui/search-form-elements.goml7
-rw-r--r--tests/rustdoc-gui/search-no-result.goml5
-rw-r--r--tests/rustdoc-gui/search-reexport.goml4
-rw-r--r--tests/rustdoc-gui/search-result-color.goml19
-rw-r--r--tests/rustdoc-gui/search-result-display.goml4
-rw-r--r--tests/rustdoc-gui/search-tab.goml5
-rw-r--r--tests/rustdoc-gui/settings.goml4
-rw-r--r--tests/rustdoc-gui/sidebar-links-color.goml4
-rw-r--r--tests/rustdoc-gui/sidebar-mobile.goml3
-rw-r--r--tests/rustdoc-gui/sidebar-source-code-display.goml4
-rw-r--r--tests/rustdoc-gui/sidebar-source-code.goml7
-rw-r--r--tests/rustdoc-gui/sidebar.goml11
-rw-r--r--tests/rustdoc-gui/source-code-page.goml4
-rw-r--r--tests/rustdoc-gui/stab-badge.goml3
-rw-r--r--tests/rustdoc-gui/target.goml4
-rw-r--r--tests/rustdoc-gui/theme-change.goml7
-rw-r--r--tests/rustdoc-gui/theme-in-history.goml10
-rw-r--r--tests/rustdoc-gui/toggle-docs.goml6
-rw-r--r--tests/rustdoc-gui/unsafe-fn.goml6
-rw-r--r--tests/rustdoc-gui/utils.goml11
-rw-r--r--tests/rustdoc-gui/warning-block.goml4
-rw-r--r--tests/ui/abi/extern/extern-pass-FiveU16s.rs30
-rw-r--r--tests/ui/abi/extern/extern-return-FiveU16s.rs26
-rw-r--r--tests/ui/asm/x86_64/goto.mirunsafeck.stderr23
-rw-r--r--tests/ui/asm/x86_64/goto.rs2
-rw-r--r--tests/ui/asm/x86_64/goto.stderr (renamed from tests/ui/asm/x86_64/goto.thirunsafeck.stderr)4
-rw-r--r--tests/ui/async-await/async-closures/captures.rs116
-rw-r--r--tests/ui/async-await/async-closures/captures.run.stdout14
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.rs10
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.stderr49
-rw-r--r--tests/ui/async-await/coroutine-desc.stderr28
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr4
-rw-r--r--tests/ui/closures/issue-1460.rs (renamed from tests/ui/issues/issue-1460.rs)0
-rw-r--r--tests/ui/closures/issue-1460.stderr (renamed from tests/ui/issues/issue-1460.stderr)0
-rw-r--r--tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr10
-rw-r--r--tests/ui/coherence/skip-reporting-if-references-err.current.stderr27
-rw-r--r--tests/ui/coherence/skip-reporting-if-references-err.next.stderr14
-rw-r--r--tests/ui/coherence/skip-reporting-if-references-err.rs19
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.rs18
-rw-r--r--tests/ui/const-generics/generic_const_exprs/opaque_type.stderr22
-rw-r--r--tests/ui/const-generics/opaque_types.rs13
-rw-r--r--tests/ui/const-generics/opaque_types.stderr125
-rw-r--r--tests/ui/const-generics/opaque_types2.rs17
-rw-r--r--tests/ui/const-generics/opaque_types2.stderr15
-rw-r--r--tests/ui/extern/issue-95829.stderr9
-rw-r--r--tests/ui/feature-gates/feature-gate-f128.e2015.stderr (renamed from tests/ui/feature-gates/feature-gate-f128.stderr)10
-rw-r--r--tests/ui/feature-gates/feature-gate-f128.e2018.stderr53
-rw-r--r--tests/ui/feature-gates/feature-gate-f128.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-f16.e2015.stderr (renamed from tests/ui/feature-gates/feature-gate-f16.stderr)10
-rw-r--r--tests/ui/feature-gates/feature-gate-f16.e2018.stderr53
-rw-r--r--tests/ui/feature-gates/feature-gate-f16.rs4
-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.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs11
-rw-r--r--tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr13
-rw-r--r--tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs14
-rw-r--r--tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr49
-rw-r--r--tests/ui/fn/fn-item-lifetime-bounds.rs37
-rw-r--r--tests/ui/fn/fn-item-type.stderr50
-rw-r--r--tests/ui/fn/issue-1451.rs (renamed from tests/ui/issues/issue-1451.rs)0
-rw-r--r--tests/ui/fn/issue-1900.rs (renamed from tests/ui/issues/issue-1900.rs)0
-rw-r--r--tests/ui/fn/issue-1900.stderr (renamed from tests/ui/issues/issue-1900.stderr)0
-rw-r--r--tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr34
-rw-r--r--tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr2
-rw-r--r--tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs4
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs28
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr26
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr25
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr19
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr26
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs20
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr54
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr67
-rw-r--r--tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs62
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-1.rs (renamed from tests/ui/higher-ranked/leak-check-in-selection.rs)0
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr23
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr23
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs18
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr35
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr48
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs39
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-4-hr-nested.rs29
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs (renamed from tests/ui/higher-ranked/trait-bounds/issue-30786.rs)20
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr27
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs116
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr27
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr22
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs32
-rw-r--r--tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr86
-rw-r--r--tests/ui/higher-ranked/trait-bounds/issue-30786.stderr51
-rw-r--r--tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs1
-rw-r--r--tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr19
-rw-r--r--tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.rs11
-rw-r--r--tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.stderr27
-rw-r--r--tests/ui/impl-trait/nested_impl_trait.rs4
-rw-r--r--tests/ui/impl-trait/nested_impl_trait.stderr8
-rw-r--r--tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr28
-rw-r--r--tests/ui/impl-trait/recursive-coroutine-boxed.rs6
-rw-r--r--tests/ui/implied-bounds/issue-100690.rs11
-rw-r--r--tests/ui/implied-bounds/issue-100690.stderr49
-rw-r--r--tests/ui/issues/issue-1476.rs3
-rw-r--r--tests/ui/issues/issue-1476.stderr9
-rw-r--r--tests/ui/issues/issue-1696.rs8
-rw-r--r--tests/ui/layout/ice-non-last-unsized-field-issue-121473.rs79
-rw-r--r--tests/ui/layout/ice-non-last-unsized-field-issue-121473.stderr106
-rw-r--r--tests/ui/lint/lint-strict-provenance-lossy-casts.stderr8
-rw-r--r--tests/ui/lint/non_local_definitions.rs89
-rw-r--r--tests/ui/lint/non_local_definitions.stderr279
-rw-r--r--tests/ui/loops/issue-1962.fixed (renamed from tests/ui/issues/issue-1962.fixed)0
-rw-r--r--tests/ui/loops/issue-1962.rs (renamed from tests/ui/issues/issue-1962.rs)0
-rw-r--r--tests/ui/loops/issue-1962.stderr (renamed from tests/ui/issues/issue-1962.stderr)0
-rw-r--r--tests/ui/loops/issue-1974.rs (renamed from tests/ui/issues/issue-1974.rs)0
-rw-r--r--tests/ui/match/postfix-match/match-after-as.rs7
-rw-r--r--tests/ui/match/postfix-match/match-after-as.stderr28
-rw-r--r--tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs16
-rw-r--r--tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr44
-rw-r--r--tests/ui/match/ref_pat_everywhere.rs18
-rw-r--r--tests/ui/methods/opaque_param_in_ufc.rs30
-rw-r--r--tests/ui/methods/opaque_param_in_ufc.stderr36
-rw-r--r--tests/ui/mir/const_eval_select_cycle.rs18
-rw-r--r--tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs14
-rw-r--r--tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr97
-rw-r--r--tests/ui/mismatched_types/issue-1362.rs (renamed from tests/ui/issues/issue-1362.rs)0
-rw-r--r--tests/ui/mismatched_types/issue-1362.stderr (renamed from tests/ui/issues/issue-1362.stderr)0
-rw-r--r--tests/ui/mismatched_types/issue-1448-2.rs (renamed from tests/ui/issues/issue-1448-2.rs)0
-rw-r--r--tests/ui/mismatched_types/issue-1448-2.stderr (renamed from tests/ui/issues/issue-1448-2.stderr)0
-rw-r--r--tests/ui/nll/match-cfg-fake-edges.rs97
-rw-r--r--tests/ui/nll/match-cfg-fake-edges.stderr158
-rw-r--r--tests/ui/nll/match-cfg-fake-edges2.rs21
-rw-r--r--tests/ui/nll/match-cfg-fake-edges2.stderr4
-rw-r--r--tests/ui/parser/fn-header-semantic-fail.rs5
-rw-r--r--tests/ui/parser/fn-header-semantic-fail.stderr68
-rw-r--r--tests/ui/parser/no-const-fn-in-extern-block.rs1
-rw-r--r--tests/ui/parser/no-const-fn-in-extern-block.stderr27
-rw-r--r--tests/ui/parser/unsafe-foreign-mod-2.stderr9
-rw-r--r--tests/ui/pattern/usefulness/unions.rs35
-rw-r--r--tests/ui/pattern/usefulness/unions.stderr34
-rw-r--r--tests/ui/privacy/generic_struct_field_projection.rs38
-rw-r--r--tests/ui/proc-macro/auxiliary/api/mod.rs2
-rw-r--r--tests/ui/proc-macro/bad-projection.rs1
-rw-r--r--tests/ui/proc-macro/bad-projection.stderr14
-rw-r--r--tests/ui/resolve/primitive-f16-f128-shadowed-mod.rs19
-rw-r--r--tests/ui/resolve/primitive-f16-f128-shadowed.rs3
-rw-r--r--tests/ui/sanitizer/cfi-closures.rs15
-rw-r--r--tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs42
-rw-r--r--tests/ui/self/arbitrary-self-opaque.rs12
-rw-r--r--tests/ui/self/arbitrary-self-opaque.stderr20
-rw-r--r--tests/ui/simd/intrinsic/ptr-cast.rs4
-rw-r--r--tests/ui/specialization/min_specialization/impl-on-opaque.rs31
-rw-r--r--tests/ui/specialization/min_specialization/impl-on-opaque2.rs28
-rw-r--r--tests/ui/specialization/min_specialization/impl-on-opaque2.stderr12
-rw-r--r--tests/ui/static/issue-1660.rs (renamed from tests/ui/issues/issue-1660.rs)0
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr17
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr14
-rw-r--r--tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs29
-rw-r--r--tests/ui/unpretty/hir-tree.rs10
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-1.rs44
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-1.stderr15
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-2.rs44
-rw-r--r--tests/ui/wf/wf-fn-def-check-sig-2.stderr15
-rw-r--r--triagebot.toml23
1170 files changed, 14434 insertions, 7397 deletions
diff --git a/Cargo.lock b/Cargo.lock
index d5c9a5e4d0d..bf31bf72d4c 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -593,7 +593,6 @@ dependencies = [
  "syn 2.0.55",
  "tempfile",
  "termize",
- "tester",
  "tokio",
  "toml 0.7.8",
  "ui_test 0.22.2",
@@ -5509,19 +5508,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "tester"
-version = "0.9.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "89e8bf7e0eb2dd7b4228cc1b6821fc5114cd6841ae59f652a85488c016091e5f"
-dependencies = [
- "cfg-if",
- "getopts",
- "libc",
- "num_cpus",
- "term",
-]
-
-[[package]]
 name = "thin-vec"
 version = "0.2.13"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/README.md b/README.md
index 6d6383351ca..3690a9c93c5 100644
--- a/README.md
+++ b/README.md
@@ -1,27 +1,36 @@
-# The Rust Programming Language
-
-[![Rust Community](https://img.shields.io/badge/Rust_Community%20-Join_us-brightgreen?style=plastic&logo=rust)](https://www.rust-lang.org/community)
+<div align="center">
+  <picture>
+    <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/rust-lang/www.rust-lang.org/master/static/images/rust-social-wide-dark.svg">
+    <source media="(prefers-color-scheme: light)" srcset="https://raw.githubusercontent.com/rust-lang/www.rust-lang.org/master/static/images/rust-social-wide-light.svg">
+    <img alt="The Rust Programming Language: A language empowering everyone to build reliable and efficient software"
+         src="https://raw.githubusercontent.com/rust-lang/www.rust-lang.org/master/static/images/rust-social-wide-light.svg"
+         width="50%">
+  </picture>
+
+[Website][Rust] | [Getting started] | [Learn] | [Documentation] | [Contributing]
+</div>
 
 This is the main source code repository for [Rust]. It contains the compiler,
 standard library, and documentation.
 
 [Rust]: https://www.rust-lang.org/
+[Getting Started]: https://www.rust-lang.org/learn/get-started
+[Learn]: https://www.rust-lang.org/learn
+[Documentation]: https://www.rust-lang.org/learn#learn-use
+[Contributing]: CONTRIBUTING.md
+
+## Why Rust?
 
-**Note: this README is for _users_ rather than _contributors_.**
-If you wish to _contribute_ to the compiler, you should read
-[CONTRIBUTING.md](CONTRIBUTING.md) instead.
+- **Performance:** Fast and memory-efficient, suitable for critical services, embedded devices, and easily integrate with other languages.
 
-<details>
-<summary>Table of Contents</summary>
+- **Reliability:** Our rich type system and ownership model ensure memory and thread safety, reducing bugs at compile-time.
 
-- [Quick Start](#quick-start)
-- [Installing from Source](#installing-from-source)
-- [Getting Help](#getting-help)
-- [Contributing](#contributing)
-- [License](#license)
-- [Trademark](#trademark)
+- **Productivity:** Comprehensive documentation, a compiler committed to providing great diagnostics, and advanced tooling including package manager and build tool ([Cargo]), auto-formatter ([rustfmt]), linter ([Clippy]) and editor support ([rust-analyzer]).
 
-</details>
+[Cargo]: https://github.com/rust-lang/cargo
+[rustfmt]: https://github.com/rust-lang/rustfmt
+[Clippy]: https://github.com/rust-lang/rust-clippy
+[rust-analyzer]: https://github.com/rust-lang/rust-analyzer
 
 ## Quick Start
 
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index aba94f4d817..e29ef591bcb 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1276,7 +1276,8 @@ impl Expr {
             ExprKind::While(..) => ExprPrecedence::While,
             ExprKind::ForLoop { .. } => ExprPrecedence::ForLoop,
             ExprKind::Loop(..) => ExprPrecedence::Loop,
-            ExprKind::Match(..) => ExprPrecedence::Match,
+            ExprKind::Match(_, _, MatchKind::Prefix) => ExprPrecedence::Match,
+            ExprKind::Match(_, _, MatchKind::Postfix) => ExprPrecedence::PostfixMatch,
             ExprKind::Closure(..) => ExprPrecedence::Closure,
             ExprKind::Block(..) => ExprPrecedence::Block,
             ExprKind::TryBlock(..) => ExprPrecedence::TryBlock,
@@ -2483,6 +2484,14 @@ pub enum CoroutineKind {
 }
 
 impl CoroutineKind {
+    pub fn span(self) -> Span {
+        match self {
+            CoroutineKind::Async { span, .. } => span,
+            CoroutineKind::Gen { span, .. } => span,
+            CoroutineKind::AsyncGen { span, .. } => span,
+        }
+    }
+
     pub fn is_async(self) -> bool {
         matches!(self, CoroutineKind::Async { .. })
     }
@@ -3341,7 +3350,7 @@ impl TryFrom<ItemKind> for ForeignItemKind {
 pub type ForeignItem = Item<ForeignItemKind>;
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_ast/src/ptr.rs b/compiler/rustc_ast/src/ptr.rs
index 0140fb752bf..e22a523dbc3 100644
--- a/compiler/rustc_ast/src/ptr.rs
+++ b/compiler/rustc_ast/src/ptr.rs
@@ -1,6 +1,6 @@
 //! The AST pointer.
 //!
-//! Provides `P<T>`, a frozen owned smart pointer.
+//! Provides [`P<T>`][struct@P], an owned smart pointer.
 //!
 //! # Motivations and benefits
 //!
@@ -8,18 +8,14 @@
 //!   passes (e.g., one may be able to bypass the borrow checker with a shared
 //!   `ExprKind::AddrOf` node taking a mutable borrow).
 //!
-//! * **Immutability**: `P<T>` disallows mutating its inner `T`, unlike `Box<T>`
-//!   (unless it contains an `Unsafe` interior, but that may be denied later).
-//!   This mainly prevents mistakes, but also enforces a kind of "purity".
-//!
 //! * **Efficiency**: folding can reuse allocation space for `P<T>` and `Vec<T>`,
 //!   the latter even when the input and output types differ (as it would be the
 //!   case with arenas or a GADT AST using type parameters to toggle features).
 //!
-//! * **Maintainability**: `P<T>` provides a fixed interface - `Deref`,
-//!   `and_then` and `map` - which can remain fully functional even if the
-//!   implementation changes (using a special thread-local heap, for example).
-//!   Moreover, a switch to, e.g., `P<'a, T>` would be easy and mostly automated.
+//! * **Maintainability**: `P<T>` provides an interface, which can remain fully
+//!   functional even if the implementation changes (using a special thread-local
+//!   heap, for example). Moreover, a switch to, e.g., `P<'a, T>` would be easy
+//!   and mostly automated.
 
 use std::fmt::{self, Debug, Display};
 use std::ops::{Deref, DerefMut};
@@ -29,6 +25,8 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 
 use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
 /// An owned smart pointer.
+///
+/// See the [module level documentation][crate::ptr] for details.
 pub struct P<T: ?Sized> {
     ptr: Box<T>,
 }
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index f49eb2f22c5..5060bbec421 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -1021,7 +1021,7 @@ where
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 239735456ad..f3249f3e5a8 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -768,7 +768,7 @@ impl DelimSpacing {
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_ast/src/util/parser.rs b/compiler/rustc_ast/src/util/parser.rs
index 13768c12017..373c0ebcc5c 100644
--- a/compiler/rustc_ast/src/util/parser.rs
+++ b/compiler/rustc_ast/src/util/parser.rs
@@ -281,6 +281,7 @@ pub enum ExprPrecedence {
     ForLoop,
     Loop,
     Match,
+    PostfixMatch,
     ConstBlock,
     Block,
     TryBlock,
@@ -334,7 +335,8 @@ impl ExprPrecedence {
             | ExprPrecedence::InlineAsm
             | ExprPrecedence::Mac
             | ExprPrecedence::FormatArgs
-            | ExprPrecedence::OffsetOf => PREC_POSTFIX,
+            | ExprPrecedence::OffsetOf
+            | ExprPrecedence::PostfixMatch => PREC_POSTFIX,
 
             // Never need parens
             ExprPrecedence::Array
@@ -390,7 +392,8 @@ pub fn contains_exterior_struct_lit(value: &ast::Expr) -> bool {
         | ast::ExprKind::Cast(x, _)
         | ast::ExprKind::Type(x, _)
         | ast::ExprKind::Field(x, _)
-        | ast::ExprKind::Index(x, _, _) => {
+        | ast::ExprKind::Index(x, _, _)
+        | ast::ExprKind::Match(x, _, ast::MatchKind::Postfix) => {
             // &X { y: 1 }, X { y: 1 }.y
             contains_exterior_struct_lit(x)
         }
diff --git a/compiler/rustc_ast_lowering/src/index.rs b/compiler/rustc_ast_lowering/src/index.rs
index a1164008d0d..1c34fd0afbb 100644
--- a/compiler/rustc_ast_lowering/src/index.rs
+++ b/compiler/rustc_ast_lowering/src/index.rs
@@ -3,7 +3,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::{LocalDefId, LocalDefIdMap};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::*;
-use rustc_index::{Idx, IndexVec};
+use rustc_index::IndexVec;
 use rustc_middle::span_bug;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::{Span, DUMMY_SP};
@@ -19,7 +19,7 @@ struct NodeCollector<'a, 'hir> {
     parenting: LocalDefIdMap<ItemLocalId>,
 
     /// The parent of this node
-    parent_node: hir::ItemLocalId,
+    parent_node: ItemLocalId,
 
     owner: OwnerId,
 }
@@ -31,17 +31,16 @@ pub(super) fn index_hir<'hir>(
     bodies: &SortedMap<ItemLocalId, &'hir Body<'hir>>,
     num_nodes: usize,
 ) -> (IndexVec<ItemLocalId, ParentedNode<'hir>>, LocalDefIdMap<ItemLocalId>) {
-    let zero_id = ItemLocalId::new(0);
-    let err_node = ParentedNode { parent: zero_id, node: Node::Err(item.span()) };
+    let err_node = ParentedNode { parent: ItemLocalId::ZERO, node: Node::Err(item.span()) };
     let mut nodes = IndexVec::from_elem_n(err_node, num_nodes);
     // This node's parent should never be accessed: the owner's parent is computed by the
     // hir_owner_parent query. Make it invalid (= ItemLocalId::MAX) to force an ICE whenever it is
     // used.
-    nodes[zero_id] = ParentedNode { parent: ItemLocalId::INVALID, node: item.into() };
+    nodes[ItemLocalId::ZERO] = ParentedNode { parent: ItemLocalId::INVALID, node: item.into() };
     let mut collector = NodeCollector {
         tcx,
         owner: item.def_id(),
-        parent_node: zero_id,
+        parent_node: ItemLocalId::ZERO,
         nodes,
         bodies,
         parenting: Default::default(),
@@ -112,7 +111,9 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
     }
 
     fn insert_nested(&mut self, item: LocalDefId) {
-        self.parenting.insert(item, self.parent_node);
+        if self.parent_node != ItemLocalId::ZERO {
+            self.parenting.insert(item, self.parent_node);
+        }
     }
 }
 
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index c9786328565..abfea6078f2 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -11,7 +11,7 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::{LocalDefId, CRATE_DEF_ID};
 use rustc_hir::PredicateOrigin;
-use rustc_index::{Idx, IndexSlice, IndexVec};
+use rustc_index::{IndexSlice, IndexVec};
 use rustc_middle::span_bug;
 use rustc_middle::ty::{ResolverAstLowering, TyCtxt};
 use rustc_span::edit_distance::find_best_match_for_name;
@@ -563,7 +563,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
                         let kind =
                             this.lower_use_tree(use_tree, &prefix, id, vis_span, &mut ident, attrs);
                         if let Some(attrs) = attrs {
-                            this.attrs.insert(hir::ItemLocalId::new(0), attrs);
+                            this.attrs.insert(hir::ItemLocalId::ZERO, attrs);
                         }
 
                         let item = hir::Item {
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 833b0e9b567..8cf347bfa96 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -157,7 +157,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             attrs: SortedMap::default(),
             children: Vec::default(),
             current_hir_id_owner: hir::CRATE_OWNER_ID,
-            item_local_id_counter: hir::ItemLocalId::new(0),
+            item_local_id_counter: hir::ItemLocalId::ZERO,
             node_id_to_local_id: Default::default(),
             trait_map: Default::default(),
 
@@ -583,7 +583,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
         // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s.
 
         // Always allocate the first `HirId` for the owner itself.
-        let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::new(0));
+        let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO);
         debug_assert_eq!(_old, None);
 
         let item = f(self);
@@ -677,7 +677,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 v.insert(local_id);
                 self.item_local_id_counter.increment_by(1);
 
-                assert_ne!(local_id, hir::ItemLocalId::new(0));
+                assert_ne!(local_id, hir::ItemLocalId::ZERO);
                 if let Some(def_id) = self.opt_local_def_id(ast_node_id) {
                     self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id)));
                 }
@@ -696,7 +696,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn next_id(&mut self) -> hir::HirId {
         let owner = self.current_hir_id_owner;
         let local_id = self.item_local_id_counter;
-        assert_ne!(local_id, hir::ItemLocalId::new(0));
+        assert_ne!(local_id, hir::ItemLocalId::ZERO);
         self.item_local_id_counter.increment_by(1);
         hir::HirId { owner, local_id }
     }
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl
index 28a13d275a5..ac3799e7a05 100644
--- a/compiler/rustc_ast_passes/messages.ftl
+++ b/compiler/rustc_ast_passes/messages.ftl
@@ -68,7 +68,7 @@ ast_passes_extern_block_suggestion = if you meant to declare an externally defin
 
 ast_passes_extern_fn_qualifiers = functions in `extern` blocks cannot have qualifiers
     .label = in this `extern` block
-    .suggestion = remove the qualifiers
+    .suggestion = remove this qualifier
 
 ast_passes_extern_item_ascii = items in `extern` blocks cannot use non-ascii identifiers
     .label = in this `extern` block
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 80c62d3fecf..093a985495c 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -514,13 +514,32 @@ impl<'a> AstValidator<'a> {
     }
 
     /// An `fn` in `extern { ... }` cannot have qualifiers, e.g. `async fn`.
-    fn check_foreign_fn_headerless(&self, ident: Ident, span: Span, header: FnHeader) {
-        if header.has_qualifiers() {
+    fn check_foreign_fn_headerless(
+        &self,
+        // Deconstruct to ensure exhaustiveness
+        FnHeader { unsafety, coroutine_kind, constness, ext }: FnHeader,
+    ) {
+        let report_err = |span| {
             self.dcx().emit_err(errors::FnQualifierInExtern {
-                span: ident.span,
+                span: span,
                 block: self.current_extern_span(),
-                sugg_span: span.until(ident.span.shrink_to_lo()),
             });
+        };
+        match unsafety {
+            Unsafe::Yes(span) => report_err(span),
+            Unsafe::No => (),
+        }
+        match coroutine_kind {
+            Some(knd) => report_err(knd.span()),
+            None => (),
+        }
+        match constness {
+            Const::Yes(span) => report_err(span),
+            Const::No => (),
+        }
+        match ext {
+            Extern::None => (),
+            Extern::Implicit(span) | Extern::Explicit(_, span) => report_err(span),
         }
     }
 
@@ -1145,7 +1164,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             ForeignItemKind::Fn(box Fn { defaultness, sig, body, .. }) => {
                 self.check_defaultness(fi.span, *defaultness);
                 self.check_foreign_fn_bodyless(fi.ident, body.as_deref());
-                self.check_foreign_fn_headerless(fi.ident, fi.span, sig.header);
+                self.check_foreign_fn_headerless(sig.header);
                 self.check_foreign_item_ascii_only(fi.ident);
             }
             ForeignItemKind::TyAlias(box TyAlias {
diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs
index 9e8c1d7f5fd..8ae9f7d3966 100644
--- a/compiler/rustc_ast_passes/src/errors.rs
+++ b/compiler/rustc_ast_passes/src/errors.rs
@@ -270,11 +270,10 @@ pub struct FnBodyInExtern {
 #[diag(ast_passes_extern_fn_qualifiers)]
 pub struct FnQualifierInExtern {
     #[primary_span]
+    #[suggestion(code = "", applicability = "maybe-incorrect")]
     pub span: Span,
     #[label]
     pub block: Span,
-    #[suggestion(code = "fn ", applicability = "maybe-incorrect", style = "verbose")]
-    pub sugg_span: Span,
 }
 
 #[derive(Diagnostic)]
diff --git a/compiler/rustc_borrowck/src/borrow_set.rs b/compiler/rustc_borrowck/src/borrow_set.rs
index 6a683d129de..a38dd286be5 100644
--- a/compiler/rustc_borrowck/src/borrow_set.rs
+++ b/compiler/rustc_borrowck/src/borrow_set.rs
@@ -159,7 +159,7 @@ impl<'tcx> BorrowSet<'tcx> {
     }
 
     pub(crate) fn indices(&self) -> impl Iterator<Item = BorrowIndex> {
-        BorrowIndex::from_usize(0)..BorrowIndex::from_usize(self.len())
+        BorrowIndex::ZERO..BorrowIndex::from_usize(self.len())
     }
 
     pub(crate) fn iter_enumerated(&self) -> impl Iterator<Item = (BorrowIndex, &BorrowData<'tcx>)> {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 6405364c30c..71b54a761a2 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -2261,7 +2261,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                         }
                     }
 
-                    CastKind::PointerExposeAddress => {
+                    CastKind::PointerExposeProvenance => {
                         let ty_from = op.ty(body, tcx);
                         let cast_ty_from = CastTy::from_ty(ty_from);
                         let cast_ty_to = CastTy::from_ty(*ty);
@@ -2271,7 +2271,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 span_mirbug!(
                                     self,
                                     rvalue,
-                                    "Invalid PointerExposeAddress cast {:?} -> {:?}",
+                                    "Invalid PointerExposeProvenance cast {:?} -> {:?}",
                                     ty_from,
                                     ty
                                 )
diff --git a/compiler/rustc_codegen_cranelift/.cirrus.yml b/compiler/rustc_codegen_cranelift/.cirrus.yml
index aa1a2bad2cf..97c2f45d31e 100644
--- a/compiler/rustc_codegen_cranelift/.cirrus.yml
+++ b/compiler/rustc_codegen_cranelift/.cirrus.yml
@@ -13,4 +13,7 @@ task:
     - ./y.sh prepare
   test_script:
     - . $HOME/.cargo/env
+    # Disabling incr comp reduces cache size and incr comp doesn't save as much
+    # on CI anyway.
+    - export CARGO_BUILD_INCREMENTAL=false
     - ./y.sh test
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
index e6bf944f552..a745f2801cc 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/abi-cafe.yml
@@ -3,6 +3,8 @@ name: Abi-cafe
 on:
   - push
 
+permissions: {}
+
 jobs:
   abi_cafe:
     runs-on: ${{ matrix.os }}
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
index 526871d0c05..913a5c5a850 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/main.yml
@@ -4,6 +4,20 @@ on:
   - push
   - pull_request
 
+defaults:
+  run:
+    shell: bash
+
+permissions: {}
+
+env:
+  # Disabling incr comp reduces cache size and incr comp doesn't save as much
+  # on CI anyway.
+  CARGO_BUILD_INCREMENTAL: false
+  # Rust's CI denies warnings. Deny them here too to ensure subtree syncs don't
+  # fail because of warnings.
+  RUSTFLAGS: "-Dwarnings"
+
 jobs:
   rustfmt:
     runs-on: ubuntu-latest
@@ -23,15 +37,15 @@ jobs:
         cargo fmt --check
         rustfmt --check build_system/main.rs
         rustfmt --check example/*
+        rustfmt --check scripts/*.rs
 
 
   test:
     runs-on: ${{ matrix.os }}
     timeout-minutes: 60
 
-    defaults:
-      run:
-        shell: bash
+    env:
+      CG_CLIF_EXPENSIVE_CHECKS: 1
 
     strategy:
       fail-fast: false
@@ -47,15 +61,19 @@ jobs:
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: x86_64-pc-windows-gnu
+            apt_deps: gcc-mingw-w64-x86-64 wine-stable
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: aarch64-unknown-linux-gnu
+            apt_deps: gcc-aarch64-linux-gnu qemu-user
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: s390x-unknown-linux-gnu
+            apt_deps: gcc-s390x-linux-gnu qemu-user
           - os: ubuntu-latest
             env:
               TARGET_TRIPLE: riscv64gc-unknown-linux-gnu
+            apt_deps: gcc-riscv64-linux-gnu qemu-user
           - os: windows-latest
             env:
               TARGET_TRIPLE: x86_64-pc-windows-msvc
@@ -80,29 +98,11 @@ jobs:
       if: matrix.os == 'windows-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
       run: rustup set default-host x86_64-pc-windows-gnu
 
-    - name: Install MinGW toolchain and wine
-      if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'x86_64-pc-windows-gnu'
-      run: |
-        sudo apt-get update
-        sudo apt-get install -y gcc-mingw-w64-x86-64 wine-stable
-
-    - name: Install AArch64 toolchain and qemu
-      if: matrix.os == 'ubuntu-latest' && matrix.env.TARGET_TRIPLE == 'aarch64-unknown-linux-gnu'
-      run: |
-        sudo apt-get update
-        sudo apt-get install -y gcc-aarch64-linux-gnu qemu-user
-
-    - name: Install s390x toolchain and qemu
-      if: matrix.env.TARGET_TRIPLE == 's390x-unknown-linux-gnu'
+    - name: Install toolchain and emulator
+      if: matrix.apt_deps != null
       run: |
         sudo apt-get update
-        sudo apt-get install -y gcc-s390x-linux-gnu qemu-user
-
-    - name: Install riscv64gc toolchain and qemu
-      if: matrix.env.TARGET_TRIPLE == 'riscv64gc-unknown-linux-gnu'
-      run: |
-        sudo apt-get update
-        sudo apt-get install -y gcc-riscv64-linux-gnu qemu-user
+        sudo apt-get install -y ${{ matrix.apt_deps }}
 
     - name: Prepare dependencies
       run: ./y.sh prepare
@@ -142,10 +142,6 @@ jobs:
     runs-on: ubuntu-latest
     timeout-minutes: 60
 
-    defaults:
-      run:
-        shell: bash
-
     steps:
     - uses: actions/checkout@v4
 
@@ -168,10 +164,6 @@ jobs:
     runs-on: ubuntu-latest
     timeout-minutes: 60
 
-    defaults:
-      run:
-        shell: bash
-
     steps:
     - uses: actions/checkout@v4
 
@@ -193,20 +185,16 @@ jobs:
       run: ./y.sh prepare
 
     - name: Build
-      run: CI_OPT=1 ./y.sh build --sysroot none
+      run: ./y.sh build --sysroot none
 
     - name: Benchmark
-      run: CI_OPT=1 ./y.sh bench
+      run: ./y.sh bench
 
 
   dist:
     runs-on: ${{ matrix.os }}
     timeout-minutes: 60
 
-    defaults:
-      run:
-        shell: bash
-
     strategy:
       fail-fast: false
       matrix:
@@ -252,10 +240,10 @@ jobs:
       run: ./y.sh prepare
 
     - name: Build backend
-      run: CI_OPT=1 ./y.sh build --sysroot none
+      run: ./y.sh build --sysroot none
 
     - name: Build sysroot
-      run: CI_OPT=1 ./y.sh build
+      run: ./y.sh build
 
     - name: Package prebuilt cg_clif
       run: tar cvfJ cg_clif.tar.xz dist
diff --git a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
index 930d025b73e..75ea94ee797 100644
--- a/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
+++ b/compiler/rustc_codegen_cranelift/.github/workflows/rustc.yml
@@ -3,6 +3,8 @@ name: Various rustc tests
 on:
   - push
 
+permissions: {}
+
 jobs:
   bootstrap_rustc:
     runs-on: ubuntu-latest
diff --git a/compiler/rustc_codegen_cranelift/Readme.md b/compiler/rustc_codegen_cranelift/Readme.md
index a297b22326f..00ea15cb38c 100644
--- a/compiler/rustc_codegen_cranelift/Readme.md
+++ b/compiler/rustc_codegen_cranelift/Readme.md
@@ -101,27 +101,7 @@ For additional ways to use rustc_codegen_cranelift like the JIT mode see [usage.
 
 ## Building and testing with changes in rustc code
 
-This is useful when changing code in `rustc_codegen_cranelift` as part of changing [main Rust repository](https://github.com/rust-lang/rust/).
-This can happen, for example, when you are implementing a new compiler intrinsic.
-
-Instruction below uses `$RustCheckoutDir` as substitute for any folder where you cloned Rust repository.
-
-You need to do this steps to successfully compile and use the cranelift backend with your changes in rustc code:
-
-1. `cd $RustCheckoutDir`
-2. Run `python x.py setup` and choose option for compiler (`b`).
-3. Build compiler and necessary tools: `python x.py build --stage=2 compiler library/std src/tools/rustdoc src/tools/rustfmt`
-   * (Optional) You can also build cargo by adding `src/tools/cargo` to previous command.
-4. Copy cargo from a nightly toolchain: `cp $(rustup +nightly which cargo) ./build/host/stage2/bin/cargo`. Note that you would need to do this every time you rebuilt `rust` repository.
-5. Link your new `rustc` to toolchain: `rustup toolchain link stage2 ./build/host/stage2/`.
-6. (Windows only) compile the build system: `rustc +stage2 -O build_system/main.rs -o y.exe`.
-7. You need to prefix every `./y.sh` (or `y` if you built `build_system/main.rs` as `y`) command by `rustup run stage2` to make cg_clif use your local changes in rustc.
-  * `rustup run stage2 ./y.sh prepare`
-  * `rustup run stage2 ./y.sh build`
-  * (Optional) run tests: `rustup run stage2 ./y.sh test`
-8. Now you can use your cg_clif build to compile other Rust programs, e.g. you can open any Rust crate and run commands like `$RustCheckoutDir/compiler/rustc_codegen_cranelift/dist/cargo-clif build --release`.
-
-You can also set `rust-analyzer.rustc.source` to your rust workspace to get rust-analyzer to understand your changes.
+See [rustc_testing.md](docs/rustc_testing.md).
 
 ## Not yet supported
 
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
index d90111adf77..129713e574a 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_backend.rs
@@ -1,9 +1,10 @@
+use std::env;
 use std::path::PathBuf;
 
 use crate::path::{Dirs, RelPath};
 use crate::rustc_info::get_file_name;
 use crate::shared_utils::{rustflags_from_env, rustflags_to_cmd_env};
-use crate::utils::{is_ci, is_ci_opt, maybe_incremental, CargoProject, Compiler, LogGroup};
+use crate::utils::{CargoProject, Compiler, LogGroup};
 
 pub(crate) static CG_CLIF: CargoProject = CargoProject::new(&RelPath::SOURCE, "cg_clif");
 
@@ -16,20 +17,15 @@ pub(crate) fn build_backend(
     let _group = LogGroup::guard("Build backend");
 
     let mut cmd = CG_CLIF.build(&bootstrap_host_compiler, dirs);
-    maybe_incremental(&mut cmd);
 
     let mut rustflags = rustflags_from_env("RUSTFLAGS");
 
     rustflags.push("-Zallow-features=rustc_private".to_owned());
 
-    if is_ci() {
-        // Deny warnings on CI
-        rustflags.push("-Dwarnings".to_owned());
-
-        if !is_ci_opt() {
-            cmd.env("CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS", "true");
-            cmd.env("CARGO_PROFILE_RELEASE_OVERFLOW_CHECKS", "true");
-        }
+    if env::var("CG_CLIF_EXPENSIVE_CHECKS").is_ok() {
+        // Enabling debug assertions implicitly enables the clif ir verifier
+        cmd.env("CARGO_PROFILE_RELEASE_DEBUG_ASSERTIONS", "true");
+        cmd.env("CARGO_PROFILE_RELEASE_OVERFLOW_CHECKS", "true");
     }
 
     if use_unstable_features {
diff --git a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
index 1ed896c6bf0..10c3f9cfa2c 100644
--- a/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/build_sysroot.rs
@@ -6,8 +6,7 @@ use std::process::Command;
 use crate::path::{Dirs, RelPath};
 use crate::rustc_info::get_file_name;
 use crate::utils::{
-    maybe_incremental, remove_dir_if_exists, spawn_and_wait, try_hard_link, CargoProject, Compiler,
-    LogGroup,
+    remove_dir_if_exists, spawn_and_wait, try_hard_link, CargoProject, Compiler, LogGroup,
 };
 use crate::{config, CodegenBackend, SysrootKind};
 
@@ -270,7 +269,6 @@ fn build_clif_sysroot_for_triple(
     }
     compiler.rustflags.extend(rustflags);
     let mut build_cmd = STANDARD_LIBRARY.build(&compiler, dirs);
-    maybe_incremental(&mut build_cmd);
     if channel == "release" {
         build_cmd.arg("--release");
     }
diff --git a/compiler/rustc_codegen_cranelift/build_system/main.rs b/compiler/rustc_codegen_cranelift/build_system/main.rs
index e8cf486e966..cdd2bae03f8 100644
--- a/compiler/rustc_codegen_cranelift/build_system/main.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/main.rs
@@ -6,7 +6,7 @@ use std::env;
 use std::path::PathBuf;
 use std::process;
 
-use self::utils::{is_ci, is_ci_opt, Compiler};
+use self::utils::Compiler;
 
 mod abi_cafe;
 mod bench;
@@ -60,14 +60,9 @@ fn main() {
     }
     env::set_var("CG_CLIF_DISABLE_INCR_CACHE", "1");
 
-    if is_ci() {
-        // Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
-        env::set_var("CARGO_BUILD_INCREMENTAL", "false");
-
-        if !is_ci_opt() {
-            // Enable the Cranelift verifier
-            env::set_var("CG_CLIF_ENABLE_VERIFIER", "1");
-        }
+    // Force incr comp even in release mode unless in CI or incremental builds are explicitly disabled
+    if env::var_os("CARGO_BUILD_INCREMENTAL").is_none() {
+        env::set_var("CARGO_BUILD_INCREMENTAL", "true");
     }
 
     let mut args = env::args().skip(1);
diff --git a/compiler/rustc_codegen_cranelift/build_system/prepare.rs b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
index 3677d0a7d36..5525a5f63e9 100644
--- a/compiler/rustc_codegen_cranelift/build_system/prepare.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/prepare.rs
@@ -15,7 +15,6 @@ pub(crate) fn prepare(dirs: &Dirs) {
     RelPath::DOWNLOAD.ensure_exists(dirs);
     crate::tests::RAND_REPO.fetch(dirs);
     crate::tests::REGEX_REPO.fetch(dirs);
-    crate::tests::PORTABLE_SIMD_REPO.fetch(dirs);
 }
 
 pub(crate) fn prepare_stdlib(dirs: &Dirs, rustc: &Path) {
diff --git a/compiler/rustc_codegen_cranelift/build_system/tests.rs b/compiler/rustc_codegen_cranelift/build_system/tests.rs
index 1c3e615c7ab..9efb6ed715c 100644
--- a/compiler/rustc_codegen_cranelift/build_system/tests.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/tests.rs
@@ -130,16 +130,10 @@ pub(crate) static REGEX_REPO: GitRepo = GitRepo::github(
 
 pub(crate) static REGEX: CargoProject = CargoProject::new(&REGEX_REPO.source_dir(), "regex_target");
 
-pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github(
-    "rust-lang",
-    "portable-simd",
-    "5794c837bc605c4cd9dbb884285976dfdb293cce",
-    "a64d8fdd0ed0d9c4",
-    "portable-simd",
-);
+pub(crate) static PORTABLE_SIMD_SRC: RelPath = RelPath::BUILD.join("coretests");
 
 pub(crate) static PORTABLE_SIMD: CargoProject =
-    CargoProject::new(&PORTABLE_SIMD_REPO.source_dir(), "portable-simd_target");
+    CargoProject::new(&PORTABLE_SIMD_SRC, "portable-simd_target");
 
 static LIBCORE_TESTS_SRC: RelPath = RelPath::BUILD.join("coretests");
 
@@ -221,7 +215,12 @@ const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[
         }
     }),
     TestCase::custom("test.portable-simd", &|runner| {
-        PORTABLE_SIMD_REPO.patch(&runner.dirs);
+        apply_patches(
+            &runner.dirs,
+            "portable-simd",
+            &runner.stdlib_source.join("library/portable-simd"),
+            &PORTABLE_SIMD_SRC.to_path(&runner.dirs),
+        );
 
         PORTABLE_SIMD.clean(&runner.dirs);
 
diff --git a/compiler/rustc_codegen_cranelift/build_system/utils.rs b/compiler/rustc_codegen_cranelift/build_system/utils.rs
index 149f1618f5c..9f95122b341 100644
--- a/compiler/rustc_codegen_cranelift/build_system/utils.rs
+++ b/compiler/rustc_codegen_cranelift/build_system/utils.rs
@@ -254,14 +254,6 @@ pub(crate) fn copy_dir_recursively(from: &Path, to: &Path) {
     }
 }
 
-pub(crate) fn is_ci() -> bool {
-    env::var("CI").is_ok()
-}
-
-pub(crate) fn is_ci_opt() -> bool {
-    env::var("CI_OPT").is_ok()
-}
-
 static IN_GROUP: AtomicBool = AtomicBool::new(false);
 pub(crate) struct LogGroup {
     is_gha: bool,
@@ -288,13 +280,3 @@ impl Drop for LogGroup {
         IN_GROUP.store(false, Ordering::SeqCst);
     }
 }
-
-pub(crate) fn maybe_incremental(cmd: &mut Command) {
-    if is_ci() || std::env::var("CARGO_BUILD_INCREMENTAL").map_or(false, |val| val == "false") {
-        // Disabling incr comp reduces cache size and incr comp doesn't save as much on CI anyway
-        cmd.env("CARGO_BUILD_INCREMENTAL", "false");
-    } else {
-        // Force incr comp even in release mode unless in CI or incremental builds are explicitly disabled
-        cmd.env("CARGO_BUILD_INCREMENTAL", "true");
-    }
-}
diff --git a/compiler/rustc_codegen_cranelift/docs/rustc_testing.md b/compiler/rustc_codegen_cranelift/docs/rustc_testing.md
new file mode 100644
index 00000000000..88c55557231
--- /dev/null
+++ b/compiler/rustc_codegen_cranelift/docs/rustc_testing.md
@@ -0,0 +1,23 @@
+# Building and testing with changes in rustc code
+
+This is useful when changing code in `rustc_codegen_cranelift` as part of changing [main Rust repository](https://github.com/rust-lang/rust/).
+This can happen, for example, when you are implementing a new compiler intrinsic.
+
+Instruction below uses `$RustCheckoutDir` as substitute for any folder where you cloned Rust repository.
+
+You need to do this steps to successfully compile and use the cranelift backend with your changes in rustc code:
+
+1. `cd $RustCheckoutDir`
+2. Run `python x.py setup` and choose option for compiler (`b`).
+3. Build compiler and necessary tools: `python x.py build --stage=2 compiler library/std src/tools/rustdoc src/tools/rustfmt`
+   * (Optional) You can also build cargo by adding `src/tools/cargo` to previous command.
+4. Copy cargo from a nightly toolchain: `cp $(rustup +nightly which cargo) ./build/host/stage2/bin/cargo`. Note that you would need to do this every time you rebuilt `rust` repository.
+5. Link your new `rustc` to toolchain: `rustup toolchain link stage2 ./build/host/stage2/`.
+6. (Windows only) compile the build system: `rustc +stage2 -O build_system/main.rs -o y.exe`.
+7. You need to prefix every `./y.sh` (or `y` if you built `build_system/main.rs` as `y`) command by `rustup run stage2` to make cg_clif use your local changes in rustc.
+  * `rustup run stage2 ./y.sh prepare`
+  * `rustup run stage2 ./y.sh build`
+  * (Optional) run tests: `rustup run stage2 ./y.sh test`
+8. Now you can use your cg_clif build to compile other Rust programs, e.g. you can open any Rust crate and run commands like `$RustCheckoutDir/compiler/rustc_codegen_cranelift/dist/cargo-clif build --release`.
+
+You can also set `rust-analyzer.rustc.source` to your rust workspace to get rust-analyzer to understand your changes.
diff --git a/compiler/rustc_codegen_cranelift/example/mini_core.rs b/compiler/rustc_codegen_cranelift/example/mini_core.rs
index 1cee5131907..e45c16ee280 100644
--- a/compiler/rustc_codegen_cranelift/example/mini_core.rs
+++ b/compiler/rustc_codegen_cranelift/example/mini_core.rs
@@ -90,8 +90,9 @@ unsafe impl Sync for i16 {}
 unsafe impl Sync for i32 {}
 unsafe impl Sync for isize {}
 unsafe impl Sync for char {}
+unsafe impl Sync for f32 {}
 unsafe impl<'a, T: ?Sized> Sync for &'a T {}
-unsafe impl Sync for [u8; 16] {}
+unsafe impl<T: Sync, const N: usize> Sync for [T; N] {}
 
 #[lang = "freeze"]
 unsafe auto trait Freeze {}
@@ -467,7 +468,6 @@ pub fn panic(_msg: &'static str) -> ! {
 
 macro_rules! panic_const {
     ($($lang:ident = $message:expr,)+) => {
-        #[cfg(not(bootstrap))]
         pub mod panic_const {
             use super::*;
 
diff --git a/compiler/rustc_codegen_cranelift/rust-toolchain b/compiler/rustc_codegen_cranelift/rust-toolchain
index 612fc61ec27..09e436b3eed 100644
--- a/compiler/rustc_codegen_cranelift/rust-toolchain
+++ b/compiler/rustc_codegen_cranelift/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-03-28"
+channel = "nightly-2024-04-05"
 components = ["rust-src", "rustc-dev", "llvm-tools"]
diff --git a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
index 03912b18ea5..0252d5b3340 100755
--- a/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
+++ b/compiler/rustc_codegen_cranelift/scripts/filter_profile.rs
@@ -1,5 +1,5 @@
 #!/usr/bin/env bash
-#![forbid(unsafe_code)]/* This line is ignored by bash
+#![rustfmt::skip]/* This line is ignored by bash
 # This block is ignored by rustc
 pushd $(dirname "$0")/../
 RUSTC="$(pwd)/dist/rustc-clif"
@@ -26,11 +26,8 @@ fn main() -> Result<(), Box<dyn std::error::Error>> {
     }
     let profile = std::fs::read_to_string(profile_name)
         .map_err(|err| format!("Failed to read profile {}", err))?;
-    let mut output = std::fs::OpenOptions::new()
-        .create(true)
-        .write(true)
-        .truncate(true)
-        .open(output_name)?;
+    let mut output =
+        std::fs::OpenOptions::new().create(true).write(true).truncate(true).open(output_name)?;
 
     for line in profile.lines() {
         let mut stack = &line[..line.rfind(" ").unwrap()];
diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index 249c16898ce..0aa2bae8f78 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -649,7 +649,7 @@ fn codegen_stmt<'tcx>(
                     | CastKind::IntToFloat
                     | CastKind::FnPtrToPtr
                     | CastKind::PtrToPtr
-                    | CastKind::PointerExposeAddress
+                    | CastKind::PointerExposeProvenance
                     | CastKind::PointerWithExposedProvenance,
                     ref operand,
                     to_ty,
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
index 1615dc5de69..8df83c706a1 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/llvm_x86.rs
@@ -1393,7 +1393,7 @@ fn llvm_add_sub<'tcx>(
 
     // c + carry -> c + first intermediate carry or borrow respectively
     let int0 = crate::num::codegen_checked_int_binop(fx, bin_op, a, b);
-    let c = int0.value_field(fx, FieldIdx::new(0));
+    let c = int0.value_field(fx, FieldIdx::ZERO);
     let cb0 = int0.value_field(fx, FieldIdx::new(1)).load_scalar(fx);
 
     // c + carry -> c + second intermediate carry or borrow respectively
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
index 783ad5d1dd1..67f9d831062 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/simd.rs
@@ -965,7 +965,7 @@ pub(super) fn codegen_simd_intrinsic_call<'tcx>(
             });
         }
 
-        sym::simd_expose_addr | sym::simd_with_exposed_provenance | sym::simd_cast_ptr => {
+        sym::simd_expose_provenance | sym::simd_with_exposed_provenance | sym::simd_cast_ptr => {
             intrinsic_args!(fx, args => (arg); intrinsic);
             ret.write_cvalue_transmute(fx, arg);
         }
diff --git a/compiler/rustc_codegen_cranelift/src/num.rs b/compiler/rustc_codegen_cranelift/src/num.rs
index 796182418ad..714858084ec 100644
--- a/compiler/rustc_codegen_cranelift/src/num.rs
+++ b/compiler/rustc_codegen_cranelift/src/num.rs
@@ -130,7 +130,7 @@ pub(crate) fn codegen_int_binop<'tcx>(
     in_lhs: CValue<'tcx>,
     in_rhs: CValue<'tcx>,
 ) -> CValue<'tcx> {
-    if bin_op != BinOp::Shl && bin_op != BinOp::Shr {
+    if !matches!(bin_op, BinOp::Shl | BinOp::ShlUnchecked | BinOp::Shr | BinOp::ShrUnchecked) {
         assert_eq!(
             in_lhs.layout().ty,
             in_rhs.layout().ty,
diff --git a/compiler/rustc_codegen_cranelift/src/vtable.rs b/compiler/rustc_codegen_cranelift/src/vtable.rs
index 86ebf37d105..04e24320f91 100644
--- a/compiler/rustc_codegen_cranelift/src/vtable.rs
+++ b/compiler/rustc_codegen_cranelift/src/vtable.rs
@@ -61,7 +61,7 @@ pub(crate) fn get_ptr_and_method_ref<'tcx>(
             if ty.is_dyn_star() {
                 let inner_layout = fx.layout_of(arg.layout().ty.builtin_deref(true).unwrap().ty);
                 let dyn_star = CPlace::for_ptr(Pointer::new(arg.load_scalar(fx)), inner_layout);
-                let ptr = dyn_star.place_field(fx, FieldIdx::new(0)).to_ptr();
+                let ptr = dyn_star.place_field(fx, FieldIdx::ZERO).to_ptr();
                 let vtable =
                     dyn_star.place_field(fx, FieldIdx::new(1)).to_cvalue(fx).load_scalar(fx);
                 break 'block (ptr, vtable);
diff --git a/compiler/rustc_codegen_gcc/Cargo.lock b/compiler/rustc_codegen_gcc/Cargo.lock
index ab2c7ca8a47..3ecb0ef6b4d 100644
--- a/compiler/rustc_codegen_gcc/Cargo.lock
+++ b/compiler/rustc_codegen_gcc/Cargo.lock
@@ -79,16 +79,18 @@ dependencies = [
 
 [[package]]
 name = "gccjit"
-version = "1.0.0"
-source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "ecaa4c3da2d74c1a991b4faff75d49ab1d0522d9a99d8e2614b3b04d226417ce"
 dependencies = [
  "gccjit_sys",
 ]
 
 [[package]]
 name = "gccjit_sys"
-version = "0.0.1"
-source = "git+https://github.com/antoyo/gccjit.rs#9f8f67edc006d543b17529a001803ffece48349e"
+version = "0.1.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "406a66fba005f1a02661f2f9443e5693dd3a667b7c58e70aa4ccc4c8b50b4758"
 dependencies = [
  "libc",
 ]
diff --git a/compiler/rustc_codegen_gcc/Cargo.toml b/compiler/rustc_codegen_gcc/Cargo.toml
index 100c10ef1d7..c5aa2eed1e0 100644
--- a/compiler/rustc_codegen_gcc/Cargo.toml
+++ b/compiler/rustc_codegen_gcc/Cargo.toml
@@ -22,7 +22,7 @@ master = ["gccjit/master"]
 default = ["master"]
 
 [dependencies]
-gccjit = { git = "https://github.com/antoyo/gccjit.rs" }
+gccjit = "2.0"
 
 # Local copy.
 #gccjit = { path = "../gccjit.rs" }
diff --git a/compiler/rustc_codegen_llvm/src/abi.rs b/compiler/rustc_codegen_llvm/src/abi.rs
index e5f5146fac8..d2828669d43 100644
--- a/compiler/rustc_codegen_llvm/src/abi.rs
+++ b/compiler/rustc_codegen_llvm/src/abi.rs
@@ -16,13 +16,15 @@ pub use rustc_middle::ty::layout::{FAT_PTR_ADDR, FAT_PTR_EXTRA};
 use rustc_middle::ty::Ty;
 use rustc_session::config;
 pub use rustc_target::abi::call::*;
-use rustc_target::abi::{self, HasDataLayout, Int};
+use rustc_target::abi::{self, HasDataLayout, Int, Size};
 pub use rustc_target::spec::abi::Abi;
 use rustc_target::spec::SanitizerSet;
 
 use libc::c_uint;
 use smallvec::SmallVec;
 
+use std::cmp;
+
 pub trait ArgAttributesExt {
     fn apply_attrs_to_llfn(&self, idx: AttributePlace, cx: &CodegenCx<'_, '_>, llfn: &Value);
     fn apply_attrs_to_callsite(
@@ -130,42 +132,36 @@ impl LlvmType for Reg {
 impl LlvmType for CastTarget {
     fn llvm_type<'ll>(&self, cx: &CodegenCx<'ll, '_>) -> &'ll Type {
         let rest_ll_unit = self.rest.unit.llvm_type(cx);
-        let (rest_count, rem_bytes) = if self.rest.unit.size.bytes() == 0 {
-            (0, 0)
+        let rest_count = if self.rest.total == Size::ZERO {
+            0
         } else {
-            (
-                self.rest.total.bytes() / self.rest.unit.size.bytes(),
-                self.rest.total.bytes() % self.rest.unit.size.bytes(),
-            )
+            assert_ne!(
+                self.rest.unit.size,
+                Size::ZERO,
+                "total size {:?} cannot be divided into units of zero size",
+                self.rest.total
+            );
+            if self.rest.total.bytes() % self.rest.unit.size.bytes() != 0 {
+                assert_eq!(self.rest.unit.kind, RegKind::Integer, "only int regs can be split");
+            }
+            self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes())
         };
 
+        // Simplify to a single unit or an array if there's no prefix.
+        // This produces the same layout, but using a simpler type.
         if self.prefix.iter().all(|x| x.is_none()) {
-            // Simplify to a single unit when there is no prefix and size <= unit size
-            if self.rest.total <= self.rest.unit.size {
+            if rest_count == 1 {
                 return rest_ll_unit;
             }
 
-            // Simplify to array when all chunks are the same size and type
-            if rem_bytes == 0 {
-                return cx.type_array(rest_ll_unit, rest_count);
-            }
-        }
-
-        // Create list of fields in the main structure
-        let mut args: Vec<_> = self
-            .prefix
-            .iter()
-            .flat_map(|option_reg| option_reg.map(|reg| reg.llvm_type(cx)))
-            .chain((0..rest_count).map(|_| rest_ll_unit))
-            .collect();
-
-        // Append final integer
-        if rem_bytes != 0 {
-            // Only integers can be really split further.
-            assert_eq!(self.rest.unit.kind, RegKind::Integer);
-            args.push(cx.type_ix(rem_bytes * 8));
+            return cx.type_array(rest_ll_unit, rest_count);
         }
 
+        // Generate a struct type with the prefix and the "rest" arguments.
+        let prefix_args =
+            self.prefix.iter().flat_map(|option_reg| option_reg.map(|reg| reg.llvm_type(cx)));
+        let rest_args = (0..rest_count).map(|_| rest_ll_unit);
+        let args: Vec<_> = prefix_args.chain(rest_args).collect();
         cx.type_struct(&args, false)
     }
 }
@@ -215,47 +211,33 @@ impl<'ll, 'tcx> ArgAbiExt<'ll, 'tcx> for ArgAbi<'tcx, Ty<'tcx>> {
                 bug!("unsized `ArgAbi` must be handled through `store_fn_arg`");
             }
             PassMode::Cast { cast, pad_i32: _ } => {
-                // FIXME(eddyb): Figure out when the simpler Store is safe, clang
-                // uses it for i16 -> {i8, i8}, but not for i24 -> {i8, i8, i8}.
-                let can_store_through_cast_ptr = false;
-                if can_store_through_cast_ptr {
-                    bx.store(val, dst.llval, self.layout.align.abi);
-                } else {
-                    // The actual return type is a struct, but the ABI
-                    // adaptation code has cast it into some scalar type. The
-                    // code that follows is the only reliable way I have
-                    // found to do a transform like i64 -> {i32,i32}.
-                    // Basically we dump the data onto the stack then memcpy it.
-                    //
-                    // Other approaches I tried:
-                    // - Casting rust ret pointer to the foreign type and using Store
-                    //   is (a) unsafe if size of foreign type > size of rust type and
-                    //   (b) runs afoul of strict aliasing rules, yielding invalid
-                    //   assembly under -O (specifically, the store gets removed).
-                    // - Truncating foreign type to correct integral type and then
-                    //   bitcasting to the struct type yields invalid cast errors.
-
-                    // We instead thus allocate some scratch space...
-                    let scratch_size = cast.size(bx);
-                    let scratch_align = cast.align(bx);
-                    let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align);
-                    bx.lifetime_start(llscratch, scratch_size);
-
-                    // ... where we first store the value...
-                    bx.store(val, llscratch, scratch_align);
-
-                    // ... and then memcpy it to the intended destination.
-                    bx.memcpy(
-                        dst.llval,
-                        self.layout.align.abi,
-                        llscratch,
-                        scratch_align,
-                        bx.const_usize(self.layout.size.bytes()),
-                        MemFlags::empty(),
-                    );
-
-                    bx.lifetime_end(llscratch, scratch_size);
-                }
+                // The ABI mandates that the value is passed as a different struct representation.
+                // Spill and reload it from the stack to convert from the ABI representation to
+                // the Rust representation.
+                let scratch_size = cast.size(bx);
+                let scratch_align = cast.align(bx);
+                // Note that the ABI type may be either larger or smaller than the Rust type,
+                // due to the presence or absence of trailing padding. For example:
+                // - On some ABIs, the Rust layout { f64, f32, <f32 padding> } may omit padding
+                //   when passed by value, making it smaller.
+                // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes
+                //   when passed by value, making it larger.
+                let copy_bytes = cmp::min(scratch_size.bytes(), self.layout.size.bytes());
+                // Allocate some scratch space...
+                let llscratch = bx.alloca(cast.llvm_type(bx), scratch_align);
+                bx.lifetime_start(llscratch, scratch_size);
+                // ...store the value...
+                bx.store(val, llscratch, scratch_align);
+                // ... and then memcpy it to the intended destination.
+                bx.memcpy(
+                    dst.llval,
+                    self.layout.align.abi,
+                    llscratch,
+                    scratch_align,
+                    bx.const_usize(copy_bytes),
+                    MemFlags::empty(),
+                );
+                bx.lifetime_end(llscratch, scratch_size);
             }
             _ => {
                 OperandRef::from_immediate_or_packed_pair(bx, val, self.layout).val.store(bx, dst);
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 4efea66a7f1..68ba8cbf7b7 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -912,6 +912,7 @@ fn target_is_apple(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
         || cgcx.opts.target_triple.triple().contains("-darwin")
         || cgcx.opts.target_triple.triple().contains("-tvos")
         || cgcx.opts.target_triple.triple().contains("-watchos")
+        || cgcx.opts.target_triple.triple().contains("-visionos")
 }
 
 fn target_is_aix(cgcx: &CodegenContext<LlvmCodegenBackend>) -> bool {
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 278db21b0a1..3f3969bbca3 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -17,11 +17,11 @@ use rustc_span::Symbol;
 
 /// Generates and exports the Coverage Map.
 ///
-/// Rust Coverage Map generation supports LLVM Coverage Mapping Format version
-/// 6 (zero-based encoded as 5), as defined at
-/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/13.0-2021-09-30/llvm/docs/CoverageMappingFormat.rst#llvm-code-coverage-mapping-format).
+/// Rust Coverage Map generation supports LLVM Coverage Mapping Format versions
+/// 6 and 7 (encoded as 5 and 6 respectively), as described at
+/// [LLVM Code Coverage Mapping Format](https://github.com/rust-lang/llvm-project/blob/rustc/18.0-2024-02-13/llvm/docs/CoverageMappingFormat.rst).
 /// These versions are supported by the LLVM coverage tools (`llvm-profdata` and `llvm-cov`)
-/// bundled with Rust's fork of LLVM.
+/// distributed in the `llvm-tools-preview` rustup component.
 ///
 /// Consequently, Rust's bundled version of Clang also generates Coverage Maps compliant with
 /// the same version. Clang's implementation of Coverage Map generation was referenced when
@@ -31,10 +31,21 @@ use rustc_span::Symbol;
 pub fn finalize(cx: &CodegenCx<'_, '_>) {
     let tcx = cx.tcx;
 
-    // Ensure the installed version of LLVM supports Coverage Map Version 6
-    // (encoded as a zero-based value: 5), which was introduced with LLVM 13.
-    let version = coverageinfo::mapping_version();
-    assert_eq!(version, 5, "The `CoverageMappingVersion` exposed by `llvm-wrapper` is out of sync");
+    // Ensure that LLVM is using a version of the coverage mapping format that
+    // agrees with our Rust-side code. Expected versions (encoded as n-1) are:
+    // - `CovMapVersion::Version6` (5) used by LLVM 13-17
+    // - `CovMapVersion::Version7` (6) used by LLVM 18
+    let covmap_version = {
+        let llvm_covmap_version = coverageinfo::mapping_version();
+        let expected_versions = 5..=6;
+        assert!(
+            expected_versions.contains(&llvm_covmap_version),
+            "Coverage mapping version exposed by `llvm-wrapper` is out of sync; \
+            expected {expected_versions:?} but was {llvm_covmap_version}"
+        );
+        // This is the version number that we will embed in the covmap section:
+        llvm_covmap_version
+    };
 
     debug!("Generating coverage map for CodegenUnit: `{}`", cx.codegen_unit.name());
 
@@ -74,7 +85,7 @@ pub fn finalize(cx: &CodegenCx<'_, '_>) {
 
     // Generate the coverage map header, which contains the filenames used by
     // this CGU's coverage mappings, and store it in a well-known global.
-    let cov_data_val = generate_coverage_map(cx, version, filenames_size, filenames_val);
+    let cov_data_val = generate_coverage_map(cx, covmap_version, filenames_size, filenames_val);
     coverageinfo::save_cov_data_to_mod(cx, cov_data_val);
 
     let mut unused_function_names = Vec::new();
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index 68c1770c1d4..140566e8da9 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -24,8 +24,6 @@ pub(crate) mod ffi;
 pub(crate) mod map_data;
 pub mod mapgen;
 
-const VAR_ALIGN: Align = Align::EIGHT;
-
 /// A context object for maintaining all state needed by the coverageinfo module.
 pub struct CrateCoverageContext<'ll, 'tcx> {
     /// Coverage data for each instrumented function identified by DefId.
@@ -226,7 +224,8 @@ pub(crate) fn save_cov_data_to_mod<'ll, 'tcx>(
     llvm::set_global_constant(llglobal, true);
     llvm::set_linkage(llglobal, llvm::Linkage::PrivateLinkage);
     llvm::set_section(llglobal, &covmap_section_name);
-    llvm::set_alignment(llglobal, VAR_ALIGN);
+    // LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
+    llvm::set_alignment(llglobal, Align::EIGHT);
     cx.add_used_global(llglobal);
 }
 
@@ -256,7 +255,8 @@ pub(crate) fn save_func_record_to_mod<'ll, 'tcx>(
     llvm::set_linkage(llglobal, llvm::Linkage::LinkOnceODRLinkage);
     llvm::set_visibility(llglobal, llvm::Visibility::Hidden);
     llvm::set_section(llglobal, covfun_section_name);
-    llvm::set_alignment(llglobal, VAR_ALIGN);
+    // LLVM's coverage mapping format specifies 8-byte alignment for items in this section.
+    llvm::set_alignment(llglobal, Align::EIGHT);
     llvm::set_comdat(cx.llmod, llglobal, &func_record_var_name);
     cx.add_used_global(llglobal);
 }
diff --git a/compiler/rustc_codegen_llvm/src/declare.rs b/compiler/rustc_codegen_llvm/src/declare.rs
index 3ef8538ced3..f86cdcaa6f7 100644
--- a/compiler/rustc_codegen_llvm/src/declare.rs
+++ b/compiler/rustc_codegen_llvm/src/declare.rs
@@ -147,7 +147,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
                 for options in [
                     TypeIdOptions::GENERALIZE_POINTERS,
                     TypeIdOptions::NORMALIZE_INTEGERS,
-                    TypeIdOptions::NO_SELF_TYPE_ERASURE,
+                    TypeIdOptions::USE_CONCRETE_SELF,
                 ]
                 .into_iter()
                 .powerset()
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index e4ec7974e90..dc52dd156b7 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -2111,7 +2111,7 @@ fn generic_simd_intrinsic<'ll, 'tcx>(
         return Ok(args[0].immediate());
     }
 
-    if name == sym::simd_expose_addr {
+    if name == sym::simd_expose_provenance {
         let (out_len, out_elem) = require_simd!(ret_ty, SimdReturn);
         require!(
             in_len == out_len,
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 22b58c13949..ef55682d541 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -231,7 +231,11 @@ impl<'a> ArArchiveBuilder<'a> {
             "gnu" => ArchiveKind::Gnu,
             "bsd" => ArchiveKind::Bsd,
             "darwin" => ArchiveKind::Darwin,
-            "coff" => ArchiveKind::Coff,
+            "coff" => {
+                // FIXME: ar_archive_writer doesn't support COFF archives yet.
+                // https://github.com/rust-lang/ar_archive_writer/issues/9
+                ArchiveKind::Gnu
+            }
             "aix_big" => ArchiveKind::AixBig,
             kind => {
                 self.sess.dcx().emit_fatal(UnknownArchiveKind { kind });
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 7c7f702b2c3..ac278de02af 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -2946,7 +2946,7 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
     let os = &sess.target.os;
     let llvm_target = &sess.target.llvm_target;
     if sess.target.vendor != "apple"
-        || !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "macos")
+        || !matches!(os.as_ref(), "ios" | "tvos" | "watchos" | "visionos" | "macos")
         || !matches!(flavor, LinkerFlavor::Darwin(..))
     {
         return;
@@ -2971,6 +2971,8 @@ fn add_apple_sdk(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavor) {
         ("arm64_32", "watchos") => "watchos",
         ("aarch64", "watchos") if llvm_target.ends_with("-simulator") => "watchsimulator",
         ("aarch64", "watchos") => "watchos",
+        ("aarch64", "visionos") if llvm_target.ends_with("-simulator") => "xrsimulator",
+        ("aarch64", "visionos") => "xros",
         ("arm", "watchos") => "watchos",
         (_, "macos") => "macosx",
         _ => {
@@ -3027,6 +3029,10 @@ fn get_apple_sdk_root(sdk_name: &str) -> Result<String, errors::AppleSdkRootErro
                     || sdkroot.contains("MacOSX.platform") => {}
             "watchsimulator"
                 if sdkroot.contains("WatchOS.platform") || sdkroot.contains("MacOSX.platform") => {}
+            "visionos"
+                if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {}
+            "visionossimulator"
+                if sdkroot.contains("XROS.platform") || sdkroot.contains("MacOSX.platform") => {}
             // Ignore `SDKROOT` if it's not a valid path.
             _ if !p.is_absolute() || p == Path::new("/") || !p.exists() => {}
             _ => return Ok(sdkroot),
diff --git a/compiler/rustc_codegen_ssa/src/mir/block.rs b/compiler/rustc_codegen_ssa/src/mir/block.rs
index d4123329f44..1aa52a985ef 100644
--- a/compiler/rustc_codegen_ssa/src/mir/block.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/block.rs
@@ -1505,9 +1505,35 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
 
         if by_ref && !arg.is_indirect() {
             // Have to load the argument, maybe while casting it.
-            if let PassMode::Cast { cast: ty, .. } = &arg.mode {
-                let llty = bx.cast_backend_type(ty);
-                llval = bx.load(llty, llval, align.min(arg.layout.align.abi));
+            if let PassMode::Cast { cast, pad_i32: _ } = &arg.mode {
+                // The ABI mandates that the value is passed as a different struct representation.
+                // Spill and reload it from the stack to convert from the Rust representation to
+                // the ABI representation.
+                let scratch_size = cast.size(bx);
+                let scratch_align = cast.align(bx);
+                // Note that the ABI type may be either larger or smaller than the Rust type,
+                // due to the presence or absence of trailing padding. For example:
+                // - On some ABIs, the Rust layout { f64, f32, <f32 padding> } may omit padding
+                //   when passed by value, making it smaller.
+                // - On some ABIs, the Rust layout { u16, u16, u16 } may be padded up to 8 bytes
+                //   when passed by value, making it larger.
+                let copy_bytes = cmp::min(scratch_size.bytes(), arg.layout.size.bytes());
+                // Allocate some scratch space...
+                let llscratch = bx.alloca(bx.cast_backend_type(cast), scratch_align);
+                bx.lifetime_start(llscratch, scratch_size);
+                // ...memcpy the value...
+                bx.memcpy(
+                    llscratch,
+                    scratch_align,
+                    llval,
+                    align,
+                    bx.const_usize(copy_bytes),
+                    MemFlags::empty(),
+                );
+                // ...and then load it with the ABI type.
+                let cast_ty = bx.cast_backend_type(cast);
+                llval = bx.load(cast_ty, llscratch, scratch_align);
+                bx.lifetime_end(llscratch, scratch_size);
             } else {
                 // We can't use `PlaceRef::load` here because the argument
                 // may have a type we don't treat as immediate, but the ABI
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 6f7b98a262d..4d746c89f1f 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -405,7 +405,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 let cast = bx.cx().layout_of(self.monomorphize(mir_cast_ty));
 
                 let val = match *kind {
-                    mir::CastKind::PointerExposeAddress => {
+                    mir::CastKind::PointerExposeProvenance => {
                         assert!(bx.cx().is_backend_immediate(cast));
                         let llptr = operand.immediate();
                         let llcast_ty = bx.cx().immediate_backend_type(cast);
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index e0d45f1fe11..9447d18fe8c 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -34,9 +34,9 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 self.unsize_into(src, cast_layout, dest)?;
             }
 
-            CastKind::PointerExposeAddress => {
+            CastKind::PointerExposeProvenance => {
                 let src = self.read_immediate(src)?;
-                let res = self.pointer_expose_address_cast(&src, cast_layout)?;
+                let res = self.pointer_expose_provenance_cast(&src, cast_layout)?;
                 self.write_immediate(*res, dest)?;
             }
 
@@ -225,7 +225,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         }
     }
 
-    pub fn pointer_expose_address_cast(
+    pub fn pointer_expose_provenance_cast(
         &mut self,
         src: &ImmTy<'tcx, M::Provenance>,
         cast_to: TyAndLayout<'tcx>,
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 831787a92c8..842fb6d204c 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -792,7 +792,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 1a2f1194f89..e32aea39fc5 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -1058,7 +1058,7 @@ where
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_const_eval/src/transform/check_consts/check.rs b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
index b6dcc334147..543996c86ba 100644
--- a/compiler/rustc_const_eval/src/transform/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/transform/check_consts/check.rs
@@ -544,7 +544,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 // Unsizing is implemented for CTFE.
             }
 
-            Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
+            Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
                 self.check_op(ops::RawPtrToIntCast);
             }
             Rvalue::Cast(CastKind::PointerWithExposedProvenance, _, _) => {
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index e1e98ebc1e9..a499e4b980f 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -1077,7 +1077,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                     }
                     // FIXME: Add Checks for these
                     CastKind::PointerWithExposedProvenance
-                    | CastKind::PointerExposeAddress
+                    | CastKind::PointerExposeProvenance
                     | CastKind::PointerCoercion(_) => {}
                     CastKind::IntToInt | CastKind::IntToFloat => {
                         let input_valid = op_ty.is_integral() || op_ty.is_char() || op_ty.is_bool();
diff --git a/compiler/rustc_data_structures/src/graph/dominators/mod.rs b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
index a45f1dd72a1..30e240cf85b 100644
--- a/compiler/rustc_data_structures/src/graph/dominators/mod.rs
+++ b/compiler/rustc_data_structures/src/graph/dominators/mod.rs
@@ -72,7 +72,7 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
         IndexVec::with_capacity(graph.num_nodes());
 
     let mut stack = vec![PreOrderFrame {
-        pre_order_idx: PreorderIndex::new(0),
+        pre_order_idx: PreorderIndex::ZERO,
         iter: graph.successors(graph.start_node()),
     }];
     let mut pre_order_to_real: IndexVec<PreorderIndex, G::Node> =
@@ -80,8 +80,8 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
     let mut real_to_pre_order: IndexVec<G::Node, Option<PreorderIndex>> =
         IndexVec::from_elem_n(None, graph.num_nodes());
     pre_order_to_real.push(graph.start_node());
-    parent.push(PreorderIndex::new(0)); // the parent of the root node is the root for now.
-    real_to_pre_order[graph.start_node()] = Some(PreorderIndex::new(0));
+    parent.push(PreorderIndex::ZERO); // the parent of the root node is the root for now.
+    real_to_pre_order[graph.start_node()] = Some(PreorderIndex::ZERO);
     let mut post_order_idx = 0;
 
     // Traverse the graph, collecting a number of things:
@@ -111,7 +111,7 @@ fn dominators_impl<G: ControlFlowGraph>(graph: &G) -> Inner<G::Node> {
 
     let reachable_vertices = pre_order_to_real.len();
 
-    let mut idom = IndexVec::from_elem_n(PreorderIndex::new(0), reachable_vertices);
+    let mut idom = IndexVec::from_elem_n(PreorderIndex::ZERO, reachable_vertices);
     let mut semi = IndexVec::from_fn_n(std::convert::identity, reachable_vertices);
     let mut label = semi.clone();
     let mut bucket = IndexVec::from_elem_n(vec![], reachable_vertices);
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index 7b40954e735..b4107bd4a2b 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -102,9 +102,9 @@ pub type PResult<'a, T> = Result<T, PErr<'a>>;
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 // `PResult` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(PResult<'_, ()>, 16);
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(PResult<'_, bool>, 16);
 
 #[derive(Debug, PartialEq, Eq, Clone, Copy, Hash, Encodable, Decodable)]
@@ -1951,6 +1951,39 @@ pub fn report_ambiguity_error<'a, G: EmissionGuarantee>(
     }
 }
 
+/// Grammatical tool for displaying messages to end users in a nice form.
+///
+/// Returns "an" if the given string starts with a vowel, and "a" otherwise.
+pub fn a_or_an(s: &str) -> &'static str {
+    let mut chars = s.chars();
+    let Some(mut first_alpha_char) = chars.next() else {
+        return "a";
+    };
+    if first_alpha_char == '`' {
+        let Some(next) = chars.next() else {
+            return "a";
+        };
+        first_alpha_char = next;
+    }
+    if ["a", "e", "i", "o", "u", "&"].contains(&&first_alpha_char.to_lowercase().to_string()[..]) {
+        "an"
+    } else {
+        "a"
+    }
+}
+
+/// Grammatical tool for displaying messages to end users in a nice form.
+///
+/// Take a list ["a", "b", "c"] and output a display friendly version "a, b and c"
+pub fn display_list_with_comma_and<T: std::fmt::Display>(v: &[T]) -> String {
+    match v.len() {
+        0 => "".to_string(),
+        1 => v[0].to_string(),
+        2 => format!("{} and {}", v[0], v[1]),
+        _ => format!("{}, {}", v[0], display_list_with_comma_and(&v[1..])),
+    }
+}
+
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum TerminalUrl {
     No,
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index a31be05ccc4..9fff00ffeae 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -266,7 +266,7 @@ struct MatcherPos {
 }
 
 // This type is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(MatcherPos, 16);
 
 impl MatcherPos {
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 4c975c7b9e0..36db377f7e0 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -567,6 +567,8 @@ declare_features! (
     (unstable, proc_macro_hygiene, "1.30.0", Some(54727)),
     /// Allows `&raw const $place_expr` and `&raw mut $place_expr` expressions.
     (unstable, raw_ref_op, "1.41.0", Some(64490)),
+    /// Allows `&` and `&mut` patterns to consume match-ergonomics-inserted references.
+    (incomplete, ref_pat_everywhere, "CURRENT_RUSTC_VERSION", Some(123076)),
     /// Allows using the `#[register_tool]` attribute.
     (unstable, register_tool, "1.41.0", Some(66079)),
     /// Allows the `#[repr(i128)]` attribute for enums.
diff --git a/compiler/rustc_hir/src/def.rs b/compiler/rustc_hir/src/def.rs
index e8cecb1930f..2662f5661ba 100644
--- a/compiler/rustc_hir/src/def.rs
+++ b/compiler/rustc_hir/src/def.rs
@@ -113,6 +113,9 @@ pub enum DefKind {
     InlineConst,
     /// Opaque type, aka `impl Trait`.
     OpaqueTy,
+    /// A field in a struct, enum or union. e.g.
+    /// - `bar` in `struct Foo { bar: u8 }`
+    /// - `Foo::Bar::0` in `enum Foo { Bar(u8) }`
     Field,
     /// Lifetime parameter: the `'a` in `struct Foo<'a> { ... }`
     LifetimeParam,
diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs
index f538d6bcb98..cd5da279a26 100644
--- a/compiler/rustc_hir/src/definitions.rs
+++ b/compiler/rustc_hir/src/definitions.rs
@@ -380,14 +380,19 @@ impl Definitions {
     pub fn local_def_path_hash_to_def_id(
         &self,
         hash: DefPathHash,
-        err: &mut dyn FnMut() -> !,
+        err_msg: &dyn std::fmt::Debug,
     ) -> LocalDefId {
         debug_assert!(hash.stable_crate_id() == self.table.stable_crate_id);
+        #[cold]
+        #[inline(never)]
+        fn err(err_msg: &dyn std::fmt::Debug) -> ! {
+            panic!("{err_msg:?}")
+        }
         self.table
             .def_path_hash_to_index
             .get(&hash.local_hash())
             .map(|local_def_index| LocalDefId { local_def_index })
-            .unwrap_or_else(|| err())
+            .unwrap_or_else(|| err(err_msg))
     }
 
     pub fn def_path_hash_to_def_index_map(&self) -> &DefPathHashMap {
diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs
index a0f86565929..f21cd653f96 100644
--- a/compiler/rustc_hir/src/hir.rs
+++ b/compiler/rustc_hir/src/hir.rs
@@ -846,9 +846,8 @@ pub struct OwnerNodes<'tcx> {
 
 impl<'tcx> OwnerNodes<'tcx> {
     pub fn node(&self) -> OwnerNode<'tcx> {
-        use rustc_index::Idx;
         // Indexing must ensure it is an OwnerNode.
-        self.nodes[ItemLocalId::new(0)].node.as_owner().unwrap()
+        self.nodes[ItemLocalId::ZERO].node.as_owner().unwrap()
     }
 }
 
@@ -856,7 +855,7 @@ impl fmt::Debug for OwnerNodes<'_> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
         f.debug_struct("OwnerNodes")
             // Do not print all the pointers to all the nodes, as it would be unreadable.
-            .field("node", &self.nodes[ItemLocalId::from_u32(0)])
+            .field("node", &self.nodes[ItemLocalId::ZERO])
             .field(
                 "parents",
                 &self
@@ -3762,7 +3761,7 @@ impl<'hir> Node<'hir> {
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     // tidy-alphabetical-start
diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs
index d339075c171..0341a482fa8 100644
--- a/compiler/rustc_hir/src/hir_id.rs
+++ b/compiler/rustc_hir/src/hir_id.rs
@@ -17,7 +17,7 @@ impl Debug for OwnerId {
 
 impl From<OwnerId> for HirId {
     fn from(owner: OwnerId) -> HirId {
-        HirId { owner, local_id: ItemLocalId::from_u32(0) }
+        HirId { owner, local_id: ItemLocalId::ZERO }
     }
 }
 
@@ -110,7 +110,7 @@ impl HirId {
 
     #[inline]
     pub fn make_owner(owner: LocalDefId) -> Self {
-        Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::from_u32(0) }
+        Self { owner: OwnerId { def_id: owner }, local_id: ItemLocalId::ZERO }
     }
 
     pub fn index(self) -> (usize, usize) {
@@ -172,6 +172,6 @@ unsafe impl StableOrd for ItemLocalId {
 
 /// The `HirId` corresponding to `CRATE_NODE_ID` and `CRATE_DEF_ID`.
 pub const CRATE_HIR_ID: HirId =
-    HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::from_u32(0) };
+    HirId { owner: OwnerId { def_id: CRATE_DEF_ID }, local_id: ItemLocalId::ZERO };
 
 pub const CRATE_OWNER_ID: OwnerId = OwnerId { def_id: CRATE_DEF_ID };
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index a880445a27c..739a7086992 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -899,7 +899,7 @@ pub fn check_simd(tcx: TyCtxt<'_>, sp: Span, def_id: LocalDefId) {
             struct_span_code_err!(tcx.dcx(), sp, E0075, "SIMD vector cannot be empty").emit();
             return;
         }
-        let e = fields[FieldIdx::from_u32(0)].ty(tcx, args);
+        let e = fields[FieldIdx::ZERO].ty(tcx, args);
         if !fields.iter().all(|f| f.ty(tcx, args) == e) {
             struct_span_code_err!(tcx.dcx(), sp, E0076, "SIMD vector should be homogeneous")
                 .with_span_label(sp, "SIMD elements must have the same type")
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 00a0fca4907..bd64621f077 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -183,7 +183,7 @@ pub fn check_intrinsic_type(
             let region = ty::Region::new_bound(
                 tcx,
                 ty::INNERMOST,
-                ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
+                ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon },
             );
             let env_region = ty::Region::new_bound(
                 tcx,
@@ -495,7 +495,7 @@ pub fn check_intrinsic_type(
                 );
                 let discriminant_def_id = assoc_items[0];
 
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
+                let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon };
                 (
                     1,
                     0,
@@ -555,7 +555,7 @@ pub fn check_intrinsic_type(
             }
 
             sym::raw_eq => {
-                let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon };
+                let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon };
                 let param_ty_lhs =
                     Ty::new_imm_ref(tcx, ty::Region::new_bound(tcx, ty::INNERMOST, br), param(0));
                 let br = ty::BoundRegion { var: ty::BoundVar::from_u32(1), kind: ty::BrAnon };
@@ -627,7 +627,7 @@ pub fn check_intrinsic_type(
             sym::simd_cast
             | sym::simd_as
             | sym::simd_cast_ptr
-            | sym::simd_expose_addr
+            | sym::simd_expose_provenance
             | sym::simd_with_exposed_provenance => (2, 0, vec![param(0)], param(1)),
             sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
             sym::simd_select | sym::simd_select_bitmask => {
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index df4db3ec3fb..1958a80d47c 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -67,7 +67,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             ty::RawPtr(ty, _) if self.is_thin_ptr_ty(ty) => Some(asm_ty_isize),
             ty::Adt(adt, args) if adt.repr().simd() => {
                 let fields = &adt.non_enum_variant().fields;
-                let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
+                let elem_ty = fields[FieldIdx::ZERO].ty(self.tcx, args);
 
                 let (size, ty) = match elem_ty.kind() {
                     ty::Array(ty, len) => {
@@ -146,7 +146,7 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
                     "expected first field of `MaybeUnit` to be `ManuallyDrop`"
                 );
                 let fields = &ty.non_enum_variant().fields;
-                let ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, args);
+                let ty = fields[FieldIdx::ZERO].ty(self.tcx, args);
                 self.get_asm_ty(ty)
             }
             _ => self.get_asm_ty(ty),
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index 722def2563c..9d7deebac48 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -474,9 +474,9 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             VariantData::Unit(..) | VariantData::Struct { .. } => {
                 tcx.type_of(tcx.hir().get_parent_item(hir_id)).instantiate_identity()
             }
-            VariantData::Tuple(..) => {
+            VariantData::Tuple(_, _, ctor) => {
                 let args = ty::GenericArgs::identity_for_item(tcx, def_id);
-                Ty::new_fn_def(tcx, def_id.to_def_id(), args)
+                Ty::new_fn_def(tcx, ctor.to_def_id(), args)
             }
         },
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
index 7a0890e50da..70f09dd6175 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs
@@ -628,7 +628,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     let projection_ty = pred.skip_binder().projection_ty;
 
                     let args_with_infer_self = tcx.mk_args_from_iter(
-                        std::iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into())
+                        std::iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into())
                             .chain(projection_ty.args.iter().skip(1)),
                     );
 
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
index d3ca35ba481..97ba946b7e0 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/object_safety.rs
@@ -6,9 +6,10 @@ use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
 use rustc_lint_defs::builtin::UNUSED_ASSOCIATED_TYPE_BOUNDS;
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty::fold::BottomUpFolder;
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeFoldable};
 use rustc_middle::ty::{DynKind, ToPredicate};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_trait_selection::traits::error_reporting::report_object_safety_error;
 use rustc_trait_selection::traits::{self, hir_ty_lowering_object_safety_violations};
 
@@ -228,12 +229,17 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         if arg == dummy_self.into() {
                             let param = &generics.params[index];
                             missing_type_params.push(param.name);
-                            return Ty::new_misc_error(tcx).into();
+                            Ty::new_misc_error(tcx).into()
                         } else if arg.walk().any(|arg| arg == dummy_self.into()) {
                             references_self = true;
-                            return Ty::new_misc_error(tcx).into();
+                            let guar = tcx.dcx().span_delayed_bug(
+                                span,
+                                "trait object trait bounds reference `Self`",
+                            );
+                            replace_dummy_self_with_error(tcx, arg, guar)
+                        } else {
+                            arg
                         }
-                        arg
                     })
                     .collect();
                 let args = tcx.mk_args(&args);
@@ -288,18 +294,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                     let guar = tcx
                         .dcx()
                         .span_delayed_bug(span, "trait object projection bounds reference `Self`");
-                    let args: Vec<_> = b
-                        .projection_ty
-                        .args
-                        .iter()
-                        .map(|arg| {
-                            if arg.walk().any(|arg| arg == dummy_self.into()) {
-                                return Ty::new_error(tcx, guar).into();
-                            }
-                            arg
-                        })
-                        .collect();
-                    b.projection_ty.args = tcx.mk_args(&args);
+                    b.projection_ty = replace_dummy_self_with_error(tcx, b.projection_ty, guar);
                 }
 
                 ty::ExistentialProjection::erase_self_ty(tcx, b)
@@ -357,3 +352,18 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         Ty::new_dynamic(tcx, existential_predicates, region_bound, representation)
     }
 }
+
+fn replace_dummy_self_with_error<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
+    tcx: TyCtxt<'tcx>,
+    t: T,
+    guar: ErrorGuaranteed,
+) -> T {
+    t.fold_with(&mut BottomUpFolder {
+        tcx,
+        ty_op: |ty| {
+            if ty == tcx.types.trait_object_dummy_self { Ty::new_error(tcx, guar) } else { ty }
+        },
+        lt_op: |lt| lt,
+        ct_op: |ct| ct,
+    })
+}
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index fbdc3d1adb8..1d51101c940 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -91,7 +91,7 @@ hir_typeck_lossy_provenance_int2ptr =
 hir_typeck_lossy_provenance_ptr2int =
     under strict provenance it is considered bad style to cast pointer `{$expr_ty}` to integer `{$cast_ty}`
     .suggestion = use `.addr()` to obtain the address of a pointer
-    .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+    .help = if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 
 hir_typeck_method_call_on_unknown_raw_pointee =
     cannot call a method on a raw pointer with an unknown pointee type
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 0e75a47683d..aa94632b2b0 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -918,7 +918,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let param = callee_args.const_at(host_effect_index);
         let cause = self.misc(span);
-        match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::No, effect, param) {
+        // We know the type of `effect` to be `bool`, there will be no opaque type inference.
+        match self.at(&cause, self.param_env).eq(infer::DefineOpaqueTypes::Yes, effect, param) {
             Ok(infer::InferOk { obligations, value: () }) => {
                 self.register_predicates(obligations);
             }
diff --git a/compiler/rustc_hir_typeck/src/check.rs b/compiler/rustc_hir_typeck/src/check.rs
index 5841392dbcf..59a043d1d69 100644
--- a/compiler/rustc_hir_typeck/src/check.rs
+++ b/compiler/rustc_hir_typeck/src/check.rs
@@ -182,7 +182,7 @@ fn check_panic_info_fn(tcx: TyCtxt<'_>, fn_id: LocalDefId, fn_sig: ty::FnSig<'_>
         ty::Region::new_bound(
             tcx,
             ty::INNERMOST,
-            ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind: ty::BrAnon },
+            ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BrAnon },
         ),
         panic_info_ty,
     );
diff --git a/compiler/rustc_hir_typeck/src/closure.rs b/compiler/rustc_hir_typeck/src/closure.rs
index 36af5394015..dbae8bfb542 100644
--- a/compiler/rustc_hir_typeck/src/closure.rs
+++ b/compiler/rustc_hir_typeck/src/closure.rs
@@ -227,11 +227,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     kind: TypeVariableOriginKind::ClosureSynthetic,
                     span: expr_span,
                 });
-                let closure_kind_ty = self.next_ty_var(TypeVariableOrigin {
-                    // FIXME(eddyb) distinguish closure kind inference variables from the rest.
-                    kind: TypeVariableOriginKind::ClosureSynthetic,
-                    span: expr_span,
-                });
+
+                let closure_kind_ty = match expected_kind {
+                    Some(kind) => Ty::from_closure_kind(tcx, kind),
+
+                    // Create a type variable (for now) to represent the closure kind.
+                    // It will be unified during the upvar inference phase (`upvar.rs`)
+                    None => self.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::ClosureSynthetic,
+                        span: expr_span,
+                    }),
+                };
+
                 let coroutine_captures_by_ref_ty = self.next_ty_var(TypeVariableOrigin {
                     kind: TypeVariableOriginKind::ClosureSynthetic,
                     span: expr_span,
@@ -262,10 +269,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     },
                 );
 
-                let coroutine_kind_ty = self.next_ty_var(TypeVariableOrigin {
-                    kind: TypeVariableOriginKind::ClosureSynthetic,
-                    span: expr_span,
-                });
+                let coroutine_kind_ty = match expected_kind {
+                    Some(kind) => Ty::from_coroutine_closure_kind(tcx, kind),
+
+                    // Create a type variable (for now) to represent the closure kind.
+                    // It will be unified during the upvar inference phase (`upvar.rs`)
+                    None => self.next_ty_var(TypeVariableOrigin {
+                        kind: TypeVariableOriginKind::ClosureSynthetic,
+                        span: expr_span,
+                    }),
+                };
+
                 let coroutine_upvars_ty = self.next_ty_var(TypeVariableOrigin {
                     kind: TypeVariableOriginKind::ClosureSynthetic,
                     span: expr_span,
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index 564de4ab9e7..75a68f16cf1 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -400,7 +400,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // what our ideal rcvr ty would look like.
                     let _ = self
                         .at(&ObligationCause::dummy(), self.param_env)
-                        .eq(DefineOpaqueTypes::No, method.sig.inputs()[idx + 1], arg_ty)
+                        .eq(DefineOpaqueTypes::Yes, method.sig.inputs()[idx + 1], arg_ty)
                         .ok()?;
                     self.select_obligations_where_possible(|errs| {
                         // Yeet the errors, we're already reporting errors.
@@ -479,7 +479,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     .and_then(|method| {
                         let _ = self
                             .at(&ObligationCause::dummy(), self.param_env)
-                            .eq(DefineOpaqueTypes::No, ideal_rcvr_ty, expected_ty)
+                            .eq(DefineOpaqueTypes::Yes, ideal_rcvr_ty, expected_ty)
                             .ok()?;
                         Some(method)
                     });
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 6d9dc098fbe..4da45303d12 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -44,10 +44,7 @@ use rustc_infer::infer::InferOk;
 use rustc_infer::traits::query::NoSolution;
 use rustc_infer::traits::ObligationCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase};
-use rustc_middle::ty::error::{
-    ExpectedFound,
-    TypeError::{FieldMisMatch, Sorts},
-};
+use rustc_middle::ty::error::{ExpectedFound, TypeError::Sorts};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_middle::ty::{self, AdtKind, Ty, TypeVisitableExt};
 use rustc_session::errors::ExprParenthesesNeeded;
@@ -1818,7 +1815,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                 let target_ty = self.field_ty(base_expr.span, f, args);
                                 let cause = self.misc(base_expr.span);
                                 match self.at(&cause, self.param_env).sup(
-                                    DefineOpaqueTypes::No,
+                                    // We're already using inference variables for any params, and don't allow converting
+                                    // between different structs, so there is no way this ever actually defines an opaque type.
+                                    // Thus choosing `Yes` is fine.
+                                    DefineOpaqueTypes::Yes,
                                     target_ty,
                                     fru_ty,
                                 ) {
@@ -1826,16 +1826,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                                         self.register_predicates(obligations)
                                     }
                                     Err(_) => {
-                                        // This should never happen, since we're just subtyping the
-                                        // remaining_fields, but it's fine to emit this, I guess.
-                                        self.err_ctxt()
-                                            .report_mismatched_types(
-                                                &cause,
-                                                target_ty,
-                                                fru_ty,
-                                                FieldMisMatch(variant.name, ident.name),
-                                            )
-                                            .emit();
+                                        span_bug!(
+                                            cause.span(),
+                                            "subtyping remaining fields of type changing FRU failed: {target_ty} != {fru_ty}: {}::{}",
+                                            variant.name,
+                                            ident.name,
+                                        );
                                     }
                                 }
                             }
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 8d4d0833eef..85d04f7d1c4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -461,7 +461,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     where
         T: TypeVisitable<TyCtxt<'tcx>>,
     {
-        t.has_free_regions() || t.has_projections() || t.has_infer_types()
+        t.has_free_regions() || t.has_aliases() || t.has_infer_types()
     }
 
     pub fn node_ty(&self, id: hir::HirId) -> Ty<'tcx> {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 5f5ff40fb9f..64b816553df 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -17,7 +17,8 @@ use itertools::Itertools;
 use rustc_ast as ast;
 use rustc_data_structures::fx::FxIndexSet;
 use rustc_errors::{
-    codes::*, pluralize, Applicability, Diag, ErrorGuaranteed, MultiSpan, StashKey,
+    a_or_an, codes::*, display_list_with_comma_and, pluralize, Applicability, Diag,
+    ErrorGuaranteed, MultiSpan, StashKey,
 };
 use rustc_hir as hir;
 use rustc_hir::def::{CtorOf, DefKind, Res};
@@ -686,7 +687,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Using probe here, since we don't want this subtyping to affect inference.
             let subtyping_error = self.probe(|_| {
                 self.at(&self.misc(arg_span), self.param_env)
-                    .sup(DefineOpaqueTypes::No, formal_input_ty, coerced_ty)
+                    .sup(DefineOpaqueTypes::Yes, formal_input_ty, coerced_ty)
                     .err()
             });
 
@@ -818,6 +819,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         call_expr,
                         None,
                         Some(mismatch_idx),
+                        &matched_inputs,
+                        &formal_and_expected_inputs,
                         is_method,
                     );
                     suggest_confusable(&mut err);
@@ -904,6 +907,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
             err.span_label(full_call_span, format!("arguments to this {call_name} are incorrect"));
 
+            self.label_generic_mismatches(
+                &mut err,
+                fn_def_id,
+                &matched_inputs,
+                &provided_arg_tys,
+                &formal_and_expected_inputs,
+                is_method,
+            );
+
             if let hir::ExprKind::MethodCall(_, rcvr, _, _) = call_expr.kind
                 && provided_idx.as_usize() == expected_idx.as_usize()
             {
@@ -932,6 +944,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 call_expr,
                 Some(expected_ty),
                 Some(expected_idx.as_usize()),
+                &matched_inputs,
+                &formal_and_expected_inputs,
                 is_method,
             );
             suggest_confusable(&mut err);
@@ -1270,6 +1284,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
         }
 
+        self.label_generic_mismatches(
+            &mut err,
+            fn_def_id,
+            &matched_inputs,
+            &provided_arg_tys,
+            &formal_and_expected_inputs,
+            is_method,
+        );
+
         // Incorporate the argument changes in the removal suggestion.
         // When a type is *missing*, and the rest are additional, we want to suggest these with a
         // multipart suggestion, but in order to do so we need to figure out *where* the arg that
@@ -1317,7 +1340,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
 
         // Call out where the function is defined
-        self.label_fn_like(&mut err, fn_def_id, callee_ty, call_expr, None, None, is_method);
+        self.label_fn_like(
+            &mut err,
+            fn_def_id,
+            callee_ty,
+            call_expr,
+            None,
+            None,
+            &matched_inputs,
+            &formal_and_expected_inputs,
+            is_method,
+        );
 
         // And add a suggestion block for all of the parameters
         let suggestion_text = match suggestion_text {
@@ -2094,6 +2127,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         expected_ty: Option<Ty<'tcx>>,
         // A specific argument should be labeled, instead of all of them
         expected_idx: Option<usize>,
+        matched_inputs: &IndexVec<ExpectedIdx, Option<ProvidedIdx>>,
+        formal_and_expected_inputs: &IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
         is_method: bool,
     ) {
         let Some(mut def_id) = callable_def_id else {
@@ -2185,21 +2220,164 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         {
             let mut spans: MultiSpan = def_span.into();
 
-            let params = self
+            let params_with_generics = self.get_hir_params_with_generics(def_id, is_method);
+            let mut generics_with_unmatched_params = Vec::new();
+
+            let check_for_matched_generics = || {
+                if matched_inputs.iter().any(|x| x.is_some())
+                    && params_with_generics.iter().any(|x| x.0.is_some())
+                {
+                    for (idx, (generic, _)) in params_with_generics.iter().enumerate() {
+                        // Param has to have a generic and be matched to be relevant
+                        if matched_inputs[idx.into()].is_none() {
+                            continue;
+                        }
+
+                        let Some(generic) = generic else {
+                            continue;
+                        };
+
+                        for unmatching_idx in idx + 1..params_with_generics.len() {
+                            if matched_inputs[unmatching_idx.into()].is_none()
+                                && let Some(unmatched_idx_param_generic) =
+                                    params_with_generics[unmatching_idx].0
+                                && unmatched_idx_param_generic.name.ident() == generic.name.ident()
+                            {
+                                // We found a parameter that didn't match that needed to
+                                return true;
+                            }
+                        }
+                    }
+                }
+                false
+            };
+
+            let check_for_matched_generics = check_for_matched_generics();
+
+            for (idx, (generic_param, param)) in
+                params_with_generics.iter().enumerate().filter(|(idx, _)| {
+                    check_for_matched_generics
+                        || expected_idx.map_or(true, |expected_idx| expected_idx == *idx)
+                })
+            {
+                let Some(generic_param) = generic_param else {
+                    spans.push_span_label(param.span, "");
+                    continue;
+                };
+
+                let other_params_matched: Vec<(usize, &hir::Param<'_>)> = params_with_generics
+                    .iter()
+                    .enumerate()
+                    .filter(|(other_idx, (other_generic_param, _))| {
+                        if *other_idx == idx {
+                            return false;
+                        }
+                        let Some(other_generic_param) = other_generic_param else {
+                            return false;
+                        };
+                        if matched_inputs[idx.into()].is_none()
+                            && matched_inputs[(*other_idx).into()].is_none()
+                        {
+                            return false;
+                        }
+                        if matched_inputs[idx.into()].is_some()
+                            && matched_inputs[(*other_idx).into()].is_some()
+                        {
+                            return false;
+                        }
+                        other_generic_param.name.ident() == generic_param.name.ident()
+                    })
+                    .map(|(other_idx, (_, other_param))| (other_idx, *other_param))
+                    .collect();
+
+                if !other_params_matched.is_empty() {
+                    let other_param_matched_names: Vec<String> = other_params_matched
+                        .iter()
+                        .map(|(_, other_param)| {
+                            if let hir::PatKind::Binding(_, _, ident, _) = other_param.pat.kind {
+                                format!("`{ident}`")
+                            } else {
+                                "{unknown}".to_string()
+                            }
+                        })
+                        .collect();
+
+                    let matched_ty = self
+                        .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
+                        .sort_string(self.tcx);
+
+                    if matched_inputs[idx.into()].is_some() {
+                        spans.push_span_label(
+                            param.span,
+                            format!(
+                                "{} {} to match the {} type of this parameter",
+                                display_list_with_comma_and(&other_param_matched_names),
+                                format!(
+                                    "need{}",
+                                    pluralize!(if other_param_matched_names.len() == 1 {
+                                        0
+                                    } else {
+                                        1
+                                    })
+                                ),
+                                matched_ty,
+                            ),
+                        );
+                    } else {
+                        spans.push_span_label(
+                            param.span,
+                            format!(
+                                "this parameter needs to match the {} type of {}",
+                                matched_ty,
+                                display_list_with_comma_and(&other_param_matched_names),
+                            ),
+                        );
+                    }
+                    generics_with_unmatched_params.push(generic_param);
+                } else {
+                    spans.push_span_label(param.span, "");
+                }
+            }
+
+            for generic_param in self
                 .tcx
                 .hir()
                 .get_if_local(def_id)
-                .and_then(|node| node.body_id())
-                .into_iter()
-                .flat_map(|id| self.tcx.hir().body(id).params)
-                .skip(if is_method { 1 } else { 0 });
-
-            for (_, param) in params
+                .and_then(|node| node.generics())
                 .into_iter()
-                .enumerate()
-                .filter(|(idx, _)| expected_idx.map_or(true, |expected_idx| expected_idx == *idx))
+                .flat_map(|x| x.params)
+                .filter(|x| {
+                    generics_with_unmatched_params.iter().any(|y| x.name.ident() == y.name.ident())
+                })
             {
-                spans.push_span_label(param.span, "");
+                let param_idents_matching: Vec<String> = params_with_generics
+                    .iter()
+                    .filter(|(generic, _)| {
+                        if let Some(generic) = generic {
+                            generic.name.ident() == generic_param.name.ident()
+                        } else {
+                            false
+                        }
+                    })
+                    .map(|(_, param)| {
+                        if let hir::PatKind::Binding(_, _, ident, _) = param.pat.kind {
+                            format!("`{ident}`")
+                        } else {
+                            "{unknown}".to_string()
+                        }
+                    })
+                    .collect();
+
+                if !param_idents_matching.is_empty() {
+                    spans.push_span_label(
+                        generic_param.span,
+                        format!(
+                            "{} all reference this parameter {}",
+                            display_list_with_comma_and(&param_idents_matching),
+                            generic_param.name.ident().name,
+                        ),
+                    );
+                }
             }
 
             err.span_note(spans, format!("{} defined here", self.tcx.def_descr(def_id)));
@@ -2260,6 +2438,115 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
         }
     }
+
+    fn label_generic_mismatches(
+        &self,
+        err: &mut Diag<'_>,
+        callable_def_id: Option<DefId>,
+        matched_inputs: &IndexVec<ExpectedIdx, Option<ProvidedIdx>>,
+        provided_arg_tys: &IndexVec<ProvidedIdx, (Ty<'tcx>, Span)>,
+        formal_and_expected_inputs: &IndexVec<ExpectedIdx, (Ty<'tcx>, Ty<'tcx>)>,
+        is_method: bool,
+    ) {
+        let Some(def_id) = callable_def_id else {
+            return;
+        };
+
+        let params_with_generics = self.get_hir_params_with_generics(def_id, is_method);
+
+        for (idx, (generic_param, _)) in params_with_generics.iter().enumerate() {
+            if matched_inputs[idx.into()].is_none() {
+                continue;
+            }
+
+            let Some((_, matched_arg_span)) = provided_arg_tys.get(idx.into()) else {
+                continue;
+            };
+
+            let Some(generic_param) = generic_param else {
+                continue;
+            };
+
+            let mut idxs_matched: Vec<usize> = vec![];
+            for (other_idx, (_, _)) in params_with_generics.iter().enumerate().filter(
+                |(other_idx, (other_generic_param, _))| {
+                    if *other_idx == idx {
+                        return false;
+                    }
+                    let Some(other_generic_param) = other_generic_param else {
+                        return false;
+                    };
+                    if matched_inputs[(*other_idx).into()].is_some() {
+                        return false;
+                    }
+                    other_generic_param.name.ident() == generic_param.name.ident()
+                },
+            ) {
+                idxs_matched.push(other_idx.into());
+            }
+
+            if idxs_matched.is_empty() {
+                continue;
+            }
+
+            let expected_display_type = self
+                .resolve_vars_if_possible(formal_and_expected_inputs[idx.into()].1)
+                .sort_string(self.tcx);
+            let label = if idxs_matched.len() == params_with_generics.len() - 1 {
+                format!(
+                    "expected all arguments to be this {} type because they need to match the type of this parameter",
+                    expected_display_type
+                )
+            } else {
+                format!(
+                    "expected some other arguments to be {} {} type to match the type of this parameter",
+                    a_or_an(&expected_display_type),
+                    expected_display_type,
+                )
+            };
+
+            err.span_label(*matched_arg_span, label);
+        }
+    }
+
+    fn get_hir_params_with_generics(
+        &self,
+        def_id: DefId,
+        is_method: bool,
+    ) -> Vec<(Option<&hir::GenericParam<'_>>, &hir::Param<'_>)> {
+        let fn_node = self.tcx.hir().get_if_local(def_id);
+
+        let generic_params: Vec<Option<&hir::GenericParam<'_>>> = fn_node
+            .and_then(|node| node.fn_decl())
+            .into_iter()
+            .flat_map(|decl| decl.inputs)
+            .skip(if is_method { 1 } else { 0 })
+            .map(|param| {
+                if let hir::TyKind::Path(QPath::Resolved(
+                    _,
+                    hir::Path { res: Res::Def(_, res_def_id), .. },
+                )) = param.kind
+                {
+                    fn_node
+                        .and_then(|node| node.generics())
+                        .into_iter()
+                        .flat_map(|generics| generics.params)
+                        .find(|gen| &gen.def_id.to_def_id() == res_def_id)
+                } else {
+                    None
+                }
+            })
+            .collect();
+
+        let params: Vec<&hir::Param<'_>> = fn_node
+            .and_then(|node| node.body_id())
+            .into_iter()
+            .flat_map(|id| self.tcx.hir().body(id).params)
+            .skip(if is_method { 1 } else { 0 })
+            .collect();
+
+        generic_params.into_iter().zip(params).collect()
+    }
 }
 
 struct FindClosureArg<'tcx> {
diff --git a/compiler/rustc_hir_typeck/src/intrinsicck.rs b/compiler/rustc_hir_typeck/src/intrinsicck.rs
index 9e3867e630d..62711e40049 100644
--- a/compiler/rustc_hir_typeck/src/intrinsicck.rs
+++ b/compiler/rustc_hir_typeck/src/intrinsicck.rs
@@ -17,7 +17,7 @@ fn unpack_option_like<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
         let data_idx;
 
         let one = VariantIdx::new(1);
-        let zero = VariantIdx::new(0);
+        let zero = VariantIdx::ZERO;
 
         if def.variant(zero).fields.is_empty() {
             data_idx = one;
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 12f522d1adc..a199f57aad9 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -774,7 +774,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         let projection_ty = pred.skip_binder().projection_ty;
 
                         let args_with_infer_self = tcx.mk_args_from_iter(
-                            iter::once(Ty::new_var(tcx, ty::TyVid::from_u32(0)).into())
+                            iter::once(Ty::new_var(tcx, ty::TyVid::ZERO).into())
                                 .chain(projection_ty.args.iter().skip(1)),
                         );
 
diff --git a/compiler/rustc_hir_typeck/src/pat.rs b/compiler/rustc_hir_typeck/src/pat.rs
index 9d247c46bab..bb47f8dfba4 100644
--- a/compiler/rustc_hir_typeck/src/pat.rs
+++ b/compiler/rustc_hir_typeck/src/pat.rs
@@ -130,7 +130,14 @@ enum AdjustMode {
     /// Peel off all immediate reference types.
     Peel,
     /// Reset binding mode to the initial mode.
+    /// Used for destructuring assignment, where we don't want any match ergonomics.
     Reset,
+    /// Produced by ref patterns.
+    /// Reset the binding mode to the initial mode,
+    /// and if the old biding mode was by-reference
+    /// with mutability matching the pattern,
+    /// mark the pattern as having consumed this reference.
+    ResetAndConsumeRef(Mutability),
     /// Pass on the input binding mode and expected type.
     Pass,
 }
@@ -174,7 +181,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             _ => None,
         };
         let adjust_mode = self.calc_adjust_mode(pat, path_res.map(|(res, ..)| res));
-        let (expected, def_bm) = self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
+        let (expected, def_bm, ref_pattern_already_consumed) =
+            self.calc_default_binding_mode(pat, expected, def_bm, adjust_mode);
         let pat_info = PatInfo {
             binding_mode: def_bm,
             top_info: ti,
@@ -211,7 +219,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             }
             PatKind::Box(inner) => self.check_pat_box(pat.span, inner, expected, pat_info),
             PatKind::Deref(inner) => self.check_pat_deref(pat.span, inner, expected, pat_info),
-            PatKind::Ref(inner, mutbl) => self.check_pat_ref(pat, inner, mutbl, expected, pat_info),
+            PatKind::Ref(inner, mutbl) => self.check_pat_ref(
+                pat,
+                inner,
+                mutbl,
+                expected,
+                pat_info,
+                ref_pattern_already_consumed,
+            ),
             PatKind::Slice(before, slice, after) => {
                 self.check_pat_slice(pat.span, before, slice, after, expected, pat_info)
             }
@@ -264,17 +279,27 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
     /// Compute the new expected type and default binding mode from the old ones
     /// as well as the pattern form we are currently checking.
+    ///
+    /// Last entry is only relevant for ref patterns (`&` and `&mut`);
+    /// if `true`, then the ref pattern consumed a match ergonomics inserted reference
+    /// and so does no need to match against a reference in the scrutinee type.
     fn calc_default_binding_mode(
         &self,
         pat: &'tcx Pat<'tcx>,
         expected: Ty<'tcx>,
         def_bm: BindingAnnotation,
         adjust_mode: AdjustMode,
-    ) -> (Ty<'tcx>, BindingAnnotation) {
+    ) -> (Ty<'tcx>, BindingAnnotation, bool) {
         match adjust_mode {
-            AdjustMode::Pass => (expected, def_bm),
-            AdjustMode::Reset => (expected, INITIAL_BM),
-            AdjustMode::Peel => self.peel_off_references(pat, expected, def_bm),
+            AdjustMode::Pass => (expected, def_bm, false),
+            AdjustMode::Reset => (expected, INITIAL_BM, false),
+            AdjustMode::ResetAndConsumeRef(mutbl) => {
+                (expected, INITIAL_BM, def_bm.0 == ByRef::Yes(mutbl))
+            }
+            AdjustMode::Peel => {
+                let peeled = self.peel_off_references(pat, expected, def_bm);
+                (peeled.0, peeled.1, false)
+            }
         }
     }
 
@@ -329,7 +354,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // ```
             //
             // See issue #46688.
-            PatKind::Ref(..) => AdjustMode::Reset,
+            PatKind::Ref(_, mutbl) => AdjustMode::ResetAndConsumeRef(*mutbl),
             // A `_` pattern works with any expected type, so there's no need to do anything.
             PatKind::Wild
             // A malformed pattern doesn't have an expected type, so let's just accept any type.
@@ -840,8 +865,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             && let Some(mt) = self.shallow_resolve(expected).builtin_deref(true)
             && let ty::Dynamic(..) = mt.ty.kind()
         {
-            // This is "x = SomeTrait" being reduced from
-            // "let &x = &SomeTrait" or "let box x = Box<SomeTrait>", an error.
+            // This is "x = dyn SomeTrait" being reduced from
+            // "let &x = &dyn SomeTrait" or "let box x = Box<dyn SomeTrait>", an error.
             let type_str = self.ty_to_string(expected);
             let mut err = struct_span_code_err!(
                 self.dcx(),
@@ -2036,6 +2061,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         mutbl: Mutability,
         expected: Ty<'tcx>,
         pat_info: PatInfo<'tcx, '_>,
+        consumed_inherited_ref: bool,
     ) -> Ty<'tcx> {
         let tcx = self.tcx;
         let expected = self.shallow_resolve(expected);
@@ -2051,26 +2077,37 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 match *expected.kind() {
                     ty::Ref(_, r_ty, r_mutbl) if r_mutbl == mutbl => (expected, r_ty),
                     _ => {
-                        let inner_ty = self.next_ty_var(TypeVariableOrigin {
-                            kind: TypeVariableOriginKind::TypeInference,
-                            span: inner.span,
-                        });
-                        let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
-                        debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
-                        let err = self.demand_eqtype_pat_diag(
-                            pat.span,
-                            expected,
-                            ref_ty,
-                            pat_info.top_info,
-                        );
+                        if consumed_inherited_ref && self.tcx.features().ref_pat_everywhere {
+                            // We already matched against a match-ergonmics inserted reference,
+                            // so we don't need to match against a reference from the original type.
+                            // Save this infor for use in lowering later
+                            self.typeck_results
+                                .borrow_mut()
+                                .skipped_ref_pats_mut()
+                                .insert(pat.hir_id);
+                            (expected, expected)
+                        } else {
+                            let inner_ty = self.next_ty_var(TypeVariableOrigin {
+                                kind: TypeVariableOriginKind::TypeInference,
+                                span: inner.span,
+                            });
+                            let ref_ty = self.new_ref_ty(pat.span, mutbl, inner_ty);
+                            debug!("check_pat_ref: demanding {:?} = {:?}", expected, ref_ty);
+                            let err = self.demand_eqtype_pat_diag(
+                                pat.span,
+                                expected,
+                                ref_ty,
+                                pat_info.top_info,
+                            );
 
-                        // Look for a case like `fn foo(&foo: u32)` and suggest
-                        // `fn foo(foo: &u32)`
-                        if let Some(mut err) = err {
-                            self.borrow_pat_suggestion(&mut err, pat);
-                            err.emit();
+                            // Look for a case like `fn foo(&foo: u32)` and suggest
+                            // `fn foo(foo: &u32)`
+                            if let Some(mut err) = err {
+                                self.borrow_pat_suggestion(&mut err, pat);
+                                err.emit();
+                            }
+                            (ref_ty, inner_ty)
                         }
-                        (ref_ty, inner_ty)
                     }
                 }
             }
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 54344adaabd..c987bfb9a0e 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -166,7 +166,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         span: Span,
         body_id: hir::BodyId,
         body: &'tcx hir::Body<'tcx>,
-        capture_clause: hir::CaptureBy,
+        mut capture_clause: hir::CaptureBy,
     ) {
         // Extract the type of the closure.
         let ty = self.node_ty(closure_hir_id);
@@ -259,6 +259,28 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         )
         .consume_body(body);
 
+        // If a coroutine is comes from a coroutine-closure that is `move`, but
+        // the coroutine-closure was inferred to be `FnOnce` during signature
+        // inference, then it's still possible that we try to borrow upvars from
+        // the coroutine-closure because they are not used by the coroutine body
+        // in a way that forces a move.
+        //
+        // This would lead to an impossible to satisfy situation, since `AsyncFnOnce`
+        // coroutine bodies can't borrow from their parent closure. To fix this,
+        // we force the inner coroutine to also be `move`. This only matters for
+        // coroutine-closures that are `move` since otherwise they themselves will
+        // be borrowing from the outer environment, so there's no self-borrows occuring.
+        if let UpvarArgs::Coroutine(..) = args
+            && let hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure) =
+                self.tcx.coroutine_kind(closure_def_id).expect("coroutine should have kind")
+            && let parent_hir_id =
+                self.tcx.local_def_id_to_hir_id(self.tcx.local_parent(closure_def_id))
+            && let parent_ty = self.node_ty(parent_hir_id)
+            && let Some(ty::ClosureKind::FnOnce) = self.closure_kind(parent_ty)
+        {
+            capture_clause = self.tcx.hir_node(parent_hir_id).expect_closure().capture_clause;
+        }
+
         debug!(
             "For closure={:?}, capture_information={:#?}",
             closure_def_id, delegate.capture_information
@@ -343,10 +365,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let closure_env_region: ty::Region<'_> = ty::Region::new_bound(
                 self.tcx,
                 ty::INNERMOST,
-                ty::BoundRegion {
-                    var: ty::BoundVar::from_usize(0),
-                    kind: ty::BoundRegionKind::BrEnv,
-                },
+                ty::BoundRegion { var: ty::BoundVar::ZERO, kind: ty::BoundRegionKind::BrEnv },
             );
             let tupled_upvars_ty_for_borrow = Ty::new_tup_from_iter(
                 self.tcx,
@@ -402,16 +421,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             );
 
             // Additionally, we can now constrain the coroutine's kind type.
-            let ty::Coroutine(_, coroutine_args) =
-                *self.typeck_results.borrow().expr_ty(body.value).kind()
-            else {
-                bug!();
-            };
-            self.demand_eqtype(
-                span,
-                coroutine_args.as_coroutine().kind_ty(),
-                Ty::from_coroutine_closure_kind(self.tcx, closure_kind),
-            );
+            //
+            // We only do this if `infer_kind`, because if we have constrained
+            // the kind from closure signature inference, the kind inferred
+            // for the inner coroutine may actually be more restrictive.
+            if infer_kind {
+                let ty::Coroutine(_, coroutine_args) =
+                    *self.typeck_results.borrow().expr_ty(body.value).kind()
+                else {
+                    bug!();
+                };
+                self.demand_eqtype(
+                    span,
+                    coroutine_args.as_coroutine().kind_ty(),
+                    Ty::from_coroutine_closure_kind(self.tcx, closure_kind),
+                );
+            }
         }
 
         self.log_closure_min_capture_info(closure_def_id, span);
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index f4516b684c3..6604bf094c1 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -345,6 +345,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for WritebackCx<'cx, 'tcx> {
             _ => {}
         };
 
+        self.visit_skipped_ref_pats(p.hir_id);
         self.visit_pat_adjustments(p.span, p.hir_id);
 
         self.visit_node_id(p.span, p.hir_id);
@@ -674,6 +675,14 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
         }
     }
 
+    #[instrument(skip(self), level = "debug")]
+    fn visit_skipped_ref_pats(&mut self, hir_id: hir::HirId) {
+        if self.fcx.typeck_results.borrow_mut().skipped_ref_pats_mut().remove(hir_id) {
+            debug!("node is a skipped ref pat");
+            self.typeck_results.skipped_ref_pats_mut().insert(hir_id);
+        }
+    }
+
     fn visit_liberated_fn_sigs(&mut self) {
         let fcx_typeck_results = self.fcx.typeck_results.borrow();
         assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
diff --git a/compiler/rustc_incremental/src/persist/load.rs b/compiler/rustc_incremental/src/persist/load.rs
index 357f2ae92d4..26aaa24771f 100644
--- a/compiler/rustc_incremental/src/persist/load.rs
+++ b/compiler/rustc_incremental/src/persist/load.rs
@@ -11,6 +11,7 @@ use rustc_session::config::IncrementalStateAssertion;
 use rustc_session::Session;
 use rustc_span::ErrorGuaranteed;
 use std::path::{Path, PathBuf};
+use std::sync::Arc;
 
 use super::data::*;
 use super::file_format;
@@ -88,7 +89,7 @@ fn delete_dirty_work_product(sess: &Session, swp: SerializedWorkProduct) {
     work_product::delete_workproduct_files(sess, &swp.work_product);
 }
 
-fn load_dep_graph(sess: &Session) -> LoadResult<(SerializedDepGraph, WorkProductMap)> {
+fn load_dep_graph(sess: &Session) -> LoadResult<(Arc<SerializedDepGraph>, WorkProductMap)> {
     let prof = sess.prof.clone();
 
     if sess.opts.incremental.is_none() {
diff --git a/compiler/rustc_incremental/src/persist/save.rs b/compiler/rustc_incremental/src/persist/save.rs
index 32759f5284a..9777f769280 100644
--- a/compiler/rustc_incremental/src/persist/save.rs
+++ b/compiler/rustc_incremental/src/persist/save.rs
@@ -10,6 +10,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder};
 use rustc_serialize::Encodable as RustcEncodable;
 use rustc_session::Session;
 use std::fs;
+use std::sync::Arc;
 
 use super::data::*;
 use super::dirty_clean;
@@ -147,7 +148,7 @@ fn encode_query_cache(tcx: TyCtxt<'_>, encoder: FileEncoder) -> FileEncodeResult
 /// and moves it to the permanent dep-graph path
 pub(crate) fn build_dep_graph(
     sess: &Session,
-    prev_graph: SerializedDepGraph,
+    prev_graph: Arc<SerializedDepGraph>,
     prev_work_products: WorkProductMap,
 ) -> Option<DepGraph> {
     if sess.opts.incremental.is_none() {
diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs
index 12f8e42c78f..c7e563035fc 100644
--- a/compiler/rustc_index/src/bit_set.rs
+++ b/compiler/rustc_index/src/bit_set.rs
@@ -400,7 +400,7 @@ enum Chunk {
 }
 
 // This type is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 crate::static_assert_size!(Chunk, 16);
 
 impl<T> ChunkedBitSet<T> {
diff --git a/compiler/rustc_index_macros/src/newtype.rs b/compiler/rustc_index_macros/src/newtype.rs
index e5c2ba42483..fe9a048734f 100644
--- a/compiler/rustc_index_macros/src/newtype.rs
+++ b/compiler/rustc_index_macros/src/newtype.rs
@@ -174,6 +174,9 @@ impl Parse for Newtype {
                 /// Maximum value the index can take.
                 #vis const MAX: Self = Self::from_u32(#max);
 
+                /// Zero value of the index.
+                #vis const ZERO: Self = Self::from_u32(0);
+
                 /// Creates a new index from a given `usize`.
                 ///
                 /// # Panics
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index 339c8ac10b3..6e5ed0a31cb 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -483,7 +483,7 @@ pub enum SubregionOrigin<'tcx> {
 }
 
 // `SubregionOrigin` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(SubregionOrigin<'_>, 32);
 
 impl<'tcx> SubregionOrigin<'tcx> {
@@ -843,7 +843,9 @@ impl<'tcx> InferCtxt<'tcx> {
     {
         let origin = &ObligationCause::dummy();
         self.probe(|_| {
-            self.at(origin, param_env).sub(DefineOpaqueTypes::No, expected, actual).is_ok()
+            // We're only answering whether there could be a subtyping relation, and with
+            // opaque types, "there could be one", via registering a hidden type.
+            self.at(origin, param_env).sub(DefineOpaqueTypes::Yes, expected, actual).is_ok()
         })
     }
 
@@ -852,7 +854,9 @@ impl<'tcx> InferCtxt<'tcx> {
         T: at::ToTrace<'tcx>,
     {
         let origin = &ObligationCause::dummy();
-        self.probe(|_| self.at(origin, param_env).eq(DefineOpaqueTypes::No, a, b).is_ok())
+        // We're only answering whether the types could be the same, and with
+        // opaque types, "they can be the same", via registering a hidden type.
+        self.probe(|_| self.at(origin, param_env).eq(DefineOpaqueTypes::Yes, a, b).is_ok())
     }
 
     #[instrument(skip(self), level = "debug")]
diff --git a/compiler/rustc_infer/src/lib.rs b/compiler/rustc_infer/src/lib.rs
index ee9ce842d00..0444cbe2ee4 100644
--- a/compiler/rustc_infer/src/lib.rs
+++ b/compiler/rustc_infer/src/lib.rs
@@ -32,7 +32,7 @@
 
 #[macro_use]
 extern crate rustc_macros;
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 #[macro_use]
 extern crate rustc_data_structures;
 #[macro_use]
diff --git a/compiler/rustc_infer/src/traits/mod.rs b/compiler/rustc_infer/src/traits/mod.rs
index 616f5cc0456..94ad0f5b1c8 100644
--- a/compiler/rustc_infer/src/traits/mod.rs
+++ b/compiler/rustc_infer/src/traits/mod.rs
@@ -112,7 +112,7 @@ impl<'tcx> PolyTraitObligation<'tcx> {
 }
 
 // `PredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(PredicateObligation<'_>, 48);
 
 pub type PredicateObligations<'tcx> = Vec<PredicateObligation<'tcx>>;
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index d763a12f816..1f92cc4d763 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -748,9 +748,6 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
 
     sess.time("MIR_effect_checking", || {
         for def_id in tcx.hir().body_owners() {
-            if !tcx.sess.opts.unstable_opts.thir_unsafeck {
-                rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id);
-            }
             tcx.ensure().has_ffi_unwind_calls(def_id);
 
             // If we need to codegen, ensure that we emit all errors from
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 3b78e6a43ab..b9025917d13 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -840,7 +840,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(stack_protector, StackProtector::All);
     tracked!(teach, true);
     tracked!(thinlto, Some(true));
-    tracked!(thir_unsafeck, false);
     tracked!(tiny_const_eval_limit, true);
     tracked!(tls_model, Some(TlsModel::GeneralDynamic));
     tracked!(translate_remapped_path_to_local_path, false);
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index d938a0ccb39..797c0df4d73 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -443,7 +443,7 @@ lint_non_local_definitions_impl = non-local `impl` definition, they should be av
             [one] `{$body_name}`
            *[other] `{$body_name}` and up {$depth} bodies
         }
-    .non_local = an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+    .non_local = an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
     .exception = one exception to the rule are anon-const (`const _: () = {"{"} ... {"}"}`) at top-level module and anon-const at the same nesting as the trait or type
     .const_anon = use a const-anon item to suppress this lint
 
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 7c4d92d3ce0..1e9c60a540d 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -1,6 +1,18 @@
-use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, Path, QPath, TyKind};
+use rustc_hir::{def::DefKind, Body, Item, ItemKind, Node, TyKind};
+use rustc_hir::{Path, QPath};
+use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
+use rustc_infer::infer::InferCtxt;
+use rustc_infer::traits::{Obligation, ObligationCause};
+use rustc_middle::query::Key;
+use rustc_middle::ty::{self, Binder, Ty, TyCtxt, TypeFoldable, TypeFolder};
+use rustc_middle::ty::{EarlyBinder, TraitRef, TypeSuperFoldable};
 use rustc_span::def_id::{DefId, LOCAL_CRATE};
+use rustc_span::Span;
 use rustc_span::{sym, symbol::kw, ExpnKind, MacroKind};
+use rustc_trait_selection::infer::TyCtxtInferExt;
+use rustc_trait_selection::traits::error_reporting::ambiguity::{
+    compute_applicable_impls_for_diagnostics, CandidateSource,
+};
 
 use crate::lints::{NonLocalDefinitionsCargoUpdateNote, NonLocalDefinitionsDiag};
 use crate::{LateContext, LateLintPass, LintContext};
@@ -35,7 +47,7 @@ declare_lint! {
     /// All nested bodies (functions, enum discriminant, array length, consts) (expect for
     /// `const _: Ty = { ... }` in top-level module, which is still undecided) are checked.
     pub NON_LOCAL_DEFINITIONS,
-    Allow,
+    Warn,
     "checks for non-local definitions",
     report_in_external_macro
 }
@@ -66,7 +78,8 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
             return;
         }
 
-        let parent = cx.tcx.parent(item.owner_id.def_id.into());
+        let def_id = item.owner_id.def_id.into();
+        let parent = cx.tcx.parent(def_id);
         let parent_def_kind = cx.tcx.def_kind(parent);
         let parent_opt_item_name = cx.tcx.opt_item_name(parent);
 
@@ -121,6 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     None
                 };
 
+                // Part 1: Is the Self type local?
                 let self_ty_has_local_parent = match impl_.self_ty.kind {
                     TyKind::Path(QPath::Resolved(_, ty_path)) => {
                         path_has_local_parent(ty_path, cx, parent, parent_parent)
@@ -150,41 +164,70 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                     | TyKind::Err(_) => false,
                 };
 
+                if self_ty_has_local_parent {
+                    return;
+                }
+
+                // Part 2: Is the Trait local?
                 let of_trait_has_local_parent = impl_
                     .of_trait
                     .map(|of_trait| path_has_local_parent(of_trait.path, cx, parent, parent_parent))
                     .unwrap_or(false);
 
-                // If none of them have a local parent (LOGICAL NOR) this means that
-                // this impl definition is a non-local definition and so we lint on it.
-                if !(self_ty_has_local_parent || of_trait_has_local_parent) {
-                    let const_anon = if self.body_depth == 1
-                        && parent_def_kind == DefKind::Const
-                        && parent_opt_item_name != Some(kw::Underscore)
-                        && let Some(parent) = parent.as_local()
-                        && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
-                        && let ItemKind::Const(ty, _, _) = item.kind
-                        && let TyKind::Tup(&[]) = ty.kind
-                    {
-                        Some(item.ident.span)
-                    } else {
-                        None
-                    };
-
-                    cx.emit_span_lint(
-                        NON_LOCAL_DEFINITIONS,
-                        item.span,
-                        NonLocalDefinitionsDiag::Impl {
-                            depth: self.body_depth,
-                            body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
-                            body_name: parent_opt_item_name
-                                .map(|s| s.to_ident_string())
-                                .unwrap_or_else(|| "<unnameable>".to_string()),
-                            cargo_update: cargo_update(),
-                            const_anon,
-                        },
-                    )
+                if of_trait_has_local_parent {
+                    return;
+                }
+
+                // Part 3: Is the impl definition leaking outside it's defining scope?
+                //
+                // We always consider inherent impls to be leaking.
+                let impl_has_enough_non_local_candidates = cx
+                    .tcx
+                    .impl_trait_ref(def_id)
+                    .map(|binder| {
+                        impl_trait_ref_has_enough_non_local_candidates(
+                            cx.tcx,
+                            item.span,
+                            def_id,
+                            binder,
+                            |did| did_has_local_parent(did, cx.tcx, parent, parent_parent),
+                        )
+                    })
+                    .unwrap_or(false);
+
+                if impl_has_enough_non_local_candidates {
+                    return;
                 }
+
+                // Get the span of the parent const item ident (if it's a not a const anon).
+                //
+                // Used to suggest changing the const item to a const anon.
+                let span_for_const_anon_suggestion = if self.body_depth == 1
+                    && parent_def_kind == DefKind::Const
+                    && parent_opt_item_name != Some(kw::Underscore)
+                    && let Some(parent) = parent.as_local()
+                    && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent)
+                    && let ItemKind::Const(ty, _, _) = item.kind
+                    && let TyKind::Tup(&[]) = ty.kind
+                {
+                    Some(item.ident.span)
+                } else {
+                    None
+                };
+
+                cx.emit_span_lint(
+                    NON_LOCAL_DEFINITIONS,
+                    item.span,
+                    NonLocalDefinitionsDiag::Impl {
+                        depth: self.body_depth,
+                        body_kind_descr: cx.tcx.def_kind_descr(parent_def_kind, parent),
+                        body_name: parent_opt_item_name
+                            .map(|s| s.to_ident_string())
+                            .unwrap_or_else(|| "<unnameable>".to_string()),
+                        cargo_update: cargo_update(),
+                        const_anon: span_for_const_anon_suggestion,
+                    },
+                )
             }
             ItemKind::Macro(_macro, MacroKind::Bang)
                 if cx.tcx.has_attr(item.owner_id.def_id, sym::macro_export) =>
@@ -207,6 +250,81 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
     }
 }
 
+// Detecting if the impl definition is leaking outside of it's defining scope.
+//
+// Rule: for each impl, instantiate all local types with inference vars and
+// then assemble candidates for that goal, if there are more than 1 (non-private
+// impls), it does not leak.
+//
+// https://github.com/rust-lang/rust/issues/121621#issuecomment-1976826895
+fn impl_trait_ref_has_enough_non_local_candidates<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    infer_span: Span,
+    trait_def_id: DefId,
+    binder: EarlyBinder<TraitRef<'tcx>>,
+    mut did_has_local_parent: impl FnMut(DefId) -> bool,
+) -> bool {
+    let infcx = tcx.infer_ctxt().build();
+    let trait_ref = binder.instantiate(tcx, infcx.fresh_args_for_item(infer_span, trait_def_id));
+
+    let trait_ref = trait_ref.fold_with(&mut ReplaceLocalTypesWithInfer {
+        infcx: &infcx,
+        infer_span,
+        did_has_local_parent: &mut did_has_local_parent,
+    });
+
+    let poly_trait_obligation = Obligation::new(
+        tcx,
+        ObligationCause::dummy(),
+        ty::ParamEnv::empty(),
+        Binder::dummy(trait_ref),
+    );
+
+    let ambiguities = compute_applicable_impls_for_diagnostics(&infcx, &poly_trait_obligation);
+
+    let mut it = ambiguities.iter().filter(|ambi| match ambi {
+        CandidateSource::DefId(did) => !did_has_local_parent(*did),
+        CandidateSource::ParamEnv(_) => unreachable!(),
+    });
+
+    let _ = it.next();
+    it.next().is_some()
+}
+
+/// Replace every local type by inference variable.
+///
+/// ```text
+/// <Global<Local> as std::cmp::PartialEq<Global<Local>>>
+/// to
+/// <Global<_> as std::cmp::PartialEq<Global<_>>>
+/// ```
+struct ReplaceLocalTypesWithInfer<'a, 'tcx, F: FnMut(DefId) -> bool> {
+    infcx: &'a InferCtxt<'tcx>,
+    did_has_local_parent: F,
+    infer_span: Span,
+}
+
+impl<'a, 'tcx, F: FnMut(DefId) -> bool> TypeFolder<TyCtxt<'tcx>>
+    for ReplaceLocalTypesWithInfer<'a, 'tcx, F>
+{
+    fn interner(&self) -> TyCtxt<'tcx> {
+        self.infcx.tcx
+    }
+
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        if let Some(ty_did) = t.ty_def_id()
+            && (self.did_has_local_parent)(ty_did)
+        {
+            self.infcx.next_ty_var(TypeVariableOrigin {
+                kind: TypeVariableOriginKind::TypeInference,
+                span: self.infer_span,
+            })
+        } else {
+            t.super_fold_with(self)
+        }
+    }
+}
+
 /// Given a path and a parent impl def id, this checks if the if parent resolution
 /// def id correspond to the def id of the parent impl definition.
 ///
@@ -216,16 +334,29 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
 ///    std::convert::PartialEq<Foo<Bar>>
 ///    ^^^^^^^^^^^^^^^^^^^^^^^
 /// ```
+#[inline]
 fn path_has_local_parent(
     path: &Path<'_>,
     cx: &LateContext<'_>,
     impl_parent: DefId,
     impl_parent_parent: Option<DefId>,
 ) -> bool {
-    path.res.opt_def_id().is_some_and(|did| {
-        did.is_local() && {
-            let res_parent = cx.tcx.parent(did);
-            res_parent == impl_parent || Some(res_parent) == impl_parent_parent
-        }
-    })
+    path.res
+        .opt_def_id()
+        .is_some_and(|did| did_has_local_parent(did, cx.tcx, impl_parent, impl_parent_parent))
+}
+
+/// Given a def id and a parent impl def id, this checks if the parent
+/// def id correspond to the def id of the parent impl definition.
+#[inline]
+fn did_has_local_parent(
+    did: DefId,
+    tcx: TyCtxt<'_>,
+    impl_parent: DefId,
+    impl_parent_parent: Option<DefId>,
+) -> bool {
+    did.is_local() && {
+        let res_parent = tcx.parent(did);
+        res_parent == impl_parent || Some(res_parent) == impl_parent_parent
+    }
 }
diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs
index 7e9d35ca6c1..30522628f46 100644
--- a/compiler/rustc_lint_defs/src/builtin.rs
+++ b/compiler/rustc_lint_defs/src/builtin.rs
@@ -2797,17 +2797,17 @@ declare_lint! {
     /// Since this cast is lossy, it is considered good style to use the
     /// [`ptr::addr`] method instead, which has a similar effect, but doesn't
     /// "expose" the pointer provenance. This improves optimisation potential.
-    /// See the docs of [`ptr::addr`] and [`ptr::expose_addr`] for more information
+    /// See the docs of [`ptr::addr`] and [`ptr::expose_provenance`] for more information
     /// about exposing pointer provenance.
     ///
     /// If your code can't comply with strict provenance and needs to expose
-    /// the provenance, then there is [`ptr::expose_addr`] as an escape hatch,
+    /// the provenance, then there is [`ptr::expose_provenance`] as an escape hatch,
     /// which preserves the behaviour of `as usize` casts while being explicit
     /// about the semantics.
     ///
     /// [issue #95228]: https://github.com/rust-lang/rust/issues/95228
     /// [`ptr::addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.addr
-    /// [`ptr::expose_addr`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_addr
+    /// [`ptr::expose_provenance`]: https://doc.rust-lang.org/core/primitive.pointer.html#method.expose_provenance
     pub LOSSY_PROVENANCE_CASTS,
     Allow,
     "a lossy pointer to integer cast is used",
diff --git a/compiler/rustc_llvm/build.rs b/compiler/rustc_llvm/build.rs
index 4b0c1229da1..66ca94d1d9c 100644
--- a/compiler/rustc_llvm/build.rs
+++ b/compiler/rustc_llvm/build.rs
@@ -112,28 +112,10 @@ fn main() {
 
     restore_library_path();
 
-    let target = env::var("TARGET").expect("TARGET was not set");
     let llvm_config =
-        tracked_env_var_os("LLVM_CONFIG").map(|x| Some(PathBuf::from(x))).unwrap_or_else(|| {
-            if let Some(dir) = tracked_env_var_os("CARGO_TARGET_DIR").map(PathBuf::from) {
-                let to_test = dir
-                    .parent()
-                    .unwrap()
-                    .parent()
-                    .unwrap()
-                    .join(&target)
-                    .join("llvm/bin/llvm-config");
-                if Command::new(&to_test).output().is_ok() {
-                    return Some(to_test);
-                }
-            }
-            None
-        });
+        PathBuf::from(tracked_env_var_os("LLVM_CONFIG").expect("LLVM_CONFIG was not set"));
 
-    if let Some(llvm_config) = &llvm_config {
-        println!("cargo:rerun-if-changed={}", llvm_config.display());
-    }
-    let llvm_config = llvm_config.unwrap_or_else(|| PathBuf::from("llvm-config"));
+    println!("cargo:rerun-if-changed={}", llvm_config.display());
 
     // Test whether we're cross-compiling LLVM. This is a pretty rare case
     // currently where we're producing an LLVM for a different platform than
@@ -391,6 +373,12 @@ fn main() {
         }
     }
 
+    // libc++abi and libunwind have to be specified explicitly on AIX.
+    if target.contains("aix") {
+        println!("cargo:rustc-link-lib=c++abi");
+        println!("cargo:rustc-link-lib=unwind");
+    }
+
     // Libstdc++ depends on pthread which Rust doesn't link on MinGW
     // since nothing else requires it.
     if target.ends_with("windows-gnu") {
diff --git a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
index 60789b07e54..0998b463a88 100644
--- a/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/CoverageMappingWrapper.cpp
@@ -1,8 +1,8 @@
 #include "LLVMWrapper.h"
+#include "llvm/ADT/ArrayRef.h"
 #include "llvm/ProfileData/Coverage/CoverageMapping.h"
 #include "llvm/ProfileData/Coverage/CoverageMappingWriter.h"
 #include "llvm/ProfileData/InstrProf.h"
-#include "llvm/ADT/ArrayRef.h"
 
 #include <iostream>
 
@@ -103,35 +103,30 @@ fromRust(LLVMRustCounterExprKind Kind) {
 }
 
 extern "C" void LLVMRustCoverageWriteFilenamesSectionToBuffer(
-    const char *const Filenames[],
-    size_t FilenamesLen,
-    const size_t *const Lengths,
-    size_t LengthsLen,
+    const char *const Filenames[], size_t FilenamesLen, // String start pointers
+    const size_t *const Lengths, size_t LengthsLen,     // Corresponding lengths
     RustStringRef BufferOut) {
   if (FilenamesLen != LengthsLen) {
     report_fatal_error(
         "Mismatched lengths in LLVMRustCoverageWriteFilenamesSectionToBuffer");
   }
 
-  SmallVector<std::string,32> FilenameRefs;
+  SmallVector<std::string, 32> FilenameRefs;
   FilenameRefs.reserve(FilenamesLen);
   for (size_t i = 0; i < FilenamesLen; i++) {
     FilenameRefs.emplace_back(Filenames[i], Lengths[i]);
   }
-  auto FilenamesWriter =
-      coverage::CoverageFilenamesSectionWriter(ArrayRef<std::string>(FilenameRefs));
+  auto FilenamesWriter = coverage::CoverageFilenamesSectionWriter(
+      ArrayRef<std::string>(FilenameRefs));
   auto OS = RawRustStringOstream(BufferOut);
   FilenamesWriter.write(OS);
 }
 
 extern "C" void LLVMRustCoverageWriteMappingToBuffer(
-    const unsigned *VirtualFileMappingIDs,
-    unsigned NumVirtualFileMappingIDs,
-    const LLVMRustCounterExpression *RustExpressions,
-    unsigned NumExpressions,
+    const unsigned *VirtualFileMappingIDs, unsigned NumVirtualFileMappingIDs,
+    const LLVMRustCounterExpression *RustExpressions, unsigned NumExpressions,
     const LLVMRustCounterMappingRegion *RustMappingRegions,
-    unsigned NumMappingRegions,
-    RustStringRef BufferOut) {
+    unsigned NumMappingRegions, RustStringRef BufferOut) {
   // Convert from FFI representation to LLVM representation.
   SmallVector<coverage::CounterMappingRegion, 0> MappingRegions;
   MappingRegions.reserve(NumMappingRegions);
@@ -142,7 +137,7 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
 #if LLVM_VERSION_GE(18, 0) && LLVM_VERSION_LT(19, 0)
         coverage::CounterMappingRegion::MCDCParameters{},
 #endif
-        Region.FileID, Region.ExpandedFileID,
+        Region.FileID, Region.ExpandedFileID, // File IDs, then region info.
         Region.LineStart, Region.ColumnStart, Region.LineEnd, Region.ColumnEnd,
         fromRust(Region.Kind));
   }
@@ -158,29 +153,25 @@ extern "C" void LLVMRustCoverageWriteMappingToBuffer(
 
   auto CoverageMappingWriter = coverage::CoverageMappingWriter(
       ArrayRef<unsigned>(VirtualFileMappingIDs, NumVirtualFileMappingIDs),
-      Expressions,
-      MappingRegions);
+      Expressions, MappingRegions);
   auto OS = RawRustStringOstream(BufferOut);
   CoverageMappingWriter.write(OS);
 }
 
-extern "C" LLVMValueRef LLVMRustCoverageCreatePGOFuncNameVar(
-    LLVMValueRef F,
-    const char *FuncName,
-    size_t FuncNameLen) {
+extern "C" LLVMValueRef
+LLVMRustCoverageCreatePGOFuncNameVar(LLVMValueRef F, const char *FuncName,
+                                     size_t FuncNameLen) {
   auto FuncNameRef = StringRef(FuncName, FuncNameLen);
   return wrap(createPGOFuncNameVar(*cast<Function>(unwrap(F)), FuncNameRef));
 }
 
-extern "C" uint64_t LLVMRustCoverageHashByteArray(
-    const char *Bytes,
-    size_t NumBytes) {
+extern "C" uint64_t LLVMRustCoverageHashByteArray(const char *Bytes,
+                                                  size_t NumBytes) {
   auto StrRef = StringRef(Bytes, NumBytes);
   return IndexedInstrProf::ComputeHash(StrRef);
 }
 
-static void WriteSectionNameToString(LLVMModuleRef M,
-                                     InstrProfSectKind SK,
+static void WriteSectionNameToString(LLVMModuleRef M, InstrProfSectKind SK,
                                      RustStringRef Str) {
   auto TargetTriple = Triple(unwrap(M)->getTargetTriple());
   auto name = getInstrProfSectionName(SK, TargetTriple.getObjectFormat());
@@ -193,8 +184,9 @@ extern "C" void LLVMRustCoverageWriteMapSectionNameToString(LLVMModuleRef M,
   WriteSectionNameToString(M, IPSK_covmap, Str);
 }
 
-extern "C" void LLVMRustCoverageWriteFuncSectionNameToString(LLVMModuleRef M,
-                                                             RustStringRef Str) {
+extern "C" void
+LLVMRustCoverageWriteFuncSectionNameToString(LLVMModuleRef M,
+                                             RustStringRef Str) {
   WriteSectionNameToString(M, IPSK_covfun, Str);
 }
 
@@ -205,5 +197,8 @@ extern "C" void LLVMRustCoverageWriteMappingVarNameToString(RustStringRef Str) {
 }
 
 extern "C" uint32_t LLVMRustCoverageMappingVersion() {
-  return coverage::CovMapVersion::Version6;
+  // This should always be `CurrentVersion`, because that's the version LLVM
+  // will use when encoding the data we give it. If for some reason we ever
+  // want to override the version number we _emit_, do it on the Rust side.
+  return coverage::CovMapVersion::CurrentVersion;
 }
diff --git a/compiler/rustc_middle/src/arena.rs b/compiler/rustc_middle/src/arena.rs
index c90427256b8..bd11b3eb04c 100644
--- a/compiler/rustc_middle/src/arena.rs
+++ b/compiler/rustc_middle/src/arena.rs
@@ -35,7 +35,6 @@ macro_rules! arena_types {
             )>,
             [] crate_for_resolver: rustc_data_structures::steal::Steal<(rustc_ast::Crate, rustc_ast::AttrVec)>,
             [] resolutions: rustc_middle::ty::ResolverGlobalCtxt,
-            [decode] unsafety_check_result: rustc_middle::mir::UnsafetyCheckResult,
             [decode] code_region: rustc_middle::mir::coverage::CodeRegion,
             [] const_allocs: rustc_middle::mir::interpret::Allocation,
             [] region_scope_tree: rustc_middle::middle::region::ScopeTree,
diff --git a/compiler/rustc_middle/src/dep_graph/dep_node.rs b/compiler/rustc_middle/src/dep_graph/dep_node.rs
index 39d82c489d5..3c5bf6eb824 100644
--- a/compiler/rustc_middle/src/dep_graph/dep_node.rs
+++ b/compiler/rustc_middle/src/dep_graph/dep_node.rs
@@ -194,9 +194,10 @@ impl DepNodeExt for DepNode {
     /// has been removed.
     fn extract_def_id(&self, tcx: TyCtxt<'_>) -> Option<DefId> {
         if tcx.fingerprint_style(self.kind) == FingerprintStyle::DefPathHash {
-            Some(tcx.def_path_hash_to_def_id(DefPathHash(self.hash.into()), &mut || {
-                panic!("Failed to extract DefId: {:?} {}", self.kind, self.hash)
-            }))
+            Some(tcx.def_path_hash_to_def_id(
+                DefPathHash(self.hash.into()),
+                &("Failed to extract DefId", self.kind, self.hash),
+            ))
         } else {
             None
         }
@@ -390,9 +391,10 @@ impl<'tcx> DepNodeParams<TyCtxt<'tcx>> for HirId {
             let (local_hash, local_id) = Fingerprint::from(dep_node.hash).split();
             let def_path_hash = DefPathHash::new(tcx.stable_crate_id(LOCAL_CRATE), local_hash);
             let def_id = tcx
-                .def_path_hash_to_def_id(def_path_hash, &mut || {
-                    panic!("Failed to extract HirId: {:?} {}", dep_node.kind, dep_node.hash)
-                })
+                .def_path_hash_to_def_id(
+                    def_path_hash,
+                    &("Failed to extract HirId", dep_node.kind, dep_node.hash),
+                )
                 .expect_local();
             let local_id = local_id
                 .as_u64()
diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs
index 53cb05198cd..72f849b534a 100644
--- a/compiler/rustc_middle/src/hir/map/mod.rs
+++ b/compiler/rustc_middle/src/hir/map/mod.rs
@@ -13,7 +13,6 @@ use rustc_hir::def_id::{DefId, LocalDefId, LocalModDefId, LOCAL_CRATE};
 use rustc_hir::definitions::{DefKey, DefPath, DefPathHash};
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::*;
-use rustc_index::Idx;
 use rustc_middle::hir::nested_filter;
 use rustc_span::def_id::StableCrateId;
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -69,7 +68,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
 
     fn next(&mut self) -> Option<Self::Item> {
         if self.current_id.local_id.index() != 0 {
-            self.current_id.local_id = ItemLocalId::new(0);
+            self.current_id.local_id = ItemLocalId::ZERO;
             let node = self.map.tcx.hir_owner_node(self.current_id.owner);
             return Some((self.current_id.owner, node));
         }
@@ -133,7 +132,7 @@ impl<'tcx> TyCtxt<'tcx> {
     /// If calling repeatedly and iterating over parents, prefer [`Map::parent_iter`].
     pub fn parent_hir_id(self, hir_id: HirId) -> HirId {
         let HirId { owner, local_id } = hir_id;
-        if local_id == ItemLocalId::from_u32(0) {
+        if local_id == ItemLocalId::ZERO {
             self.hir_owner_parent(owner)
         } else {
             let parent_local_id = self.hir_owner_nodes(owner).nodes[local_id].parent;
diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs
index 28f7574f66f..94d1039c763 100644
--- a/compiler/rustc_middle/src/hir/mod.rs
+++ b/compiler/rustc_middle/src/hir/mod.rs
@@ -174,8 +174,12 @@ pub fn provide(providers: &mut Providers) {
             let parent_owner_id = tcx.local_def_id_to_hir_id(parent_def_id).owner;
             HirId {
                 owner: parent_owner_id,
-                local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id].unwrap().parenting
-                    [&owner_id.def_id],
+                local_id: tcx.hir_crate(()).owners[parent_owner_id.def_id]
+                    .unwrap()
+                    .parenting
+                    .get(&owner_id.def_id)
+                    .copied()
+                    .unwrap_or(ItemLocalId::ZERO),
             }
         })
     };
diff --git a/compiler/rustc_middle/src/infer/canonical.rs b/compiler/rustc_middle/src/infer/canonical.rs
index 7b65c11bc3c..acea89e4aab 100644
--- a/compiler/rustc_middle/src/infer/canonical.rs
+++ b/compiler/rustc_middle/src/infer/canonical.rs
@@ -82,7 +82,7 @@ impl CanonicalVarValues<'_> {
     }
 
     pub fn is_identity_modulo_regions(&self) -> bool {
-        let mut var = ty::BoundVar::from_u32(0);
+        let mut var = ty::BoundVar::ZERO;
         for arg in self.var_values {
             match arg.unpack() {
                 ty::GenericArgKind::Lifetime(r) => {
diff --git a/compiler/rustc_middle/src/mir/consts.rs b/compiler/rustc_middle/src/mir/consts.rs
index 2663a6b551e..155af062012 100644
--- a/compiler/rustc_middle/src/mir/consts.rs
+++ b/compiler/rustc_middle/src/mir/consts.rs
@@ -70,7 +70,7 @@ pub enum ConstValue<'tcx> {
     },
 }
 
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(ConstValue<'_>, 24);
 
 impl<'tcx> ConstValue<'tcx> {
diff --git a/compiler/rustc_middle/src/mir/coverage.rs b/compiler/rustc_middle/src/mir/coverage.rs
index 588aa1f40d7..582a1806688 100644
--- a/compiler/rustc_middle/src/mir/coverage.rs
+++ b/compiler/rustc_middle/src/mir/coverage.rs
@@ -33,10 +33,6 @@ rustc_index::newtype_index! {
     pub struct CounterId {}
 }
 
-impl CounterId {
-    pub const START: Self = Self::from_u32(0);
-}
-
 rustc_index::newtype_index! {
     /// ID of a coverage-counter expression. Values ascend from 0.
     ///
@@ -55,10 +51,6 @@ rustc_index::newtype_index! {
     pub struct ExpressionId {}
 }
 
-impl ExpressionId {
-    pub const START: Self = Self::from_u32(0);
-}
-
 /// Enum that can hold a constant zero value, the ID of an physical coverage
 /// counter, or the ID of a coverage-counter expression.
 ///
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index c86970635a5..e9be26d058b 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -88,7 +88,7 @@ pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
 /// This is needed in `thir::pattern::lower_inline_const`.
 pub type EvalToValTreeResult<'tcx> = Result<Option<ValTree<'tcx>>, ErrorHandled>;
 
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(InterpErrorInfo<'_>, 8);
 
 /// Packages the kind of error we got from the const code interpreter
diff --git a/compiler/rustc_middle/src/mir/interpret/value.rs b/compiler/rustc_middle/src/mir/interpret/value.rs
index 24d4a79c7d7..9f9433e483b 100644
--- a/compiler/rustc_middle/src/mir/interpret/value.rs
+++ b/compiler/rustc_middle/src/mir/interpret/value.rs
@@ -37,7 +37,7 @@ pub enum Scalar<Prov = CtfeProvenance> {
     Ptr(Pointer<Prov>, u8),
 }
 
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(Scalar, 24);
 
 // We want the `Debug` output to be readable as it is used by `derive(Debug)` for
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index e5a650c5ac4..ad166620bcc 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -845,17 +845,6 @@ impl<'tcx> Body<'tcx> {
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug, TyEncodable, TyDecodable, HashStable)]
-pub enum Safety {
-    Safe,
-    /// Unsafe because of compiler-generated unsafe code, like `await` desugaring
-    BuiltinUnsafe,
-    /// Unsafe because of an unsafe fn
-    FnUnsafe,
-    /// Unsafe because of an `unsafe` block
-    ExplicitUnsafe(hir::HirId),
-}
-
 impl<'tcx> Index<BasicBlock> for Body<'tcx> {
     type Output = BasicBlockData<'tcx>;
 
@@ -1611,8 +1600,6 @@ pub struct SourceScopeData<'tcx> {
 pub struct SourceScopeLocalData {
     /// An `HirId` with lint levels equivalent to this scope's lint levels.
     pub lint_root: hir::HirId,
-    /// The unsafe block that contains this node.
-    pub safety: Safety,
 }
 
 /// A collection of projections into user types.
@@ -1881,14 +1868,14 @@ impl DefLocation {
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
     // tidy-alphabetical-start
     static_assert_size!(BasicBlockData<'_>, 144);
     static_assert_size!(LocalDecl<'_>, 40);
-    static_assert_size!(SourceScopeData<'_>, 72);
+    static_assert_size!(SourceScopeData<'_>, 64);
     static_assert_size!(Statement<'_>, 32);
     static_assert_size!(StatementKind<'_>, 16);
     static_assert_size!(Terminator<'_>, 112);
diff --git a/compiler/rustc_middle/src/mir/query.rs b/compiler/rustc_middle/src/mir/query.rs
index 731e050ca9b..0f622127430 100644
--- a/compiler/rustc_middle/src/mir/query.rs
+++ b/compiler/rustc_middle/src/mir/query.rs
@@ -3,9 +3,7 @@
 use crate::mir;
 use crate::ty::{self, OpaqueHiddenType, Ty, TyCtxt};
 use rustc_data_structures::fx::FxIndexMap;
-use rustc_data_structures::unord::UnordSet;
 use rustc_errors::ErrorGuaranteed;
-use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_index::bit_set::BitMatrix;
 use rustc_index::{Idx, IndexVec};
@@ -18,67 +16,6 @@ use std::fmt::{self, Debug};
 
 use super::{ConstValue, SourceInfo};
 
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UnsafetyViolationKind {
-    /// Unsafe operation outside `unsafe`.
-    General,
-    /// Unsafe operation in an `unsafe fn` but outside an `unsafe` block.
-    /// Has to be handled as a lint for backwards compatibility.
-    UnsafeFn,
-}
-
-#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UnsafetyViolationDetails {
-    CallToUnsafeFunction,
-    UseOfInlineAssembly,
-    InitializingTypeWith,
-    CastOfPointerToInt,
-    UseOfMutableStatic,
-    UseOfExternStatic,
-    DerefOfRawPointer,
-    AccessToUnionField,
-    MutationOfLayoutConstrainedField,
-    BorrowOfLayoutConstrainedField,
-    CallToFunctionWith {
-        /// Target features enabled in callee's `#[target_feature]` but missing in
-        /// caller's `#[target_feature]`.
-        missing: Vec<Symbol>,
-        /// Target features in `missing` that are enabled at compile time
-        /// (e.g., with `-C target-feature`).
-        build_enabled: Vec<Symbol>,
-    },
-}
-
-#[derive(Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub struct UnsafetyViolation {
-    pub source_info: SourceInfo,
-    pub lint_root: hir::HirId,
-    pub kind: UnsafetyViolationKind,
-    pub details: UnsafetyViolationDetails,
-}
-
-#[derive(Copy, Clone, PartialEq, TyEncodable, TyDecodable, HashStable, Debug)]
-pub enum UnusedUnsafe {
-    /// `unsafe` block contains no unsafe operations
-    /// > ``unnecessary `unsafe` block``
-    Unused,
-    /// `unsafe` block nested under another (used) `unsafe` block
-    /// > ``… because it's nested under this `unsafe` block``
-    InUnsafeBlock(hir::HirId),
-}
-
-#[derive(TyEncodable, TyDecodable, HashStable, Debug)]
-pub struct UnsafetyCheckResult {
-    /// Violations that are propagated *upwards* from this function.
-    pub violations: Vec<UnsafetyViolation>,
-
-    /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
-    pub used_unsafe_blocks: UnordSet<hir::HirId>,
-
-    /// This is `Some` iff the item is not a closure.
-    pub unused_unsafes: Option<Vec<(hir::HirId, UnusedUnsafe)>>,
-}
-
 rustc_index::newtype_index! {
     #[derive(HashStable)]
     #[encodable]
@@ -276,7 +213,7 @@ pub struct ClosureOutlivesRequirement<'tcx> {
 }
 
 // Make sure this enum doesn't unintentionally grow
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(ConstraintCategory<'_>, 16);
 
 /// Outlives-constraints can be categorized to determine whether and why they
diff --git a/compiler/rustc_middle/src/mir/statement.rs b/compiler/rustc_middle/src/mir/statement.rs
index 947764307e4..069c8019cb2 100644
--- a/compiler/rustc_middle/src/mir/statement.rs
+++ b/compiler/rustc_middle/src/mir/statement.rs
@@ -409,7 +409,7 @@ impl<'tcx> Rvalue<'tcx> {
             // Pointer to int casts may be side-effects due to exposing the provenance.
             // While the model is undecided, we should be conservative. See
             // <https://www.ralfj.de/blog/2022/04/11/provenance-exposed.html>
-            Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false,
+            Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => false,
 
             Rvalue::Use(_)
             | Rvalue::CopyForDeref(_)
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 1f6165babdf..c78c225b0cd 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1309,8 +1309,8 @@ pub enum Rvalue<'tcx> {
 pub enum CastKind {
     /// An exposing pointer to address cast. A cast between a pointer and an integer type, or
     /// between a function pointer and an integer type.
-    /// See the docs on `expose_addr` for more details.
-    PointerExposeAddress,
+    /// See the docs on `expose_provenance` for more details.
+    PointerExposeProvenance,
     /// An address-to-pointer cast that picks up an exposed provenance.
     /// See the docs on `with_exposed_provenance` for more details.
     PointerWithExposedProvenance,
@@ -1453,7 +1453,7 @@ pub enum BinOp {
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     // tidy-alphabetical-start
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 74c2aef8fcc..b86aa601ce8 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -14,7 +14,7 @@ pub struct PlaceTy<'tcx> {
 }
 
 // At least on 64 bit systems, `PlaceTy` should not be larger than two or three pointers.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(PlaceTy<'_>, 16);
 
 impl<'tcx> PlaceTy<'tcx> {
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 3835bd371d9..4f7b2f7cbe4 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -341,7 +341,7 @@ macro_rules! make_mir_visitor {
 
                         ty::InstanceDef::Intrinsic(_def_id) |
                         ty::InstanceDef::VTableShim(_def_id) |
-                        ty::InstanceDef::ReifyShim(_def_id) |
+                        ty::InstanceDef::ReifyShim(_def_id, _) |
                         ty::InstanceDef::Virtual(_def_id, _) |
                         ty::InstanceDef::ThreadLocalShim(_def_id) |
                         ty::InstanceDef::ClosureOnceShim { call_once: _def_id, track_caller: _ } |
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 5e4454db3e2..62a60a650ec 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -877,12 +877,6 @@ rustc_queries! {
         desc { |tcx| "collecting all inherent impls for `{:?}`", key }
     }
 
-    /// The result of unsafety-checking this `LocalDefId` with the old checker.
-    query mir_unsafety_check_result(key: LocalDefId) -> &'tcx mir::UnsafetyCheckResult {
-        desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) }
-        cache_on_disk_if { true }
-    }
-
     /// Unsafety-check this `LocalDefId`.
     query check_unsafety(key: LocalDefId) {
         desc { |tcx| "unsafety-checking `{}`", tcx.def_path_str(key) }
diff --git a/compiler/rustc_middle/src/query/on_disk_cache.rs b/compiler/rustc_middle/src/query/on_disk_cache.rs
index 9c7c46f2ad2..8f02b3121ac 100644
--- a/compiler/rustc_middle/src/query/on_disk_cache.rs
+++ b/compiler/rustc_middle/src/query/on_disk_cache.rs
@@ -737,9 +737,10 @@ impl<'a, 'tcx> SpanDecoder for CacheDecoder<'a, 'tcx> {
         // If we get to this point, then all of the query inputs were green,
         // which means that the definition with this hash is guaranteed to
         // still exist in the current compilation session.
-        self.tcx.def_path_hash_to_def_id(def_path_hash, &mut || {
-            panic!("Failed to convert DefPathHash {def_path_hash:?}")
-        })
+        self.tcx.def_path_hash_to_def_id(
+            def_path_hash,
+            &("Failed to convert DefPathHash", def_path_hash),
+        )
     }
 
     fn decode_attr_id(&mut self) -> rustc_span::AttrId {
diff --git a/compiler/rustc_middle/src/query/plumbing.rs b/compiler/rustc_middle/src/query/plumbing.rs
index e3588a7afdc..8cb4ee7bd41 100644
--- a/compiler/rustc_middle/src/query/plumbing.rs
+++ b/compiler/rustc_middle/src/query/plumbing.rs
@@ -339,7 +339,7 @@ macro_rules! define_callbacks {
                 pub type Storage<'tcx> = <$($K)* as keys::Key>::Cache<Erase<$V>>;
 
                 // Ensure that keys grow no larger than 64 bytes
-                #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+                #[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
                 const _: () = {
                     if mem::size_of::<Key<'static>>() > 64 {
                         panic!("{}", concat!(
@@ -353,7 +353,7 @@ macro_rules! define_callbacks {
                 };
 
                 // Ensure that values grow no larger than 64 bytes
-                #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+                #[cfg(all(any(target_arch = "x86_64", target_arch="aarch64"), target_pointer_width = "64"))]
                 const _: () = {
                     if mem::size_of::<Value<'static>>() > 64 {
                         panic!("{}", concat!(
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 05f6fbbbfa3..f10b204cd47 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -12,7 +12,7 @@ use rustc_ast::{InlineAsmOptions, InlineAsmTemplatePiece};
 use rustc_errors::{DiagArgValue, IntoDiagArg};
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{BindingAnnotation, ByRef, RangeEnd};
+use rustc_hir::{BindingAnnotation, ByRef, MatchSource, RangeEnd};
 use rustc_index::newtype_index;
 use rustc_index::IndexVec;
 use rustc_middle::middle::region;
@@ -358,6 +358,7 @@ pub enum ExprKind<'tcx> {
         scrutinee: ExprId,
         scrutinee_hir_id: hir::HirId,
         arms: Box<[ArmId]>,
+        match_source: MatchSource,
     },
     /// A block.
     Block {
@@ -1120,7 +1121,8 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
                             printed += 1;
                         }
 
-                        if printed < variant.fields.len() {
+                        let is_union = self.ty.ty_adt_def().is_some_and(|adt| adt.is_union());
+                        if printed < variant.fields.len() && (!is_union || printed == 0) {
                             write!(f, "{}..", start_or_comma())?;
                         }
 
@@ -1204,7 +1206,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
 }
 
 // Some nodes are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     // tidy-alphabetical-start
diff --git a/compiler/rustc_middle/src/traits/mod.rs b/compiler/rustc_middle/src/traits/mod.rs
index efea2a66bb2..ee816791919 100644
--- a/compiler/rustc_middle/src/traits/mod.rs
+++ b/compiler/rustc_middle/src/traits/mod.rs
@@ -550,7 +550,7 @@ impl<'tcx> ObligationCauseCode<'tcx> {
 }
 
 // `ObligationCauseCode` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(ObligationCauseCode<'_>, 48);
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs
index 16842c8208f..52cdbae1e56 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect.rs
@@ -121,8 +121,6 @@ pub enum ProbeStep<'tcx> {
     /// used whenever there are multiple candidates to prove the
     /// current goalby .
     NestedProbe(Probe<'tcx>),
-    CommitIfOkStart,
-    CommitIfOkSuccess,
 }
 
 /// What kind of probe we're in. In case the probe represents a candidate, or
@@ -132,6 +130,8 @@ pub enum ProbeStep<'tcx> {
 pub enum ProbeKind<'tcx> {
     /// The root inference context while proving a goal.
     Root { result: QueryResult<'tcx> },
+    /// Trying to normalize an alias by at least one step in `NormalizesTo`.
+    TryNormalizeNonRigid { result: QueryResult<'tcx> },
     /// Probe entered when normalizing the self ty during candidate assembly
     NormalizedSelfTyAssembly,
     /// Some candidate to prove the current goal.
@@ -143,9 +143,6 @@ pub enum ProbeKind<'tcx> {
     /// Used in the probe that wraps normalizing the non-self type for the unsize
     /// trait, which is also structurally matched on.
     UnsizeAssembly,
-    /// A call to `EvalCtxt::commit_if_ok` which failed, causing the work
-    /// to be discarded.
-    CommitIfOk,
     /// During upcasting from some source object to target object type, used to
     /// do a probe to find out what projection type(s) may be used to prove that
     /// the source type upholds all of the target type's object bounds.
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index 43931205017..98f01fe8772 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -100,6 +100,9 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
             ProbeKind::Root { result } => {
                 write!(self.f, "ROOT RESULT: {result:?}")
             }
+            ProbeKind::TryNormalizeNonRigid { result } => {
+                write!(self.f, "TRY NORMALIZE NON-RIGID: {result:?}")
+            }
             ProbeKind::NormalizedSelfTyAssembly => {
                 write!(self.f, "NORMALIZING SELF TY FOR ASSEMBLY:")
             }
@@ -109,9 +112,6 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
             ProbeKind::UpcastProjectionCompatibility => {
                 write!(self.f, "PROBING FOR PROJECTION COMPATIBILITY FOR UPCASTING:")
             }
-            ProbeKind::CommitIfOk => {
-                write!(self.f, "COMMIT_IF_OK:")
-            }
             ProbeKind::MiscCandidate { name, result } => {
                 write!(self.f, "CANDIDATE {name}: {result:?}")
             }
@@ -132,8 +132,6 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
                     }
                     ProbeStep::EvaluateGoals(eval) => this.format_added_goals_evaluation(eval)?,
                     ProbeStep::NestedProbe(probe) => this.format_probe(probe)?,
-                    ProbeStep::CommitIfOkStart => writeln!(this.f, "COMMIT_IF_OK START")?,
-                    ProbeStep::CommitIfOkSuccess => writeln!(this.f, "COMMIT_IF_OK SUCCESS")?,
                 }
             }
             Ok(())
diff --git a/compiler/rustc_middle/src/ty/cast.rs b/compiler/rustc_middle/src/ty/cast.rs
index 9bdc679d4e5..c9fd20bc112 100644
--- a/compiler/rustc_middle/src/ty/cast.rs
+++ b/compiler/rustc_middle/src/ty/cast.rs
@@ -83,7 +83,7 @@ pub fn mir_cast_kind<'tcx>(from_ty: Ty<'tcx>, cast_ty: Ty<'tcx>) -> mir::CastKin
     let cast = CastTy::from_ty(cast_ty);
     let cast_kind = match (from, cast) {
         (Some(CastTy::Ptr(_) | CastTy::FnPtr), Some(CastTy::Int(_))) => {
-            mir::CastKind::PointerExposeAddress
+            mir::CastKind::PointerExposeProvenance
         }
         (Some(CastTy::Int(_)), Some(CastTy::Ptr(_))) => mir::CastKind::PointerWithExposedProvenance,
         (_, Some(CastTy::DynStar)) => mir::CastKind::DynStar,
diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs
index ddbc0bffaed..e7a1679b151 100644
--- a/compiler/rustc_middle/src/ty/codec.rs
+++ b/compiler/rustc_middle/src/ty/codec.rs
@@ -458,7 +458,6 @@ impl_decodable_via_ref! {
     &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>,
     &'tcx traits::ImplSource<'tcx, ()>,
     &'tcx mir::Body<'tcx>,
-    &'tcx mir::UnsafetyCheckResult,
     &'tcx mir::BorrowCheckResult<'tcx>,
     &'tcx mir::coverage::CodeRegion,
     &'tcx ty::List<ty::BoundVariableKind>,
diff --git a/compiler/rustc_middle/src/ty/consts.rs b/compiler/rustc_middle/src/ty/consts.rs
index 3713883eb00..49b806b8369 100644
--- a/compiler/rustc_middle/src/ty/consts.rs
+++ b/compiler/rustc_middle/src/ty/consts.rs
@@ -59,7 +59,7 @@ pub struct ConstData<'tcx> {
     pub kind: ConstKind<'tcx>,
 }
 
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(ConstData<'_>, 40);
 
 impl<'tcx> Const<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/consts/kind.rs b/compiler/rustc_middle/src/ty/consts/kind.rs
index ea02faca5f3..94e41709f5d 100644
--- a/compiler/rustc_middle/src/ty/consts/kind.rs
+++ b/compiler/rustc_middle/src/ty/consts/kind.rs
@@ -71,8 +71,8 @@ pub enum Expr<'tcx> {
     Cast(CastKind, Const<'tcx>, Ty<'tcx>),
 }
 
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(Expr<'_>, 24);
 
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(super::ConstKind<'_>, 32);
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 23881c4b124..75deffe6957 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -1121,7 +1121,11 @@ impl<'tcx> TyCtxt<'tcx> {
     /// Converts a `DefPathHash` to its corresponding `DefId` in the current compilation
     /// session, if it still exists. This is used during incremental compilation to
     /// turn a deserialized `DefPathHash` into its current `DefId`.
-    pub fn def_path_hash_to_def_id(self, hash: DefPathHash, err: &mut dyn FnMut() -> !) -> DefId {
+    pub fn def_path_hash_to_def_id(
+        self,
+        hash: DefPathHash,
+        err_msg: &dyn std::fmt::Debug,
+    ) -> DefId {
         debug!("def_path_hash_to_def_id({:?})", hash);
 
         let stable_crate_id = hash.stable_crate_id();
@@ -1129,7 +1133,11 @@ impl<'tcx> TyCtxt<'tcx> {
         // If this is a DefPathHash from the local crate, we can look up the
         // DefId in the tcx's `Definitions`.
         if stable_crate_id == self.stable_crate_id(LOCAL_CRATE) {
-            self.untracked.definitions.read().local_def_path_hash_to_def_id(hash, err).to_def_id()
+            self.untracked
+                .definitions
+                .read()
+                .local_def_path_hash_to_def_id(hash, err_msg)
+                .to_def_id()
         } else {
             // If this is a DefPathHash from an upstream crate, let the CrateStore map
             // it to a DefId.
@@ -1961,33 +1969,104 @@ impl<'tcx> TyCtxt<'tcx> {
         if pred.kind() != binder { self.mk_predicate(binder) } else { pred }
     }
 
-    #[inline(always)]
-    pub(crate) fn check_and_mk_args(
+    pub fn check_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) -> bool {
+        self.check_args_compatible_inner(def_id, args, false)
+    }
+
+    fn check_args_compatible_inner(
         self,
-        _def_id: DefId,
-        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
-    ) -> GenericArgsRef<'tcx> {
-        let args = args.into_iter().map(Into::into);
-        #[cfg(debug_assertions)]
+        def_id: DefId,
+        args: &'tcx [ty::GenericArg<'tcx>],
+        nested: bool,
+    ) -> bool {
+        let generics = self.generics_of(def_id);
+
+        // IATs themselves have a weird arg setup (self + own args), but nested items *in* IATs
+        // (namely: opaques, i.e. ATPITs) do not.
+        let own_args = if !nested
+            && let DefKind::AssocTy = self.def_kind(def_id)
+            && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
         {
-            let generics = self.generics_of(_def_id);
+            if generics.params.len() + 1 != args.len() {
+                return false;
+            }
+
+            if !matches!(args[0].unpack(), ty::GenericArgKind::Type(_)) {
+                return false;
+            }
+
+            &args[1..]
+        } else {
+            if generics.count() != args.len() {
+                return false;
+            }
+
+            let (parent_args, own_args) = args.split_at(generics.parent_count);
 
-            let n = if let DefKind::AssocTy = self.def_kind(_def_id)
-                && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(_def_id))
+            if let Some(parent) = generics.parent
+                && !self.check_args_compatible_inner(parent, parent_args, true)
             {
-                // If this is an inherent projection.
-                generics.params.len() + 1
-            } else {
-                generics.count()
-            };
-            assert_eq!(
-                (n, Some(n)),
-                args.size_hint(),
-                "wrong number of generic parameters for {_def_id:?}: {:?}",
-                args.collect::<Vec<_>>(),
-            );
+                return false;
+            }
+
+            own_args
+        };
+
+        for (param, arg) in std::iter::zip(&generics.params, own_args) {
+            match (&param.kind, arg.unpack()) {
+                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
+                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
+                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
+                _ => return false,
+            }
         }
-        self.mk_args_from_iter(args)
+
+        true
+    }
+
+    /// With `cfg(debug_assertions)`, assert that args are compatible with their generics,
+    /// and print out the args if not.
+    pub fn debug_assert_args_compatible(self, def_id: DefId, args: &'tcx [ty::GenericArg<'tcx>]) {
+        if cfg!(debug_assertions) {
+            if !self.check_args_compatible(def_id, args) {
+                if let DefKind::AssocTy = self.def_kind(def_id)
+                    && let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(def_id))
+                {
+                    bug!(
+                        "args not compatible with generics for {}: args={:#?}, generics={:#?}",
+                        self.def_path_str(def_id),
+                        args,
+                        // Make `[Self, GAT_ARGS...]` (this could be simplified)
+                        self.mk_args_from_iter(
+                            [self.types.self_param.into()].into_iter().chain(
+                                self.generics_of(def_id)
+                                    .own_args(ty::GenericArgs::identity_for_item(self, def_id))
+                                    .iter()
+                                    .copied()
+                            )
+                        )
+                    );
+                } else {
+                    bug!(
+                        "args not compatible with generics for {}: args={:#?}, generics={:#?}",
+                        self.def_path_str(def_id),
+                        args,
+                        ty::GenericArgs::identity_for_item(self, def_id)
+                    );
+                }
+            }
+        }
+    }
+
+    #[inline(always)]
+    pub(crate) fn check_and_mk_args(
+        self,
+        def_id: DefId,
+        args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
+    ) -> GenericArgsRef<'tcx> {
+        let args = self.mk_args_from_iter(args.into_iter().map(Into::into));
+        self.debug_assert_args_compatible(def_id, args);
+        args
     }
 
     #[inline]
diff --git a/compiler/rustc_middle/src/ty/instance.rs b/compiler/rustc_middle/src/ty/instance.rs
index 4fec5653a79..4a7720b38f8 100644
--- a/compiler/rustc_middle/src/ty/instance.rs
+++ b/compiler/rustc_middle/src/ty/instance.rs
@@ -31,6 +31,28 @@ pub struct Instance<'tcx> {
     pub args: GenericArgsRef<'tcx>,
 }
 
+/// Describes why a `ReifyShim` was created. This is needed to distingish a ReifyShim created to
+/// adjust for things like `#[track_caller]` in a vtable from a `ReifyShim` created to produce a
+/// function pointer from a vtable entry.
+/// Currently, this is only used when KCFI is enabled, as only KCFI needs to treat those two
+/// `ReifyShim`s differently.
+#[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
+#[derive(TyEncodable, TyDecodable, HashStable)]
+pub enum ReifyReason {
+    /// The `ReifyShim` was created to produce a function pointer. This happens when:
+    /// * A vtable entry is directly converted to a function call (e.g. creating a fn ptr from a
+    ///   method on a `dyn` object).
+    /// * A function with `#[track_caller]` is converted to a function pointer
+    /// * If KCFI is enabled, creating a function pointer from a method on an object-safe trait.
+    /// This includes the case of converting `::call`-like methods on closure-likes to function
+    /// pointers.
+    FnPtr,
+    /// This `ReifyShim` was created to populate a vtable. Currently, this happens when a
+    /// `#[track_caller]` mismatch occurs between the implementation of a method and the method.
+    /// This includes the case of `::call`-like methods in closure-likes' vtables.
+    Vtable,
+}
+
 #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)]
 #[derive(TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable, Lift)]
 pub enum InstanceDef<'tcx> {
@@ -67,7 +89,13 @@ pub enum InstanceDef<'tcx> {
     /// Because this is a required part of the function's ABI but can't be tracked
     /// as a property of the function pointer, we use a single "caller location"
     /// (the definition of the function itself).
-    ReifyShim(DefId),
+    ///
+    /// The second field encodes *why* this shim was created. This allows distinguishing between
+    /// a `ReifyShim` that appears in a vtable vs one that appears as a function pointer.
+    ///
+    /// This field will only be populated if we are compiling in a mode that needs these shims
+    /// to be separable, currently only when KCFI is enabled.
+    ReifyShim(DefId, Option<ReifyReason>),
 
     /// `<fn() as FnTrait>::call_*` (generated `FnTrait` implementation for `fn()` pointers).
     ///
@@ -194,7 +222,7 @@ impl<'tcx> InstanceDef<'tcx> {
         match self {
             InstanceDef::Item(def_id)
             | InstanceDef::VTableShim(def_id)
-            | InstanceDef::ReifyShim(def_id)
+            | InstanceDef::ReifyShim(def_id, _)
             | InstanceDef::FnPtrShim(def_id, _)
             | InstanceDef::Virtual(def_id, _)
             | InstanceDef::Intrinsic(def_id)
@@ -354,7 +382,9 @@ fn fmt_instance(
     match instance.def {
         InstanceDef::Item(_) => Ok(()),
         InstanceDef::VTableShim(_) => write!(f, " - shim(vtable)"),
-        InstanceDef::ReifyShim(_) => write!(f, " - shim(reify)"),
+        InstanceDef::ReifyShim(_, None) => write!(f, " - shim(reify)"),
+        InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr)) => write!(f, " - shim(reify-fnptr)"),
+        InstanceDef::ReifyShim(_, Some(ReifyReason::Vtable)) => write!(f, " - shim(reify-vtable)"),
         InstanceDef::ThreadLocalShim(_) => write!(f, " - shim(tls)"),
         InstanceDef::Intrinsic(_) => write!(f, " - intrinsic"),
         InstanceDef::Virtual(_, num) => write!(f, " - virtual#{num}"),
@@ -476,15 +506,34 @@ impl<'tcx> Instance<'tcx> {
         debug!("resolve(def_id={:?}, args={:?})", def_id, args);
         // Use either `resolve_closure` or `resolve_for_vtable`
         assert!(!tcx.is_closure_like(def_id), "Called `resolve_for_fn_ptr` on closure: {def_id:?}");
+        let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::FnPtr);
         Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
             match resolved.def {
                 InstanceDef::Item(def) if resolved.def.requires_caller_location(tcx) => {
                     debug!(" => fn pointer created for function with #[track_caller]");
-                    resolved.def = InstanceDef::ReifyShim(def);
+                    resolved.def = InstanceDef::ReifyShim(def, reason);
                 }
                 InstanceDef::Virtual(def_id, _) => {
                     debug!(" => fn pointer created for virtual call");
-                    resolved.def = InstanceDef::ReifyShim(def_id);
+                    resolved.def = InstanceDef::ReifyShim(def_id, reason);
+                }
+                // Reify `Trait::method` implementations if KCFI is enabled
+                // FIXME(maurer) only reify it if it is a vtable-safe function
+                _ if tcx.sess.is_sanitizer_kcfi_enabled()
+                    && tcx.associated_item(def_id).trait_item_def_id.is_some() =>
+                {
+                    // If this function could also go in a vtable, we need to `ReifyShim` it with
+                    // KCFI because it can only attach one type per function.
+                    resolved.def = InstanceDef::ReifyShim(resolved.def_id(), reason)
+                }
+                // Reify `::call`-like method implementations if KCFI is enabled
+                _ if tcx.sess.is_sanitizer_kcfi_enabled()
+                    && tcx.is_closure_like(resolved.def_id()) =>
+                {
+                    // Reroute through a reify via the *unresolved* instance. The resolved one can't
+                    // be directly reified because it's closure-like. The reify can handle the
+                    // unresolved instance.
+                    resolved = Instance { def: InstanceDef::ReifyShim(def_id, reason), args }
                 }
                 _ => {}
             }
@@ -508,6 +557,7 @@ impl<'tcx> Instance<'tcx> {
             debug!(" => associated item with unsizeable self: Self");
             Some(Instance { def: InstanceDef::VTableShim(def_id), args })
         } else {
+            let reason = tcx.sess.is_sanitizer_kcfi_enabled().then_some(ReifyReason::Vtable);
             Instance::resolve(tcx, param_env, def_id, args).ok().flatten().map(|mut resolved| {
                 match resolved.def {
                     InstanceDef::Item(def) => {
@@ -544,18 +594,18 @@ impl<'tcx> Instance<'tcx> {
                                 // Create a shim for the `FnOnce/FnMut/Fn` method we are calling
                                 // - unlike functions, invoking a closure always goes through a
                                 // trait.
-                                resolved = Instance { def: InstanceDef::ReifyShim(def_id), args };
+                                resolved = Instance { def: InstanceDef::ReifyShim(def_id, reason), args };
                             } else {
                                 debug!(
                                     " => vtable fn pointer created for function with #[track_caller]: {:?}", def
                                 );
-                                resolved.def = InstanceDef::ReifyShim(def);
+                                resolved.def = InstanceDef::ReifyShim(def, reason);
                             }
                         }
                     }
                     InstanceDef::Virtual(def_id, _) => {
                         debug!(" => vtable fn pointer created for virtual call");
-                        resolved.def = InstanceDef::ReifyShim(def_id);
+                        resolved.def = InstanceDef::ReifyShim(def_id, reason)
                     }
                     _ => {}
                 }
diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs
index 4e1baaec39e..fb56c71c517 100644
--- a/compiler/rustc_middle/src/ty/mod.rs
+++ b/compiler/rustc_middle/src/ty/mod.rs
@@ -88,7 +88,7 @@ pub use self::context::{
     tls, CtxtInterners, CurrentGcx, DeducedParamAttrs, Feed, FreeRegionInfo, GlobalCtxt, Lift,
     TyCtxt, TyCtxtFeed,
 };
-pub use self::instance::{Instance, InstanceDef, ShortInstance, UnusedGenericParams};
+pub use self::instance::{Instance, InstanceDef, ReifyReason, ShortInstance, UnusedGenericParams};
 pub use self::list::List;
 pub use self::parameterized::ParameterizedOverTcx;
 pub use self::predicate::{
@@ -1324,7 +1324,7 @@ impl VariantDef {
     pub fn single_field(&self) -> &FieldDef {
         assert!(self.fields.len() == 1);
 
-        &self.fields[FieldIdx::from_u32(0)]
+        &self.fields[FieldIdx::ZERO]
     }
 
     /// Returns the last field in this variant, if present.
@@ -2168,7 +2168,7 @@ pub struct DestructuredConst<'tcx> {
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
index d4c8f5900f9..58543674460 100644
--- a/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
+++ b/compiler/rustc_middle/src/ty/normalize_erasing_regions.rs
@@ -49,7 +49,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let value = self.erase_regions(value);
         debug!(?value);
 
-        if !value.has_projections() {
+        if !value.has_aliases() {
             value
         } else {
             value.fold_with(&mut NormalizeAfterErasingRegionsFolder { tcx: self, param_env })
@@ -81,7 +81,7 @@ impl<'tcx> TyCtxt<'tcx> {
         let value = self.erase_regions(value);
         debug!(?value);
 
-        if !value.has_projections() {
+        if !value.has_aliases() {
             Ok(value)
         } else {
             let mut folder = TryNormalizeAfterErasingRegionsFolder::new(self, param_env);
diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs
index 5ff98dc8c87..2a898430ce9 100644
--- a/compiler/rustc_middle/src/ty/print/pretty.rs
+++ b/compiler/rustc_middle/src/ty/print/pretty.rs
@@ -2589,7 +2589,7 @@ impl<'a, 'tcx> ty::TypeFolder<TyCtxt<'tcx>> for RegionFolder<'a, 'tcx> {
                     ty::BrAnon | ty::BrEnv => r,
                     _ => {
                         // Index doesn't matter, since this is just for naming and these never get bound
-                        let br = ty::BoundRegion { var: ty::BoundVar::from_u32(0), kind };
+                        let br = ty::BoundRegion { var: ty::BoundVar::ZERO, kind };
                         *self
                             .region_map
                             .entry(br)
diff --git a/compiler/rustc_middle/src/ty/structural_impls.rs b/compiler/rustc_middle/src/ty/structural_impls.rs
index a62379def53..0e7010e67d7 100644
--- a/compiler/rustc_middle/src/ty/structural_impls.rs
+++ b/compiler/rustc_middle/src/ty/structural_impls.rs
@@ -449,6 +449,7 @@ TrivialTypeTraversalAndLiftImpls! {
     crate::ty::ClosureKind,
     crate::ty::ParamConst,
     crate::ty::ParamTy,
+    crate::ty::instance::ReifyReason,
     interpret::AllocId,
     interpret::CtfeProvenance,
     interpret::Scalar,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index b5e619f1e2a..2ab63f01e7c 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -11,7 +11,7 @@ use crate::ty::{
 };
 use crate::ty::{GenericArg, GenericArgs, GenericArgsRef};
 use crate::ty::{List, ParamEnv};
-use hir::def::DefKind;
+use hir::def::{CtorKind, DefKind};
 use rustc_data_structures::captures::Captures;
 use rustc_errors::{DiagArgValue, ErrorGuaranteed, IntoDiagArg, MultiSpan};
 use rustc_hir as hir;
@@ -1624,13 +1624,7 @@ impl<'tcx> Ty<'tcx> {
 
     #[inline]
     pub fn new_adt(tcx: TyCtxt<'tcx>, def: AdtDef<'tcx>, args: GenericArgsRef<'tcx>) -> Ty<'tcx> {
-        debug_assert_eq!(
-            tcx.generics_of(def.did()).count(),
-            args.len(),
-            "wrong number of args for ADT: {:#?} vs {:#?}",
-            tcx.generics_of(def.did()).params,
-            args
-        );
+        tcx.debug_assert_args_compatible(def.did(), args);
         Ty::new(tcx, Adt(def, args))
     }
 
@@ -1677,6 +1671,10 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
     ) -> Ty<'tcx> {
+        debug_assert_matches!(
+            tcx.def_kind(def_id),
+            DefKind::AssocFn | DefKind::Fn | DefKind::Ctor(_, CtorKind::Fn)
+        );
         let args = tcx.check_and_mk_args(def_id, args);
         Ty::new(tcx, FnDef(def_id, args))
     }
@@ -1711,11 +1709,7 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         closure_args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        debug_assert_eq!(
-            closure_args.len(),
-            tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 3,
-            "closure constructed with incorrect generic parameters"
-        );
+        tcx.debug_assert_args_compatible(def_id, closure_args);
         Ty::new(tcx, Closure(def_id, closure_args))
     }
 
@@ -1725,11 +1719,7 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         closure_args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        debug_assert_eq!(
-            closure_args.len(),
-            tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 5,
-            "closure constructed with incorrect generic parameters"
-        );
+        tcx.debug_assert_args_compatible(def_id, closure_args);
         Ty::new(tcx, CoroutineClosure(def_id, closure_args))
     }
 
@@ -1739,11 +1729,7 @@ impl<'tcx> Ty<'tcx> {
         def_id: DefId,
         coroutine_args: GenericArgsRef<'tcx>,
     ) -> Ty<'tcx> {
-        debug_assert_eq!(
-            coroutine_args.len(),
-            tcx.generics_of(tcx.typeck_root_def_id(def_id)).count() + 6,
-            "coroutine constructed with incorrect number of generic parameters"
-        );
+        tcx.debug_assert_args_compatible(def_id, coroutine_args);
         Ty::new(tcx, Coroutine(def_id, coroutine_args))
     }
 
@@ -1954,7 +1940,7 @@ impl<'tcx> Ty<'tcx> {
             Adt(def, args) => {
                 assert!(def.repr().simd(), "`simd_size_and_type` called on non-SIMD type");
                 let variant = def.non_enum_variant();
-                let f0_ty = variant.fields[FieldIdx::from_u32(0)].ty(tcx, args);
+                let f0_ty = variant.fields[FieldIdx::ZERO].ty(tcx, args);
 
                 match f0_ty.kind() {
                     // If the first field is an array, we assume it is the only field and its
@@ -2699,7 +2685,7 @@ impl<'tcx> VarianceDiagInfo<'tcx> {
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_middle/src/ty/typeck_results.rs b/compiler/rustc_middle/src/ty/typeck_results.rs
index d60926bf796..995feeaa148 100644
--- a/compiler/rustc_middle/src/ty/typeck_results.rs
+++ b/compiler/rustc_middle/src/ty/typeck_results.rs
@@ -19,7 +19,7 @@ use rustc_hir::{
     hir_id::OwnerId,
     BindingAnnotation, ByRef, HirId, ItemLocalId, ItemLocalMap, ItemLocalSet, Mutability,
 };
-use rustc_index::{Idx, IndexVec};
+use rustc_index::IndexVec;
 use rustc_macros::HashStable;
 use rustc_middle::mir::FakeReadCause;
 use rustc_session::Session;
@@ -96,6 +96,10 @@ pub struct TypeckResults<'tcx> {
     /// <https://github.com/rust-lang/rfcs/blob/master/text/2005-match-ergonomics.md#definitions>
     pat_adjustments: ItemLocalMap<Vec<Ty<'tcx>>>,
 
+    /// Set of reference patterns that match against a match-ergonomics inserted reference
+    /// (as opposed to against a reference in the scrutinee type).
+    skipped_ref_pats: ItemLocalSet,
+
     /// Records the reasons that we picked the kind of each closure;
     /// not all closures are present in the map.
     closure_kind_origins: ItemLocalMap<(Span, HirPlace<'tcx>)>,
@@ -228,6 +232,7 @@ impl<'tcx> TypeckResults<'tcx> {
             adjustments: Default::default(),
             pat_binding_modes: Default::default(),
             pat_adjustments: Default::default(),
+            skipped_ref_pats: Default::default(),
             closure_kind_origins: Default::default(),
             liberated_fn_sigs: Default::default(),
             fru_field_types: Default::default(),
@@ -435,6 +440,14 @@ impl<'tcx> TypeckResults<'tcx> {
         LocalTableInContextMut { hir_owner: self.hir_owner, data: &mut self.pat_adjustments }
     }
 
+    pub fn skipped_ref_pats(&self) -> LocalSetInContext<'_> {
+        LocalSetInContext { hir_owner: self.hir_owner, data: &self.skipped_ref_pats }
+    }
+
+    pub fn skipped_ref_pats_mut(&mut self) -> LocalSetInContextMut<'_> {
+        LocalSetInContextMut { hir_owner: self.hir_owner, data: &mut self.skipped_ref_pats }
+    }
+
     /// Does the pattern recursively contain a `ref mut` binding in it?
     ///
     /// This is used to determined whether a `deref` pattern should emit a `Deref`
@@ -629,6 +642,49 @@ impl<'a, V> LocalTableInContextMut<'a, V> {
     }
 }
 
+#[derive(Clone, Copy, Debug)]
+pub struct LocalSetInContext<'a> {
+    hir_owner: OwnerId,
+    data: &'a ItemLocalSet,
+}
+
+impl<'a> LocalSetInContext<'a> {
+    pub fn is_empty(&self) -> bool {
+        self.data.is_empty()
+    }
+
+    pub fn contains(&self, id: hir::HirId) -> bool {
+        validate_hir_id_for_typeck_results(self.hir_owner, id);
+        self.data.contains(&id.local_id)
+    }
+}
+
+#[derive(Debug)]
+pub struct LocalSetInContextMut<'a> {
+    hir_owner: OwnerId,
+    data: &'a mut ItemLocalSet,
+}
+
+impl<'a> LocalSetInContextMut<'a> {
+    pub fn is_empty(&self) -> bool {
+        self.data.is_empty()
+    }
+
+    pub fn contains(&self, id: hir::HirId) -> bool {
+        validate_hir_id_for_typeck_results(self.hir_owner, id);
+        self.data.contains(&id.local_id)
+    }
+    pub fn insert(&mut self, id: hir::HirId) -> bool {
+        validate_hir_id_for_typeck_results(self.hir_owner, id);
+        self.data.insert(id.local_id)
+    }
+
+    pub fn remove(&mut self, id: hir::HirId) -> bool {
+        validate_hir_id_for_typeck_results(self.hir_owner, id);
+        self.data.remove(&id.local_id)
+    }
+}
+
 rustc_index::newtype_index! {
     #[derive(HashStable)]
     #[encodable]
@@ -680,7 +736,7 @@ impl<'tcx> IsIdentity for CanonicalUserType<'tcx> {
                     return false;
                 }
 
-                iter::zip(user_args.args, BoundVar::new(0)..).all(|(kind, cvar)| {
+                iter::zip(user_args.args, BoundVar::ZERO..).all(|(kind, cvar)| {
                     match kind.unpack() {
                         GenericArgKind::Type(ty) => match ty.kind() {
                             ty::Bound(debruijn, b) => {
diff --git a/compiler/rustc_mir_build/src/build/block.rs b/compiler/rustc_mir_build/src/build/block.rs
index 6200f4bda6b..00e99f330f7 100644
--- a/compiler/rustc_mir_build/src/build/block.rs
+++ b/compiler/rustc_mir_build/src/build/block.rs
@@ -13,31 +13,15 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         ast_block: BlockId,
         source_info: SourceInfo,
     ) -> BlockAnd<()> {
-        let Block { region_scope, span, ref stmts, expr, targeted_by_break, safety_mode } =
+        let Block { region_scope, span, ref stmts, expr, targeted_by_break, safety_mode: _ } =
             self.thir[ast_block];
         self.in_scope((region_scope, source_info), LintLevel::Inherited, move |this| {
             if targeted_by_break {
                 this.in_breakable_scope(None, destination, span, |this| {
-                    Some(this.ast_block_stmts(
-                        destination,
-                        block,
-                        span,
-                        stmts,
-                        expr,
-                        safety_mode,
-                        region_scope,
-                    ))
+                    Some(this.ast_block_stmts(destination, block, span, stmts, expr, region_scope))
                 })
             } else {
-                this.ast_block_stmts(
-                    destination,
-                    block,
-                    span,
-                    stmts,
-                    expr,
-                    safety_mode,
-                    region_scope,
-                )
+                this.ast_block_stmts(destination, block, span, stmts, expr, region_scope)
             }
         })
     }
@@ -49,7 +33,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         span: Span,
         stmts: &[StmtId],
         expr: Option<ExprId>,
-        safety_mode: BlockSafety,
         region_scope: Scope,
     ) -> BlockAnd<()> {
         let this = self;
@@ -72,13 +55,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         // First we build all the statements in the block.
         let mut let_scope_stack = Vec::with_capacity(8);
         let outer_source_scope = this.source_scope;
-        let outer_in_scope_unsafe = this.in_scope_unsafe;
         // This scope information is kept for breaking out of the parent remainder scope in case
         // one let-else pattern matching fails.
         // By doing so, we can be sure that even temporaries that receive extended lifetime
         // assignments are dropped, too.
         let mut last_remainder_scope = region_scope;
-        this.update_source_scope_for_safety_mode(span, safety_mode);
 
         let source_info = this.source_info(span);
         for stmt in stmts {
@@ -202,7 +183,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     let_scope_stack.push(remainder_scope);
 
                     let visibility_scope =
-                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
+                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited));
 
                     let initializer_span = this.thir[*initializer].span;
                     let scope = (*init_scope, source_info);
@@ -271,7 +252,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     let remainder_span = remainder_scope.span(this.tcx, this.region_scope_tree);
 
                     let visibility_scope =
-                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited, None));
+                        Some(this.new_source_scope(remainder_span, LintLevel::Inherited));
 
                     // Evaluate the initializer, if present.
                     if let Some(init) = *initializer {
@@ -364,22 +345,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         }
         // Restore the original source scope.
         this.source_scope = outer_source_scope;
-        this.in_scope_unsafe = outer_in_scope_unsafe;
         block.unit()
     }
-
-    /// If we are entering an unsafe block, create a new source scope
-    fn update_source_scope_for_safety_mode(&mut self, span: Span, safety_mode: BlockSafety) {
-        debug!("update_source_scope_for({:?}, {:?})", span, safety_mode);
-        let new_unsafety = match safety_mode {
-            BlockSafety::Safe => return,
-            BlockSafety::BuiltinUnsafe => Safety::BuiltinUnsafe,
-            BlockSafety::ExplicitUnsafe(hir_id) => {
-                self.in_scope_unsafe = Safety::ExplicitUnsafe(hir_id);
-                Safety::ExplicitUnsafe(hir_id)
-            }
-        };
-
-        self.source_scope = self.new_source_scope(span, LintLevel::Inherited, Some(new_unsafety));
-    }
 }
diff --git a/compiler/rustc_mir_build/src/build/custom/mod.rs b/compiler/rustc_mir_build/src/build/custom/mod.rs
index 0475bb8908b..30877e38318 100644
--- a/compiler/rustc_mir_build/src/build/custom/mod.rs
+++ b/compiler/rustc_mir_build/src/build/custom/mod.rs
@@ -72,10 +72,7 @@ pub(super) fn build_custom_mir<'tcx>(
         parent_scope: None,
         inlined: None,
         inlined_parent_scope: None,
-        local_data: ClearCrossCrate::Set(SourceScopeLocalData {
-            lint_root: hir_id,
-            safety: Safety::Safe,
-        }),
+        local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }),
     });
     body.injection_phase = Some(parse_attribute(attr));
 
diff --git a/compiler/rustc_mir_build/src/build/custom/parse.rs b/compiler/rustc_mir_build/src/build/custom/parse.rs
index a6f9caada2d..0384b9bc154 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse.rs
@@ -215,7 +215,7 @@ impl<'tcx, 'body> ParseCtxt<'tcx, 'body> {
 
     fn parse_local_decls(&mut self, mut stmts: impl Iterator<Item = StmtId>) -> PResult<()> {
         let (ret_var, ..) = self.parse_let_statement(stmts.next().unwrap())?;
-        self.local_map.insert(ret_var, Local::from_u32(0));
+        self.local_map.insert(ret_var, Local::ZERO);
 
         for stmt in stmts {
             let (var, ty, span) = self.parse_let_statement(stmt)?;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
index c77f4a06d05..260ab058e60 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -118,19 +118,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             ExprKind::Box { value } => {
                 let value_ty = this.thir[value].ty;
                 let tcx = this.tcx;
-
-                // `exchange_malloc` is unsafe but box is safe, so need a new scope.
-                let synth_scope = this.new_source_scope(
-                    expr_span,
-                    LintLevel::Inherited,
-                    Some(Safety::BuiltinUnsafe),
-                );
-                let synth_info = SourceInfo { span: expr_span, scope: synth_scope };
+                let source_info = this.source_info(expr_span);
 
                 let size = this.temp(tcx.types.usize, expr_span);
                 this.cfg.push_assign(
                     block,
-                    synth_info,
+                    source_info,
                     size,
                     Rvalue::NullaryOp(NullOp::SizeOf, value_ty),
                 );
@@ -138,7 +131,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let align = this.temp(tcx.types.usize, expr_span);
                 this.cfg.push_assign(
                     block,
-                    synth_info,
+                    source_info,
                     align,
                     Rvalue::NullaryOp(NullOp::AlignOf, value_ty),
                 );
@@ -154,7 +147,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 let success = this.cfg.start_new_block();
                 this.cfg.terminate(
                     block,
-                    synth_info,
+                    source_info,
                     TerminatorKind::Call {
                         func: exchange_malloc,
                         args: vec![
@@ -580,7 +573,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     result_value,
                     Rvalue::CheckedBinaryOp(op, Box::new((lhs.to_copy(), rhs.to_copy()))),
                 );
-                let val_fld = FieldIdx::new(0);
+                let val_fld = FieldIdx::ZERO;
                 let of_fld = FieldIdx::new(1);
 
                 let tcx = self.tcx;
diff --git a/compiler/rustc_mir_build/src/build/expr/into.rs b/compiler/rustc_mir_build/src/build/expr/into.rs
index b4eeeccc127..c8360b6a5fd 100644
--- a/compiler/rustc_mir_build/src/build/expr/into.rs
+++ b/compiler/rustc_mir_build/src/build/expr/into.rs
@@ -69,7 +69,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                         // FIXME: Does this need extra logic to handle let-chains?
                         let source_info = if this.is_let(cond) {
                             let variable_scope =
-                                this.new_source_scope(then_span, LintLevel::Inherited, None);
+                                this.new_source_scope(then_span, LintLevel::Inherited);
                             this.source_scope = variable_scope;
                             SourceInfo { span: then_span, scope: variable_scope }
                         } else {
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index a6b513ce7d0..367c391b45a 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -214,12 +214,77 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// ## False edges
     ///
-    /// We don't want to have the exact structure of the decision tree be
-    /// visible through borrow checking. False edges ensure that the CFG as
-    /// seen by borrow checking doesn't encode this. False edges are added:
+    /// We don't want to have the exact structure of the decision tree be visible through borrow
+    /// checking. Specifically we want borrowck to think that:
+    /// - at any point, any or none of the patterns and guards seen so far may have been tested;
+    /// - after the match, any of the patterns may have matched.
     ///
-    /// * From each pre-binding block to the next pre-binding block.
-    /// * From each otherwise block to the next pre-binding block.
+    /// For example, all of these would fail to error if borrowck could see the real CFG (examples
+    /// taken from `tests/ui/nll/match-cfg-fake-edges.rs`):
+    /// ```ignore (too many errors, this is already in the test suite)
+    /// let x = String::new();
+    /// let _ = match true {
+    ///     _ => {},
+    ///     _ => drop(x),
+    /// };
+    /// // Borrowck must not know the second arm is never run.
+    /// drop(x); //~ ERROR use of moved value
+    ///
+    /// let x;
+    /// # let y = true;
+    /// match y {
+    ///     _ if { x = 2; true } => {},
+    ///     // Borrowck must not know the guard is always run.
+    ///     _ => drop(x), //~ ERROR used binding `x` is possibly-uninitialized
+    /// };
+    ///
+    /// let x = String::new();
+    /// # let y = true;
+    /// match y {
+    ///     false if { drop(x); true } => {},
+    ///     // Borrowck must not know the guard is not run in the `true` case.
+    ///     true => drop(x), //~ ERROR use of moved value: `x`
+    ///     false => {},
+    /// };
+    ///
+    /// # let mut y = (true, true);
+    /// let r = &mut y.1;
+    /// match y {
+    ///     //~^ ERROR cannot use `y.1` because it was mutably borrowed
+    ///     (false, true) => {}
+    ///     // Borrowck must not know we don't test `y.1` when `y.0` is `true`.
+    ///     (true, _) => drop(r),
+    ///     (false, _) => {}
+    /// };
+    /// ```
+    ///
+    /// We add false edges to act as if we were naively matching each arm in order. What we need is
+    /// a (fake) path from each candidate to the next, specifically from candidate C's pre-binding
+    /// block to next candidate D's pre-binding block. For maximum precision (needed for deref
+    /// patterns), we choose the earliest node on D's success path that doesn't also lead to C (to
+    /// avoid loops).
+    ///
+    /// This turns out to be easy to compute: that block is the `start_block` of the first call to
+    /// `match_candidates` where D is the first candidate in the list.
+    ///
+    /// For example:
+    /// ```rust
+    /// # let (x, y) = (true, true);
+    /// match (x, y) {
+    ///   (true, true) => 1,
+    ///   (false, true) => 2,
+    ///   (true, false) => 3,
+    ///   _ => 4,
+    /// }
+    /// # ;
+    /// ```
+    /// In this example, the pre-binding block of arm 1 has a false edge to the block for result
+    /// `false` of the first test on `x`. The other arms have false edges to the pre-binding blocks
+    /// of the next arm.
+    ///
+    /// On top of this, we also add a false edge from the otherwise_block of each guard to the
+    /// aforementioned start block of the next candidate, to ensure borrock doesn't rely on which
+    /// guards may have run.
     #[instrument(level = "debug", skip(self, arms))]
     pub(crate) fn match_expr(
         &mut self,
@@ -365,7 +430,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         for candidate in candidates {
             candidate.visit_leaves(|leaf_candidate| {
                 if let Some(ref mut prev) = previous_candidate {
-                    prev.next_candidate_pre_binding_block = leaf_candidate.pre_binding_block;
+                    assert!(leaf_candidate.false_edge_start_block.is_some());
+                    prev.next_candidate_start_block = leaf_candidate.false_edge_start_block;
                 }
                 previous_candidate = Some(leaf_candidate);
             });
@@ -732,7 +798,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             &mut |this, name, mode, var, span, ty, user_ty| {
                 if visibility_scope.is_none() {
                     visibility_scope =
-                        Some(this.new_source_scope(scope_span, LintLevel::Inherited, None));
+                        Some(this.new_source_scope(scope_span, LintLevel::Inherited));
                 }
                 let source_info = SourceInfo { span, scope: this.source_scope };
                 let visibility_scope = visibility_scope.unwrap();
@@ -1010,8 +1076,12 @@ struct Candidate<'pat, 'tcx> {
 
     /// The block before the `bindings` have been established.
     pre_binding_block: Option<BasicBlock>,
-    /// The pre-binding block of the next candidate.
-    next_candidate_pre_binding_block: Option<BasicBlock>,
+
+    /// The earliest block that has only candidates >= this one as descendents. Used for false
+    /// edges, see the doc for [`Builder::match_expr`].
+    false_edge_start_block: Option<BasicBlock>,
+    /// The `false_edge_start_block` of the next candidate.
+    next_candidate_start_block: Option<BasicBlock>,
 }
 
 impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
@@ -1033,7 +1103,8 @@ impl<'tcx, 'pat> Candidate<'pat, 'tcx> {
             or_span: None,
             otherwise_block: None,
             pre_binding_block: None,
-            next_candidate_pre_binding_block: None,
+            false_edge_start_block: None,
+            next_candidate_start_block: None,
         }
     }
 
@@ -1325,6 +1396,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         otherwise_block: BasicBlock,
         candidates: &mut [&mut Candidate<'_, 'tcx>],
     ) {
+        if let [first, ..] = candidates {
+            if first.false_edge_start_block.is_none() {
+                first.false_edge_start_block = Some(start_block);
+            }
+        }
+
         match candidates {
             [] => {
                 // If there are no candidates that still need testing, we're done. Since all matches are
@@ -1545,6 +1622,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             .into_iter()
             .map(|flat_pat| Candidate::from_flat_pat(flat_pat, candidate.has_guard))
             .collect();
+        candidate.subcandidates[0].false_edge_start_block = candidate.false_edge_start_block;
     }
 
     /// Try to merge all of the subcandidates of the given candidate into one. This avoids
@@ -1564,6 +1642,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let any_matches = self.cfg.start_new_block();
             let or_span = candidate.or_span.take().unwrap();
             let source_info = self.source_info(or_span);
+            if candidate.false_edge_start_block.is_none() {
+                candidate.false_edge_start_block =
+                    candidate.subcandidates[0].false_edge_start_block;
+            }
             for subcandidate in mem::take(&mut candidate.subcandidates) {
                 let or_block = subcandidate.pre_binding_block.unwrap();
                 self.cfg.goto(or_block, source_info, any_matches);
@@ -1979,12 +2061,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         let mut block = candidate.pre_binding_block.unwrap();
 
-        if candidate.next_candidate_pre_binding_block.is_some() {
+        if candidate.next_candidate_start_block.is_some() {
             let fresh_block = self.cfg.start_new_block();
             self.false_edges(
                 block,
                 fresh_block,
-                candidate.next_candidate_pre_binding_block,
+                candidate.next_candidate_start_block,
                 candidate_source_info,
             );
             block = fresh_block;
@@ -2132,7 +2214,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             self.false_edges(
                 otherwise_post_guard_block,
                 otherwise_block,
-                candidate.next_candidate_pre_binding_block,
+                candidate.next_candidate_start_block,
                 source_info,
             );
 
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 274edf358e0..6972bc00e0b 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -66,17 +66,10 @@ pub(crate) fn mir_build<'tcx>(tcx: TyCtxtAt<'tcx>, def: LocalDefId) -> Body<'tcx
             // maybe move the check to a MIR pass?
             tcx.ensure().check_liveness(def);
 
-            if tcx.sess.opts.unstable_opts.thir_unsafeck {
-                // Don't steal here if THIR unsafeck is being used. Instead
-                // steal in unsafeck. This is so that pattern inline constants
-                // can be evaluated as part of building the THIR of the parent
-                // function without a cycle.
-                build_mir(&thir.borrow())
-            } else {
-                // We ran all queries that depended on THIR at the beginning
-                // of `mir_build`, so now we can steal it
-                build_mir(&thir.steal())
-            }
+            // Don't steal here, instead steal in unsafeck. This is so that
+            // pattern inline constants can be evaluated as part of building the
+            // THIR of the parent function without a cycle.
+            build_mir(&thir.borrow())
         }
     };
 
@@ -190,9 +183,6 @@ struct Builder<'a, 'tcx> {
     /// `{ STMTS; EXPR1 } + EXPR2`.
     block_context: BlockContext,
 
-    /// The current unsafe block in scope
-    in_scope_unsafe: Safety,
-
     /// The vector of all scopes that we have created thus far;
     /// we track this for debuginfo later.
     source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
@@ -470,11 +460,6 @@ fn construct_fn<'tcx>(
         .output
         .span();
 
-    let safety = match fn_sig.unsafety {
-        hir::Unsafety::Normal => Safety::Safe,
-        hir::Unsafety::Unsafe => Safety::FnUnsafe,
-    };
-
     let mut abi = fn_sig.abi;
     if let DefKind::Closure = tcx.def_kind(fn_def) {
         // HACK(eddyb) Avoid having RustCall on closures,
@@ -520,7 +505,6 @@ fn construct_fn<'tcx>(
         fn_id,
         span_with_body,
         arguments.len(),
-        safety,
         return_ty,
         return_ty_span,
         coroutine,
@@ -590,18 +574,8 @@ fn construct_const<'a, 'tcx>(
     };
 
     let infcx = tcx.infer_ctxt().build();
-    let mut builder = Builder::new(
-        thir,
-        infcx,
-        def,
-        hir_id,
-        span,
-        0,
-        Safety::Safe,
-        const_ty,
-        const_ty_span,
-        None,
-    );
+    let mut builder =
+        Builder::new(thir, infcx, def, hir_id, span, 0, const_ty, const_ty_span, None);
 
     let mut block = START_BLOCK;
     unpack!(block = builder.expr_into_dest(Place::return_place(), block, expr));
@@ -723,10 +697,7 @@ fn construct_error(tcx: TyCtxt<'_>, def_id: LocalDefId, guar: ErrorGuaranteed) -
         parent_scope: None,
         inlined: None,
         inlined_parent_scope: None,
-        local_data: ClearCrossCrate::Set(SourceScopeLocalData {
-            lint_root: hir_id,
-            safety: Safety::Safe,
-        }),
+        local_data: ClearCrossCrate::Set(SourceScopeLocalData { lint_root: hir_id }),
     });
 
     cfg.terminate(START_BLOCK, source_info, TerminatorKind::Unreachable);
@@ -753,7 +724,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         hir_id: hir::HirId,
         span: Span,
         arg_count: usize,
-        safety: Safety,
         return_ty: Ty<'tcx>,
         return_span: Span,
         coroutine: Option<Box<CoroutineInfo<'tcx>>>,
@@ -795,7 +765,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             guard_context: vec![],
             fixed_temps: Default::default(),
             fixed_temps_scope: None,
-            in_scope_unsafe: safety,
             local_decls: IndexVec::from_elem_n(LocalDecl::new(return_ty, return_span), 1),
             canonical_user_type_annotations: IndexVec::new(),
             upvars: CaptureMap::new(),
@@ -807,10 +776,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         };
 
         assert_eq!(builder.cfg.start_new_block(), START_BLOCK);
-        assert_eq!(
-            builder.new_source_scope(span, lint_level, Some(safety)),
-            OUTERMOST_SOURCE_SCOPE
-        );
+        assert_eq!(builder.new_source_scope(span, lint_level), OUTERMOST_SOURCE_SCOPE);
         builder.source_scopes[OUTERMOST_SOURCE_SCOPE].parent_scope = None;
 
         builder
@@ -1024,7 +990,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             .as_ref()
             .assert_crate_local()
             .lint_root;
-        self.maybe_new_source_scope(pattern_span, None, arg_hir_id, parent_id);
+        self.maybe_new_source_scope(pattern_span, arg_hir_id, parent_id);
     }
 
     fn get_unit_temp(&mut self) -> Place<'tcx> {
diff --git a/compiler/rustc_mir_build/src/build/scope.rs b/compiler/rustc_mir_build/src/build/scope.rs
index aef63896dde..2d31e84aba7 100644
--- a/compiler/rustc_mir_build/src/build/scope.rs
+++ b/compiler/rustc_mir_build/src/build/scope.rs
@@ -190,7 +190,7 @@ rustc_index::newtype_index! {
     struct DropIdx {}
 }
 
-const ROOT_NODE: DropIdx = DropIdx::from_u32(0);
+const ROOT_NODE: DropIdx = DropIdx::ZERO;
 
 /// A tree of drops that we have deferred lowering. It's used for:
 ///
@@ -578,7 +578,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         if let LintLevel::Explicit(current_hir_id) = lint_level {
             let parent_id =
                 self.source_scopes[source_scope].local_data.as_ref().assert_crate_local().lint_root;
-            self.maybe_new_source_scope(region_scope.1.span, None, current_hir_id, parent_id);
+            self.maybe_new_source_scope(region_scope.1.span, current_hir_id, parent_id);
         }
         self.push_scope(region_scope);
         let mut block;
@@ -767,7 +767,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     pub(crate) fn maybe_new_source_scope(
         &mut self,
         span: Span,
-        safety: Option<Safety>,
         current_id: HirId,
         parent_id: HirId,
     ) {
@@ -797,7 +796,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
 
         if current_root != parent_root {
             let lint_level = LintLevel::Explicit(current_root);
-            self.source_scope = self.new_source_scope(span, lint_level, safety);
+            self.source_scope = self.new_source_scope(span, lint_level);
         }
     }
 
@@ -846,18 +845,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     /// Creates a new source scope, nested in the current one.
-    pub(crate) fn new_source_scope(
-        &mut self,
-        span: Span,
-        lint_level: LintLevel,
-        safety: Option<Safety>,
-    ) -> SourceScope {
+    pub(crate) fn new_source_scope(&mut self, span: Span, lint_level: LintLevel) -> SourceScope {
         let parent = self.source_scope;
         debug!(
-            "new_source_scope({:?}, {:?}, {:?}) - parent({:?})={:?}",
+            "new_source_scope({:?}, {:?}) - parent({:?})={:?}",
             span,
             lint_level,
-            safety,
             parent,
             self.source_scopes.get(parent)
         );
@@ -867,9 +860,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             } else {
                 self.source_scopes[parent].local_data.as_ref().assert_crate_local().lint_root
             },
-            safety: safety.unwrap_or_else(|| {
-                self.source_scopes[parent].local_data.as_ref().assert_crate_local().safety
-            }),
         };
         self.source_scopes.push(SourceScopeData {
             span,
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 07dc332b791..8aa9a75d96a 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -909,11 +909,6 @@ impl UnsafeOpKind {
 }
 
 pub fn check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
-    // THIR unsafeck can be disabled with `-Z thir-unsafeck=off`
-    if !tcx.sess.opts.unstable_opts.thir_unsafeck {
-        return;
-    }
-
     // Closures and inline consts are handled by their owner, if it has a body
     // Also, don't safety check custom MIR
     if tcx.is_typeck_child(def.to_def_id()) || tcx.has_attr(def, sym::custom_mir) {
diff --git a/compiler/rustc_mir_build/src/errors.rs b/compiler/rustc_mir_build/src/errors.rs
index 848da56f981..26f10fdd333 100644
--- a/compiler/rustc_mir_build/src/errors.rs
+++ b/compiler/rustc_mir_build/src/errors.rs
@@ -456,8 +456,8 @@ pub enum UnusedUnsafeEnclosing {
 
 pub(crate) struct NonExhaustivePatternsTypeNotEmpty<'p, 'tcx, 'm> {
     pub cx: &'m RustcPatCtxt<'p, 'tcx>,
-    pub expr_span: Span,
-    pub span: Span,
+    pub scrut_span: Span,
+    pub braces_span: Option<Span>,
     pub ty: Ty<'tcx>,
 }
 
@@ -465,7 +465,7 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo
     fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'_, G> {
         let mut diag =
             Diag::new(dcx, level, fluent::mir_build_non_exhaustive_patterns_type_not_empty);
-        diag.span(self.span);
+        diag.span(self.scrut_span);
         diag.code(E0004);
         let peeled_ty = self.ty.peel_refs();
         diag.arg("ty", self.ty);
@@ -502,26 +502,19 @@ impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for NonExhaustivePatternsTypeNo
             }
         }
 
-        let mut suggestion = None;
         let sm = self.cx.tcx.sess.source_map();
-        if self.span.eq_ctxt(self.expr_span) {
+        if let Some(braces_span) = self.braces_span {
             // Get the span for the empty match body `{}`.
-            let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.span) {
+            let (indentation, more) = if let Some(snippet) = sm.indentation_before(self.scrut_span)
+            {
                 (format!("\n{snippet}"), "    ")
             } else {
                 (" ".to_string(), "")
             };
-            suggestion = Some((
-                self.span.shrink_to_hi().with_hi(self.expr_span.hi()),
-                format!(" {{{indentation}{more}_ => todo!(),{indentation}}}",),
-            ));
-        }
-
-        if let Some((span, sugg)) = suggestion {
             diag.span_suggestion_verbose(
-                span,
+                braces_span,
                 fluent::mir_build_suggestion,
-                sugg,
+                format!(" {{{indentation}{more}_ => todo!(),{indentation}}}"),
                 Applicability::HasPlaceholders,
             );
         } else {
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 1e508ffc1e7..c697e16217b 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -716,10 +716,11 @@ impl<'tcx> Cx<'tcx> {
                 then: self.mirror_expr(then),
                 else_opt: else_opt.map(|el| self.mirror_expr(el)),
             },
-            hir::ExprKind::Match(discr, arms, _) => ExprKind::Match {
+            hir::ExprKind::Match(discr, arms, match_source) => ExprKind::Match {
                 scrutinee: self.mirror_expr(discr),
                 scrutinee_hir_id: discr.hir_id,
                 arms: arms.iter().map(|a| self.convert_arm(a)).collect(),
+                match_source,
             },
             hir::ExprKind::Loop(body, ..) => {
                 let block_ty = self.typeck_results().node_type(body.hir_id);
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index 3a688a14dd5..a3e6c2abc51 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -144,16 +144,8 @@ impl<'p, 'tcx> Visitor<'p, 'tcx> for MatchVisitor<'p, 'tcx> {
                 });
                 return;
             }
-            ExprKind::Match { scrutinee, scrutinee_hir_id, box ref arms } => {
-                let source = match ex.span.desugaring_kind() {
-                    Some(DesugaringKind::ForLoop) => hir::MatchSource::ForLoopDesugar,
-                    Some(DesugaringKind::QuestionMark) => {
-                        hir::MatchSource::TryDesugar(scrutinee_hir_id)
-                    }
-                    Some(DesugaringKind::Await) => hir::MatchSource::AwaitDesugar,
-                    _ => hir::MatchSource::Normal,
-                };
-                self.check_match(scrutinee, arms, source, ex.span);
+            ExprKind::Match { scrutinee, scrutinee_hir_id: _, box ref arms, match_source } => {
+                self.check_match(scrutinee, arms, match_source, ex.span);
             }
             ExprKind::Let { box ref pat, expr } => {
                 self.check_let(pat, Some(expr), ex.span);
@@ -505,8 +497,41 @@ impl<'p, 'tcx> MatchVisitor<'p, 'tcx> {
                     None,
                 );
             } else {
+                // span after scrutinee, or after `.match`. That is, the braces, arms,
+                // and any whitespace preceding the braces.
+                let braces_span = match source {
+                    hir::MatchSource::Normal => scrut
+                        .span
+                        .find_ancestor_in_same_ctxt(expr_span)
+                        .map(|scrut_span| scrut_span.shrink_to_hi().with_hi(expr_span.hi())),
+                    hir::MatchSource::Postfix => {
+                        // This is horrendous, and we should deal with it by just
+                        // stashing the span of the braces somewhere (like in the match source).
+                        scrut.span.find_ancestor_in_same_ctxt(expr_span).and_then(|scrut_span| {
+                            let sm = self.tcx.sess.source_map();
+                            let brace_span = sm.span_extend_to_next_char(scrut_span, '{', true);
+                            if sm.span_to_snippet(sm.next_point(brace_span)).as_deref() == Ok("{") {
+                                let sp = brace_span.shrink_to_hi().with_hi(expr_span.hi());
+                                // We also need to extend backwards for whitespace
+                                sm.span_extend_prev_while(sp, |c| c.is_whitespace()).ok()
+                            } else {
+                                None
+                            }
+                        })
+                    }
+                    hir::MatchSource::ForLoopDesugar
+                    | hir::MatchSource::TryDesugar(_)
+                    | hir::MatchSource::AwaitDesugar
+                    | hir::MatchSource::FormatArgs => None,
+                };
                 self.error = Err(report_non_exhaustive_match(
-                    &cx, self.thir, scrut.ty, scrut.span, witnesses, arms, expr_span,
+                    &cx,
+                    self.thir,
+                    scrut.ty,
+                    scrut.span,
+                    witnesses,
+                    arms,
+                    braces_span,
                 ));
             }
         }
@@ -929,7 +954,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     sp: Span,
     witnesses: Vec<WitnessPat<'p, 'tcx>>,
     arms: &[ArmId],
-    expr_span: Span,
+    braces_span: Option<Span>,
 ) -> ErrorGuaranteed {
     let is_empty_match = arms.is_empty();
     let non_empty_enum = match scrut_ty.kind() {
@@ -941,8 +966,8 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     if is_empty_match && !non_empty_enum {
         return cx.tcx.dcx().emit_err(NonExhaustivePatternsTypeNotEmpty {
             cx,
-            expr_span,
-            span: sp,
+            scrut_span: sp,
+            braces_span,
             ty: scrut_ty,
         });
     }
@@ -1028,7 +1053,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
     let mut suggestion = None;
     let sm = cx.tcx.sess.source_map();
     match arms {
-        [] if sp.eq_ctxt(expr_span) => {
+        [] if let Some(braces_span) = braces_span => {
             // Get the span for the empty match body `{}`.
             let (indentation, more) = if let Some(snippet) = sm.indentation_before(sp) {
                 (format!("\n{snippet}"), "    ")
@@ -1036,7 +1061,7 @@ fn report_non_exhaustive_match<'p, 'tcx>(
                 (" ".to_string(), "")
             };
             suggestion = Some((
-                sp.shrink_to_hi().with_hi(expr_span.hi()),
+                braces_span,
                 format!(" {{{indentation}{more}{suggested_arm},{indentation}}}",),
             ));
         }
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index a4992da679e..133cf8e3349 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -65,7 +65,14 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         // we wrap the unadjusted pattern in `PatKind::Deref` repeatedly, consuming the
         // adjustments in *reverse order* (last-in-first-out, so that the last `Deref` inserted
         // gets the least-dereferenced type).
-        let unadjusted_pat = self.lower_pattern_unadjusted(pat);
+        let unadjusted_pat = match pat.kind {
+            hir::PatKind::Ref(inner, _)
+                if self.typeck_results.skipped_ref_pats().contains(pat.hir_id) =>
+            {
+                self.lower_pattern_unadjusted(inner)
+            }
+            _ => self.lower_pattern_unadjusted(pat),
+        };
         self.typeck_results.pat_adjustments().get(pat.hir_id).unwrap_or(&vec![]).iter().rev().fold(
             unadjusted_pat,
             |pat: Box<_>, ref_ty| {
diff --git a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
index 256add3153c..d63db6ea8ed 100644
--- a/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
+++ b/compiler/rustc_mir_dataflow/src/elaborate_drops.rs
@@ -420,14 +420,14 @@ where
     ) -> BasicBlock {
         // drop glue is sent straight to codegen
         // box cannot be directly dereferenced
-        let unique_ty = adt.non_enum_variant().fields[FieldIdx::new(0)].ty(self.tcx(), args);
+        let unique_ty = adt.non_enum_variant().fields[FieldIdx::ZERO].ty(self.tcx(), args);
         let unique_variant = unique_ty.ty_adt_def().unwrap().non_enum_variant();
-        let nonnull_ty = unique_variant.fields[FieldIdx::from_u32(0)].ty(self.tcx(), args);
+        let nonnull_ty = unique_variant.fields[FieldIdx::ZERO].ty(self.tcx(), args);
         let ptr_ty = Ty::new_imm_ptr(self.tcx(), args[0].expect_ty());
 
-        let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::new(0), unique_ty);
-        let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::new(0), nonnull_ty);
-        let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::new(0), ptr_ty);
+        let unique_place = self.tcx().mk_place_field(self.place, FieldIdx::ZERO, unique_ty);
+        let nonnull_place = self.tcx().mk_place_field(unique_place, FieldIdx::ZERO, nonnull_ty);
+        let ptr_place = self.tcx().mk_place_field(nonnull_place, FieldIdx::ZERO, ptr_ty);
         let interior = self.tcx().mk_place_deref(ptr_place);
 
         let interior_path = self.elaborator.deref_subpath(self.path);
diff --git a/compiler/rustc_mir_transform/messages.ftl b/compiler/rustc_mir_transform/messages.ftl
index b8dbdf18db3..f9b79d72b05 100644
--- a/compiler/rustc_mir_transform/messages.ftl
+++ b/compiler/rustc_mir_transform/messages.ftl
@@ -1,6 +1,4 @@
 mir_transform_arithmetic_overflow = this arithmetic operation will overflow
-mir_transform_call_to_unsafe_label = call to unsafe function
-mir_transform_call_to_unsafe_note = consult the function's documentation for information on how to avoid undefined behavior
 mir_transform_const_defined_here = `const` item defined here
 
 mir_transform_const_modify = attempting to modify a `const` item
@@ -11,10 +9,6 @@ mir_transform_const_mut_borrow = taking a mutable reference to a `const` item
     .note2 = the mutable reference will refer to this temporary, not the original `const` item
     .note3 = mutable reference created due to call to this method
 
-mir_transform_const_ptr2int_label = cast of pointer to int
-mir_transform_const_ptr2int_note = casting pointers to integers in constants
-mir_transform_deref_ptr_label = dereference of raw pointer
-mir_transform_deref_ptr_note = raw pointers may be null, dangling or unaligned; they can violate aliasing rules and cause data races: all of these are undefined behavior
 mir_transform_ffi_unwind_call = call to {$foreign ->
     [true] foreign function
     *[false] function pointer
@@ -23,56 +17,13 @@ mir_transform_ffi_unwind_call = call to {$foreign ->
 mir_transform_fn_item_ref = taking a reference to a function item does not give a function pointer
     .suggestion = cast `{$ident}` to obtain a function pointer
 
-mir_transform_initializing_valid_range_label = initializing type with `rustc_layout_scalar_valid_range` attr
-mir_transform_initializing_valid_range_note = initializing a layout restricted type's field with a value outside the valid range is undefined behavior
 mir_transform_must_not_suspend = {$pre}`{$def_path}`{$post} held across a suspend point, but should not be
     .label = the value is held across this suspend point
     .note = {$reason}
     .help = consider using a block (`{"{ ... }"}`) to shrink the value's scope, ending before the suspend point
-
-mir_transform_mutation_layout_constrained_borrow_label = borrow of layout constrained field with interior mutability
-mir_transform_mutation_layout_constrained_borrow_note = references to fields of layout constrained fields lose the constraints. Coupled with interior mutability, the field can be changed to invalid values
-mir_transform_mutation_layout_constrained_label = mutation of layout constrained field
-mir_transform_mutation_layout_constrained_note = mutating layout constrained fields cannot statically be checked for valid values
 mir_transform_operation_will_panic = this operation will panic at runtime
 
-mir_transform_requires_unsafe = {$details} is unsafe and requires unsafe {$op_in_unsafe_fn_allowed ->
-    [true] function or block
-    *[false] block
-    }
-    .not_inherited = items do not inherit unsafety from separate enclosing items
-
-mir_transform_target_feature_call_help = in order for the call to be safe, the context requires the following additional target {$missing_target_features_count ->
-    [1] feature
-    *[count] features
-    }: {$missing_target_features}
-
-mir_transform_target_feature_call_label = call to function with `#[target_feature]`
-mir_transform_target_feature_call_note = the {$build_target_features} target {$build_target_features_count ->
-    [1] feature
-    *[count] features
-    } being enabled in the build configuration does not remove the requirement to list {$build_target_features_count ->
-    [1] it
-    *[count] them
-    } in `#[target_feature]`
-
 mir_transform_unaligned_packed_ref = reference to packed field is unaligned
     .note = packed structs are only aligned by one byte, and many modern architectures penalize unaligned field accesses
     .note_ub = creating a misaligned reference is undefined behavior (even if that reference is never dereferenced)
     .help = copy the field contents to a local variable, or replace the reference with a raw pointer and use `read_unaligned`/`write_unaligned` (loads and stores via `*p` must be properly aligned even when using raw pointers)
-
-mir_transform_union_access_label = access to union field
-mir_transform_union_access_note = the field may not be properly initialized: using uninitialized data will cause undefined behavior
-mir_transform_unsafe_op_in_unsafe_fn = {$details} is unsafe and requires unsafe block (error E0133)
-    .suggestion = consider wrapping the function body in an unsafe block
-    .note = an unsafe function restricts its caller, but its body is safe by default
-
-mir_transform_unused_unsafe = unnecessary `unsafe` block
-    .label = because it's nested under this `unsafe` block
-
-mir_transform_use_of_asm_label = use of inline assembly
-mir_transform_use_of_asm_note = inline assembly is entirely unchecked and can cause undefined behavior
-mir_transform_use_of_extern_static_label = use of extern static
-mir_transform_use_of_extern_static_note = extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
-mir_transform_use_of_static_mut_label = use of mutable static
-mir_transform_use_of_static_mut_note = mutable statics can be mutated by multiple threads: aliasing violations or data races will cause undefined behavior
diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs
deleted file mode 100644
index a0c3de3af58..00000000000
--- a/compiler/rustc_mir_transform/src/check_unsafety.rs
+++ /dev/null
@@ -1,615 +0,0 @@
-use rustc_data_structures::unord::{ExtendUnord, UnordItems, UnordSet};
-use rustc_hir as hir;
-use rustc_hir::def::DefKind;
-use rustc_hir::def_id::{DefId, LocalDefId};
-use rustc_hir::hir_id::HirId;
-use rustc_hir::intravisit;
-use rustc_hir::{BlockCheckMode, ExprKind, Node};
-use rustc_middle::mir::visit::{MutatingUseContext, PlaceContext, Visitor};
-use rustc_middle::mir::*;
-use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, TyCtxt};
-use rustc_session::lint::builtin::{UNSAFE_OP_IN_UNSAFE_FN, UNUSED_UNSAFE};
-use rustc_session::lint::Level;
-
-use std::ops::Bound;
-
-use crate::errors;
-
-pub struct UnsafetyChecker<'a, 'tcx> {
-    body: &'a Body<'tcx>,
-    body_did: LocalDefId,
-    violations: Vec<UnsafetyViolation>,
-    source_info: SourceInfo,
-    tcx: TyCtxt<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
-
-    /// Used `unsafe` blocks in this function. This is used for the "unused_unsafe" lint.
-    used_unsafe_blocks: UnordSet<HirId>,
-}
-
-impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
-    fn new(
-        body: &'a Body<'tcx>,
-        body_did: LocalDefId,
-        tcx: TyCtxt<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Self {
-        Self {
-            body,
-            body_did,
-            violations: vec![],
-            source_info: SourceInfo::outermost(body.span),
-            tcx,
-            param_env,
-            used_unsafe_blocks: Default::default(),
-        }
-    }
-}
-
-impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> {
-    fn visit_terminator(&mut self, terminator: &Terminator<'tcx>, location: Location) {
-        self.source_info = terminator.source_info;
-        match terminator.kind {
-            TerminatorKind::Goto { .. }
-            | TerminatorKind::SwitchInt { .. }
-            | TerminatorKind::Drop { .. }
-            | TerminatorKind::Yield { .. }
-            | TerminatorKind::Assert { .. }
-            | TerminatorKind::CoroutineDrop
-            | TerminatorKind::UnwindResume
-            | TerminatorKind::UnwindTerminate(_)
-            | TerminatorKind::Return
-            | TerminatorKind::Unreachable
-            | TerminatorKind::FalseEdge { .. }
-            | TerminatorKind::FalseUnwind { .. } => {
-                // safe (at least as emitted during MIR construction)
-            }
-
-            TerminatorKind::Call { ref func, .. } => {
-                let func_ty = func.ty(self.body, self.tcx);
-                let func_id =
-                    if let ty::FnDef(func_id, _) = func_ty.kind() { Some(func_id) } else { None };
-                let sig = func_ty.fn_sig(self.tcx);
-                if let hir::Unsafety::Unsafe = sig.unsafety() {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::CallToUnsafeFunction,
-                    )
-                }
-
-                if let Some(func_id) = func_id {
-                    self.check_target_features(*func_id);
-                }
-            }
-
-            TerminatorKind::InlineAsm { .. } => self.require_unsafe(
-                UnsafetyViolationKind::General,
-                UnsafetyViolationDetails::UseOfInlineAssembly,
-            ),
-        }
-        self.super_terminator(terminator, location);
-    }
-
-    fn visit_statement(&mut self, statement: &Statement<'tcx>, location: Location) {
-        self.source_info = statement.source_info;
-        match statement.kind {
-            StatementKind::Assign(..)
-            | StatementKind::FakeRead(..)
-            | StatementKind::SetDiscriminant { .. }
-            | StatementKind::Deinit(..)
-            | StatementKind::StorageLive(..)
-            | StatementKind::StorageDead(..)
-            | StatementKind::Retag { .. }
-            | StatementKind::PlaceMention(..)
-            | StatementKind::Coverage(..)
-            | StatementKind::Intrinsic(..)
-            | StatementKind::ConstEvalCounter
-            | StatementKind::Nop => {
-                // safe (at least as emitted during MIR construction)
-            }
-            // `AscribeUserType` just exists to help MIR borrowck.
-            // It has no semantics, and everything is already reported by `PlaceMention`.
-            StatementKind::AscribeUserType(..) => return,
-        }
-        self.super_statement(statement, location);
-    }
-
-    fn visit_rvalue(&mut self, rvalue: &Rvalue<'tcx>, location: Location) {
-        match rvalue {
-            Rvalue::Aggregate(box ref aggregate, _) => match aggregate {
-                &AggregateKind::Array(..) | &AggregateKind::Tuple => {}
-                &AggregateKind::Adt(adt_did, ..) => {
-                    match self.tcx.layout_scalar_valid_range(adt_did) {
-                        (Bound::Unbounded, Bound::Unbounded) => {}
-                        _ => self.require_unsafe(
-                            UnsafetyViolationKind::General,
-                            UnsafetyViolationDetails::InitializingTypeWith,
-                        ),
-                    }
-                }
-                &AggregateKind::Closure(def_id, _)
-                | &AggregateKind::CoroutineClosure(def_id, _)
-                | &AggregateKind::Coroutine(def_id, _) => {
-                    let def_id = def_id.expect_local();
-                    let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
-                        self.tcx.mir_unsafety_check_result(def_id);
-                    self.register_violations(violations, used_unsafe_blocks.items().copied());
-                }
-            },
-            _ => {}
-        }
-        self.super_rvalue(rvalue, location);
-    }
-
-    fn visit_operand(&mut self, op: &Operand<'tcx>, location: Location) {
-        if let Operand::Constant(constant) = op {
-            let maybe_uneval = match constant.const_ {
-                Const::Val(..) | Const::Ty(_) => None,
-                Const::Unevaluated(uv, _) => Some(uv),
-            };
-
-            if let Some(uv) = maybe_uneval {
-                if uv.promoted.is_none() {
-                    let def_id = uv.def;
-                    if self.tcx.def_kind(def_id) == DefKind::InlineConst {
-                        let local_def_id = def_id.expect_local();
-                        let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } =
-                            self.tcx.mir_unsafety_check_result(local_def_id);
-                        self.register_violations(violations, used_unsafe_blocks.items().copied());
-                    }
-                }
-            }
-        }
-        self.super_operand(op, location);
-    }
-
-    fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, _location: Location) {
-        // On types with `scalar_valid_range`, prevent
-        // * `&mut x.field`
-        // * `x.field = y;`
-        // * `&x.field` if `field`'s type has interior mutability
-        // because either of these would allow modifying the layout constrained field and
-        // insert values that violate the layout constraints.
-        if context.is_mutating_use() || context.is_borrow() {
-            self.check_mut_borrowing_layout_constrained_field(*place, context.is_mutating_use());
-        }
-
-        // Some checks below need the extra meta info of the local declaration.
-        let decl = &self.body.local_decls[place.local];
-
-        // Check the base local: it might be an unsafe-to-access static. We only check derefs of the
-        // temporary holding the static pointer to avoid duplicate errors
-        // <https://github.com/rust-lang/rust/pull/78068#issuecomment-731753506>.
-        if place.projection.first() == Some(&ProjectionElem::Deref) {
-            // If the projection root is an artificial local that we introduced when
-            // desugaring `static`, give a more specific error message
-            // (avoid the general "raw pointer" clause below, that would only be confusing).
-            if let LocalInfo::StaticRef { def_id, .. } = *decl.local_info() {
-                if self.tcx.is_mutable_static(def_id) {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::UseOfMutableStatic,
-                    );
-                    return;
-                } else if self.tcx.is_foreign_item(def_id) {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::UseOfExternStatic,
-                    );
-                    return;
-                }
-            }
-        }
-
-        // Check for raw pointer `Deref`.
-        for (base, proj) in place.iter_projections() {
-            if proj == ProjectionElem::Deref {
-                let base_ty = base.ty(self.body, self.tcx).ty;
-                if base_ty.is_unsafe_ptr() {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::DerefOfRawPointer,
-                    )
-                }
-            }
-        }
-
-        // Check for union fields. For this we traverse right-to-left, as the last `Deref` changes
-        // whether we *read* the union field or potentially *write* to it (if this place is being assigned to).
-        let mut saw_deref = false;
-        for (base, proj) in place.iter_projections().rev() {
-            if proj == ProjectionElem::Deref {
-                saw_deref = true;
-                continue;
-            }
-
-            let base_ty = base.ty(self.body, self.tcx).ty;
-            if base_ty.is_union() {
-                // If we did not hit a `Deref` yet and the overall place use is an assignment, the
-                // rules are different.
-                let assign_to_field = !saw_deref
-                    && matches!(
-                        context,
-                        PlaceContext::MutatingUse(
-                            MutatingUseContext::Store
-                                | MutatingUseContext::Drop
-                                | MutatingUseContext::AsmOutput
-                        )
-                    );
-                // If this is just an assignment, determine if the assigned type needs dropping.
-                if assign_to_field {
-                    // We have to check the actual type of the assignment, as that determines if the
-                    // old value is being dropped.
-                    let assigned_ty = place.ty(&self.body.local_decls, self.tcx).ty;
-                    if assigned_ty.needs_drop(self.tcx, self.param_env) {
-                        // This would be unsafe, but should be outright impossible since we reject
-                        // such unions.
-                        assert!(
-                            self.tcx.dcx().has_errors().is_some(),
-                            "union fields that need dropping should be impossible: {assigned_ty}"
-                        );
-                    }
-                } else {
-                    self.require_unsafe(
-                        UnsafetyViolationKind::General,
-                        UnsafetyViolationDetails::AccessToUnionField,
-                    )
-                }
-            }
-        }
-    }
-}
-
-impl<'tcx> UnsafetyChecker<'_, 'tcx> {
-    fn require_unsafe(&mut self, kind: UnsafetyViolationKind, details: UnsafetyViolationDetails) {
-        // Violations can turn out to be `UnsafeFn` during analysis, but they should not start out as such.
-        assert_ne!(kind, UnsafetyViolationKind::UnsafeFn);
-
-        let source_info = self.source_info;
-        let lint_root = self.body.source_scopes[self.source_info.scope]
-            .local_data
-            .as_ref()
-            .assert_crate_local()
-            .lint_root;
-        self.register_violations(
-            [&UnsafetyViolation { source_info, lint_root, kind, details }],
-            UnordItems::empty(),
-        );
-    }
-
-    fn register_violations<'a>(
-        &mut self,
-        violations: impl IntoIterator<Item = &'a UnsafetyViolation>,
-        new_used_unsafe_blocks: UnordItems<HirId, impl Iterator<Item = HirId>>,
-    ) {
-        let safety = self.body.source_scopes[self.source_info.scope]
-            .local_data
-            .as_ref()
-            .assert_crate_local()
-            .safety;
-        match safety {
-            // `unsafe` blocks are required in safe code
-            Safety::Safe => violations.into_iter().for_each(|violation| {
-                match violation.kind {
-                    UnsafetyViolationKind::General => {}
-                    UnsafetyViolationKind::UnsafeFn => {
-                        bug!("`UnsafetyViolationKind::UnsafeFn` in an `Safe` context")
-                    }
-                }
-                if !self.violations.contains(violation) {
-                    self.violations.push(violation.clone())
-                }
-            }),
-            // With the RFC 2585, no longer allow `unsafe` operations in `unsafe fn`s
-            Safety::FnUnsafe => violations.into_iter().for_each(|violation| {
-                let mut violation = violation.clone();
-                violation.kind = UnsafetyViolationKind::UnsafeFn;
-                if !self.violations.contains(&violation) {
-                    self.violations.push(violation)
-                }
-            }),
-            Safety::BuiltinUnsafe => {}
-            Safety::ExplicitUnsafe(hir_id) => violations.into_iter().for_each(|_violation| {
-                self.used_unsafe_blocks.insert(hir_id);
-            }),
-        };
-
-        self.used_unsafe_blocks.extend_unord(new_used_unsafe_blocks);
-    }
-    fn check_mut_borrowing_layout_constrained_field(
-        &mut self,
-        place: Place<'tcx>,
-        is_mut_use: bool,
-    ) {
-        for (place_base, elem) in place.iter_projections().rev() {
-            match elem {
-                // Modifications behind a dereference don't affect the value of
-                // the pointer.
-                ProjectionElem::Deref => return,
-                ProjectionElem::Field(..) => {
-                    let ty = place_base.ty(&self.body.local_decls, self.tcx).ty;
-                    if let ty::Adt(def, _) = ty.kind() {
-                        if self.tcx.layout_scalar_valid_range(def.did())
-                            != (Bound::Unbounded, Bound::Unbounded)
-                        {
-                            let details = if is_mut_use {
-                                UnsafetyViolationDetails::MutationOfLayoutConstrainedField
-
-                            // Check `is_freeze` as late as possible to avoid cycle errors
-                            // with opaque types.
-                            } else if !place
-                                .ty(self.body, self.tcx)
-                                .ty
-                                .is_freeze(self.tcx, self.param_env)
-                            {
-                                UnsafetyViolationDetails::BorrowOfLayoutConstrainedField
-                            } else {
-                                continue;
-                            };
-                            self.require_unsafe(UnsafetyViolationKind::General, details);
-                        }
-                    }
-                }
-                _ => {}
-            }
-        }
-    }
-
-    /// Checks whether calling `func_did` needs an `unsafe` context or not, i.e. whether
-    /// the called function has target features the calling function hasn't.
-    fn check_target_features(&mut self, func_did: DefId) {
-        // Unsafety isn't required on wasm targets. For more information see
-        // the corresponding check in typeck/src/collect.rs
-        if self.tcx.sess.target.options.is_like_wasm {
-            return;
-        }
-
-        let callee_features = &self.tcx.codegen_fn_attrs(func_did).target_features;
-        // The body might be a constant, so it doesn't have codegen attributes.
-        let self_features = &self.tcx.body_codegen_attrs(self.body_did.to_def_id()).target_features;
-
-        // Is `callee_features` a subset of `calling_features`?
-        if !callee_features.iter().all(|feature| self_features.contains(feature)) {
-            let missing: Vec<_> = callee_features
-                .iter()
-                .copied()
-                .filter(|feature| !self_features.contains(feature))
-                .collect();
-            let build_enabled = self
-                .tcx
-                .sess
-                .target_features
-                .iter()
-                .copied()
-                .filter(|feature| missing.contains(feature))
-                .collect();
-            self.require_unsafe(
-                UnsafetyViolationKind::General,
-                UnsafetyViolationDetails::CallToFunctionWith { missing, build_enabled },
-            )
-        }
-    }
-}
-
-pub(crate) fn provide(providers: &mut Providers) {
-    *providers = Providers { mir_unsafety_check_result, ..*providers };
-}
-
-/// Context information for [`UnusedUnsafeVisitor`] traversal,
-/// saves (innermost) relevant context
-#[derive(Copy, Clone, Debug)]
-enum Context {
-    Safe,
-    /// in an `unsafe fn`
-    UnsafeFn,
-    /// in a *used* `unsafe` block
-    /// (i.e. a block without unused-unsafe warning)
-    UnsafeBlock(HirId),
-}
-
-struct UnusedUnsafeVisitor<'a, 'tcx> {
-    tcx: TyCtxt<'tcx>,
-    used_unsafe_blocks: &'a UnordSet<HirId>,
-    context: Context,
-    unused_unsafes: &'a mut Vec<(HirId, UnusedUnsafe)>,
-}
-
-impl<'tcx> intravisit::Visitor<'tcx> for UnusedUnsafeVisitor<'_, 'tcx> {
-    fn visit_block(&mut self, block: &'tcx hir::Block<'tcx>) {
-        if let hir::BlockCheckMode::UnsafeBlock(hir::UnsafeSource::UserProvided) = block.rules {
-            let used = match self.tcx.lint_level_at_node(UNUSED_UNSAFE, block.hir_id) {
-                (Level::Allow, _) => true,
-                _ => self.used_unsafe_blocks.contains(&block.hir_id),
-            };
-            let unused_unsafe = match (self.context, used) {
-                (_, false) => UnusedUnsafe::Unused,
-                (Context::Safe, true) | (Context::UnsafeFn, true) => {
-                    let previous_context = self.context;
-                    self.context = Context::UnsafeBlock(block.hir_id);
-                    intravisit::walk_block(self, block);
-                    self.context = previous_context;
-                    return;
-                }
-                (Context::UnsafeBlock(hir_id), true) => UnusedUnsafe::InUnsafeBlock(hir_id),
-            };
-            self.unused_unsafes.push((block.hir_id, unused_unsafe));
-        }
-        intravisit::walk_block(self, block);
-    }
-
-    fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) {
-        self.visit_body(self.tcx.hir().body(c.body))
-    }
-
-    fn visit_fn(
-        &mut self,
-        fk: intravisit::FnKind<'tcx>,
-        _fd: &'tcx hir::FnDecl<'tcx>,
-        b: hir::BodyId,
-        _s: rustc_span::Span,
-        _id: LocalDefId,
-    ) {
-        if matches!(fk, intravisit::FnKind::Closure) {
-            self.visit_body(self.tcx.hir().body(b))
-        }
-    }
-}
-
-fn check_unused_unsafe(
-    tcx: TyCtxt<'_>,
-    def_id: LocalDefId,
-    used_unsafe_blocks: &UnordSet<HirId>,
-) -> Vec<(HirId, UnusedUnsafe)> {
-    let body_id = tcx.hir().maybe_body_owned_by(def_id);
-
-    let Some(body_id) = body_id else {
-        debug!("check_unused_unsafe({:?}) - no body found", def_id);
-        return vec![];
-    };
-
-    let body = tcx.hir().body(body_id);
-    let hir_id = tcx.local_def_id_to_hir_id(def_id);
-    let context = match tcx.hir().fn_sig_by_hir_id(hir_id) {
-        Some(sig) if sig.header.unsafety == hir::Unsafety::Unsafe => Context::UnsafeFn,
-        _ => Context::Safe,
-    };
-
-    debug!(
-        "check_unused_unsafe({:?}, context={:?}, body={:?}, used_unsafe_blocks={:?})",
-        def_id, body, context, used_unsafe_blocks
-    );
-
-    let mut unused_unsafes = vec![];
-
-    let mut visitor = UnusedUnsafeVisitor {
-        tcx,
-        used_unsafe_blocks,
-        context,
-        unused_unsafes: &mut unused_unsafes,
-    };
-    intravisit::Visitor::visit_body(&mut visitor, body);
-
-    unused_unsafes
-}
-
-fn mir_unsafety_check_result(tcx: TyCtxt<'_>, def: LocalDefId) -> &UnsafetyCheckResult {
-    debug!("unsafety_violations({:?})", def);
-
-    // N.B., this borrow is valid because all the consumers of
-    // `mir_built` force this.
-    let body = &tcx.mir_built(def).borrow();
-
-    if body.is_custom_mir() || body.tainted_by_errors.is_some() {
-        return tcx.arena.alloc(UnsafetyCheckResult {
-            violations: Vec::new(),
-            used_unsafe_blocks: Default::default(),
-            unused_unsafes: Some(Vec::new()),
-        });
-    }
-
-    let param_env = tcx.param_env(def);
-
-    let mut checker = UnsafetyChecker::new(body, def, tcx, param_env);
-    checker.visit_body(body);
-
-    let unused_unsafes = (!tcx.is_typeck_child(def.to_def_id()))
-        .then(|| check_unused_unsafe(tcx, def, &checker.used_unsafe_blocks));
-
-    tcx.arena.alloc(UnsafetyCheckResult {
-        violations: checker.violations,
-        used_unsafe_blocks: checker.used_unsafe_blocks,
-        unused_unsafes,
-    })
-}
-
-fn report_unused_unsafe(tcx: TyCtxt<'_>, kind: UnusedUnsafe, id: HirId) {
-    let span = tcx.sess.source_map().guess_head_span(tcx.hir().span(id));
-    let nested_parent = if let UnusedUnsafe::InUnsafeBlock(id) = kind {
-        Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id)))
-    } else {
-        None
-    };
-    tcx.emit_node_span_lint(UNUSED_UNSAFE, id, span, errors::UnusedUnsafe { span, nested_parent });
-}
-
-pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: LocalDefId) {
-    debug!("check_unsafety({:?})", def_id);
-
-    // closures and inline consts are handled by their parent fn.
-    if tcx.is_typeck_child(def_id.to_def_id()) {
-        return;
-    }
-
-    let UnsafetyCheckResult { violations, unused_unsafes, .. } =
-        tcx.mir_unsafety_check_result(def_id);
-    // Only suggest wrapping the entire function body in an unsafe block once
-    let mut suggest_unsafe_block = true;
-
-    for &UnsafetyViolation { source_info, lint_root, kind, ref details } in violations.iter() {
-        let details =
-            errors::RequiresUnsafeDetail { violation: details.clone(), span: source_info.span };
-
-        match kind {
-            UnsafetyViolationKind::General => {
-                let op_in_unsafe_fn_allowed = unsafe_op_in_unsafe_fn_allowed(tcx, lint_root);
-                let note_non_inherited = tcx.hir().parent_iter(lint_root).find(|(id, node)| {
-                    if let Node::Expr(block) = node
-                        && let ExprKind::Block(block, _) = block.kind
-                        && let BlockCheckMode::UnsafeBlock(_) = block.rules
-                    {
-                        true
-                    } else if let Some(sig) = tcx.hir().fn_sig_by_hir_id(*id)
-                        && sig.header.is_unsafe()
-                    {
-                        true
-                    } else {
-                        false
-                    }
-                });
-                let enclosing = if let Some((id, _)) = note_non_inherited {
-                    Some(tcx.sess.source_map().guess_head_span(tcx.hir().span(id)))
-                } else {
-                    None
-                };
-                tcx.dcx().emit_err(errors::RequiresUnsafe {
-                    span: source_info.span,
-                    enclosing,
-                    details,
-                    op_in_unsafe_fn_allowed,
-                });
-            }
-            UnsafetyViolationKind::UnsafeFn => {
-                tcx.emit_node_span_lint(
-                    UNSAFE_OP_IN_UNSAFE_FN,
-                    lint_root,
-                    source_info.span,
-                    errors::UnsafeOpInUnsafeFn {
-                        details,
-                        suggest_unsafe_block: suggest_unsafe_block.then(|| {
-                            let hir_id = tcx.local_def_id_to_hir_id(def_id);
-                            let fn_sig = tcx
-                                .hir()
-                                .fn_sig_by_hir_id(hir_id)
-                                .expect("this violation only occurs in fn");
-                            let body = tcx.hir().body_owned_by(def_id);
-                            let body_span = tcx.hir().body(body).value.span;
-                            let start = tcx.sess.source_map().start_point(body_span).shrink_to_hi();
-                            let end = tcx.sess.source_map().end_point(body_span).shrink_to_lo();
-                            (start, end, fn_sig.span)
-                        }),
-                    },
-                );
-                suggest_unsafe_block = false;
-            }
-        }
-    }
-
-    for &(block_id, kind) in unused_unsafes.as_ref().unwrap() {
-        report_unused_unsafe(tcx, kind, block_id);
-    }
-}
-
-fn unsafe_op_in_unsafe_fn_allowed(tcx: TyCtxt<'_>, id: HirId) -> bool {
-    tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, id).0 == Level::Allow
-}
diff --git a/compiler/rustc_mir_transform/src/coroutine.rs b/compiler/rustc_mir_transform/src/coroutine.rs
index c3f175f150d..e2a911f0dc7 100644
--- a/compiler/rustc_mir_transform/src/coroutine.rs
+++ b/compiler/rustc_mir_transform/src/coroutine.rs
@@ -168,7 +168,7 @@ impl<'tcx> MutVisitor<'tcx> for PinArgVisitor<'tcx> {
                 Place {
                     local: SELF_ARG,
                     projection: self.tcx().mk_place_elems(&[ProjectionElem::Field(
-                        FieldIdx::new(0),
+                        FieldIdx::ZERO,
                         self.ref_coroutine_ty,
                     )]),
                 },
@@ -267,7 +267,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                 Rvalue::Aggregate(
                     Box::new(AggregateKind::Adt(
                         option_def_id,
-                        VariantIdx::from_usize(0),
+                        VariantIdx::ZERO,
                         self.tcx.mk_args(&[self.old_yield_ty.into()]),
                         None,
                         None,
@@ -329,7 +329,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     Rvalue::Aggregate(
                         Box::new(AggregateKind::Adt(
                             poll_def_id,
-                            VariantIdx::from_usize(0),
+                            VariantIdx::ZERO,
                             args,
                             None,
                             None,
@@ -358,7 +358,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     Rvalue::Aggregate(
                         Box::new(AggregateKind::Adt(
                             option_def_id,
-                            VariantIdx::from_usize(0),
+                            VariantIdx::ZERO,
                             args,
                             None,
                             None,
@@ -420,7 +420,7 @@ impl<'tcx> TransformVisitor<'tcx> {
                     Rvalue::Aggregate(
                         Box::new(AggregateKind::Adt(
                             coroutine_state_def_id,
-                            VariantIdx::from_usize(0),
+                            VariantIdx::ZERO,
                             args,
                             None,
                             None,
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index 99dbb342268..de43f9faff9 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -1,7 +1,66 @@
-//! A MIR pass which duplicates a coroutine's body and removes any derefs which
-//! would be present for upvars that are taken by-ref. The result of which will
-//! be a coroutine body that takes all of its upvars by-move, and which we stash
-//! into the `CoroutineInfo` for all coroutines returned by coroutine-closures.
+//! This pass constructs a second coroutine body sufficient for return from
+//! `FnOnce`/`AsyncFnOnce` implementations for coroutine-closures (e.g. async closures).
+//!
+//! Consider an async closure like:
+//! ```rust
+//! #![feature(async_closure)]
+//!
+//! let x = vec![1, 2, 3];
+//!
+//! let closure = async move || {
+//!     println!("{x:#?}");
+//! };
+//! ```
+//!
+//! This desugars to something like:
+//! ```rust,ignore (invalid-borrowck)
+//! let x = vec![1, 2, 3];
+//!
+//! let closure = move || {
+//!     async {
+//!         println!("{x:#?}");
+//!     }
+//! };
+//! ```
+//!
+//! Important to note here is that while the outer closure *moves* `x: Vec<i32>`
+//! into its upvars, the inner `async` coroutine simply captures a ref of `x`.
+//! This is the "magic" of async closures -- the futures that they return are
+//! allowed to borrow from their parent closure's upvars.
+//!
+//! However, what happens when we call `closure` with `AsyncFnOnce` (or `FnOnce`,
+//! since all async closures implement that too)? Well, recall the signature:
+//! ```
+//! use std::future::Future;
+//! pub trait AsyncFnOnce<Args>
+//! {
+//!     type CallOnceFuture: Future<Output = Self::Output>;
+//!     type Output;
+//!     fn async_call_once(
+//!         self,
+//!         args: Args
+//!     ) -> Self::CallOnceFuture;
+//! }
+//! ```
+//!
+//! This signature *consumes* the async closure (`self`) and returns a `CallOnceFuture`.
+//! How do we deal with the fact that the coroutine is supposed to take a reference
+//! to the captured `x` from the parent closure, when that parent closure has been
+//! destroyed?
+//!
+//! This is the second piece of magic of async closures. We can simply create a
+//! *second* `async` coroutine body where that `x` that was previously captured
+//! by reference is now captured by value. This means that we consume the outer
+//! closure and return a new coroutine that will hold onto all of these captures,
+//! and drop them when it is finished (i.e. after it has been `.await`ed).
+//!
+//! We do this with the analysis below, which detects the captures that come from
+//! borrowing from the outer closure, and we simply peel off a `deref` projection
+//! from them. This second body is stored alongside the first body, and optimized
+//! with it in lockstep. When we need to resolve a body for `FnOnce` or `AsyncFnOnce`,
+//! we use this "by move" body instead.
+
+use itertools::Itertools;
 
 use rustc_data_structures::unord::UnordSet;
 use rustc_hir as hir;
@@ -14,6 +73,8 @@ pub struct ByMoveBody;
 
 impl<'tcx> MirPass<'tcx> for ByMoveBody {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut mir::Body<'tcx>) {
+        // We only need to generate by-move coroutine bodies for coroutines that come
+        // from coroutine-closures.
         let Some(coroutine_def_id) = body.source.def_id().as_local() else {
             return;
         };
@@ -22,44 +83,78 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody {
         else {
             return;
         };
+
+        // Also, let's skip processing any bodies with errors, since there's no guarantee
+        // the MIR body will be constructed well.
         let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
         if coroutine_ty.references_error() {
             return;
         }
-        let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
 
-        let coroutine_kind = args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap();
-        if coroutine_kind == ty::ClosureKind::FnOnce {
+        // We don't need to generate a by-move coroutine if the coroutine body was
+        // produced by the `CoroutineKindShim`, since it's already by-move.
+        if matches!(body.source.instance, ty::InstanceDef::CoroutineKindShim { .. }) {
             return;
         }
 
+        let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
+        let args = args.as_coroutine();
+
+        let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap();
+
+        let parent_def_id = tcx.local_parent(coroutine_def_id);
+        let ty::CoroutineClosure(_, parent_args) =
+            *tcx.type_of(parent_def_id).instantiate_identity().kind()
+        else {
+            bug!();
+        };
+        let parent_closure_args = parent_args.as_coroutine_closure();
+        let num_args = parent_closure_args
+            .coroutine_closure_sig()
+            .skip_binder()
+            .tupled_inputs_ty
+            .tuple_fields()
+            .len();
+
         let mut by_ref_fields = UnordSet::default();
-        let by_move_upvars = Ty::new_tup_from_iter(
-            tcx,
-            tcx.closure_captures(coroutine_def_id).iter().enumerate().map(|(idx, capture)| {
-                if capture.is_by_ref() {
-                    by_ref_fields.insert(FieldIdx::from_usize(idx));
-                }
-                capture.place.ty()
-            }),
-        );
-        let by_move_coroutine_ty = Ty::new_coroutine(
-            tcx,
-            coroutine_def_id.to_def_id(),
-            ty::CoroutineArgs::new(
+        for (idx, (coroutine_capture, parent_capture)) in tcx
+            .closure_captures(coroutine_def_id)
+            .iter()
+            // By construction we capture all the args first.
+            .skip(num_args)
+            .zip_eq(tcx.closure_captures(parent_def_id))
+            .enumerate()
+        {
+            // This upvar is captured by-move from the parent closure, but by-ref
+            // from the inner async block. That means that it's being borrowed from
+            // the outer closure body -- we need to change the coroutine to take the
+            // upvar by value.
+            if coroutine_capture.is_by_ref() && !parent_capture.is_by_ref() {
+                assert_ne!(
+                    coroutine_kind,
+                    ty::ClosureKind::FnOnce,
+                    "`FnOnce` coroutine-closures return coroutines that capture from \
+                    their body; it will always result in a borrowck error!"
+                );
+                by_ref_fields.insert(FieldIdx::from_usize(num_args + idx));
+            }
+
+            // Make sure we're actually talking about the same capture.
+            // FIXME(async_closures): We could look at the `hir::Upvar` instead?
+            assert_eq!(coroutine_capture.place.ty(), parent_capture.place.ty());
+        }
+
+        let by_move_coroutine_ty = tcx
+            .instantiate_bound_regions_with_erased(parent_closure_args.coroutine_closure_sig())
+            .to_coroutine_given_kind_and_upvars(
                 tcx,
-                ty::CoroutineArgsParts {
-                    parent_args: args.as_coroutine().parent_args(),
-                    kind_ty: Ty::from_closure_kind(tcx, ty::ClosureKind::FnOnce),
-                    resume_ty: args.as_coroutine().resume_ty(),
-                    yield_ty: args.as_coroutine().yield_ty(),
-                    return_ty: args.as_coroutine().return_ty(),
-                    witness: args.as_coroutine().witness(),
-                    tupled_upvars_ty: by_move_upvars,
-                },
-            )
-            .args,
-        );
+                parent_closure_args.parent_args(),
+                coroutine_def_id.to_def_id(),
+                ty::ClosureKind::FnOnce,
+                tcx.lifetimes.re_erased,
+                parent_closure_args.tupled_upvars_ty(),
+                parent_closure_args.coroutine_captures_by_ref_ty(),
+            );
 
         let mut by_move_body = body.clone();
         MakeByMoveBody { tcx, by_ref_fields, by_move_coroutine_ty }.visit_body(&mut by_move_body);
diff --git a/compiler/rustc_mir_transform/src/coverage/query.rs b/compiler/rustc_mir_transform/src/coverage/query.rs
index b5dd9dcc7b4..65715253647 100644
--- a/compiler/rustc_mir_transform/src/coverage/query.rs
+++ b/compiler/rustc_mir_transform/src/coverage/query.rs
@@ -59,7 +59,7 @@ fn coverage_ids_info<'tcx>(
             _ => None,
         })
         .max()
-        .unwrap_or(CounterId::START);
+        .unwrap_or(CounterId::ZERO);
 
     CoverageIdsInfo { max_counter_id }
 }
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index 96943435bab..318674f24e7 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -3,7 +3,6 @@
 //! Box is not actually a pointer so it is incorrect to dereference it directly.
 
 use rustc_hir::def_id::DefId;
-use rustc_index::Idx;
 use rustc_middle::mir::patch::MirPatch;
 use rustc_middle::mir::visit::MutVisitor;
 use rustc_middle::mir::*;
@@ -32,9 +31,9 @@ pub fn build_projection<'tcx>(
     ptr_ty: Ty<'tcx>,
 ) -> [PlaceElem<'tcx>; 3] {
     [
-        PlaceElem::Field(FieldIdx::new(0), unique_ty),
-        PlaceElem::Field(FieldIdx::new(0), nonnull_ty),
-        PlaceElem::Field(FieldIdx::new(0), ptr_ty),
+        PlaceElem::Field(FieldIdx::ZERO, unique_ty),
+        PlaceElem::Field(FieldIdx::ZERO, nonnull_ty),
+        PlaceElem::Field(FieldIdx::ZERO, ptr_ty),
     ]
 }
 
@@ -91,15 +90,14 @@ pub struct ElaborateBoxDerefs;
 impl<'tcx> MirPass<'tcx> for ElaborateBoxDerefs {
     fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
         if let Some(def_id) = tcx.lang_items().owned_box() {
-            let unique_did =
-                tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::from_u32(0)].did;
+            let unique_did = tcx.adt_def(def_id).non_enum_variant().fields[FieldIdx::ZERO].did;
 
             let Some(nonnull_def) = tcx.type_of(unique_did).instantiate_identity().ty_adt_def()
             else {
                 span_bug!(tcx.def_span(unique_did), "expected Box to contain Unique")
             };
 
-            let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::from_u32(0)].did;
+            let nonnull_did = nonnull_def.non_enum_variant().fields[FieldIdx::ZERO].did;
 
             let patch = MirPatch::new(body);
 
diff --git a/compiler/rustc_mir_transform/src/errors.rs b/compiler/rustc_mir_transform/src/errors.rs
index 9297bc51fad..0634e321ea3 100644
--- a/compiler/rustc_mir_transform/src/errors.rs
+++ b/compiler/rustc_mir_transform/src/errors.rs
@@ -1,11 +1,6 @@
-use std::borrow::Cow;
-
-use rustc_errors::{
-    codes::*, Applicability, Diag, DiagArgValue, DiagCtxt, DiagMessage, Diagnostic,
-    EmissionGuarantee, Level, LintDiagnostic,
-};
+use rustc_errors::{codes::*, Diag, DiagMessage, LintDiagnostic};
 use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
-use rustc_middle::mir::{AssertKind, UnsafetyViolationDetails};
+use rustc_middle::mir::AssertKind;
 use rustc_middle::ty::TyCtxt;
 use rustc_session::lint::{self, Lint};
 use rustc_span::def_id::DefId;
@@ -42,168 +37,6 @@ pub(crate) struct UnalignedPackedRef {
     pub span: Span,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(mir_transform_unused_unsafe)]
-pub(crate) struct UnusedUnsafe {
-    #[label(mir_transform_unused_unsafe)]
-    pub span: Span,
-    #[label]
-    pub nested_parent: Option<Span>,
-}
-
-pub(crate) struct RequiresUnsafe {
-    pub span: Span,
-    pub details: RequiresUnsafeDetail,
-    pub enclosing: Option<Span>,
-    pub op_in_unsafe_fn_allowed: bool,
-}
-
-// The primary message for this diagnostic should be '{$label} is unsafe and...',
-// so we need to eagerly translate the label here, which isn't supported by the derive API
-// We could also exhaustively list out the primary messages for all unsafe violations,
-// but this would result in a lot of duplication.
-impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for RequiresUnsafe {
-    #[track_caller]
-    fn into_diag(self, dcx: &'a DiagCtxt, level: Level) -> Diag<'a, G> {
-        let mut diag = Diag::new(dcx, level, fluent::mir_transform_requires_unsafe);
-        diag.code(E0133);
-        diag.span(self.span);
-        diag.span_label(self.span, self.details.label());
-        let desc = dcx.eagerly_translate_to_string(self.details.label(), [].into_iter());
-        diag.arg("details", desc);
-        diag.arg("op_in_unsafe_fn_allowed", self.op_in_unsafe_fn_allowed);
-        self.details.add_subdiagnostics(&mut diag);
-        if let Some(sp) = self.enclosing {
-            diag.span_label(sp, fluent::mir_transform_not_inherited);
-        }
-        diag
-    }
-}
-
-#[derive(Clone)]
-pub(crate) struct RequiresUnsafeDetail {
-    pub span: Span,
-    pub violation: UnsafetyViolationDetails,
-}
-
-impl RequiresUnsafeDetail {
-    // FIXME: make this translatable
-    #[allow(rustc::diagnostic_outside_of_impl)]
-    #[allow(rustc::untranslatable_diagnostic)]
-    fn add_subdiagnostics<G: EmissionGuarantee>(&self, diag: &mut Diag<'_, G>) {
-        use UnsafetyViolationDetails::*;
-        match self.violation {
-            CallToUnsafeFunction => {
-                diag.note(fluent::mir_transform_call_to_unsafe_note);
-            }
-            UseOfInlineAssembly => {
-                diag.note(fluent::mir_transform_use_of_asm_note);
-            }
-            InitializingTypeWith => {
-                diag.note(fluent::mir_transform_initializing_valid_range_note);
-            }
-            CastOfPointerToInt => {
-                diag.note(fluent::mir_transform_const_ptr2int_note);
-            }
-            UseOfMutableStatic => {
-                diag.note(fluent::mir_transform_use_of_static_mut_note);
-            }
-            UseOfExternStatic => {
-                diag.note(fluent::mir_transform_use_of_extern_static_note);
-            }
-            DerefOfRawPointer => {
-                diag.note(fluent::mir_transform_deref_ptr_note);
-            }
-            AccessToUnionField => {
-                diag.note(fluent::mir_transform_union_access_note);
-            }
-            MutationOfLayoutConstrainedField => {
-                diag.note(fluent::mir_transform_mutation_layout_constrained_note);
-            }
-            BorrowOfLayoutConstrainedField => {
-                diag.note(fluent::mir_transform_mutation_layout_constrained_borrow_note);
-            }
-            CallToFunctionWith { ref missing, ref build_enabled } => {
-                diag.help(fluent::mir_transform_target_feature_call_help);
-                diag.arg(
-                    "missing_target_features",
-                    DiagArgValue::StrListSepByAnd(
-                        missing.iter().map(|feature| Cow::from(feature.to_string())).collect(),
-                    ),
-                );
-                diag.arg("missing_target_features_count", missing.len());
-                if !build_enabled.is_empty() {
-                    diag.note(fluent::mir_transform_target_feature_call_note);
-                    diag.arg(
-                        "build_target_features",
-                        DiagArgValue::StrListSepByAnd(
-                            build_enabled
-                                .iter()
-                                .map(|feature| Cow::from(feature.to_string()))
-                                .collect(),
-                        ),
-                    );
-                    diag.arg("build_target_features_count", build_enabled.len());
-                }
-            }
-        }
-    }
-
-    fn label(&self) -> DiagMessage {
-        use UnsafetyViolationDetails::*;
-        match self.violation {
-            CallToUnsafeFunction => fluent::mir_transform_call_to_unsafe_label,
-            UseOfInlineAssembly => fluent::mir_transform_use_of_asm_label,
-            InitializingTypeWith => fluent::mir_transform_initializing_valid_range_label,
-            CastOfPointerToInt => fluent::mir_transform_const_ptr2int_label,
-            UseOfMutableStatic => fluent::mir_transform_use_of_static_mut_label,
-            UseOfExternStatic => fluent::mir_transform_use_of_extern_static_label,
-            DerefOfRawPointer => fluent::mir_transform_deref_ptr_label,
-            AccessToUnionField => fluent::mir_transform_union_access_label,
-            MutationOfLayoutConstrainedField => {
-                fluent::mir_transform_mutation_layout_constrained_label
-            }
-            BorrowOfLayoutConstrainedField => {
-                fluent::mir_transform_mutation_layout_constrained_borrow_label
-            }
-            CallToFunctionWith { .. } => fluent::mir_transform_target_feature_call_label,
-        }
-    }
-}
-
-pub(crate) struct UnsafeOpInUnsafeFn {
-    pub details: RequiresUnsafeDetail,
-
-    /// These spans point to:
-    ///  1. the start of the function body
-    ///  2. the end of the function body
-    ///  3. the function signature
-    pub suggest_unsafe_block: Option<(Span, Span, Span)>,
-}
-
-impl<'a> LintDiagnostic<'a, ()> for UnsafeOpInUnsafeFn {
-    #[track_caller]
-    fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
-        let desc = diag.dcx.eagerly_translate_to_string(self.details.label(), [].into_iter());
-        diag.arg("details", desc);
-        diag.span_label(self.details.span, self.details.label());
-        self.details.add_subdiagnostics(diag);
-
-        if let Some((start, end, fn_sig)) = self.suggest_unsafe_block {
-            diag.span_note(fn_sig, fluent::mir_transform_note);
-            diag.tool_only_multipart_suggestion(
-                fluent::mir_transform_suggestion,
-                vec![(start, " unsafe {".into()), (end, "}".into())],
-                Applicability::MaybeIncorrect,
-            );
-        }
-    }
-
-    fn msg(&self) -> DiagMessage {
-        fluent::mir_transform_unsafe_op_in_unsafe_fn
-    }
-}
-
 pub(crate) struct AssertLint<P> {
     pub span: Span,
     pub assert_kind: AssertKind<P>,
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 59d6d89cf1f..d4f736d2a50 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -355,7 +355,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
     }
 
     fn insert_tuple(&mut self, values: Vec<VnIndex>) -> VnIndex {
-        self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::from_u32(0), values))
+        self.insert(Value::Aggregate(AggregateTy::Tuple, VariantIdx::ZERO, values))
     }
 
     #[instrument(level = "trace", skip(self), ret)]
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 5f74841151c..60513a674af 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -324,7 +324,7 @@ impl<'tcx> Inliner<'tcx> {
             // do not need to catch this here, we can wait until the inliner decides to continue
             // inlining a second time.
             InstanceDef::VTableShim(_)
-            | InstanceDef::ReifyShim(_)
+            | InstanceDef::ReifyShim(..)
             | InstanceDef::FnPtrShim(..)
             | InstanceDef::ClosureOnceShim { .. }
             | InstanceDef::ConstructCoroutineInClosureShim { .. }
@@ -1077,7 +1077,7 @@ fn try_instance_mir<'tcx>(
         let fields = def.all_fields();
         for field in fields {
             let field_ty = field.ty(tcx, args);
-            if field_ty.has_param() && field_ty.has_projections() {
+            if field_ty.has_param() && field_ty.has_aliases() {
                 return Err("cannot build drop shim for polymorphic type");
             }
         }
diff --git a/compiler/rustc_mir_transform/src/inline/cycle.rs b/compiler/rustc_mir_transform/src/inline/cycle.rs
index f2b6dcac586..99c7b616f1b 100644
--- a/compiler/rustc_mir_transform/src/inline/cycle.rs
+++ b/compiler/rustc_mir_transform/src/inline/cycle.rs
@@ -5,6 +5,7 @@ use rustc_middle::mir::TerminatorKind;
 use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{self, GenericArgsRef, InstanceDef, TyCtxt};
 use rustc_session::Limit;
+use rustc_span::sym;
 
 // FIXME: check whether it is cheaper to precompute the entire call graph instead of invoking
 // this query ridiculously often.
@@ -84,7 +85,7 @@ pub(crate) fn mir_callgraph_reachable<'tcx>(
                 // again, a function item can end up getting inlined. Thus we'll be able to cause
                 // a cycle that way
                 InstanceDef::VTableShim(_)
-                | InstanceDef::ReifyShim(_)
+                | InstanceDef::ReifyShim(..)
                 | InstanceDef::FnPtrShim(..)
                 | InstanceDef::ClosureOnceShim { .. }
                 | InstanceDef::ConstructCoroutineInClosureShim { .. }
@@ -164,11 +165,20 @@ pub(crate) fn mir_inliner_callees<'tcx>(
     let mut calls = FxIndexSet::default();
     for bb_data in body.basic_blocks.iter() {
         let terminator = bb_data.terminator();
-        if let TerminatorKind::Call { func, .. } = &terminator.kind {
+        if let TerminatorKind::Call { func, args: call_args, .. } = &terminator.kind {
             let ty = func.ty(&body.local_decls, tcx);
-            let call = match ty.kind() {
-                ty::FnDef(def_id, args) => (*def_id, *args),
-                _ => continue,
+            let ty::FnDef(def_id, generic_args) = ty.kind() else {
+                continue;
+            };
+            let call = if tcx.is_intrinsic(*def_id, sym::const_eval_select) {
+                let func = &call_args[2].node;
+                let ty = func.ty(&body.local_decls, tcx);
+                let ty::FnDef(def_id, generic_args) = ty.kind() else {
+                    continue;
+                };
+                (*def_id, *generic_args)
+            } else {
+                (*def_id, *generic_args)
             };
             calls.insert(call);
         }
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index a20958e74df..2218154ea5e 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -13,7 +13,7 @@ use rustc_const_eval::interpret::{
 use rustc_data_structures::fx::FxHashSet;
 use rustc_hir::def::DefKind;
 use rustc_hir::HirId;
-use rustc_index::{bit_set::BitSet, Idx, IndexVec};
+use rustc_index::{bit_set::BitSet, IndexVec};
 use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::layout::{LayoutError, LayoutOf, LayoutOfHelpers, TyAndLayout};
@@ -124,10 +124,8 @@ impl<'tcx> Value<'tcx> {
                     fields.ensure_contains_elem(*idx, || Value::Uninit)
                 }
                 (PlaceElem::Field(..), val @ Value::Uninit) => {
-                    *val = Value::Aggregate {
-                        variant: VariantIdx::new(0),
-                        fields: Default::default(),
-                    };
+                    *val =
+                        Value::Aggregate { variant: VariantIdx::ZERO, fields: Default::default() };
                     val.project_mut(&[*proj])?
                 }
                 _ => return None,
@@ -572,7 +570,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                     self.use_ecx(|this| this.ecx.overflowing_binary_op(bin_op, &left, &right))?;
                 let overflowed = ImmTy::from_bool(overflowed, self.tcx);
                 Value::Aggregate {
-                    variant: VariantIdx::new(0),
+                    variant: VariantIdx::ZERO,
                     fields: [Value::from(val), overflowed.into()].into_iter().collect(),
                 }
             }
@@ -607,7 +605,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         | AggregateKind::Tuple
                         | AggregateKind::Closure(_, _)
                         | AggregateKind::Coroutine(_, _)
-                        | AggregateKind::CoroutineClosure(_, _) => VariantIdx::new(0),
+                        | AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
                     },
                 }
             }
diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs
index a684f9bdff1..e477c068229 100644
--- a/compiler/rustc_mir_transform/src/lib.rs
+++ b/compiler/rustc_mir_transform/src/lib.rs
@@ -53,7 +53,6 @@ mod add_moves_for_packed_drops;
 mod add_retag;
 mod check_const_item_mutation;
 mod check_packed_ref;
-pub mod check_unsafety;
 mod remove_place_mention;
 // This pass is public to allow external drivers to perform MIR cleanup
 mod add_subtyping_projections;
@@ -120,7 +119,6 @@ use rustc_mir_dataflow::rustc_peek;
 rustc_fluent_macro::fluent_messages! { "../messages.ftl" }
 
 pub fn provide(providers: &mut Providers) {
-    check_unsafety::provide(providers);
     coverage::query::provide(providers);
     ffi_unwind_calls::provide(providers);
     shim::provide(providers);
@@ -280,11 +278,6 @@ fn mir_const_qualif(tcx: TyCtxt<'_>, def: LocalDefId) -> ConstQualifs {
 }
 
 fn mir_built(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> {
-    // MIR unsafety check uses the raw mir, so make sure it is run.
-    if !tcx.sess.opts.unstable_opts.thir_unsafeck {
-        tcx.ensure_with_value().mir_unsafety_check_result(def);
-    }
-
     let mut body = tcx.build_mir(def);
 
     pass_manager::dump_mir_for_phase_change(tcx, &body);
diff --git a/compiler/rustc_mir_transform/src/promote_consts.rs b/compiler/rustc_mir_transform/src/promote_consts.rs
index d64cb9b12b2..a9d4b860b7a 100644
--- a/compiler/rustc_mir_transform/src/promote_consts.rs
+++ b/compiler/rustc_mir_transform/src/promote_consts.rs
@@ -434,7 +434,7 @@ impl<'tcx> Validator<'_, 'tcx> {
             Rvalue::ThreadLocalRef(_) => return Err(Unpromotable),
 
             // ptr-to-int casts are not possible in consts and thus not promotable
-            Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => return Err(Unpromotable),
+            Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => return Err(Unpromotable),
 
             // all other casts including int-to-ptr casts are fine, they just use the integer value
             // at pointer type.
diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs
index b60ee7649b2..fa6906bdd55 100644
--- a/compiler/rustc_mir_transform/src/shim.rs
+++ b/compiler/rustc_mir_transform/src/shim.rs
@@ -55,7 +55,7 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<'
         // a virtual call, or a direct call to a function for which
         // indirect calls must be codegen'd differently than direct ones
         // (such as `#[track_caller]`).
-        ty::InstanceDef::ReifyShim(def_id) => {
+        ty::InstanceDef::ReifyShim(def_id, _) => {
             build_call_shim(tcx, instance, None, CallKind::Direct(def_id))
         }
         ty::InstanceDef::ClosureOnceShim { call_once: _, track_caller: _ } => {
@@ -985,7 +985,7 @@ fn build_fn_ptr_addr_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'t
     let locals = local_decls_for_sig(&sig, span);
 
     let source_info = SourceInfo::outermost(span);
-    // FIXME: use `expose_addr` once we figure out whether function pointers have meaningful provenance.
+    // FIXME: use `expose_provenance` once we figure out whether function pointers have meaningful provenance.
     let rvalue = Rvalue::Cast(
         CastKind::FnPtrToPtr,
         Operand::Move(Place::from(Local::new(1))),
diff --git a/compiler/rustc_mir_transform/src/simplify.rs b/compiler/rustc_mir_transform/src/simplify.rs
index 14772080ce5..5bbe3bb747f 100644
--- a/compiler/rustc_mir_transform/src/simplify.rs
+++ b/compiler/rustc_mir_transform/src/simplify.rs
@@ -415,7 +415,7 @@ fn make_local_map<V>(
     used_locals: &UsedLocals,
 ) -> IndexVec<Local, Option<Local>> {
     let mut map: IndexVec<Local, Option<Local>> = IndexVec::from_elem(None, local_decls);
-    let mut used = Local::new(0);
+    let mut used = Local::ZERO;
 
     for alive_index in local_decls.indices() {
         // `is_used` treats the `RETURN_PLACE` and arguments as used.
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 63b2b47630b..69b48bf0aff 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -30,7 +30,7 @@ use unescape_error_reporting::{emit_unescape_error, escaped_char};
 //
 // This assertion is in this crate, rather than in `rustc_lexer`, because that
 // crate cannot depend on `rustc_data_structures`.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(rustc_lexer::Token, 12);
 
 #[derive(Clone, Debug)]
diff --git a/compiler/rustc_parse/src/parser/attr_wrapper.rs b/compiler/rustc_parse/src/parser/attr_wrapper.rs
index a1dd7d6f673..baaed5ec37b 100644
--- a/compiler/rustc_parse/src/parser/attr_wrapper.rs
+++ b/compiler/rustc_parse/src/parser/attr_wrapper.rs
@@ -454,7 +454,7 @@ fn make_token_stream(
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 18fb858c84c..012285e4644 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -860,6 +860,7 @@ impl<'a> Parser<'a> {
                     ExprKind::MethodCall(_) => "a method call",
                     ExprKind::Call(_, _) => "a function call",
                     ExprKind::Await(_, _) => "`.await`",
+                    ExprKind::Match(_, _, MatchKind::Postfix) => "a postfix match",
                     ExprKind::Err(_) => return Ok(with_postfix),
                     _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
                 }
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 1971591364d..09bc00403f3 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -179,7 +179,7 @@ pub struct Parser<'a> {
 
 // This type is used a lot, e.g. it's cloned when matching many declarative macro rules with nonterminals. Make sure
 // it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 rustc_data_structures::static_assert_size!(Parser<'_>, 264);
 
 /// Stores span information about a closure.
diff --git a/compiler/rustc_parse_format/src/lib.rs b/compiler/rustc_parse_format/src/lib.rs
index 2bb4b09e337..ccda43c827c 100644
--- a/compiler/rustc_parse_format/src/lib.rs
+++ b/compiler/rustc_parse_format/src/lib.rs
@@ -1087,7 +1087,7 @@ fn unescape_string(string: &str) -> Option<string::String> {
 }
 
 // Assert a reasonable size for `Piece`
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 rustc_index::static_assert_size!(Piece<'_>, 16);
 
 #[cfg(test)]
diff --git a/compiler/rustc_pattern_analysis/src/constructor.rs b/compiler/rustc_pattern_analysis/src/constructor.rs
index 1c9a9ab0f72..44f09b66bf6 100644
--- a/compiler/rustc_pattern_analysis/src/constructor.rs
+++ b/compiler/rustc_pattern_analysis/src/constructor.rs
@@ -140,6 +140,34 @@
 //! [`ConstructorSet::split`]. The invariants of [`SplitConstructorSet`] are also of interest.
 //!
 //!
+//! ## Unions
+//!
+//! Unions allow us to match a value via several overlapping representations at the same time. For
+//! example, the following is exhaustive because when seeing the value as a boolean we handled all
+//! possible cases (other cases such as `n == 3` would trigger UB).
+//!
+//! ```rust
+//! # fn main() {
+//! union U8AsBool {
+//!     n: u8,
+//!     b: bool,
+//! }
+//! let x = U8AsBool { n: 1 };
+//! unsafe {
+//!     match x {
+//!         U8AsBool { n: 2 } => {}
+//!         U8AsBool { b: true } => {}
+//!         U8AsBool { b: false } => {}
+//!     }
+//! }
+//! # }
+//! ```
+//!
+//! Pattern-matching has no knowledge that e.g. `false as u8 == 0`, so the values we consider in the
+//! algorithm look like `U8AsBool { b: true, n: 2 }`. In other words, for the most part a union is
+//! treated like a struct with the same fields. The difference lies in how we construct witnesses of
+//! non-exhaustiveness.
+//!
 //!
 //! ## Opaque patterns
 //!
@@ -974,7 +1002,6 @@ impl<Cx: PatCx> ConstructorSet<Cx> {
     /// any) are missing; 2/ split constructors to handle non-trivial intersections e.g. on ranges
     /// or slices. This can get subtle; see [`SplitConstructorSet`] for details of this operation
     /// and its invariants.
-    #[instrument(level = "debug", skip(self, ctors), ret)]
     pub fn split<'a>(
         &self,
         ctors: impl Iterator<Item = &'a Constructor<Cx>> + Clone,
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index b0f506c3651..467f09e4c29 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -186,7 +186,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
 
     /// Returns the types of the fields for a given constructor. The result must have a length of
     /// `ctor.arity()`.
-    #[instrument(level = "trace", skip(self))]
     pub(crate) fn ctor_sub_tys<'a>(
         &'a self,
         ctor: &'a Constructor<'p, 'tcx>,
@@ -283,7 +282,6 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// Creates a set that represents all the constructors of `ty`.
     ///
     /// See [`crate::constructor`] for considerations of emptiness.
-    #[instrument(level = "debug", skip(self), ret)]
     pub fn ctors_for_ty(
         &self,
         ty: RevealedTy<'tcx>,
diff --git a/compiler/rustc_pattern_analysis/src/usefulness.rs b/compiler/rustc_pattern_analysis/src/usefulness.rs
index cdc03eaeb37..7246039174a 100644
--- a/compiler/rustc_pattern_analysis/src/usefulness.rs
+++ b/compiler/rustc_pattern_analysis/src/usefulness.rs
@@ -871,12 +871,14 @@ impl<Cx: PatCx> PlaceInfo<Cx> {
     where
         Cx: 'a,
     {
+        debug!(?self.ty);
         if self.private_uninhabited {
             // Skip the whole column
             return Ok((smallvec![Constructor::PrivateUninhabited], vec![]));
         }
 
         let ctors_for_ty = cx.ctors_for_ty(&self.ty)?;
+        debug!(?ctors_for_ty);
 
         // We treat match scrutinees of type `!` or `EmptyEnum` differently.
         let is_toplevel_exception =
@@ -895,6 +897,7 @@ impl<Cx: PatCx> PlaceInfo<Cx> {
 
         // Analyze the constructors present in this column.
         let mut split_set = ctors_for_ty.split(ctors);
+        debug!(?split_set);
         let all_missing = split_set.present.is_empty();
 
         // Build the set of constructors we will specialize with. It must cover the whole type, so
@@ -1254,7 +1257,7 @@ impl<'p, Cx: PatCx> Matrix<'p, Cx> {
 /// + true  + [Second(true)]    +
 /// + false + [_]               +
 /// + _     + [_, _, tail @ ..] +
-/// | ✓     | ?                 | // column validity
+/// | ✓     | ?                 | // validity
 /// ```
 impl<'p, Cx: PatCx> fmt::Debug for Matrix<'p, Cx> {
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
@@ -1285,7 +1288,7 @@ impl<'p, Cx: PatCx> fmt::Debug for Matrix<'p, Cx> {
                 write!(f, " {sep}")?;
             }
             if is_validity_row {
-                write!(f, " // column validity")?;
+                write!(f, " // validity")?;
             }
             write!(f, "\n")?;
         }
@@ -1381,12 +1384,35 @@ impl<Cx: PatCx> WitnessStack<Cx> {
     /// pats: [(false, "foo"), _, true]
     /// result: [Enum::Variant { a: (false, "foo"), b: _ }, true]
     /// ```
-    fn apply_constructor(&mut self, pcx: &PlaceCtxt<'_, Cx>, ctor: &Constructor<Cx>) {
+    fn apply_constructor(
+        mut self,
+        pcx: &PlaceCtxt<'_, Cx>,
+        ctor: &Constructor<Cx>,
+    ) -> SmallVec<[Self; 1]> {
         let len = self.0.len();
         let arity = pcx.ctor_arity(ctor);
-        let fields = self.0.drain((len - arity)..).rev().collect();
-        let pat = WitnessPat::new(ctor.clone(), fields, pcx.ty.clone());
-        self.0.push(pat);
+        let fields: Vec<_> = self.0.drain((len - arity)..).rev().collect();
+        if matches!(ctor, Constructor::UnionField)
+            && fields.iter().filter(|p| !matches!(p.ctor(), Constructor::Wildcard)).count() >= 2
+        {
+            // Convert a `Union { a: p, b: q }` witness into `Union { a: p }` and `Union { b: q }`.
+            // First add `Union { .. }` to `self`.
+            self.0.push(WitnessPat::wild_from_ctor(pcx.cx, ctor.clone(), pcx.ty.clone()));
+            fields
+                .into_iter()
+                .enumerate()
+                .filter(|(_, p)| !matches!(p.ctor(), Constructor::Wildcard))
+                .map(|(i, p)| {
+                    let mut ret = self.clone();
+                    // Fill the `i`th field of the union with `p`.
+                    ret.0.last_mut().unwrap().fields[i] = p;
+                    ret
+                })
+                .collect()
+        } else {
+            self.0.push(WitnessPat::new(ctor.clone(), fields, pcx.ty.clone()));
+            smallvec![self]
+        }
     }
 }
 
@@ -1459,8 +1485,8 @@ impl<Cx: PatCx> WitnessMatrix<Cx> {
             *self = ret;
         } else {
             // Any other constructor we unspecialize as expected.
-            for witness in self.0.iter_mut() {
-                witness.apply_constructor(pcx, ctor)
+            for witness in std::mem::take(&mut self.0) {
+                self.0.extend(witness.apply_constructor(pcx, ctor));
             }
         }
     }
@@ -1617,7 +1643,6 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: PatCx>(
     };
 
     // Analyze the constructors present in this column.
-    debug!("ty: {:?}", place.ty);
     let ctors = matrix.heads().map(|p| p.ctor());
     let (split_ctors, missing_ctors) = place.split_column_ctors(mcx.tycx, ctors)?;
 
@@ -1669,7 +1694,10 @@ fn compute_exhaustiveness_and_usefulness<'a, 'p, Cx: PatCx>(
     for row in matrix.rows() {
         if row.useful {
             if let PatOrWild::Pat(pat) = row.head() {
-                mcx.useful_subpatterns.insert(pat.uid);
+                let newly_useful = mcx.useful_subpatterns.insert(pat.uid);
+                if newly_useful {
+                    debug!("newly useful: {pat:?}");
+                }
             }
         }
     }
@@ -1768,6 +1796,7 @@ pub fn compute_match_usefulness<'p, Cx: PatCx>(
         .map(|arm| {
             debug!(?arm);
             let usefulness = collect_pattern_usefulness(&cx.useful_subpatterns, arm.pat);
+            debug!(?usefulness);
             (arm, usefulness)
         })
         .collect();
diff --git a/compiler/rustc_query_system/src/dep_graph/graph.rs b/compiler/rustc_query_system/src/dep_graph/graph.rs
index 9f067273f35..534937003eb 100644
--- a/compiler/rustc_query_system/src/dep_graph/graph.rs
+++ b/compiler/rustc_query_system/src/dep_graph/graph.rs
@@ -13,6 +13,7 @@ use std::fmt::Debug;
 use std::hash::Hash;
 use std::marker::PhantomData;
 use std::sync::atomic::Ordering;
+use std::sync::Arc;
 
 use super::query::DepGraphQuery;
 use super::serialized::{GraphEncoder, SerializedDepGraph, SerializedDepNodeIndex};
@@ -40,7 +41,7 @@ rustc_index::newtype_index! {
 }
 
 impl DepNodeIndex {
-    const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::from_u32(0);
+    const SINGLETON_DEPENDENCYLESS_ANON_NODE: DepNodeIndex = DepNodeIndex::ZERO;
     pub const FOREVER_RED_NODE: DepNodeIndex = DepNodeIndex::from_u32(1);
 }
 
@@ -81,7 +82,7 @@ pub(crate) struct DepGraphData<D: Deps> {
 
     /// The dep-graph from the previous compilation session. It contains all
     /// nodes and edges as well as all fingerprints of nodes that have them.
-    previous: SerializedDepGraph,
+    previous: Arc<SerializedDepGraph>,
 
     colors: DepNodeColorMap,
 
@@ -113,7 +114,7 @@ where
 impl<D: Deps> DepGraph<D> {
     pub fn new(
         profiler: &SelfProfilerRef,
-        prev_graph: SerializedDepGraph,
+        prev_graph: Arc<SerializedDepGraph>,
         prev_work_products: WorkProductMap,
         encoder: FileEncoder,
         record_graph: bool,
@@ -127,6 +128,7 @@ impl<D: Deps> DepGraph<D> {
             encoder,
             record_graph,
             record_stats,
+            prev_graph.clone(),
         );
 
         let colors = DepNodeColorMap::new(prev_graph_node_count);
@@ -1084,6 +1086,7 @@ impl<D: Deps> CurrentDepGraph<D> {
         encoder: FileEncoder,
         record_graph: bool,
         record_stats: bool,
+        previous: Arc<SerializedDepGraph>,
     ) -> Self {
         use std::time::{SystemTime, UNIX_EPOCH};
 
@@ -1116,6 +1119,7 @@ impl<D: Deps> CurrentDepGraph<D> {
                 record_graph,
                 record_stats,
                 profiler,
+                previous,
             ),
             new_node_to_index: Sharded::new(|| {
                 FxHashMap::with_capacity_and_hasher(
@@ -1236,16 +1240,14 @@ impl<D: Deps> CurrentDepGraph<D> {
         match prev_index_to_index[prev_index] {
             Some(dep_node_index) => dep_node_index,
             None => {
-                let key = prev_graph.index_to_node(prev_index);
-                let edges = prev_graph
-                    .edge_targets_from(prev_index)
-                    .map(|i| prev_index_to_index[i].unwrap())
-                    .collect();
-                let fingerprint = prev_graph.fingerprint_by_index(prev_index);
-                let dep_node_index = self.encoder.send(key, fingerprint, edges);
+                let dep_node_index = self.encoder.send_promoted(prev_index, &*prev_index_to_index);
                 prev_index_to_index[prev_index] = Some(dep_node_index);
                 #[cfg(debug_assertions)]
-                self.record_edge(dep_node_index, key, fingerprint);
+                self.record_edge(
+                    dep_node_index,
+                    prev_graph.index_to_node(prev_index),
+                    prev_graph.fingerprint_by_index(prev_index),
+                );
                 dep_node_index
             }
         }
diff --git a/compiler/rustc_query_system/src/dep_graph/serialized.rs b/compiler/rustc_query_system/src/dep_graph/serialized.rs
index 0c6a6358293..2bc7cb99547 100644
--- a/compiler/rustc_query_system/src/dep_graph/serialized.rs
+++ b/compiler/rustc_query_system/src/dep_graph/serialized.rs
@@ -41,6 +41,7 @@ use crate::dep_graph::edges::EdgesVec;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fingerprint::PackedFingerprint;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::outline;
 use rustc_data_structures::profiling::SelfProfilerRef;
 use rustc_data_structures::sync::Lock;
 use rustc_data_structures::unhash::UnhashMap;
@@ -49,6 +50,7 @@ use rustc_serialize::opaque::{FileEncodeResult, FileEncoder, IntEncodedWithFixed
 use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
 use std::iter;
 use std::marker::PhantomData;
+use std::sync::Arc;
 
 // The maximum value of `SerializedDepNodeIndex` leaves the upper two bits
 // unused so that we can store multiple index types in `CompressedHybridIndex`,
@@ -94,7 +96,7 @@ impl SerializedDepGraph {
     pub fn edge_targets_from(
         &self,
         source: SerializedDepNodeIndex,
-    ) -> impl Iterator<Item = SerializedDepNodeIndex> + '_ {
+    ) -> impl Iterator<Item = SerializedDepNodeIndex> + Clone + '_ {
         let header = self.edge_list_indices[source];
         let mut raw = &self.edge_list_data[header.start()..];
         // Figure out where the edge list for `source` ends by getting the start index of the next
@@ -176,7 +178,7 @@ fn mask(bits: usize) -> usize {
 
 impl SerializedDepGraph {
     #[instrument(level = "debug", skip(d))]
-    pub fn decode<D: Deps>(d: &mut MemDecoder<'_>) -> SerializedDepGraph {
+    pub fn decode<D: Deps>(d: &mut MemDecoder<'_>) -> Arc<SerializedDepGraph> {
         // The last 16 bytes are the node count and edge count.
         debug!("position: {:?}", d.position());
         let (node_count, edge_count, graph_size) =
@@ -254,7 +256,13 @@ impl SerializedDepGraph {
             index[node.kind.as_usize()].insert(node.hash, idx);
         }
 
-        SerializedDepGraph { nodes, fingerprints, edge_list_indices, edge_list_data, index }
+        Arc::new(SerializedDepGraph {
+            nodes,
+            fingerprints,
+            edge_list_indices,
+            edge_list_data,
+            index,
+        })
     }
 }
 
@@ -299,21 +307,24 @@ impl<D: Deps> SerializedNodeHeader<D> {
     const MAX_INLINE_LEN: usize = (u16::MAX as usize >> (Self::TOTAL_BITS - Self::LEN_BITS)) - 1;
 
     #[inline]
-    fn new(node_info: &NodeInfo) -> Self {
+    fn new(
+        node: DepNode,
+        fingerprint: Fingerprint,
+        edge_max_index: u32,
+        edge_count: usize,
+    ) -> Self {
         debug_assert_eq!(Self::TOTAL_BITS, Self::LEN_BITS + Self::WIDTH_BITS + Self::KIND_BITS);
 
-        let NodeInfo { node, fingerprint, edges } = node_info;
-
         let mut head = node.kind.as_inner();
 
-        let free_bytes = edges.max_index().leading_zeros() as usize / 8;
+        let free_bytes = edge_max_index.leading_zeros() as usize / 8;
         let bytes_per_index = (DEP_NODE_SIZE - free_bytes).saturating_sub(1);
         head |= (bytes_per_index as u16) << Self::KIND_BITS;
 
         // Encode number of edges + 1 so that we can reserve 0 to indicate that the len doesn't fit
         // in this bitfield.
-        if edges.len() <= Self::MAX_INLINE_LEN {
-            head |= (edges.len() as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS);
+        if edge_count <= Self::MAX_INLINE_LEN {
+            head |= (edge_count as u16 + 1) << (Self::KIND_BITS + Self::WIDTH_BITS);
         }
 
         let hash: Fingerprint = node.hash.into();
@@ -327,10 +338,10 @@ impl<D: Deps> SerializedNodeHeader<D> {
         #[cfg(debug_assertions)]
         {
             let res = Self { bytes, _marker: PhantomData };
-            assert_eq!(node_info.fingerprint, res.fingerprint());
-            assert_eq!(node_info.node, res.node());
+            assert_eq!(fingerprint, res.fingerprint());
+            assert_eq!(node, res.node());
             if let Some(len) = res.len() {
-                assert_eq!(node_info.edges.len(), len);
+                assert_eq!(edge_count, len);
             }
         }
         Self { bytes, _marker: PhantomData }
@@ -393,21 +404,61 @@ struct NodeInfo {
 
 impl NodeInfo {
     fn encode<D: Deps>(&self, e: &mut FileEncoder) {
-        let header = SerializedNodeHeader::<D>::new(self);
+        let NodeInfo { node, fingerprint, ref edges } = *self;
+        let header =
+            SerializedNodeHeader::<D>::new(node, fingerprint, edges.max_index(), edges.len());
         e.write_array(header.bytes);
 
         if header.len().is_none() {
-            e.emit_usize(self.edges.len());
+            e.emit_usize(edges.len());
         }
 
         let bytes_per_index = header.bytes_per_index();
-        for node_index in self.edges.iter() {
+        for node_index in edges.iter() {
             e.write_with(|dest| {
                 *dest = node_index.as_u32().to_le_bytes();
                 bytes_per_index
             });
         }
     }
+
+    /// Encode a node that was promoted from the previous graph. It reads the edges directly from
+    /// the previous dep graph and expects all edges to already have a new dep node index assigned.
+    /// This avoids the overhead of constructing `EdgesVec`, which would be needed to call `encode`.
+    #[inline]
+    fn encode_promoted<D: Deps>(
+        e: &mut FileEncoder,
+        node: DepNode,
+        fingerprint: Fingerprint,
+        prev_index: SerializedDepNodeIndex,
+        prev_index_to_index: &IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>,
+        previous: &SerializedDepGraph,
+    ) -> usize {
+        let edges = previous.edge_targets_from(prev_index);
+        let edge_count = edges.size_hint().0;
+
+        // Find the highest edge in the new dep node indices
+        let edge_max =
+            edges.clone().map(|i| prev_index_to_index[i].unwrap().as_u32()).max().unwrap_or(0);
+
+        let header = SerializedNodeHeader::<D>::new(node, fingerprint, edge_max, edge_count);
+        e.write_array(header.bytes);
+
+        if header.len().is_none() {
+            e.emit_usize(edge_count);
+        }
+
+        let bytes_per_index = header.bytes_per_index();
+        for node_index in edges {
+            let node_index = prev_index_to_index[node_index].unwrap();
+            e.write_with(|dest| {
+                *dest = node_index.as_u32().to_le_bytes();
+                bytes_per_index
+            });
+        }
+
+        edge_count
+    }
 }
 
 struct Stat {
@@ -417,6 +468,7 @@ struct Stat {
 }
 
 struct EncoderState<D: Deps> {
+    previous: Arc<SerializedDepGraph>,
     encoder: FileEncoder,
     total_node_count: usize,
     total_edge_count: usize,
@@ -428,8 +480,9 @@ struct EncoderState<D: Deps> {
 }
 
 impl<D: Deps> EncoderState<D> {
-    fn new(encoder: FileEncoder, record_stats: bool) -> Self {
+    fn new(encoder: FileEncoder, record_stats: bool, previous: Arc<SerializedDepGraph>) -> Self {
         Self {
+            previous,
             encoder,
             total_edge_count: 0,
             total_node_count: 0,
@@ -439,38 +492,101 @@ impl<D: Deps> EncoderState<D> {
         }
     }
 
-    fn encode_node(
+    #[inline]
+    fn record(
         &mut self,
-        node: &NodeInfo,
+        node: DepNode,
+        edge_count: usize,
+        edges: impl FnOnce(&mut Self) -> Vec<DepNodeIndex>,
         record_graph: &Option<Lock<DepGraphQuery>>,
     ) -> DepNodeIndex {
         let index = DepNodeIndex::new(self.total_node_count);
-        self.total_node_count += 1;
-        self.kind_stats[node.node.kind.as_usize()] += 1;
 
-        let edge_count = node.edges.len();
+        self.total_node_count += 1;
+        self.kind_stats[node.kind.as_usize()] += 1;
         self.total_edge_count += edge_count;
 
         if let Some(record_graph) = &record_graph {
-            // Do not ICE when a query is called from within `with_query`.
-            if let Some(record_graph) = &mut record_graph.try_lock() {
-                record_graph.push(index, node.node, &node.edges);
-            }
+            // Call `edges` before the outlined code to allow the closure to be optimized out.
+            let edges = edges(self);
+
+            // Outline the build of the full dep graph as it's typically disabled and cold.
+            outline(move || {
+                // Do not ICE when a query is called from within `with_query`.
+                if let Some(record_graph) = &mut record_graph.try_lock() {
+                    record_graph.push(index, node, &edges);
+                }
+            });
         }
 
         if let Some(stats) = &mut self.stats {
-            let kind = node.node.kind;
-
-            let stat = stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
-            stat.node_counter += 1;
-            stat.edge_counter += edge_count as u64;
+            let kind = node.kind;
+
+            // Outline the stats code as it's typically disabled and cold.
+            outline(move || {
+                let stat =
+                    stats.entry(kind).or_insert(Stat { kind, node_counter: 0, edge_counter: 0 });
+                stat.node_counter += 1;
+                stat.edge_counter += edge_count as u64;
+            });
         }
 
-        let encoder = &mut self.encoder;
-        node.encode::<D>(encoder);
         index
     }
 
+    /// Encodes a node to the current graph.
+    fn encode_node(
+        &mut self,
+        node: &NodeInfo,
+        record_graph: &Option<Lock<DepGraphQuery>>,
+    ) -> DepNodeIndex {
+        node.encode::<D>(&mut self.encoder);
+        self.record(
+            node.node,
+            node.edges.len(),
+            |_| node.edges[..].iter().copied().collect(),
+            record_graph,
+        )
+    }
+
+    /// Encodes a node that was promoted from the previous graph. It reads the information directly from
+    /// the previous dep graph for performance reasons.
+    ///
+    /// This differs from `encode_node` where you have to explictly provide the relevant `NodeInfo`.
+    ///
+    /// It expects all edges to already have a new dep node index assigned.
+    #[inline]
+    fn encode_promoted_node(
+        &mut self,
+        prev_index: SerializedDepNodeIndex,
+        record_graph: &Option<Lock<DepGraphQuery>>,
+        prev_index_to_index: &IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>,
+    ) -> DepNodeIndex {
+        let node = self.previous.index_to_node(prev_index);
+
+        let fingerprint = self.previous.fingerprint_by_index(prev_index);
+        let edge_count = NodeInfo::encode_promoted::<D>(
+            &mut self.encoder,
+            node,
+            fingerprint,
+            prev_index,
+            prev_index_to_index,
+            &self.previous,
+        );
+
+        self.record(
+            node,
+            edge_count,
+            |this| {
+                this.previous
+                    .edge_targets_from(prev_index)
+                    .map(|i| prev_index_to_index[i].unwrap())
+                    .collect()
+            },
+            record_graph,
+        )
+    }
+
     fn finish(self, profiler: &SelfProfilerRef) -> FileEncodeResult {
         let Self {
             mut encoder,
@@ -479,6 +595,7 @@ impl<D: Deps> EncoderState<D> {
             stats: _,
             kind_stats,
             marker: _,
+            previous: _,
         } = self;
 
         let node_count = total_node_count.try_into().unwrap();
@@ -520,9 +637,10 @@ impl<D: Deps> GraphEncoder<D> {
         record_graph: bool,
         record_stats: bool,
         profiler: &SelfProfilerRef,
+        previous: Arc<SerializedDepGraph>,
     ) -> Self {
         let record_graph = record_graph.then(|| Lock::new(DepGraphQuery::new(prev_node_count)));
-        let status = Lock::new(Some(EncoderState::new(encoder, record_stats)));
+        let status = Lock::new(Some(EncoderState::new(encoder, record_stats, previous)));
         GraphEncoder { status, record_graph, profiler: profiler.clone() }
     }
 
@@ -596,6 +714,22 @@ impl<D: Deps> GraphEncoder<D> {
         self.status.lock().as_mut().unwrap().encode_node(&node, &self.record_graph)
     }
 
+    /// Encodes a node that was promoted from the previous graph. It reads the information directly from
+    /// the previous dep graph and expects all edges to already have a new dep node index assigned.
+    #[inline]
+    pub(crate) fn send_promoted(
+        &self,
+        prev_index: SerializedDepNodeIndex,
+        prev_index_to_index: &IndexVec<SerializedDepNodeIndex, Option<DepNodeIndex>>,
+    ) -> DepNodeIndex {
+        let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph");
+        self.status.lock().as_mut().unwrap().encode_promoted_node(
+            prev_index,
+            &self.record_graph,
+            prev_index_to_index,
+        )
+    }
+
     pub fn finish(&self) -> FileEncodeResult {
         let _prof_timer = self.profiler.generic_activity("incr_comp_encode_dep_graph_finish");
 
diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs
index b24ed573ff9..43a43e01a9a 100644
--- a/compiler/rustc_resolve/src/ident.rs
+++ b/compiler/rustc_resolve/src/ident.rs
@@ -605,6 +605,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 && !this.tcx.features().f16
                                 && !ident.span.allows_unstable(sym::f16)
                                 && finalize.is_some()
+                                && innermost_result.is_none()
                             {
                                 feature_err(
                                     this.tcx.sess,
@@ -618,6 +619,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                                 && !this.tcx.features().f128
                                 && !ident.span.allows_unstable(sym::f128)
                                 && finalize.is_some()
+                                && innermost_result.is_none()
                             {
                                 feature_err(
                                     this.tcx.sess,
diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs
index 48711f43518..76fe36a77cb 100644
--- a/compiler/rustc_resolve/src/imports.rs
+++ b/compiler/rustc_resolve/src/imports.rs
@@ -532,7 +532,7 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
 
         let mut seen_spans = FxHashSet::default();
         let mut errors = vec![];
-        let mut prev_root_id: NodeId = NodeId::from_u32(0);
+        let mut prev_root_id: NodeId = NodeId::ZERO;
         let determined_imports = mem::take(&mut self.determined_imports);
         let indeterminate_imports = mem::take(&mut self.indeterminate_imports);
 
@@ -556,8 +556,8 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
                     }
                 }
 
-                if prev_root_id.as_u32() != 0
-                    && prev_root_id.as_u32() != import.root_id.as_u32()
+                if prev_root_id != NodeId::ZERO
+                    && prev_root_id != import.root_id
                     && !errors.is_empty()
                 {
                     // In the case of a new import line, throw a diagnostic message
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index d51fcf693ed..a4919b25fe3 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -10,19 +10,16 @@ use crate::search_paths::SearchPath;
 use crate::utils::{CanonicalizedPath, NativeLib, NativeLibKind};
 use crate::{filesearch, lint, HashStableContext};
 use crate::{EarlyDiagCtxt, Session};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::stable_hasher::{StableOrd, ToStableHashKey};
 use rustc_errors::emitter::HumanReadableErrorType;
 use rustc_errors::{ColorConfig, DiagArgValue, DiagCtxtFlags, IntoDiagArg};
 use rustc_feature::UnstableFeatures;
 use rustc_span::edition::{Edition, DEFAULT_EDITION, EDITION_NAME_LIST, LATEST_STABLE_EDITION};
 use rustc_span::source_map::FilePathMapping;
-use rustc_span::symbol::{sym, Symbol};
 use rustc_span::{FileName, FileNameDisplayPreference, RealFileName, SourceFileHashAlgorithm};
-use rustc_target::abi::Align;
 use rustc_target::spec::LinkSelfContainedComponents;
-use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet, SplitDebuginfo};
-use rustc_target::spec::{Target, TargetTriple, TARGETS};
+use rustc_target::spec::{SplitDebuginfo, Target, TargetTriple};
 use std::collections::btree_map::{
     Iter as BTreeMapIter, Keys as BTreeMapKeysIter, Values as BTreeMapValuesIter,
 };
@@ -36,8 +33,11 @@ use std::path::{Path, PathBuf};
 use std::str::{self, FromStr};
 use std::sync::LazyLock;
 
+mod cfg;
 pub mod sigpipe;
 
+pub use cfg::{Cfg, CheckCfg, ExpectedValues};
+
 /// The different settings that the `-C strip` flag can have.
 #[derive(Clone, Copy, PartialEq, Hash, Debug)]
 pub enum Strip {
@@ -1201,346 +1201,10 @@ pub(crate) const fn default_lib_output() -> CrateType {
     CrateType::Rlib
 }
 
-fn default_configuration(sess: &Session) -> Cfg {
-    let mut ret = Cfg::default();
-
-    macro_rules! ins_none {
-        ($key:expr) => {
-            ret.insert(($key, None));
-        };
-    }
-    macro_rules! ins_str {
-        ($key:expr, $val_str:expr) => {
-            ret.insert(($key, Some(Symbol::intern($val_str))));
-        };
-    }
-    macro_rules! ins_sym {
-        ($key:expr, $val_sym:expr) => {
-            ret.insert(($key, Some($val_sym)));
-        };
-    }
-
-    // Symbols are inserted in alphabetical order as much as possible.
-    // The exceptions are where control flow forces things out of order.
-    //
-    // Run `rustc --print cfg` to see the configuration in practice.
-    //
-    // NOTE: These insertions should be kept in sync with
-    // `CheckCfg::fill_well_known` below.
-
-    if sess.opts.debug_assertions {
-        ins_none!(sym::debug_assertions);
-    }
-
-    if sess.overflow_checks() {
-        ins_none!(sym::overflow_checks);
-    }
-
-    ins_sym!(sym::panic, sess.panic_strategy().desc_symbol());
-
-    // JUSTIFICATION: before wrapper fn is available
-    #[allow(rustc::bad_opt_access)]
-    if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
-        ins_none!(sym::proc_macro);
-    }
-
-    if sess.is_nightly_build() {
-        ins_sym!(sym::relocation_model, sess.target.relocation_model.desc_symbol());
-    }
-
-    for mut s in sess.opts.unstable_opts.sanitizer {
-        // KASAN is still ASAN under the hood, so it uses the same attribute.
-        if s == SanitizerSet::KERNELADDRESS {
-            s = SanitizerSet::ADDRESS;
-        }
-        ins_str!(sym::sanitize, &s.to_string());
-    }
-
-    if sess.is_sanitizer_cfi_generalize_pointers_enabled() {
-        ins_none!(sym::sanitizer_cfi_generalize_pointers);
-    }
-    if sess.is_sanitizer_cfi_normalize_integers_enabled() {
-        ins_none!(sym::sanitizer_cfi_normalize_integers);
-    }
-
-    ins_str!(sym::target_abi, &sess.target.abi);
-    ins_str!(sym::target_arch, &sess.target.arch);
-    ins_str!(sym::target_endian, sess.target.endian.as_str());
-    ins_str!(sym::target_env, &sess.target.env);
-
-    for family in sess.target.families.as_ref() {
-        ins_str!(sym::target_family, family);
-        if family == "windows" {
-            ins_none!(sym::windows);
-        } else if family == "unix" {
-            ins_none!(sym::unix);
-        }
-    }
-
-    // `target_has_atomic*`
-    let layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
-        sess.dcx().emit_fatal(err);
-    });
-    let mut has_atomic = false;
-    for (i, align) in [
-        (8, layout.i8_align.abi),
-        (16, layout.i16_align.abi),
-        (32, layout.i32_align.abi),
-        (64, layout.i64_align.abi),
-        (128, layout.i128_align.abi),
-    ] {
-        if i >= sess.target.min_atomic_width() && i <= sess.target.max_atomic_width() {
-            if !has_atomic {
-                has_atomic = true;
-                if sess.is_nightly_build() {
-                    if sess.target.atomic_cas {
-                        ins_none!(sym::target_has_atomic);
-                    }
-                    ins_none!(sym::target_has_atomic_load_store);
-                }
-            }
-            let mut insert_atomic = |sym, align: Align| {
-                if sess.target.atomic_cas {
-                    ins_sym!(sym::target_has_atomic, sym);
-                }
-                if align.bits() == i {
-                    ins_sym!(sym::target_has_atomic_equal_alignment, sym);
-                }
-                ins_sym!(sym::target_has_atomic_load_store, sym);
-            };
-            insert_atomic(sym::integer(i), align);
-            if sess.target.pointer_width as u64 == i {
-                insert_atomic(sym::ptr, layout.pointer_align.abi);
-            }
-        }
-    }
-
-    ins_str!(sym::target_os, &sess.target.os);
-    ins_sym!(sym::target_pointer_width, sym::integer(sess.target.pointer_width));
-
-    if sess.opts.unstable_opts.has_thread_local.unwrap_or(sess.target.has_thread_local) {
-        ins_none!(sym::target_thread_local);
-    }
-
-    ins_str!(sym::target_vendor, &sess.target.vendor);
-
-    // If the user wants a test runner, then add the test cfg.
-    if sess.is_test_crate() {
-        ins_none!(sym::test);
-    }
-
-    ret
-}
-
-/// The parsed `--cfg` options that define the compilation environment of the
-/// crate, used to drive conditional compilation.
-///
-/// An `FxIndexSet` is used to ensure deterministic ordering of error messages
-/// relating to `--cfg`.
-pub type Cfg = FxIndexSet<(Symbol, Option<Symbol>)>;
-
-/// The parsed `--check-cfg` options.
-#[derive(Default)]
-pub struct CheckCfg {
-    /// Is well known names activated
-    pub exhaustive_names: bool,
-    /// Is well known values activated
-    pub exhaustive_values: bool,
-    /// All the expected values for a config name
-    pub expecteds: FxHashMap<Symbol, ExpectedValues<Symbol>>,
-    /// Well known names (only used for diagnostics purposes)
-    pub well_known_names: FxHashSet<Symbol>,
-}
-
-pub enum ExpectedValues<T> {
-    Some(FxHashSet<Option<T>>),
-    Any,
-}
-
-impl<T: Eq + Hash> ExpectedValues<T> {
-    fn insert(&mut self, value: T) -> bool {
-        match self {
-            ExpectedValues::Some(expecteds) => expecteds.insert(Some(value)),
-            ExpectedValues::Any => false,
-        }
-    }
-}
-
-impl<T: Eq + Hash> Extend<T> for ExpectedValues<T> {
-    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
-        match self {
-            ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(Some)),
-            ExpectedValues::Any => {}
-        }
-    }
-}
-
-impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
-    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
-        match self {
-            ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(|a| Some(*a))),
-            ExpectedValues::Any => {}
-        }
-    }
-}
-
-impl CheckCfg {
-    pub fn fill_well_known(&mut self, current_target: &Target) {
-        if !self.exhaustive_values && !self.exhaustive_names {
-            return;
-        }
-
-        let no_values = || {
-            let mut values = FxHashSet::default();
-            values.insert(None);
-            ExpectedValues::Some(values)
-        };
-
-        let empty_values = || {
-            let values = FxHashSet::default();
-            ExpectedValues::Some(values)
-        };
-
-        macro_rules! ins {
-            ($name:expr, $values:expr) => {{
-                self.well_known_names.insert($name);
-                self.expecteds.entry($name).or_insert_with($values)
-            }};
-        }
-
-        // Symbols are inserted in alphabetical order as much as possible.
-        // The exceptions are where control flow forces things out of order.
-        //
-        // NOTE: This should be kept in sync with `default_configuration`.
-        // Note that symbols inserted conditionally in `default_configuration`
-        // are inserted unconditionally here.
-        //
-        // When adding a new config here you should also update
-        // `tests/ui/check-cfg/well-known-values.rs`.
-        //
-        // Don't forget to update `src/doc/unstable-book/src/compiler-flags/check-cfg.md`
-        // in the unstable book as well!
-
-        ins!(sym::debug_assertions, no_values);
-
-        // These four are never set by rustc, but we set them anyway: they
-        // should not trigger a lint because `cargo clippy`, `cargo doc`,
-        // `cargo test` and `cargo miri run` (respectively) can set them.
-        ins!(sym::clippy, no_values);
-        ins!(sym::doc, no_values);
-        ins!(sym::doctest, no_values);
-        ins!(sym::miri, no_values);
-
-        ins!(sym::overflow_checks, no_values);
-
-        ins!(sym::panic, empty_values).extend(&PanicStrategy::all());
-
-        ins!(sym::proc_macro, no_values);
-
-        ins!(sym::relocation_model, empty_values).extend(RelocModel::all());
-
-        let sanitize_values = SanitizerSet::all()
-            .into_iter()
-            .map(|sanitizer| Symbol::intern(sanitizer.as_str().unwrap()));
-        ins!(sym::sanitize, empty_values).extend(sanitize_values);
-
-        ins!(sym::sanitizer_cfi_generalize_pointers, no_values);
-        ins!(sym::sanitizer_cfi_normalize_integers, no_values);
-
-        ins!(sym::target_feature, empty_values).extend(
-            rustc_target::target_features::all_known_features()
-                .map(|(f, _sb)| f)
-                .chain(rustc_target::target_features::RUSTC_SPECIFIC_FEATURES.iter().cloned())
-                .map(Symbol::intern),
-        );
-
-        // sym::target_*
-        {
-            const VALUES: [&Symbol; 8] = [
-                &sym::target_abi,
-                &sym::target_arch,
-                &sym::target_endian,
-                &sym::target_env,
-                &sym::target_family,
-                &sym::target_os,
-                &sym::target_pointer_width,
-                &sym::target_vendor,
-            ];
-
-            // Initialize (if not already initialized)
-            for &e in VALUES {
-                if !self.exhaustive_values {
-                    ins!(e, || ExpectedValues::Any);
-                } else {
-                    ins!(e, empty_values);
-                }
-            }
-
-            if self.exhaustive_values {
-                // Get all values map at once otherwise it would be costly.
-                // (8 values * 220 targets ~= 1760 times, at the time of writing this comment).
-                let [
-                    values_target_abi,
-                    values_target_arch,
-                    values_target_endian,
-                    values_target_env,
-                    values_target_family,
-                    values_target_os,
-                    values_target_pointer_width,
-                    values_target_vendor,
-                ] = self
-                    .expecteds
-                    .get_many_mut(VALUES)
-                    .expect("unable to get all the check-cfg values buckets");
-
-                for target in TARGETS
-                    .iter()
-                    .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
-                    .chain(iter::once(current_target.clone()))
-                {
-                    values_target_abi.insert(Symbol::intern(&target.options.abi));
-                    values_target_arch.insert(Symbol::intern(&target.arch));
-                    values_target_endian.insert(Symbol::intern(target.options.endian.as_str()));
-                    values_target_env.insert(Symbol::intern(&target.options.env));
-                    values_target_family.extend(
-                        target.options.families.iter().map(|family| Symbol::intern(family)),
-                    );
-                    values_target_os.insert(Symbol::intern(&target.options.os));
-                    values_target_pointer_width.insert(sym::integer(target.pointer_width));
-                    values_target_vendor.insert(Symbol::intern(&target.options.vendor));
-                }
-            }
-        }
-
-        let atomic_values = &[
-            sym::ptr,
-            sym::integer(8usize),
-            sym::integer(16usize),
-            sym::integer(32usize),
-            sym::integer(64usize),
-            sym::integer(128usize),
-        ];
-        for sym in [
-            sym::target_has_atomic,
-            sym::target_has_atomic_equal_alignment,
-            sym::target_has_atomic_load_store,
-        ] {
-            ins!(sym, no_values).extend(atomic_values);
-        }
-
-        ins!(sym::target_thread_local, no_values);
-
-        ins!(sym::test, no_values);
-
-        ins!(sym::unix, no_values);
-        ins!(sym::windows, no_values);
-    }
-}
-
 pub fn build_configuration(sess: &Session, mut user_cfg: Cfg) -> Cfg {
     // Combine the configuration requested by the session (command line) with
     // some default and generated configuration items.
-    user_cfg.extend(default_configuration(sess));
+    user_cfg.extend(cfg::default_configuration(sess));
     user_cfg
 }
 
diff --git a/compiler/rustc_session/src/config/cfg.rs b/compiler/rustc_session/src/config/cfg.rs
new file mode 100644
index 00000000000..337019f720b
--- /dev/null
+++ b/compiler/rustc_session/src/config/cfg.rs
@@ -0,0 +1,373 @@
+//! cfg and check-cfg configuration
+//!
+//! This module contains the definition of [`Cfg`] and [`CheckCfg`]
+//! as well as the logic for creating the default configuration for a
+//! given [`Session`].
+//!
+//! It also contains the filling of the well known configs, which should
+//! ALWAYS be in sync with the default_configuration.
+//!
+//! ## Adding a new cfg
+//!
+//! Adding a new feature requires two new symbols one for the cfg it-self
+//! and the second one for the unstable feature gate, those are defined in
+//! `rustc_span::symbol`.
+//!
+//! As well as the following points,
+//!  - Add the activation logic in [`default_configuration`]
+//!  - Add the cfg to [`CheckCfg::fill_well_known`] (and related files),
+//!    so that the compiler can know the cfg is expected
+//!  - Add the feature gating in `compiler/rustc_feature/src/builtin_attrs.rs`
+
+use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_span::symbol::{sym, Symbol};
+use rustc_target::abi::Align;
+use rustc_target::spec::{PanicStrategy, RelocModel, SanitizerSet};
+use rustc_target::spec::{Target, TargetTriple, TARGETS};
+
+use crate::config::CrateType;
+use crate::Session;
+
+use std::hash::Hash;
+use std::iter;
+
+/// The parsed `--cfg` options that define the compilation environment of the
+/// crate, used to drive conditional compilation.
+///
+/// An `FxIndexSet` is used to ensure deterministic ordering of error messages
+/// relating to `--cfg`.
+pub type Cfg = FxIndexSet<(Symbol, Option<Symbol>)>;
+
+/// The parsed `--check-cfg` options.
+#[derive(Default)]
+pub struct CheckCfg {
+    /// Is well known names activated
+    pub exhaustive_names: bool,
+    /// Is well known values activated
+    pub exhaustive_values: bool,
+    /// All the expected values for a config name
+    pub expecteds: FxHashMap<Symbol, ExpectedValues<Symbol>>,
+    /// Well known names (only used for diagnostics purposes)
+    pub well_known_names: FxHashSet<Symbol>,
+}
+
+pub enum ExpectedValues<T> {
+    Some(FxHashSet<Option<T>>),
+    Any,
+}
+
+impl<T: Eq + Hash> ExpectedValues<T> {
+    fn insert(&mut self, value: T) -> bool {
+        match self {
+            ExpectedValues::Some(expecteds) => expecteds.insert(Some(value)),
+            ExpectedValues::Any => false,
+        }
+    }
+}
+
+impl<T: Eq + Hash> Extend<T> for ExpectedValues<T> {
+    fn extend<I: IntoIterator<Item = T>>(&mut self, iter: I) {
+        match self {
+            ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(Some)),
+            ExpectedValues::Any => {}
+        }
+    }
+}
+
+impl<'a, T: Eq + Hash + Copy + 'a> Extend<&'a T> for ExpectedValues<T> {
+    fn extend<I: IntoIterator<Item = &'a T>>(&mut self, iter: I) {
+        match self {
+            ExpectedValues::Some(expecteds) => expecteds.extend(iter.into_iter().map(|a| Some(*a))),
+            ExpectedValues::Any => {}
+        }
+    }
+}
+
+/// Generate the default configs for a given session
+pub(crate) fn default_configuration(sess: &Session) -> Cfg {
+    let mut ret = Cfg::default();
+
+    macro_rules! ins_none {
+        ($key:expr) => {
+            ret.insert(($key, None));
+        };
+    }
+    macro_rules! ins_str {
+        ($key:expr, $val_str:expr) => {
+            ret.insert(($key, Some(Symbol::intern($val_str))));
+        };
+    }
+    macro_rules! ins_sym {
+        ($key:expr, $val_sym:expr) => {
+            ret.insert(($key, Some($val_sym)));
+        };
+    }
+
+    // Symbols are inserted in alphabetical order as much as possible.
+    // The exceptions are where control flow forces things out of order.
+    //
+    // Run `rustc --print cfg` to see the configuration in practice.
+    //
+    // NOTE: These insertions should be kept in sync with
+    // `CheckCfg::fill_well_known` below.
+
+    if sess.opts.debug_assertions {
+        ins_none!(sym::debug_assertions);
+    }
+
+    if sess.overflow_checks() {
+        ins_none!(sym::overflow_checks);
+    }
+
+    ins_sym!(sym::panic, sess.panic_strategy().desc_symbol());
+
+    // JUSTIFICATION: before wrapper fn is available
+    #[allow(rustc::bad_opt_access)]
+    if sess.opts.crate_types.contains(&CrateType::ProcMacro) {
+        ins_none!(sym::proc_macro);
+    }
+
+    if sess.is_nightly_build() {
+        ins_sym!(sym::relocation_model, sess.target.relocation_model.desc_symbol());
+    }
+
+    for mut s in sess.opts.unstable_opts.sanitizer {
+        // KASAN is still ASAN under the hood, so it uses the same attribute.
+        if s == SanitizerSet::KERNELADDRESS {
+            s = SanitizerSet::ADDRESS;
+        }
+        ins_str!(sym::sanitize, &s.to_string());
+    }
+
+    if sess.is_sanitizer_cfi_generalize_pointers_enabled() {
+        ins_none!(sym::sanitizer_cfi_generalize_pointers);
+    }
+    if sess.is_sanitizer_cfi_normalize_integers_enabled() {
+        ins_none!(sym::sanitizer_cfi_normalize_integers);
+    }
+
+    ins_str!(sym::target_abi, &sess.target.abi);
+    ins_str!(sym::target_arch, &sess.target.arch);
+    ins_str!(sym::target_endian, sess.target.endian.as_str());
+    ins_str!(sym::target_env, &sess.target.env);
+
+    for family in sess.target.families.as_ref() {
+        ins_str!(sym::target_family, family);
+        if family == "windows" {
+            ins_none!(sym::windows);
+        } else if family == "unix" {
+            ins_none!(sym::unix);
+        }
+    }
+
+    // `target_has_atomic*`
+    let layout = sess.target.parse_data_layout().unwrap_or_else(|err| {
+        sess.dcx().emit_fatal(err);
+    });
+    let mut has_atomic = false;
+    for (i, align) in [
+        (8, layout.i8_align.abi),
+        (16, layout.i16_align.abi),
+        (32, layout.i32_align.abi),
+        (64, layout.i64_align.abi),
+        (128, layout.i128_align.abi),
+    ] {
+        if i >= sess.target.min_atomic_width() && i <= sess.target.max_atomic_width() {
+            if !has_atomic {
+                has_atomic = true;
+                if sess.is_nightly_build() {
+                    if sess.target.atomic_cas {
+                        ins_none!(sym::target_has_atomic);
+                    }
+                    ins_none!(sym::target_has_atomic_load_store);
+                }
+            }
+            let mut insert_atomic = |sym, align: Align| {
+                if sess.target.atomic_cas {
+                    ins_sym!(sym::target_has_atomic, sym);
+                }
+                if align.bits() == i {
+                    ins_sym!(sym::target_has_atomic_equal_alignment, sym);
+                }
+                ins_sym!(sym::target_has_atomic_load_store, sym);
+            };
+            insert_atomic(sym::integer(i), align);
+            if sess.target.pointer_width as u64 == i {
+                insert_atomic(sym::ptr, layout.pointer_align.abi);
+            }
+        }
+    }
+
+    ins_str!(sym::target_os, &sess.target.os);
+    ins_sym!(sym::target_pointer_width, sym::integer(sess.target.pointer_width));
+
+    if sess.opts.unstable_opts.has_thread_local.unwrap_or(sess.target.has_thread_local) {
+        ins_none!(sym::target_thread_local);
+    }
+
+    ins_str!(sym::target_vendor, &sess.target.vendor);
+
+    // If the user wants a test runner, then add the test cfg.
+    if sess.is_test_crate() {
+        ins_none!(sym::test);
+    }
+
+    ret
+}
+
+impl CheckCfg {
+    /// Fill the current [`CheckCfg`] with all the well known cfgs
+    pub fn fill_well_known(&mut self, current_target: &Target) {
+        if !self.exhaustive_values && !self.exhaustive_names {
+            return;
+        }
+
+        // for `#[cfg(foo)]` (ie. cfg value is none)
+        let no_values = || {
+            let mut values = FxHashSet::default();
+            values.insert(None);
+            ExpectedValues::Some(values)
+        };
+
+        // preparation for inserting some values
+        let empty_values = || {
+            let values = FxHashSet::default();
+            ExpectedValues::Some(values)
+        };
+
+        macro_rules! ins {
+            ($name:expr, $values:expr) => {{
+                self.well_known_names.insert($name);
+                self.expecteds.entry($name).or_insert_with($values)
+            }};
+        }
+
+        // Symbols are inserted in alphabetical order as much as possible.
+        // The exceptions are where control flow forces things out of order.
+        //
+        // NOTE: This should be kept in sync with `default_configuration`.
+        // Note that symbols inserted conditionally in `default_configuration`
+        // are inserted unconditionally here.
+        //
+        // When adding a new config here you should also update
+        // `tests/ui/check-cfg/well-known-values.rs` (in order to test the
+        // expected values of the new config) and bless the all directory.
+        //
+        // Don't forget to update `src/doc/unstable-book/src/compiler-flags/check-cfg.md`
+        // in the unstable book as well!
+
+        ins!(sym::debug_assertions, no_values);
+
+        // These four are never set by rustc, but we set them anyway: they
+        // should not trigger a lint because `cargo clippy`, `cargo doc`,
+        // `cargo test` and `cargo miri run` (respectively) can set them.
+        ins!(sym::clippy, no_values);
+        ins!(sym::doc, no_values);
+        ins!(sym::doctest, no_values);
+        ins!(sym::miri, no_values);
+
+        ins!(sym::overflow_checks, no_values);
+
+        ins!(sym::panic, empty_values).extend(&PanicStrategy::all());
+
+        ins!(sym::proc_macro, no_values);
+
+        ins!(sym::relocation_model, empty_values).extend(RelocModel::all());
+
+        let sanitize_values = SanitizerSet::all()
+            .into_iter()
+            .map(|sanitizer| Symbol::intern(sanitizer.as_str().unwrap()));
+        ins!(sym::sanitize, empty_values).extend(sanitize_values);
+
+        ins!(sym::sanitizer_cfi_generalize_pointers, no_values);
+        ins!(sym::sanitizer_cfi_normalize_integers, no_values);
+
+        ins!(sym::target_feature, empty_values).extend(
+            rustc_target::target_features::all_known_features()
+                .map(|(f, _sb)| f)
+                .chain(rustc_target::target_features::RUSTC_SPECIFIC_FEATURES.iter().cloned())
+                .map(Symbol::intern),
+        );
+
+        // sym::target_*
+        {
+            const VALUES: [&Symbol; 8] = [
+                &sym::target_abi,
+                &sym::target_arch,
+                &sym::target_endian,
+                &sym::target_env,
+                &sym::target_family,
+                &sym::target_os,
+                &sym::target_pointer_width,
+                &sym::target_vendor,
+            ];
+
+            // Initialize (if not already initialized)
+            for &e in VALUES {
+                if !self.exhaustive_values {
+                    ins!(e, || ExpectedValues::Any);
+                } else {
+                    ins!(e, empty_values);
+                }
+            }
+
+            if self.exhaustive_values {
+                // Get all values map at once otherwise it would be costly.
+                // (8 values * 220 targets ~= 1760 times, at the time of writing this comment).
+                let [
+                    values_target_abi,
+                    values_target_arch,
+                    values_target_endian,
+                    values_target_env,
+                    values_target_family,
+                    values_target_os,
+                    values_target_pointer_width,
+                    values_target_vendor,
+                ] = self
+                    .expecteds
+                    .get_many_mut(VALUES)
+                    .expect("unable to get all the check-cfg values buckets");
+
+                for target in TARGETS
+                    .iter()
+                    .map(|target| Target::expect_builtin(&TargetTriple::from_triple(target)))
+                    .chain(iter::once(current_target.clone()))
+                {
+                    values_target_abi.insert(Symbol::intern(&target.options.abi));
+                    values_target_arch.insert(Symbol::intern(&target.arch));
+                    values_target_endian.insert(Symbol::intern(target.options.endian.as_str()));
+                    values_target_env.insert(Symbol::intern(&target.options.env));
+                    values_target_family.extend(
+                        target.options.families.iter().map(|family| Symbol::intern(family)),
+                    );
+                    values_target_os.insert(Symbol::intern(&target.options.os));
+                    values_target_pointer_width.insert(sym::integer(target.pointer_width));
+                    values_target_vendor.insert(Symbol::intern(&target.options.vendor));
+                }
+            }
+        }
+
+        let atomic_values = &[
+            sym::ptr,
+            sym::integer(8usize),
+            sym::integer(16usize),
+            sym::integer(32usize),
+            sym::integer(64usize),
+            sym::integer(128usize),
+        ];
+        for sym in [
+            sym::target_has_atomic,
+            sym::target_has_atomic_equal_alignment,
+            sym::target_has_atomic_load_store,
+        ] {
+            ins!(sym, no_values).extend(atomic_values);
+        }
+
+        ins!(sym::target_thread_local, no_values);
+
+        ins!(sym::test, no_values);
+
+        ins!(sym::unix, no_values);
+        ins!(sym::windows, no_values);
+    }
+}
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 6204f868385..a76eb6b06aa 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1950,8 +1950,6 @@ written to standard error output)"),
     #[rustc_lint_opt_deny_field_access("use `Session::lto` instead of this field")]
     thinlto: Option<bool> = (None, parse_opt_bool, [TRACKED],
         "enable ThinLTO when possible"),
-    thir_unsafeck: bool = (true, parse_bool, [TRACKED],
-        "use the THIR unsafety checker (default: yes)"),
     /// We default to 1 here since we want to behave like
     /// a sequential compiler for now. This'll likely be adjusted
     /// in the future. Note that -Zthreads=0 is the way to get
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index 9d91032c1d2..c9f66612590 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -267,7 +267,7 @@ impl<'tcx> Stable<'tcx> for mir::CastKind {
     fn stable(&self, tables: &mut Tables<'_>) -> Self::T {
         use rustc_middle::mir::CastKind::*;
         match self {
-            PointerExposeAddress => stable_mir::mir::CastKind::PointerExposeAddress,
+            PointerExposeProvenance => stable_mir::mir::CastKind::PointerExposeAddress,
             PointerWithExposedProvenance => stable_mir::mir::CastKind::PointerWithExposedProvenance,
             PointerCoercion(c) => stable_mir::mir::CastKind::PointerCoercion(c.stable(tables)),
             DynStar => stable_mir::mir::CastKind::DynStar,
diff --git a/compiler/rustc_span/src/def_id.rs b/compiler/rustc_span/src/def_id.rs
index 8f721bac951..8925b7a42d4 100644
--- a/compiler/rustc_span/src/def_id.rs
+++ b/compiler/rustc_span/src/def_id.rs
@@ -22,7 +22,7 @@ rustc_index::newtype_index! {
 
 /// Item definitions in the currently-compiled crate would have the `CrateNum`
 /// `LOCAL_CRATE` in their `DefId`.
-pub const LOCAL_CRATE: CrateNum = CrateNum::from_u32(0);
+pub const LOCAL_CRATE: CrateNum = CrateNum::ZERO;
 
 impl CrateNum {
     #[inline]
diff --git a/compiler/rustc_span/src/hygiene.rs b/compiler/rustc_span/src/hygiene.rs
index 37fea6c122c..1df2b357ac1 100644
--- a/compiler/rustc_span/src/hygiene.rs
+++ b/compiler/rustc_span/src/hygiene.rs
@@ -165,7 +165,7 @@ pub enum Transparency {
 
 impl LocalExpnId {
     /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST.
-    pub const ROOT: LocalExpnId = LocalExpnId::from_u32(0);
+    pub const ROOT: LocalExpnId = LocalExpnId::ZERO;
 
     #[inline]
     fn from_raw(idx: ExpnIndex) -> LocalExpnId {
@@ -242,7 +242,7 @@ impl ExpnId {
     /// The ID of the theoretical expansion that generates freshly parsed, unexpanded AST.
     /// Invariant: we do not create any ExpnId with local_id == 0 and krate != 0.
     pub const fn root() -> ExpnId {
-        ExpnId { krate: LOCAL_CRATE, local_id: ExpnIndex::from_u32(0) }
+        ExpnId { krate: LOCAL_CRATE, local_id: ExpnIndex::ZERO }
     }
 
     #[inline]
diff --git a/compiler/rustc_span/src/source_map/tests.rs b/compiler/rustc_span/src/source_map/tests.rs
index 81a9e470688..dcb02da3719 100644
--- a/compiler/rustc_span/src/source_map/tests.rs
+++ b/compiler/rustc_span/src/source_map/tests.rs
@@ -243,7 +243,7 @@ fn t10() {
         src_hash,
         stable_id,
         source_len.to_u32(),
-        CrateNum::new(0),
+        CrateNum::ZERO,
         FreezeLock::new(lines.read().clone()),
         multibyte_chars,
         non_narrow_chars,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index b1d4a63812f..ea0f7adf6f9 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -1456,6 +1456,7 @@ symbols! {
         receiver,
         recursion_limit,
         reexport_test_harness_main,
+        ref_pat_everywhere,
         ref_unwind_safe_trait,
         reference,
         reflect,
@@ -1659,7 +1660,7 @@ symbols! {
         simd_cttz,
         simd_div,
         simd_eq,
-        simd_expose_addr,
+        simd_expose_provenance,
         simd_extract,
         simd_fabs,
         simd_fcos,
diff --git a/compiler/rustc_symbol_mangling/src/legacy.rs b/compiler/rustc_symbol_mangling/src/legacy.rs
index 1c62ce2d214..f68668a91e6 100644
--- a/compiler/rustc_symbol_mangling/src/legacy.rs
+++ b/compiler/rustc_symbol_mangling/src/legacy.rs
@@ -2,7 +2,7 @@ use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
 use rustc_hir::def_id::CrateNum;
 use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_middle::ty::print::{PrettyPrinter, Print, PrintError, Printer};
-use rustc_middle::ty::{self, Instance, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{self, Instance, ReifyReason, Ty, TyCtxt, TypeVisitableExt};
 use rustc_middle::ty::{GenericArg, GenericArgKind};
 
 use std::fmt::{self, Write};
@@ -71,8 +71,14 @@ pub(super) fn mangle<'tcx>(
         ty::InstanceDef::VTableShim(..) => {
             printer.write_str("{{vtable-shim}}").unwrap();
         }
-        ty::InstanceDef::ReifyShim(..) => {
-            printer.write_str("{{reify-shim}}").unwrap();
+        ty::InstanceDef::ReifyShim(_, reason) => {
+            printer.write_str("{{reify-shim").unwrap();
+            match reason {
+                Some(ReifyReason::FnPtr) => printer.write_str("-fnptr").unwrap(),
+                Some(ReifyReason::Vtable) => printer.write_str("-vtable").unwrap(),
+                None => (),
+            }
+            printer.write_str("}}").unwrap();
         }
         // FIXME(async_closures): This shouldn't be needed when we fix
         // `Instance::ty`/`Instance::def_id`.
diff --git a/compiler/rustc_symbol_mangling/src/typeid.rs b/compiler/rustc_symbol_mangling/src/typeid.rs
index fc1e8e46e8d..7bd998294dd 100644
--- a/compiler/rustc_symbol_mangling/src/typeid.rs
+++ b/compiler/rustc_symbol_mangling/src/typeid.rs
@@ -4,7 +4,7 @@
 /// For more information about LLVM CFI and cross-language LLVM CFI support for the Rust compiler,
 /// see design document in the tracking issue #89653.
 use bitflags::bitflags;
-use rustc_middle::ty::{Instance, Ty, TyCtxt};
+use rustc_middle::ty::{Instance, InstanceDef, ReifyReason, Ty, TyCtxt};
 use rustc_target::abi::call::FnAbi;
 use std::hash::Hasher;
 use twox_hash::XxHash64;
@@ -26,7 +26,12 @@ bitflags! {
         const NORMALIZE_INTEGERS = 4;
         /// Do not perform self type erasure for attaching a secondary type id to methods with their
         /// concrete self so they can be used as function pointers.
-        const NO_SELF_TYPE_ERASURE = 8;
+        ///
+        /// (This applies to typeid_for_instance only and should be used to attach a secondary type
+        /// id to methods during their declaration/definition so they match the type ids returned by
+        /// either typeid_for_instance or typeid_for_fnabi at call sites during code generation for
+        /// type membership tests when methods are used as function pointers.)
+        const USE_CONCRETE_SELF = 8;
     }
 }
 
@@ -67,8 +72,26 @@ pub fn kcfi_typeid_for_fnabi<'tcx>(
 pub fn kcfi_typeid_for_instance<'tcx>(
     tcx: TyCtxt<'tcx>,
     instance: Instance<'tcx>,
-    options: TypeIdOptions,
+    mut options: TypeIdOptions,
 ) -> u32 {
+    // KCFI support for Rust shares most of its implementation with the CFI support, with some key
+    // differences:
+    //
+    // 1. KCFI performs type tests differently and are implemented as different LLVM passes than CFI
+    //    to not require LTO.
+    // 2. KCFI has the limitation that a function or method may have one type id assigned only.
+    //
+    // Because of the limitation listed above (2), the current KCFI implementation (not CFI) does
+    // reifying of types (i.e., adds shims/trampolines for indirect calls in these cases) for:
+    //
+    // * Supporting casting between function items, closures, and Fn trait objects.
+    // * Supporting methods being cast as function pointers.
+    //
+    // This was implemented for KCFI support in #123106 and #123052 (which introduced the
+    // ReifyReason). The tracking issue for KCFI support for Rust is #123479.
+    if matches!(instance.def, InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr))) {
+        options.insert(TypeIdOptions::USE_CONCRETE_SELF);
+    }
     // A KCFI type metadata identifier is a 32-bit constant produced by taking the lower half of the
     // xxHash64 of the type metadata identifier. (See llvm/llvm-project@cff5bef.)
     let mut hash: XxHash64 = Default::default();
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 5f5d90f359a..a3a18fb768f 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
@@ -11,13 +11,14 @@ use rustc_data_structures::base_n;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::lang_items::LangItem;
+use rustc_middle::ty::fold::{TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::layout::IntegerExt;
-use rustc_middle::ty::TypeVisitableExt;
 use rustc_middle::ty::{
     self, Const, ExistentialPredicate, FloatTy, FnSig, Instance, IntTy, List, Region, RegionKind,
     TermKind, Ty, TyCtxt, UintTy,
 };
 use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgsRef};
+use rustc_middle::ty::{TypeFoldable, TypeVisitableExt};
 use rustc_span::def_id::DefId;
 use rustc_span::sym;
 use rustc_target::abi::call::{Conv, FnAbi, PassMode};
@@ -182,14 +183,15 @@ fn encode_fnsig<'tcx>(
     // Encode the return type
     let transform_ty_options = TransformTyOptions::from_bits(options.bits())
         .unwrap_or_else(|| bug!("encode_fnsig: invalid option(s) `{:?}`", options.bits()));
-    let ty = transform_ty(tcx, fn_sig.output(), &mut Vec::new(), transform_ty_options);
+    let mut type_folder = TransformTy::new(tcx, transform_ty_options);
+    let ty = fn_sig.output().fold_with(&mut type_folder);
     s.push_str(&encode_ty(tcx, ty, dict, encode_ty_options));
 
     // Encode the parameter types
     let tys = fn_sig.inputs();
     if !tys.is_empty() {
         for ty in tys {
-            let ty = transform_ty(tcx, *ty, &mut Vec::new(), transform_ty_options);
+            let ty = ty.fold_with(&mut type_folder);
             s.push_str(&encode_ty(tcx, ty, dict, encode_ty_options));
         }
 
@@ -281,12 +283,12 @@ fn encode_region<'tcx>(region: Region<'tcx>, dict: &mut FxHashMap<DictKey<'tcx>,
             s.push('E');
             compress(dict, DictKey::Region(region), &mut s);
         }
-        // FIXME(@lcnr): Why is `ReEarlyParam` reachable here.
-        RegionKind::ReEarlyParam(..) | RegionKind::ReErased => {
+        RegionKind::ReErased => {
             s.push_str("u6region");
             compress(dict, DictKey::Region(region), &mut s);
         }
-        RegionKind::ReLateParam(..)
+        RegionKind::ReEarlyParam(..)
+        | RegionKind::ReLateParam(..)
         | RegionKind::ReStatic
         | RegionKind::ReError(_)
         | RegionKind::ReVar(..)
@@ -523,15 +525,9 @@ fn encode_ty<'tcx>(
 
         ty::Array(ty0, len) => {
             // A<array-length><element-type>
+            let len = len.eval_target_usize(tcx, ty::ParamEnv::reveal_all());
             let mut s = String::from("A");
-            let _ = write!(
-                s,
-                "{}",
-                &len.try_to_scalar()
-                    .unwrap()
-                    .to_target_usize(&tcx.data_layout)
-                    .expect("Array lens are defined in usize")
-            );
+            let _ = write!(s, "{}", &len);
             s.push_str(&encode_ty(tcx, *ty0, dict, options));
             compress(dict, DictKey::Ty(ty, TyQ::None), &mut s);
             typeid.push_str(&s);
@@ -756,278 +752,192 @@ fn encode_ty<'tcx>(
     typeid
 }
 
-/// Transforms predicates for being encoded and used in the substitution dictionary.
-fn transform_predicates<'tcx>(
+struct TransformTy<'tcx> {
     tcx: TyCtxt<'tcx>,
-    predicates: &List<ty::PolyExistentialPredicate<'tcx>>,
-) -> &'tcx List<ty::PolyExistentialPredicate<'tcx>> {
-    tcx.mk_poly_existential_predicates_from_iter(predicates.iter().filter_map(|predicate| {
-        match predicate.skip_binder() {
-            ty::ExistentialPredicate::Trait(trait_ref) => {
-                let trait_ref = ty::TraitRef::identity(tcx, trait_ref.def_id);
-                Some(ty::Binder::dummy(ty::ExistentialPredicate::Trait(
-                    ty::ExistentialTraitRef::erase_self_ty(tcx, trait_ref),
-                )))
-            }
-            ty::ExistentialPredicate::Projection(..) => None,
-            ty::ExistentialPredicate::AutoTrait(..) => Some(predicate),
-        }
-    }))
-}
-
-/// Transforms args for being encoded and used in the substitution dictionary.
-fn transform_args<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    args: GenericArgsRef<'tcx>,
-    parents: &mut Vec<Ty<'tcx>>,
     options: TransformTyOptions,
-) -> GenericArgsRef<'tcx> {
-    let args = args.iter().map(|arg| match arg.unpack() {
-        GenericArgKind::Type(ty) if ty.is_c_void(tcx) => Ty::new_unit(tcx).into(),
-        GenericArgKind::Type(ty) => transform_ty(tcx, ty, parents, options).into(),
-        _ => arg,
-    });
-    tcx.mk_args_from_iter(args)
+    parents: Vec<Ty<'tcx>>,
 }
 
-// Transforms a ty:Ty for being encoded and used in the substitution dictionary. It transforms all
-// c_void types into unit types unconditionally, generalizes pointers if
-// TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
-// TransformTyOptions::NORMALIZE_INTEGERS option is set.
-fn transform_ty<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    mut ty: Ty<'tcx>,
-    parents: &mut Vec<Ty<'tcx>>,
-    options: TransformTyOptions,
-) -> Ty<'tcx> {
-    match ty.kind() {
-        ty::Float(..) | ty::Str | ty::Never | ty::Foreign(..) | ty::CoroutineWitness(..) => {}
+impl<'tcx> TransformTy<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, options: TransformTyOptions) -> Self {
+        TransformTy { tcx, options, parents: Vec::new() }
+    }
+}
 
-        ty::Bool => {
-            if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
-                // Note: on all platforms that Rust's currently supports, its size and alignment are
-                // 1, and its ABI class is INTEGER - see Rust Layout and ABIs.
-                //
-                // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#bool.)
-                //
-                // Clang represents bool as an 8-bit unsigned integer.
-                ty = tcx.types.u8;
+impl<'tcx> TypeFolder<TyCtxt<'tcx>> for TransformTy<'tcx> {
+    // Transforms a ty:Ty for being encoded and used in the substitution dictionary. It transforms
+    // all c_void types into unit types unconditionally, generalizes pointers if
+    // TransformTyOptions::GENERALIZE_POINTERS option is set, and normalizes integers if
+    // TransformTyOptions::NORMALIZE_INTEGERS option is set.
+    fn fold_ty(&mut self, t: Ty<'tcx>) -> Ty<'tcx> {
+        match t.kind() {
+            ty::Array(..)
+            | ty::Closure(..)
+            | ty::Coroutine(..)
+            | ty::CoroutineClosure(..)
+            | ty::CoroutineWitness(..)
+            | ty::Dynamic(..)
+            | ty::Float(..)
+            | ty::FnDef(..)
+            | ty::Foreign(..)
+            | ty::Never
+            | ty::Slice(..)
+            | ty::Str
+            | ty::Tuple(..) => t.super_fold_with(self),
+
+            ty::Bool => {
+                if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
+                    // Note: on all platforms that Rust's currently supports, its size and alignment
+                    // are 1, and its ABI class is INTEGER - see Rust Layout and ABIs.
+                    //
+                    // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#bool.)
+                    //
+                    // Clang represents bool as an 8-bit unsigned integer.
+                    self.tcx.types.u8
+                } else {
+                    t
+                }
             }
-        }
 
-        ty::Char => {
-            if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
-                // Since #118032, char is guaranteed to have the same size, alignment, and function
-                // call ABI as u32 on all platforms.
-                ty = tcx.types.u32;
+            ty::Char => {
+                if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
+                    // Since #118032, char is guaranteed to have the same size, alignment, and
+                    // function call ABI as u32 on all platforms.
+                    self.tcx.types.u32
+                } else {
+                    t
+                }
             }
-        }
 
-        ty::Int(..) | ty::Uint(..) => {
-            if options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
-                // Note: C99 7.18.2.4 requires uintptr_t and intptr_t to be at least 16-bit wide.
-                // All platforms we currently support have a C platform, and as a consequence,
-                // isize/usize are at least 16-bit wide for all of them.
-                //
-                // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize.)
-                match ty.kind() {
-                    ty::Int(IntTy::Isize) => match tcx.sess.target.pointer_width {
-                        16 => ty = tcx.types.i16,
-                        32 => ty = tcx.types.i32,
-                        64 => ty = tcx.types.i64,
-                        128 => ty = tcx.types.i128,
-                        _ => bug!(
-                            "transform_ty: unexpected pointer width `{}`",
-                            tcx.sess.target.pointer_width
-                        ),
-                    },
-                    ty::Uint(UintTy::Usize) => match tcx.sess.target.pointer_width {
-                        16 => ty = tcx.types.u16,
-                        32 => ty = tcx.types.u32,
-                        64 => ty = tcx.types.u64,
-                        128 => ty = tcx.types.u128,
-                        _ => bug!(
-                            "transform_ty: unexpected pointer width `{}`",
-                            tcx.sess.target.pointer_width
-                        ),
-                    },
-                    _ => (),
+            ty::Int(..) | ty::Uint(..) => {
+                if self.options.contains(EncodeTyOptions::NORMALIZE_INTEGERS) {
+                    // Note: C99 7.18.2.4 requires uintptr_t and intptr_t to be at least 16-bit
+                    // wide. All platforms we currently support have a C platform, and as a
+                    // consequence, isize/usize are at least 16-bit wide for all of them.
+                    //
+                    // (See https://rust-lang.github.io/unsafe-code-guidelines/layout/scalars.html#isize-and-usize.)
+                    match t.kind() {
+                        ty::Int(IntTy::Isize) => match self.tcx.sess.target.pointer_width {
+                            16 => self.tcx.types.i16,
+                            32 => self.tcx.types.i32,
+                            64 => self.tcx.types.i64,
+                            128 => self.tcx.types.i128,
+                            _ => bug!(
+                                "fold_ty: unexpected pointer width `{}`",
+                                self.tcx.sess.target.pointer_width
+                            ),
+                        },
+                        ty::Uint(UintTy::Usize) => match self.tcx.sess.target.pointer_width {
+                            16 => self.tcx.types.u16,
+                            32 => self.tcx.types.u32,
+                            64 => self.tcx.types.u64,
+                            128 => self.tcx.types.u128,
+                            _ => bug!(
+                                "fold_ty: unexpected pointer width `{}`",
+                                self.tcx.sess.target.pointer_width
+                            ),
+                        },
+                        _ => t,
+                    }
+                } else {
+                    t
                 }
             }
-        }
-
-        _ if ty.is_unit() => {}
-
-        ty::Tuple(tys) => {
-            ty = Ty::new_tup_from_iter(
-                tcx,
-                tys.iter().map(|ty| transform_ty(tcx, ty, parents, options)),
-            );
-        }
-
-        ty::Array(ty0, len) => {
-            let len = len.eval_target_usize(tcx, ty::ParamEnv::reveal_all());
 
-            ty = Ty::new_array(tcx, transform_ty(tcx, *ty0, parents, options), len);
-        }
+            ty::Adt(..) if t.is_c_void(self.tcx) => self.tcx.types.unit,
 
-        ty::Slice(ty0) => {
-            ty = Ty::new_slice(tcx, transform_ty(tcx, *ty0, parents, options));
-        }
-
-        ty::Adt(adt_def, args) => {
-            if ty.is_c_void(tcx) {
-                ty = Ty::new_unit(tcx);
-            } else if options.contains(TransformTyOptions::GENERALIZE_REPR_C) && adt_def.repr().c()
-            {
-                ty = Ty::new_adt(tcx, *adt_def, ty::List::empty());
-            } else if adt_def.repr().transparent() && adt_def.is_struct() && !parents.contains(&ty)
-            {
-                // Don't transform repr(transparent) types with an user-defined CFI encoding to
-                // preserve the user-defined CFI encoding.
-                if let Some(_) = tcx.get_attr(adt_def.did(), sym::cfi_encoding) {
-                    return ty;
-                }
-                let variant = adt_def.non_enum_variant();
-                let param_env = tcx.param_env(variant.def_id);
-                let field = variant.fields.iter().find(|field| {
-                    let ty = tcx.type_of(field.did).instantiate_identity();
-                    let is_zst =
-                        tcx.layout_of(param_env.and(ty)).is_ok_and(|layout| layout.is_zst());
-                    !is_zst
-                });
-                if let Some(field) = field {
-                    let ty0 = tcx.type_of(field.did).instantiate(tcx, args);
-                    // Generalize any repr(transparent) user-defined type that is either a pointer
-                    // or reference, and either references itself or any other type that contains or
-                    // references itself, to avoid a reference cycle.
-
-                    // If the self reference is not through a pointer, for example, due
-                    // to using `PhantomData`, need to skip normalizing it if we hit it again.
-                    parents.push(ty);
-                    if ty0.is_any_ptr() && ty0.contains(ty) {
-                        ty = transform_ty(
-                            tcx,
-                            ty0,
-                            parents,
-                            options | TransformTyOptions::GENERALIZE_POINTERS,
-                        );
+            ty::Adt(adt_def, args) => {
+                if adt_def.repr().transparent() && adt_def.is_struct() && !self.parents.contains(&t)
+                {
+                    // Don't transform repr(transparent) types with an user-defined CFI encoding to
+                    // preserve the user-defined CFI encoding.
+                    if let Some(_) = self.tcx.get_attr(adt_def.did(), sym::cfi_encoding) {
+                        return t;
+                    }
+                    let variant = adt_def.non_enum_variant();
+                    let param_env = self.tcx.param_env(variant.def_id);
+                    let field = variant.fields.iter().find(|field| {
+                        let ty = self.tcx.type_of(field.did).instantiate_identity();
+                        let is_zst = self
+                            .tcx
+                            .layout_of(param_env.and(ty))
+                            .is_ok_and(|layout| layout.is_zst());
+                        !is_zst
+                    });
+                    if let Some(field) = field {
+                        let ty0 = self.tcx.type_of(field.did).instantiate(self.tcx, args);
+                        // Generalize any repr(transparent) user-defined type that is either a
+                        // pointer or reference, and either references itself or any other type that
+                        // contains or references itself, to avoid a reference cycle.
+
+                        // If the self reference is not through a pointer, for example, due
+                        // to using `PhantomData`, need to skip normalizing it if we hit it again.
+                        self.parents.push(t);
+                        let ty = if ty0.is_any_ptr() && ty0.contains(t) {
+                            let options = self.options;
+                            self.options |= TransformTyOptions::GENERALIZE_POINTERS;
+                            let ty = ty0.fold_with(self);
+                            self.options = options;
+                            ty
+                        } else {
+                            ty0.fold_with(self)
+                        };
+                        self.parents.pop();
+                        ty
                     } else {
-                        ty = transform_ty(tcx, ty0, parents, options);
+                        // Transform repr(transparent) types without non-ZST field into ()
+                        self.tcx.types.unit
                     }
-                    parents.pop();
                 } else {
-                    // Transform repr(transparent) types without non-ZST field into ()
-                    ty = Ty::new_unit(tcx);
+                    t.super_fold_with(self)
                 }
-            } else {
-                ty = Ty::new_adt(tcx, *adt_def, transform_args(tcx, args, parents, options));
             }
-        }
-
-        ty::FnDef(def_id, args) => {
-            ty = Ty::new_fn_def(tcx, *def_id, transform_args(tcx, args, parents, options));
-        }
-
-        ty::Closure(def_id, args) => {
-            ty = Ty::new_closure(tcx, *def_id, transform_args(tcx, args, parents, options));
-        }
-
-        ty::CoroutineClosure(def_id, args) => {
-            ty = Ty::new_coroutine_closure(
-                tcx,
-                *def_id,
-                transform_args(tcx, args, parents, options),
-            );
-        }
 
-        ty::Coroutine(def_id, args) => {
-            ty = Ty::new_coroutine(tcx, *def_id, transform_args(tcx, args, parents, options));
-        }
-
-        ty::Ref(region, ty0, ..) => {
-            if options.contains(TransformTyOptions::GENERALIZE_POINTERS) {
-                if ty.is_mutable_ptr() {
-                    ty = Ty::new_mut_ref(tcx, tcx.lifetimes.re_static, Ty::new_unit(tcx));
-                } else {
-                    ty = Ty::new_imm_ref(tcx, tcx.lifetimes.re_static, Ty::new_unit(tcx));
-                }
-            } else {
-                if ty.is_mutable_ptr() {
-                    ty = Ty::new_mut_ref(tcx, *region, transform_ty(tcx, *ty0, parents, options));
+            ty::Ref(..) => {
+                if self.options.contains(TransformTyOptions::GENERALIZE_POINTERS) {
+                    if t.is_mutable_ptr() {
+                        Ty::new_mut_ref(self.tcx, self.tcx.lifetimes.re_static, self.tcx.types.unit)
+                    } else {
+                        Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_static, self.tcx.types.unit)
+                    }
                 } else {
-                    ty = Ty::new_imm_ref(tcx, *region, transform_ty(tcx, *ty0, parents, options));
+                    t.super_fold_with(self)
                 }
             }
-        }
 
-        ty::RawPtr(ptr_ty, _) => {
-            if options.contains(TransformTyOptions::GENERALIZE_POINTERS) {
-                if ty.is_mutable_ptr() {
-                    ty = Ty::new_mut_ptr(tcx, Ty::new_unit(tcx));
+            ty::RawPtr(..) => {
+                if self.options.contains(TransformTyOptions::GENERALIZE_POINTERS) {
+                    if t.is_mutable_ptr() {
+                        Ty::new_mut_ptr(self.tcx, self.tcx.types.unit)
+                    } else {
+                        Ty::new_imm_ptr(self.tcx, self.tcx.types.unit)
+                    }
                 } else {
-                    ty = Ty::new_imm_ptr(tcx, Ty::new_unit(tcx));
+                    t.super_fold_with(self)
                 }
-            } else {
-                if ty.is_mutable_ptr() {
-                    ty = Ty::new_mut_ptr(tcx, transform_ty(tcx, *ptr_ty, parents, options));
+            }
+
+            ty::FnPtr(..) => {
+                if self.options.contains(TransformTyOptions::GENERALIZE_POINTERS) {
+                    Ty::new_imm_ptr(self.tcx, self.tcx.types.unit)
                 } else {
-                    ty = Ty::new_imm_ptr(tcx, transform_ty(tcx, *ptr_ty, parents, options));
+                    t.super_fold_with(self)
                 }
             }
-        }
 
-        ty::FnPtr(fn_sig) => {
-            if options.contains(TransformTyOptions::GENERALIZE_POINTERS) {
-                ty = Ty::new_imm_ptr(tcx, Ty::new_unit(tcx));
-            } else {
-                let parameters: Vec<Ty<'tcx>> = fn_sig
-                    .skip_binder()
-                    .inputs()
-                    .iter()
-                    .map(|ty| transform_ty(tcx, *ty, parents, options))
-                    .collect();
-                let output = transform_ty(tcx, fn_sig.skip_binder().output(), parents, options);
-                ty = Ty::new_fn_ptr(
-                    tcx,
-                    ty::Binder::bind_with_vars(
-                        tcx.mk_fn_sig(
-                            parameters,
-                            output,
-                            fn_sig.c_variadic(),
-                            fn_sig.unsafety(),
-                            fn_sig.abi(),
-                        ),
-                        fn_sig.bound_vars(),
-                    ),
-                );
+            ty::Alias(..) => {
+                self.fold_ty(self.tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), t))
             }
-        }
-
-        ty::Dynamic(predicates, _region, kind) => {
-            ty = Ty::new_dynamic(
-                tcx,
-                transform_predicates(tcx, predicates),
-                tcx.lifetimes.re_erased,
-                *kind,
-            );
-        }
-
-        ty::Alias(..) => {
-            ty = transform_ty(
-                tcx,
-                tcx.normalize_erasing_regions(ty::ParamEnv::reveal_all(), ty),
-                parents,
-                options,
-            );
-        }
 
-        ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) => {
-            bug!("transform_ty: unexpected `{:?}`", ty.kind());
+            ty::Bound(..) | ty::Error(..) | ty::Infer(..) | ty::Param(..) | ty::Placeholder(..) => {
+                bug!("fold_ty: unexpected `{:?}`", t.kind());
+            }
         }
     }
 
-    ty
+    fn interner(&self) -> TyCtxt<'tcx> {
+        self.tcx
+    }
 }
 
 /// Returns a type metadata identifier for the specified FnAbi using the Itanium C++ ABI with vendor
@@ -1068,7 +978,8 @@ pub fn typeid_for_fnabi<'tcx>(
     // Encode the return type
     let transform_ty_options = TransformTyOptions::from_bits(options.bits())
         .unwrap_or_else(|| bug!("typeid_for_fnabi: invalid option(s) `{:?}`", options.bits()));
-    let ty = transform_ty(tcx, fn_abi.ret.layout.ty, &mut Vec::new(), transform_ty_options);
+    let mut type_folder = TransformTy::new(tcx, transform_ty_options);
+    let ty = fn_abi.ret.layout.ty.fold_with(&mut type_folder);
     typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
 
     // Encode the parameter types
@@ -1080,7 +991,7 @@ pub fn typeid_for_fnabi<'tcx>(
         let mut pushed_arg = false;
         for arg in fn_abi.args.iter().filter(|arg| arg.mode != PassMode::Ignore) {
             pushed_arg = true;
-            let ty = transform_ty(tcx, arg.layout.ty, &mut Vec::new(), transform_ty_options);
+            let ty = arg.layout.ty.fold_with(&mut type_folder);
             typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
         }
         if !pushed_arg {
@@ -1093,8 +1004,7 @@ pub fn typeid_for_fnabi<'tcx>(
             if fn_abi.args[n].mode == PassMode::Ignore {
                 continue;
             }
-            let ty =
-                transform_ty(tcx, fn_abi.args[n].layout.ty, &mut Vec::new(), transform_ty_options);
+            let ty = fn_abi.args[n].layout.ty.fold_with(&mut type_folder);
             typeid.push_str(&encode_ty(tcx, ty, &mut dict, encode_ty_options));
         }
 
@@ -1172,7 +1082,7 @@ pub fn typeid_for_instance<'tcx>(
         instance.args = tcx.mk_args_trait(invoke_ty, trait_ref.args.into_iter().skip(1));
     }
 
-    if !options.contains(EncodeTyOptions::NO_SELF_TYPE_ERASURE) {
+    if !options.contains(EncodeTyOptions::USE_CONCRETE_SELF) {
         if let Some(impl_id) = tcx.impl_of_method(instance.def_id())
             && let Some(trait_ref) = tcx.impl_trait_ref(impl_id)
         {
diff --git a/compiler/rustc_symbol_mangling/src/v0.rs b/compiler/rustc_symbol_mangling/src/v0.rs
index 4369f020d27..8cb5370bb4a 100644
--- a/compiler/rustc_symbol_mangling/src/v0.rs
+++ b/compiler/rustc_symbol_mangling/src/v0.rs
@@ -8,8 +8,8 @@ use rustc_hir::definitions::{DefPathData, DisambiguatedDefPathData};
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::print::{Print, PrintError, Printer};
 use rustc_middle::ty::{
-    self, EarlyBinder, FloatTy, Instance, IntTy, Ty, TyCtxt, TypeVisitable, TypeVisitableExt,
-    UintTy,
+    self, EarlyBinder, FloatTy, Instance, IntTy, ReifyReason, Ty, TyCtxt, TypeVisitable,
+    TypeVisitableExt, UintTy,
 };
 use rustc_middle::ty::{GenericArg, GenericArgKind};
 use rustc_span::symbol::kw;
@@ -44,7 +44,9 @@ pub(super) fn mangle<'tcx>(
     let shim_kind = match instance.def {
         ty::InstanceDef::ThreadLocalShim(_) => Some("tls"),
         ty::InstanceDef::VTableShim(_) => Some("vtable"),
-        ty::InstanceDef::ReifyShim(_) => Some("reify"),
+        ty::InstanceDef::ReifyShim(_, None) => Some("reify"),
+        ty::InstanceDef::ReifyShim(_, Some(ReifyReason::FnPtr)) => Some("reify-fnptr"),
+        ty::InstanceDef::ReifyShim(_, Some(ReifyReason::Vtable)) => Some("reify-vtable"),
 
         ty::InstanceDef::ConstructCoroutineInClosureShim { .. }
         | ty::InstanceDef::CoroutineKindShim { .. } => Some("fn_once"),
diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs
index 486afc5f8f3..cdd3f0afd79 100644
--- a/compiler/rustc_target/src/abi/call/mod.rs
+++ b/compiler/rustc_target/src/abi/call/mod.rs
@@ -251,9 +251,9 @@ pub struct Uniform {
     /// The total size of the argument, which can be:
     /// * equal to `unit.size` (one scalar/vector),
     /// * a multiple of `unit.size` (an array of scalar/vectors),
-    /// * if `unit.kind` is `Integer`, the last element
-    ///   can be shorter, i.e., `{ i64, i64, i32 }` for
-    ///   64-bit integers with a total size of 20 bytes.
+    /// * if `unit.kind` is `Integer`, the last element can be shorter, i.e., `{ i64, i64, i32 }`
+    ///   for 64-bit integers with a total size of 20 bytes. When the argument is actually passed,
+    ///   this size will be rounded up to the nearest multiple of `unit.size`.
     pub total: Size,
 }
 
@@ -319,14 +319,17 @@ impl CastTarget {
     }
 
     pub fn size<C: HasDataLayout>(&self, _cx: &C) -> Size {
-        let mut size = self.rest.total;
-        for i in 0..self.prefix.iter().count() {
-            match self.prefix[i] {
-                Some(v) => size += v.size,
-                None => {}
-            }
-        }
-        return size;
+        // Prefix arguments are passed in specific designated registers
+        let prefix_size = self
+            .prefix
+            .iter()
+            .filter_map(|x| x.map(|reg| reg.size))
+            .fold(Size::ZERO, |acc, size| acc + size);
+        // Remaining arguments are passed in chunks of the unit size
+        let rest_size =
+            self.rest.unit.size * self.rest.total.bytes().div_ceil(self.rest.unit.size.bytes());
+
+        prefix_size + rest_size
     }
 
     pub fn align<C: HasDataLayout>(&self, cx: &C) -> Align {
@@ -927,7 +930,7 @@ impl FromStr for Conv {
 }
 
 // Some types are used a lot. Make sure they don't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 mod size_asserts {
     use super::*;
     use rustc_data_structures::static_assert_size;
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index dd75377ead2..96da0b6fd1f 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -102,6 +102,7 @@ fn pre_link_args(os: &'static str, arch: Arch, abi: &'static str) -> LinkArgs {
             "ios" => ios_deployment_target(arch, abi),
             "tvos" => tvos_deployment_target(),
             "watchos" => watchos_deployment_target(),
+            "visionos" => visionos_deployment_target(),
             "macos" => macos_deployment_target(arch),
             _ => unreachable!(),
         };
@@ -202,6 +203,8 @@ pub fn sdk_version(platform: u32) -> Option<(u32, u32)> {
         | object::macho::PLATFORM_TVOSSIMULATOR
         | object::macho::PLATFORM_MACCATALYST => Some((16, 2)),
         object::macho::PLATFORM_WATCHOS | object::macho::PLATFORM_WATCHOSSIMULATOR => Some((9, 1)),
+        // FIXME: Upgrade to `object-rs` 0.33+ implementation with visionOS platform definition
+        11 | 12 => Some((1, 0)),
         _ => None,
     }
 }
@@ -216,6 +219,9 @@ pub fn platform(target: &Target) -> Option<u32> {
         ("watchos", _) => object::macho::PLATFORM_WATCHOS,
         ("tvos", "sim") => object::macho::PLATFORM_TVOSSIMULATOR,
         ("tvos", _) => object::macho::PLATFORM_TVOS,
+        // FIXME: Upgrade to `object-rs` 0.33+ implementation with visionOS platform definition
+        ("visionos", "sim") => 12,
+        ("visionos", _) => 11,
         _ => return None,
     })
 }
@@ -240,6 +246,7 @@ pub fn deployment_target(target: &Target) -> Option<(u32, u32)> {
         }
         "watchos" => watchos_deployment_target(),
         "tvos" => tvos_deployment_target(),
+        "visionos" => visionos_deployment_target(),
         _ => return None,
     };
 
@@ -290,6 +297,7 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
                 || sdkroot.contains("AppleTVSimulator.platform")
                 || sdkroot.contains("WatchOS.platform")
                 || sdkroot.contains("WatchSimulator.platform")
+                || sdkroot.contains("XROS.platform")
             {
                 env_remove.push("SDKROOT".into())
             }
@@ -299,6 +307,7 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
         // although this is apparently ignored when using the linker at "/usr/bin/ld".
         env_remove.push("IPHONEOS_DEPLOYMENT_TARGET".into());
         env_remove.push("TVOS_DEPLOYMENT_TARGET".into());
+        env_remove.push("XROS_DEPLOYMENT_TARGET".into());
         env_remove.into()
     } else {
         // Otherwise if cross-compiling for a different OS/SDK (including Mac Catalyst), remove any part
@@ -363,3 +372,18 @@ pub fn watchos_sim_llvm_target(arch: Arch) -> String {
     let (major, minor) = watchos_deployment_target();
     format!("{}-apple-watchos{}.{}.0-simulator", arch.target_name(), major, minor)
 }
+
+fn visionos_deployment_target() -> (u32, u32) {
+    // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
+    from_set_deployment_target("XROS_DEPLOYMENT_TARGET").unwrap_or((1, 0))
+}
+
+pub fn visionos_llvm_target(arch: Arch) -> String {
+    let (major, minor) = visionos_deployment_target();
+    format!("{}-apple-visionos{}.{}.0", arch.target_name(), major, minor)
+}
+
+pub fn visionos_sim_llvm_target(arch: Arch) -> String {
+    let (major, minor) = visionos_deployment_target();
+    format!("{}-apple-visionos{}.{}.0-simulator", arch.target_name(), major, minor)
+}
diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs
index 097039d6c73..7a985ad4dc0 100644
--- a/compiler/rustc_target/src/spec/base/apple/tests.rs
+++ b/compiler/rustc_target/src/spec/base/apple/tests.rs
@@ -1,6 +1,7 @@
 use crate::spec::targets::{
-    aarch64_apple_darwin, aarch64_apple_ios_sim, aarch64_apple_watchos_sim, i686_apple_darwin,
-    x86_64_apple_darwin, x86_64_apple_ios, x86_64_apple_tvos, x86_64_apple_watchos_sim,
+    aarch64_apple_darwin, aarch64_apple_ios_sim, aarch64_apple_visionos_sim,
+    aarch64_apple_watchos_sim, i686_apple_darwin, x86_64_apple_darwin, x86_64_apple_ios,
+    x86_64_apple_tvos, x86_64_apple_watchos_sim,
 };
 
 #[test]
@@ -12,6 +13,7 @@ fn simulator_targets_set_abi() {
         aarch64_apple_ios_sim::target(),
         // Note: There is currently no ARM64 tvOS simulator target
         aarch64_apple_watchos_sim::target(),
+        aarch64_apple_visionos_sim::target(),
     ];
 
     for target in &all_sim_targets {
@@ -32,7 +34,11 @@ fn macos_link_environment_unmodified() {
         // for the host.
         assert_eq!(
             target.link_env_remove,
-            crate::spec::cvs!["IPHONEOS_DEPLOYMENT_TARGET", "TVOS_DEPLOYMENT_TARGET"],
+            crate::spec::cvs![
+                "IPHONEOS_DEPLOYMENT_TARGET",
+                "TVOS_DEPLOYMENT_TARGET",
+                "XROS_DEPLOYMENT_TARGET"
+            ],
         );
     }
 }
diff --git a/compiler/rustc_target/src/spec/base/msvc.rs b/compiler/rustc_target/src/spec/base/msvc.rs
index efe949a4e90..44fc376fea0 100644
--- a/compiler/rustc_target/src/spec/base/msvc.rs
+++ b/compiler/rustc_target/src/spec/base/msvc.rs
@@ -14,6 +14,7 @@ pub fn opts() -> TargetOptions {
         pre_link_args,
         abi_return_struct_as_int: true,
         emit_debug_gdb_scripts: false,
+        archive_format: "coff".into(),
 
         // Currently this is the only supported method of debuginfo on MSVC
         // where `*.pdb` files show up next to the final artifact.
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 966da2c5eda..e94c7f3cc58 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -1557,6 +1557,9 @@ supported_targets! {
     ("aarch64-apple-watchos", aarch64_apple_watchos),
     ("aarch64-apple-watchos-sim", aarch64_apple_watchos_sim),
 
+    ("aarch64-apple-visionos", aarch64_apple_visionos),
+    ("aarch64-apple-visionos-sim", aarch64_apple_visionos_sim),
+
     ("armebv7r-none-eabi", armebv7r_none_eabi),
     ("armebv7r-none-eabihf", armebv7r_none_eabihf),
     ("armv7r-none-eabi", armv7r_none_eabi),
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
new file mode 100644
index 00000000000..7afe224163b
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
@@ -0,0 +1,27 @@
+use crate::spec::base::apple::{opts, visionos_llvm_target, Arch};
+use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let arch = Arch::Arm64;
+    let mut base = opts("visionos", arch);
+    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
+
+    Target {
+        llvm_target: visionos_llvm_target(arch).into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("ARM64 Apple visionOS".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 64,
+        data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(),
+        arch: arch.target_arch(),
+        options: TargetOptions {
+            features: "+neon,+fp-armv8,+apple-a16".into(),
+            max_atomic_width: Some(128),
+            frame_pointer: FramePointer::NonLeaf,
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
new file mode 100644
index 00000000000..422b2d7b922
--- /dev/null
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
@@ -0,0 +1,27 @@
+use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch};
+use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
+
+pub fn target() -> Target {
+    let arch = Arch::Arm64_sim;
+    let mut base = opts("visionos", arch);
+    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
+
+    Target {
+        llvm_target: visionos_sim_llvm_target(arch).into(),
+        metadata: crate::spec::TargetMetadata {
+            description: Some("ARM64 Apple visionOS simulator".into()),
+            tier: Some(3),
+            host_tools: Some(false),
+            std: Some(false),
+        },
+        pointer_width: 64,
+        data_layout: "e-m:o-i64:64-i128:128-n32:64-S128".into(),
+        arch: arch.target_arch(),
+        options: TargetOptions {
+            features: "+neon,+fp-armv8,+apple-a16".into(),
+            max_atomic_width: Some(128),
+            frame_pointer: FramePointer::NonLeaf,
+            ..base
+        },
+    }
+}
diff --git a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
index d9ebc7fbc1a..2f86506e2d0 100644
--- a/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armebv7r_none_eabihf.rs
@@ -22,7 +22,7 @@ pub fn target() -> Target {
             linker: Some("rust-lld".into()),
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
-            features: "+vfp3,-d32,-fp16".into(),
+            features: "+vfp3d16".into(),
             max_atomic_width: Some(64),
             emit_debug_gdb_scripts: false,
             // GCC defaults to 8 for arm-none here.
diff --git a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs
index a8c622ccce2..7c39d2d38de 100644
--- a/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7r_none_eabihf.rs
@@ -21,7 +21,7 @@ pub fn target() -> Target {
             linker: Some("rust-lld".into()),
             relocation_model: RelocModel::Static,
             panic_strategy: PanicStrategy::Abort,
-            features: "+vfp3,-d32,-fp16".into(),
+            features: "+vfp3d16".into(),
             max_atomic_width: Some(64),
             emit_debug_gdb_scripts: false,
             // GCC defaults to 8 for arm-none here.
diff --git a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs
index 8c6bc6d7267..bff812a5d5c 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv7em_none_eabihf.rs
@@ -25,16 +25,15 @@ pub fn target() -> Target {
 
         options: TargetOptions {
             abi: "eabihf".into(),
-            // `+vfp4` is the lowest common denominator between the Cortex-M4 (vfp4-16) and the
-            // Cortex-M7 (vfp5)
-            // `-d32` both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
-            // available
-            // `-fp64` The Cortex-M4 only supports single precision floating point operations
-            // whereas in the Cortex-M7 double precision is optional
+            // vfp4 is the lowest common denominator between the Cortex-M4F (vfp4) and the
+            // Cortex-M7 (vfp5).
+            // Both the Cortex-M4 and the Cortex-M7 only have 16 double-precision registers
+            // available, and the Cortex-M4 only supports single-precision floating point operations
+            // whereas in the Cortex-M7 double-precision is optional.
             //
             // Reference:
             // ARMv7-M Architecture Reference Manual - A2.5 The optional floating-point extension
-            features: "+vfp4,-d32,-fp64".into(),
+            features: "+vfp4d16sp".into(),
             max_atomic_width: Some(32),
             ..base::thumb::opts()
         },
diff --git a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs
index 2fef08261e1..88796e7a756 100644
--- a/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs
+++ b/compiler/rustc_target/src/spec/targets/thumbv8m_main_none_eabihf.rs
@@ -22,8 +22,7 @@ pub fn target() -> Target {
             // processor, the Cortex-M33 Technical Reference Manual states that
             // the FPU uses the FPv5 architecture, single-precision instructions
             // and 16 D registers.
-            // These parameters map to the following LLVM features.
-            features: "+fp-armv8,-fp64,-d32".into(),
+            features: "+fp-armv8d16sp".into(),
             max_atomic_width: Some(32),
             ..base::thumb::opts()
         },
diff --git a/compiler/rustc_trait_selection/src/lib.rs b/compiler/rustc_trait_selection/src/lib.rs
index e14fc62cd6f..b5fb710e4cc 100644
--- a/compiler/rustc_trait_selection/src/lib.rs
+++ b/compiler/rustc_trait_selection/src/lib.rs
@@ -30,7 +30,7 @@
 
 #[macro_use]
 extern crate rustc_macros;
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 #[macro_use]
 extern crate rustc_data_structures;
 #[macro_use]
diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
index e081a9100e2..f2c441dcbed 100644
--- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs
+++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
@@ -2,8 +2,8 @@
 //! Doing this via a separate goal is called "deferred alias relation" and part
 //! of our more general approach to "lazy normalization".
 //!
-//! This is done by first normalizing both sides of the goal, ending up in
-//! either a concrete type, rigid alias, or an infer variable.
+//! This is done by first structurally normalizing both sides of the goal, ending
+//! up in either a concrete type, rigid alias, or an infer variable.
 //! These are related further according to the rules below:
 //!
 //! (1.) If we end up with two rigid aliases, then we relate them structurally.
@@ -14,18 +14,10 @@
 //!
 //! (3.) Otherwise, if we end with two rigid (non-projection) or infer types,
 //! relate them structurally.
-//!
-//! Subtle: when relating an opaque to another type, we emit a
-//! `NormalizesTo(opaque, ?fresh_var)` goal when trying to normalize the opaque.
-//! This nested goal starts out as ambiguous and does not actually define the opaque.
-//! However, if `?fresh_var` ends up geteting equated to another type, we retry the
-//! `NormalizesTo` goal, at which point the opaque is actually defined.
 
 use super::EvalCtxt;
-use rustc_infer::traits::query::NoSolution;
-use rustc_infer::traits::solve::GoalSource;
 use rustc_middle::traits::solve::{Certainty, Goal, QueryResult};
-use rustc_middle::ty::{self, Ty};
+use rustc_middle::ty;
 
 impl<'tcx> EvalCtxt<'_, 'tcx> {
     #[instrument(level = "debug", skip(self), ret)]
@@ -36,21 +28,34 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let tcx = self.tcx();
         let Goal { param_env, predicate: (lhs, rhs, direction) } = goal;
 
-        let Some(lhs) = self.try_normalize_term(param_env, lhs)? else {
-            return self
-                .evaluate_added_goals_and_make_canonical_response(Certainty::overflow(true));
+        // Structurally normalize the lhs.
+        let lhs = if let Some(alias) = lhs.to_alias_ty(self.tcx()) {
+            let term = self.next_term_infer_of_kind(lhs);
+            self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term }));
+            term
+        } else {
+            lhs
         };
 
-        let Some(rhs) = self.try_normalize_term(param_env, rhs)? else {
-            return self
-                .evaluate_added_goals_and_make_canonical_response(Certainty::overflow(true));
+        // Structurally normalize the rhs.
+        let rhs = if let Some(alias) = rhs.to_alias_ty(self.tcx()) {
+            let term = self.next_term_infer_of_kind(rhs);
+            self.add_normalizes_to_goal(goal.with(tcx, ty::NormalizesTo { alias, term }));
+            term
+        } else {
+            rhs
         };
 
+        // Apply the constraints.
+        self.try_evaluate_added_goals()?;
+        let lhs = self.resolve_vars_if_possible(lhs);
+        let rhs = self.resolve_vars_if_possible(rhs);
+        debug!(?lhs, ?rhs);
+
         let variance = match direction {
             ty::AliasRelationDirection::Equate => ty::Variance::Invariant,
             ty::AliasRelationDirection::Subtype => ty::Variance::Covariant,
         };
-
         match (lhs.to_alias_ty(tcx), rhs.to_alias_ty(tcx)) {
             (None, None) => {
                 self.relate(param_env, lhs, variance, rhs)?;
@@ -58,14 +63,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
 
             (Some(alias), None) => {
-                self.relate_rigid_alias_non_alias(param_env, alias, variance, rhs)
+                self.relate_rigid_alias_non_alias(param_env, alias, variance, rhs)?;
+                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+            }
+            (None, Some(alias)) => {
+                self.relate_rigid_alias_non_alias(
+                    param_env,
+                    alias,
+                    variance.xform(ty::Variance::Contravariant),
+                    lhs,
+                )?;
+                self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
-            (None, Some(alias)) => self.relate_rigid_alias_non_alias(
-                param_env,
-                alias,
-                variance.xform(ty::Variance::Contravariant),
-                lhs,
-            ),
 
             (Some(alias_lhs), Some(alias_rhs)) => {
                 self.relate(param_env, alias_lhs, variance, alias_rhs)?;
@@ -73,104 +82,4 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
         }
     }
-
-    /// Relate a rigid alias with another type. This is the same as
-    /// an ordinary relate except that we treat the outer most alias
-    /// constructor as rigid.
-    #[instrument(level = "debug", skip(self, param_env), ret)]
-    fn relate_rigid_alias_non_alias(
-        &mut self,
-        param_env: ty::ParamEnv<'tcx>,
-        alias: ty::AliasTy<'tcx>,
-        variance: ty::Variance,
-        term: ty::Term<'tcx>,
-    ) -> QueryResult<'tcx> {
-        // NOTE: this check is purely an optimization, the structural eq would
-        // always fail if the term is not an inference variable.
-        if term.is_infer() {
-            let tcx = self.tcx();
-            // We need to relate `alias` to `term` treating only the outermost
-            // constructor as rigid, relating any contained generic arguments as
-            // normal. We do this by first structurally equating the `term`
-            // with the alias constructor instantiated with unconstrained infer vars,
-            // and then relate this with the whole `alias`.
-            //
-            // Alternatively we could modify `Equate` for this case by adding another
-            // variant to `StructurallyRelateAliases`.
-            let identity_args = self.fresh_args_for_item(alias.def_id);
-            let rigid_ctor = ty::AliasTy::new(tcx, alias.def_id, identity_args);
-            self.eq_structurally_relating_aliases(param_env, term, rigid_ctor.to_ty(tcx).into())?;
-            self.eq(param_env, alias, rigid_ctor)?;
-            self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-        } else {
-            Err(NoSolution)
-        }
-    }
-
-    // FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var.
-    /// Normalize the `term` to equate it later.
-    #[instrument(level = "debug", skip(self, param_env), ret)]
-    fn try_normalize_term(
-        &mut self,
-        param_env: ty::ParamEnv<'tcx>,
-        term: ty::Term<'tcx>,
-    ) -> Result<Option<ty::Term<'tcx>>, NoSolution> {
-        match term.unpack() {
-            ty::TermKind::Ty(ty) => {
-                Ok(self.try_normalize_ty_recur(param_env, 0, ty).map(Into::into))
-            }
-            ty::TermKind::Const(_) => {
-                if let Some(alias) = term.to_alias_ty(self.tcx()) {
-                    let term = self.next_term_infer_of_kind(term);
-                    self.add_normalizes_to_goal(Goal::new(
-                        self.tcx(),
-                        param_env,
-                        ty::NormalizesTo { alias, term },
-                    ));
-                    self.try_evaluate_added_goals()?;
-                    Ok(Some(self.resolve_vars_if_possible(term)))
-                } else {
-                    Ok(Some(term))
-                }
-            }
-        }
-    }
-
-    #[instrument(level = "debug", skip(self, param_env), ret)]
-    fn try_normalize_ty_recur(
-        &mut self,
-        param_env: ty::ParamEnv<'tcx>,
-        depth: usize,
-        ty: Ty<'tcx>,
-    ) -> Option<Ty<'tcx>> {
-        if !self.tcx().recursion_limit().value_within_limit(depth) {
-            return None;
-        }
-
-        let ty::Alias(kind, alias) = *ty.kind() else {
-            return Some(ty);
-        };
-
-        match self.commit_if_ok(|this| {
-            let tcx = this.tcx();
-            let normalized_ty = this.next_ty_infer();
-            let normalizes_to = ty::NormalizesTo { alias, term: normalized_ty.into() };
-            match kind {
-                ty::AliasKind::Opaque => {
-                    // HACK: Unlike for associated types, `normalizes-to` for opaques
-                    // is currently not treated as a function. We do not erase the
-                    // expected term.
-                    this.add_goal(GoalSource::Misc, Goal::new(tcx, param_env, normalizes_to));
-                }
-                ty::AliasKind::Projection | ty::AliasKind::Inherent | ty::AliasKind::Weak => {
-                    this.add_normalizes_to_goal(Goal::new(tcx, param_env, normalizes_to))
-                }
-            }
-            this.try_evaluate_added_goals()?;
-            Ok(this.resolve_vars_if_possible(normalized_ty))
-        }) {
-            Ok(ty) => self.try_normalize_ty_recur(param_env, depth + 1, ty),
-            Err(NoSolution) => Some(ty),
-        }
-    }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 5e580df01cb..35f7d1d7151 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -312,11 +312,18 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     fn forced_ambiguity(&mut self, cause: MaybeCause) -> Vec<Candidate<'tcx>> {
         let source = CandidateSource::BuiltinImpl(BuiltinImplSource::Misc);
         let certainty = Certainty::Maybe(cause);
-        let result = self.evaluate_added_goals_and_make_canonical_response(certainty).unwrap();
+        // This may fail if `try_evaluate_added_goals` overflows because it
+        // fails to reach a fixpoint but ends up getting an error after
+        // running for some additional step.
+        //
+        // FIXME: Add a test for this. It seems to be necessary for typenum but
+        // is incredibly hard to minimize as it may rely on being inside of a
+        // trait solver cycle.
+        let result = self.evaluate_added_goals_and_make_canonical_response(certainty);
         let mut dummy_probe = self.inspect.new_probe();
-        dummy_probe.probe_kind(ProbeKind::TraitCandidate { source, result: Ok(result) });
+        dummy_probe.probe_kind(ProbeKind::TraitCandidate { source, result });
         self.inspect.finish_probe(dummy_probe);
-        vec![Candidate { source, result }]
+        if let Ok(result) = result { vec![Candidate { source, result }] } else { vec![] }
     }
 
     #[instrument(level = "debug", skip_all)]
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 619435d2e8d..4a4efb6884f 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -332,7 +332,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// whether an alias is rigid by using the trait solver. When instantiating a response
     /// from the solver we assume that the solver correctly handled aliases and therefore
     /// always relate them structurally here.
-    #[instrument(level = "debug", skip(infcx), ret)]
+    #[instrument(level = "debug", skip(infcx))]
     fn unify_query_var_values(
         infcx: &InferCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs
deleted file mode 100644
index c8f9a461adf..00000000000
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/commit_if_ok.rs
+++ /dev/null
@@ -1,47 +0,0 @@
-use super::{EvalCtxt, NestedGoals};
-use crate::solve::inspect;
-use rustc_middle::traits::query::NoSolution;
-
-impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
-    pub(in crate::solve) fn commit_if_ok<T>(
-        &mut self,
-        f: impl FnOnce(&mut EvalCtxt<'_, 'tcx>) -> Result<T, NoSolution>,
-    ) -> Result<T, NoSolution> {
-        let mut nested_ecx = EvalCtxt {
-            infcx: self.infcx,
-            variables: self.variables,
-            var_values: self.var_values,
-            is_normalizes_to_goal: self.is_normalizes_to_goal,
-            predefined_opaques_in_body: self.predefined_opaques_in_body,
-            max_input_universe: self.max_input_universe,
-            search_graph: self.search_graph,
-            nested_goals: NestedGoals::new(),
-            tainted: self.tainted,
-            inspect: self.inspect.new_probe(),
-        };
-
-        let result = nested_ecx.infcx.commit_if_ok(|_| f(&mut nested_ecx));
-        if result.is_ok() {
-            let EvalCtxt {
-                infcx: _,
-                variables: _,
-                var_values: _,
-                is_normalizes_to_goal: _,
-                predefined_opaques_in_body: _,
-                max_input_universe: _,
-                search_graph: _,
-                nested_goals,
-                tainted,
-                inspect,
-            } = nested_ecx;
-            self.nested_goals.extend(nested_goals);
-            self.tainted = tainted;
-            self.inspect.integrate_snapshot(inspect);
-        } else {
-            nested_ecx.inspect.probe_kind(inspect::ProbeKind::CommitIfOk);
-            self.inspect.finish_probe(nested_ecx.inspect);
-        }
-
-        result
-    }
-}
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index a0fe6eca0fc..1739bd70e7b 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -24,7 +24,6 @@ use rustc_middle::ty::{
 use rustc_session::config::DumpSolverProofTree;
 use rustc_span::DUMMY_SP;
 use std::io::Write;
-use std::iter;
 use std::ops::ControlFlow;
 
 use crate::traits::vtable::{count_own_vtable_entries, prepare_vtable_segments, VtblSegment};
@@ -36,7 +35,6 @@ use super::{GoalSource, SolverMode};
 pub use select::InferCtxtSelectExt;
 
 mod canonical;
-mod commit_if_ok;
 mod probe;
 mod select;
 
@@ -124,11 +122,6 @@ impl<'tcx> NestedGoals<'tcx> {
     pub(super) fn is_empty(&self) -> bool {
         self.normalizes_to_goals.is_empty() && self.goals.is_empty()
     }
-
-    pub(super) fn extend(&mut self, other: NestedGoals<'tcx>) {
-        self.normalizes_to_goals.extend(other.normalizes_to_goals);
-        self.goals.extend(other.goals)
-    }
 }
 
 #[derive(PartialEq, Eq, Debug, Hash, HashStable, Clone, Copy)]
@@ -511,12 +504,6 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
 
         self.inspect.evaluate_added_goals_loop_start();
 
-        fn with_misc_source<'tcx>(
-            it: impl IntoIterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>,
-        ) -> impl Iterator<Item = (GoalSource, Goal<'tcx, ty::Predicate<'tcx>>)> {
-            iter::zip(iter::repeat(GoalSource::Misc), it)
-        }
-
         // If this loop did not result in any progress, what's our final certainty.
         let mut unchanged_certainty = Some(Certainty::Yes);
         for goal in goals.normalizes_to_goals {
@@ -534,16 +521,28 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 unconstrained_goal,
             )?;
             // Add the nested goals from normalization to our own nested goals.
+            debug!(?nested_goals);
             goals.goals.extend(nested_goals);
 
             // Finally, equate the goal's RHS with the unconstrained var.
-            // We put the nested goals from this into goals instead of
-            // next_goals to avoid needing to process the loop one extra
-            // time if this goal returns something -- I don't think this
-            // matters in practice, though.
-            let eq_goals =
-                self.eq_and_get_goals(goal.param_env, goal.predicate.term, unconstrained_rhs)?;
-            goals.goals.extend(with_misc_source(eq_goals));
+            //
+            // SUBTLE:
+            // We structurally relate aliases here. This is necessary
+            // as we otherwise emit a nested `AliasRelate` goal in case the
+            // returned term is a rigid alias, resulting in overflow.
+            //
+            // It is correct as both `goal.predicate.term` and `unconstrained_rhs`
+            // start out as an unconstrained inference variable so any aliases get
+            // fully normalized when instantiating it.
+            //
+            // FIXME: Strictly speaking this may be incomplete if the normalized-to
+            // type contains an ambiguous alias referencing bound regions. We should
+            // consider changing this to only use "shallow structural equality".
+            self.eq_structurally_relating_aliases(
+                goal.param_env,
+                goal.predicate.term,
+                unconstrained_rhs,
+            )?;
 
             // We only look at the `projection_ty` part here rather than
             // looking at the "has changed" return from evaluate_goal,
@@ -720,7 +719,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ) -> Result<(), NoSolution> {
         self.infcx
             .at(&ObligationCause::dummy(), param_env)
-            .eq(DefineOpaqueTypes::No, lhs, rhs)
+            // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+            .eq(DefineOpaqueTypes::Yes, lhs, rhs)
             .map(|InferOk { value: (), obligations }| {
                 self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
             })
@@ -730,6 +730,46 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             })
     }
 
+    /// This should be used when relating a rigid alias with another type.
+    ///
+    /// Normally we emit a nested `AliasRelate` when equating an inference
+    /// variable and an alias. This causes us to instead constrain the inference
+    /// variable to the alias without emitting a nested alias relate goals.
+    #[instrument(level = "debug", skip(self, param_env), ret)]
+    pub(super) fn relate_rigid_alias_non_alias(
+        &mut self,
+        param_env: ty::ParamEnv<'tcx>,
+        alias: ty::AliasTy<'tcx>,
+        variance: ty::Variance,
+        term: ty::Term<'tcx>,
+    ) -> Result<(), NoSolution> {
+        // NOTE: this check is purely an optimization, the structural eq would
+        // always fail if the term is not an inference variable.
+        if term.is_infer() {
+            let tcx = self.tcx();
+            // We need to relate `alias` to `term` treating only the outermost
+            // constructor as rigid, relating any contained generic arguments as
+            // normal. We do this by first structurally equating the `term`
+            // with the alias constructor instantiated with unconstrained infer vars,
+            // and then relate this with the whole `alias`.
+            //
+            // Alternatively we could modify `Equate` for this case by adding another
+            // variant to `StructurallyRelateAliases`.
+            let identity_args = self.fresh_args_for_item(alias.def_id);
+            let rigid_ctor = ty::AliasTy::new(tcx, alias.def_id, identity_args);
+            let ctor_ty = rigid_ctor.to_ty(tcx);
+            let InferOk { value: (), obligations } = self
+                .infcx
+                .at(&ObligationCause::dummy(), param_env)
+                .trace(term, ctor_ty.into())
+                .eq_structurally_relating_aliases(term, ctor_ty.into())?;
+            debug_assert!(obligations.is_empty());
+            self.relate(param_env, alias, variance, rigid_ctor)
+        } else {
+            Err(NoSolution)
+        }
+    }
+
     /// This sohuld only be used when we're either instantiating a previously
     /// unconstrained "return value" or when we're sure that all aliases in
     /// the types are rigid.
@@ -759,7 +799,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ) -> Result<(), NoSolution> {
         self.infcx
             .at(&ObligationCause::dummy(), param_env)
-            .sub(DefineOpaqueTypes::No, sub, sup)
+            // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+            .sub(DefineOpaqueTypes::Yes, sub, sup)
             .map(|InferOk { value: (), obligations }| {
                 self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
             })
@@ -779,7 +820,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ) -> Result<(), NoSolution> {
         self.infcx
             .at(&ObligationCause::dummy(), param_env)
-            .relate(DefineOpaqueTypes::No, lhs, variance, rhs)
+            // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+            .relate(DefineOpaqueTypes::Yes, lhs, variance, rhs)
             .map(|InferOk { value: (), obligations }| {
                 self.add_goals(GoalSource::Misc, obligations.into_iter().map(|o| o.into()));
             })
@@ -803,7 +845,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
         self.infcx
             .at(&ObligationCause::dummy(), param_env)
-            .eq(DefineOpaqueTypes::No, lhs, rhs)
+            // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+            .eq(DefineOpaqueTypes::Yes, lhs, rhs)
             .map(|InferOk { value: (), obligations }| {
                 obligations.into_iter().map(|o| o.into()).collect()
             })
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index e0c7804b6db..6644d3c77af 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -182,7 +182,8 @@ fn rematch_impl<'tcx>(
 
     let mut nested = infcx
         .at(&ObligationCause::dummy(), goal.param_env)
-        .eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref)
+        // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+        .eq(DefineOpaqueTypes::Yes, goal.predicate.trait_ref, impl_trait_ref)
         .map_err(|_| SelectionError::Unimplemented)?
         .into_obligations();
 
@@ -257,7 +258,8 @@ fn rematch_unsize<'tcx>(
             nested.extend(
                 infcx
                     .at(&ObligationCause::dummy(), goal.param_env)
-                    .eq(DefineOpaqueTypes::No, a_elem_ty, b_elem_ty)
+                    // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+                    .eq(DefineOpaqueTypes::Yes, a_elem_ty, b_elem_ty)
                     .expect("expected rematch to succeed")
                     .into_obligations(),
             );
@@ -300,7 +302,8 @@ fn rematch_unsize<'tcx>(
             nested.extend(
                 infcx
                     .at(&ObligationCause::dummy(), goal.param_env)
-                    .eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
+                    // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+                    .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
                     .expect("expected rematch to succeed")
                     .into_obligations(),
             );
@@ -329,7 +332,8 @@ fn rematch_unsize<'tcx>(
             nested.extend(
                 infcx
                     .at(&ObligationCause::dummy(), goal.param_env)
-                    .eq(DefineOpaqueTypes::No, unsized_a_ty, b_ty)
+                    // New solver ignores DefineOpaqueTypes, so choose Yes for consistency
+                    .eq(DefineOpaqueTypes::Yes, unsized_a_ty, b_ty)
                     .expect("expected rematch to succeed")
                     .into_obligations(),
             );
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index cfec2e9bbf3..56c32d3d539 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -130,17 +130,14 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
                     self.candidates_recur(candidates, nested_goals, probe);
                     nested_goals.truncate(num_goals);
                 }
-                inspect::ProbeStep::EvaluateGoals(_)
-                | inspect::ProbeStep::CommitIfOkStart
-                | inspect::ProbeStep::CommitIfOkSuccess => (),
+                inspect::ProbeStep::EvaluateGoals(_) => (),
             }
         }
 
         match probe.kind {
             inspect::ProbeKind::NormalizedSelfTyAssembly
             | inspect::ProbeKind::UnsizeAssembly
-            | inspect::ProbeKind::UpcastProjectionCompatibility
-            | inspect::ProbeKind::CommitIfOk => (),
+            | inspect::ProbeKind::UpcastProjectionCompatibility => (),
             // We add a candidate for the root evaluation if there
             // is only one way to prove a given goal, e.g. for `WellFormed`.
             //
@@ -157,7 +154,8 @@ impl<'a, 'tcx> InspectGoal<'a, 'tcx> {
                     });
                 }
             }
-            inspect::ProbeKind::MiscCandidate { name: _, result }
+            inspect::ProbeKind::TryNormalizeNonRigid { result }
+            | inspect::ProbeKind::MiscCandidate { name: _, result }
             | inspect::ProbeKind::TraitCandidate { source: _, result } => {
                 candidates.push(InspectCandidate {
                     goal: self,
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
index 4da999f2406..43c76cc5f4a 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
@@ -220,8 +220,6 @@ enum WipProbeStep<'tcx> {
     AddGoal(GoalSource, inspect::CanonicalState<'tcx, Goal<'tcx, ty::Predicate<'tcx>>>),
     EvaluateGoals(WipAddedGoalsEvaluation<'tcx>),
     NestedProbe(WipProbe<'tcx>),
-    CommitIfOkStart,
-    CommitIfOkSuccess,
 }
 
 impl<'tcx> WipProbeStep<'tcx> {
@@ -230,8 +228,6 @@ impl<'tcx> WipProbeStep<'tcx> {
             WipProbeStep::AddGoal(source, goal) => inspect::ProbeStep::AddGoal(source, goal),
             WipProbeStep::EvaluateGoals(eval) => inspect::ProbeStep::EvaluateGoals(eval.finalize()),
             WipProbeStep::NestedProbe(probe) => inspect::ProbeStep::NestedProbe(probe.finalize()),
-            WipProbeStep::CommitIfOkStart => inspect::ProbeStep::CommitIfOkStart,
-            WipProbeStep::CommitIfOkSuccess => inspect::ProbeStep::CommitIfOkSuccess,
         }
     }
 }
@@ -467,29 +463,6 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
         }
     }
 
-    /// Used by `EvalCtxt::commit_if_ok` to flatten the work done inside
-    /// of the probe into the parent.
-    pub fn integrate_snapshot(&mut self, probe: ProofTreeBuilder<'tcx>) {
-        if let Some(this) = self.as_mut() {
-            match (this, *probe.state.unwrap()) {
-                (
-                    DebugSolver::Probe(WipProbe { steps, .. })
-                    | DebugSolver::GoalEvaluationStep(WipGoalEvaluationStep {
-                        evaluation: WipProbe { steps, .. },
-                        ..
-                    }),
-                    DebugSolver::Probe(probe),
-                ) => {
-                    steps.push(WipProbeStep::CommitIfOkStart);
-                    assert_eq!(probe.kind, None);
-                    steps.extend(probe.steps);
-                    steps.push(WipProbeStep::CommitIfOkSuccess);
-                }
-                _ => unreachable!(),
-            }
-        }
-    }
-
     pub fn new_evaluate_added_goals(&mut self) -> ProofTreeBuilder<'tcx> {
         self.nested(|| WipAddedGoalsEvaluation { evaluations: vec![], result: None })
     }
diff --git a/compiler/rustc_trait_selection/src/solve/normalize.rs b/compiler/rustc_trait_selection/src/solve/normalize.rs
index b1c03e82cab..5b45e1a34e4 100644
--- a/compiler/rustc_trait_selection/src/solve/normalize.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalize.rs
@@ -177,7 +177,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
     fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
         let infcx = self.at.infcx;
         debug_assert_eq!(ty, infcx.shallow_resolve(ty));
-        if !ty.has_projections() {
+        if !ty.has_aliases() {
             return Ok(ty);
         }
 
@@ -204,7 +204,7 @@ impl<'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for NormalizationFolder<'_, 'tcx> {
     fn try_fold_const(&mut self, ct: ty::Const<'tcx>) -> Result<ty::Const<'tcx>, Self::Error> {
         let infcx = self.at.infcx;
         debug_assert_eq!(ct, infcx.shallow_resolve(ct));
-        if !ct.has_projections() {
+        if !ct.has_aliases() {
             return Ok(ct);
         }
 
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 66688893235..fb296d55100 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -1,4 +1,4 @@
-use crate::traits::{check_args_compatible, specialization_graph};
+use crate::traits::specialization_graph;
 
 use super::assembly::structural_traits::AsyncCallableRelevantTypes;
 use super::assembly::{self, structural_traits, Candidate};
@@ -7,6 +7,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_hir::LangItem;
 use rustc_infer::traits::query::NoSolution;
+use rustc_infer::traits::solve::inspect::ProbeKind;
 use rustc_infer::traits::specialization_graph::LeafDef;
 use rustc_infer::traits::Reveal;
 use rustc_middle::traits::solve::{
@@ -30,14 +31,41 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         &mut self,
         goal: Goal<'tcx, NormalizesTo<'tcx>>,
     ) -> QueryResult<'tcx> {
-        let def_id = goal.predicate.def_id();
-        let def_kind = self.tcx().def_kind(def_id);
-        match def_kind {
-            DefKind::OpaqueTy => return self.normalize_opaque_type(goal),
-            _ => self.set_is_normalizes_to_goal(),
+        self.set_is_normalizes_to_goal();
+        debug_assert!(self.term_is_fully_unconstrained(goal));
+        let normalize_result = self
+            .probe(|&result| ProbeKind::TryNormalizeNonRigid { result })
+            .enter(|this| this.normalize_at_least_one_step(goal));
+
+        match normalize_result {
+            Ok(res) => Ok(res),
+            Err(NoSolution) => {
+                let Goal { param_env, predicate: NormalizesTo { alias, term } } = goal;
+                if alias.opt_kind(self.tcx()).is_some() {
+                    self.relate_rigid_alias_non_alias(
+                        param_env,
+                        alias,
+                        ty::Variance::Invariant,
+                        term,
+                    )?;
+                    self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+                } else {
+                    // FIXME(generic_const_exprs): we currently do not support rigid
+                    // unevaluated constants.
+                    Err(NoSolution)
+                }
+            }
         }
+    }
 
-        debug_assert!(self.term_is_fully_unconstrained(goal));
+    /// Normalize the given alias by at least one step. If the alias is rigid, this
+    /// returns `NoSolution`.
+    #[instrument(level = "debug", skip(self), ret)]
+    fn normalize_at_least_one_step(
+        &mut self,
+        goal: Goal<'tcx, NormalizesTo<'tcx>>,
+    ) -> QueryResult<'tcx> {
+        let def_id = goal.predicate.def_id();
         match self.tcx().def_kind(def_id) {
             DefKind::AssocTy | DefKind::AssocConst => {
                 match self.tcx().associated_item(def_id).container {
@@ -52,35 +80,22 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
             DefKind::AnonConst => self.normalize_anon_const(goal),
             DefKind::TyAlias => self.normalize_weak_type(goal),
+            DefKind::OpaqueTy => self.normalize_opaque_type(goal),
             kind => bug!("unknown DefKind {} in normalizes-to goal: {goal:#?}", kind.descr(def_id)),
         }
     }
 
-    /// When normalizing an associated item, constrain the result to `term`.
-    ///
-    /// While `NormalizesTo` goals have the normalized-to term as an argument,
-    /// this argument is always fully unconstrained for associated items.
-    /// It is therefore appropriate to instead think of these `NormalizesTo` goals
-    /// as function returning a term after normalizing.
-    ///
-    /// When equating an inference variable and an alias, we tend to emit `alias-relate`
-    /// goals and only actually instantiate the inference variable with an alias if the
-    /// alias is rigid. However, this means that constraining the expected term of
-    /// such goals ends up fully structurally normalizing the resulting type instead of
-    /// only by one step. To avoid this we instead use structural equality here, resulting
-    /// in each `NormalizesTo` only projects by a single step.
+    /// When normalizing an associated item, constrain the expected term to `term`.
     ///
-    /// Not doing so, currently causes issues because trying to normalize an opaque type
-    /// during alias-relate doesn't actually constrain the opaque if the concrete type
-    /// is an inference variable. This means that `NormalizesTo` for associated types
-    /// normalizing to an opaque type always resulted in ambiguity, breaking tests e.g.
-    /// tests/ui/type-alias-impl-trait/issue-78450.rs.
+    /// We know `term` to always be a fully unconstrained inference variable, so
+    /// `eq` should never fail here. However, in case `term` contains aliases, we
+    /// emit nested `AliasRelate` goals to structurally normalize the alias.
     pub fn instantiate_normalizes_to_term(
         &mut self,
         goal: Goal<'tcx, NormalizesTo<'tcx>>,
         term: ty::Term<'tcx>,
     ) {
-        self.eq_structurally_relating_aliases(goal.param_env, goal.predicate.term, term)
+        self.eq(goal.param_env, goal.predicate.term, term)
             .expect("expected goal term to be fully unconstrained");
     }
 }
@@ -247,7 +262,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                 assoc_def.defining_node,
             );
 
-            if !check_args_compatible(tcx, assoc_def.item, args) {
+            if !tcx.check_args_compatible(assoc_def.item.def_id, args) {
                 return error_response(
                     ecx,
                     "associated item has mismatched generic item arguments",
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs
index 356c3776c04..9fdb280cdc6 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/opaque_types.rs
@@ -58,12 +58,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                     }
                 }
 
-                let expected = self.structurally_normalize_ty(goal.param_env, expected)?;
-                if expected.is_ty_var() {
-                    return self
-                        .evaluate_added_goals_and_make_canonical_response(Certainty::AMBIGUOUS);
-                }
-
                 // Otherwise, define a new opaque type
                 self.insert_hidden_type(opaque_type_key, goal.param_env, expected)?;
                 self.add_item_bounds_for_hidden_type(
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 6e768b23ef8..8625ad378f7 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -477,7 +477,8 @@ fn plug_infer_with_placeholders<'tcx>(
             if ty.is_ty_var() {
                 let Ok(InferOk { value: (), obligations }) =
                     self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
-                        DefineOpaqueTypes::No,
+                        // Comparing against a type variable never registers hidden types anyway
+                        DefineOpaqueTypes::Yes,
                         ty,
                         Ty::new_placeholder(
                             self.infcx.tcx,
@@ -504,7 +505,9 @@ fn plug_infer_with_placeholders<'tcx>(
             if ct.is_ct_infer() {
                 let Ok(InferOk { value: (), obligations }) =
                     self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
-                        DefineOpaqueTypes::No,
+                        // The types of the constants are the same, so there is no hidden type
+                        // registration happening anyway.
+                        DefineOpaqueTypes::Yes,
                         ct,
                         ty::Const::new_placeholder(
                             self.infcx.tcx,
@@ -532,7 +535,8 @@ fn plug_infer_with_placeholders<'tcx>(
                 if r.is_var() {
                     let Ok(InferOk { value: (), obligations }) =
                         self.infcx.at(&ObligationCause::dummy(), ty::ParamEnv::empty()).eq(
-                            DefineOpaqueTypes::No,
+                            // Lifetimes don't contain opaque types (or any types for that matter).
+                            DefineOpaqueTypes::Yes,
                             r,
                             ty::Region::new_placeholder(
                                 self.infcx.tcx,
@@ -554,11 +558,7 @@ fn plug_infer_with_placeholders<'tcx>(
         }
     }
 
-    value.visit_with(&mut PlugInferWithPlaceholder {
-        infcx,
-        universe,
-        var: ty::BoundVar::from_u32(0),
-    });
+    value.visit_with(&mut PlugInferWithPlaceholder { infcx, universe, var: ty::BoundVar::ZERO });
 }
 
 fn try_prove_negated_where_clause<'tcx>(
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
index c6f5af08013..ddb582ffab0 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/ambiguity.rs
@@ -7,18 +7,21 @@ use rustc_span::{Span, DUMMY_SP};
 
 use crate::traits::ObligationCtxt;
 
-pub enum Ambiguity {
+#[derive(Debug)]
+pub enum CandidateSource {
     DefId(DefId),
     ParamEnv(Span),
 }
 
-pub fn recompute_applicable_impls<'tcx>(
+pub fn compute_applicable_impls_for_diagnostics<'tcx>(
     infcx: &InferCtxt<'tcx>,
     obligation: &PolyTraitObligation<'tcx>,
-) -> Vec<Ambiguity> {
+) -> Vec<CandidateSource> {
     let tcx = infcx.tcx;
     let param_env = obligation.param_env;
 
+    let predicate_polarity = obligation.predicate.skip_binder().polarity;
+
     let impl_may_apply = |impl_def_id| {
         let ocx = ObligationCtxt::new(infcx);
         infcx.enter_forall(obligation.predicate, |placeholder_obligation| {
@@ -40,6 +43,15 @@ pub fn recompute_applicable_impls<'tcx>(
                 return false;
             }
 
+            let impl_trait_header = tcx.impl_trait_header(impl_def_id).unwrap();
+            let impl_polarity = impl_trait_header.polarity;
+
+            match (impl_polarity, predicate_polarity) {
+                (ty::ImplPolarity::Positive, ty::PredicatePolarity::Positive)
+                | (ty::ImplPolarity::Negative, ty::PredicatePolarity::Negative) => {}
+                _ => return false,
+            }
+
             let impl_predicates = tcx.predicates_of(impl_def_id).instantiate(tcx, impl_args);
             ocx.register_obligations(impl_predicates.predicates.iter().map(|&predicate| {
                 Obligation::new(tcx, ObligationCause::dummy(), param_env, predicate)
@@ -86,7 +98,7 @@ pub fn recompute_applicable_impls<'tcx>(
         obligation.predicate.skip_binder().trait_ref.self_ty(),
         |impl_def_id| {
             if infcx.probe(|_| impl_may_apply(impl_def_id)) {
-                ambiguities.push(Ambiguity::DefId(impl_def_id))
+                ambiguities.push(CandidateSource::DefId(impl_def_id))
             }
         },
     );
@@ -101,9 +113,9 @@ pub fn recompute_applicable_impls<'tcx>(
             if kind.rebind(trait_pred.trait_ref)
                 == ty::Binder::dummy(ty::TraitRef::identity(tcx, trait_pred.def_id()))
             {
-                ambiguities.push(Ambiguity::ParamEnv(tcx.def_span(trait_pred.def_id())))
+                ambiguities.push(CandidateSource::ParamEnv(tcx.def_span(trait_pred.def_id())))
             } else {
-                ambiguities.push(Ambiguity::ParamEnv(span))
+                ambiguities.push(CandidateSource::ParamEnv(span))
             }
         }
     }
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 0515b09ae46..10c03387a5b 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
@@ -1,6 +1,6 @@
 // ignore-tidy-filelength :(
 
-mod ambiguity;
+pub mod ambiguity;
 mod infer_ctxt_ext;
 pub mod on_unimplemented;
 pub mod suggestions;
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 fe2691e9d4d..af90372b97c 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs
@@ -3842,7 +3842,9 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                             self.probe(|_| {
                                 match self
                                     .at(&ObligationCause::misc(expr.span, body_id), param_env)
-                                    .eq(DefineOpaqueTypes::No, expected, actual)
+                                    // Doesn't actually matter if we define opaque types here, this is just used for
+                                    // diagnostics, and the result is never kept around.
+                                    .eq(DefineOpaqueTypes::Yes, expected, actual)
                                 {
                                     Ok(_) => (), // We ignore nested obligations here for now.
                                     Err(err) => type_diffs.push(err),
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index aef98dbad5f..144971b63c0 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -10,7 +10,7 @@ use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::InferCtxtExt as _;
 use crate::infer::{self, InferCtxt};
 use crate::traits::error_reporting::infer_ctxt_ext::InferCtxtExt;
-use crate::traits::error_reporting::{ambiguity, ambiguity::Ambiguity::*};
+use crate::traits::error_reporting::{ambiguity, ambiguity::CandidateSource::*};
 use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
 use crate::traits::specialize::to_pretty_impl_header;
 use crate::traits::NormalizeExt;
@@ -2386,7 +2386,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                     )
                 };
 
-                let mut ambiguities = ambiguity::recompute_applicable_impls(
+                let mut ambiguities = ambiguity::compute_applicable_impls_for_diagnostics(
                     self.infcx,
                     &obligation.with(self.tcx, trait_ref),
                 );
@@ -2702,7 +2702,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
     fn annotate_source_of_ambiguity(
         &self,
         err: &mut Diag<'_>,
-        ambiguities: &[ambiguity::Ambiguity],
+        ambiguities: &[ambiguity::CandidateSource],
         predicate: ty::Predicate<'tcx>,
     ) {
         let mut spans = vec![];
@@ -2711,7 +2711,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
         let mut has_param_env = false;
         for ambiguity in ambiguities {
             match ambiguity {
-                ambiguity::Ambiguity::DefId(impl_def_id) => {
+                ambiguity::CandidateSource::DefId(impl_def_id) => {
                     match self.tcx.span_of_impl(*impl_def_id) {
                         Ok(span) => spans.push(span),
                         Err(name) => {
@@ -2722,7 +2722,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
                         }
                     }
                 }
-                ambiguity::Ambiguity::ParamEnv(span) => {
+                ambiguity::CandidateSource::ParamEnv(span) => {
                     has_param_env = true;
                     spans.push(*span);
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/fulfill.rs b/compiler/rustc_trait_selection/src/traits/fulfill.rs
index 34c891d400e..a04a3bc6ebe 100644
--- a/compiler/rustc_trait_selection/src/traits/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/traits/fulfill.rs
@@ -72,7 +72,7 @@ pub struct PendingPredicateObligation<'tcx> {
 }
 
 // `PendingPredicateObligation` is used a lot. Make sure it doesn't unintentionally get bigger.
-#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]
+#[cfg(all(any(target_arch = "x86_64", target_arch = "aarch64"), target_pointer_width = "64"))]
 static_assert_size!(PendingPredicateObligation<'_>, 72);
 
 impl<'tcx> FulfillmentContext<'tcx> {
@@ -311,7 +311,7 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
 
         let infcx = self.selcx.infcx;
 
-        if obligation.predicate.has_projections() {
+        if obligation.predicate.has_aliases() {
             let mut obligations = Vec::new();
             let predicate = normalize_with_depth_to(
                 &mut self.selcx,
@@ -429,7 +429,8 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                 // as the cause of an overflow.
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
                     match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
-                        DefineOpaqueTypes::No,
+                        // Only really excercised by generic_const_exprs
+                        DefineOpaqueTypes::Yes,
                         ct.ty(),
                         ty,
                     ) {
@@ -571,7 +572,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                                 if let Ok(new_obligations) = infcx
                                     .at(&obligation.cause, obligation.param_env)
                                     .trace(c1, c2)
-                                    .eq(DefineOpaqueTypes::No, a.args, b.args)
+                                    // Can define opaque types as this is only reachable with
+                                    // `generic_const_exprs`
+                                    .eq(DefineOpaqueTypes::Yes, a.args, b.args)
                                 {
                                     return ProcessResult::Changed(mk_pending(
                                         new_obligations.into_obligations(),
@@ -582,7 +585,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                             (_, _) => {
                                 if let Ok(new_obligations) = infcx
                                     .at(&obligation.cause, obligation.param_env)
-                                    .eq(DefineOpaqueTypes::No, c1, c2)
+                                    // Can define opaque types as this is only reachable with
+                                    // `generic_const_exprs`
+                                    .eq(DefineOpaqueTypes::Yes, c1, c2)
                                 {
                                     return ProcessResult::Changed(mk_pending(
                                         new_obligations.into_obligations(),
@@ -623,7 +628,9 @@ impl<'a, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'tcx> {
                     match (evaluate(c1), evaluate(c2)) {
                         (Ok(c1), Ok(c2)) => {
                             match self.selcx.infcx.at(&obligation.cause, obligation.param_env).eq(
-                                DefineOpaqueTypes::No,
+                                // Can define opaque types as this is only reachable with
+                                // `generic_const_exprs`
+                                DefineOpaqueTypes::Yes,
                                 c1,
                                 c2,
                             ) {
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 3ab4872fffe..2c8116b779b 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -61,12 +61,12 @@ pub use self::specialize::{
 pub use self::structural_match::search_for_structural_match_violation;
 pub use self::structural_normalize::StructurallyNormalizeExt;
 pub use self::util::elaborate;
-pub use self::util::{
-    check_args_compatible, supertrait_def_ids, supertraits, transitive_bounds,
-    transitive_bounds_that_define_assoc_item, SupertraitDefIds,
-};
 pub use self::util::{expand_trait_aliases, TraitAliasExpander, TraitAliasExpansionInfo};
 pub use self::util::{get_vtable_index_of_object_method, impl_item_is_final, upcast_choices};
+pub use self::util::{
+    supertrait_def_ids, supertraits, transitive_bounds, transitive_bounds_that_define_assoc_item,
+    SupertraitDefIds,
+};
 pub use self::util::{with_replaced_escaping_bound_vars, BoundVarReplacer, PlaceholderReplacer};
 
 pub use rustc_infer::traits::*;
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 15bfffef3ce..b4969926f64 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -101,6 +101,8 @@ pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
     value: &T,
     reveal: Reveal,
 ) -> bool {
+    // This mirrors `ty::TypeFlags::HAS_ALIASES` except that we take `Reveal` into account.
+
     let mut flags = ty::TypeFlags::HAS_TY_PROJECTION
         | ty::TypeFlags::HAS_TY_WEAK
         | ty::TypeFlags::HAS_TY_INHERENT
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index c33e24b1094..9246a41a2bc 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -2,7 +2,6 @@
 
 use std::ops::ControlFlow;
 
-use super::check_args_compatible;
 use super::specialization_graph;
 use super::translate_args;
 use super::util;
@@ -432,7 +431,7 @@ pub(super) fn opt_normalize_projection_type<'a, 'b, 'tcx>(
 
             let projected_term = selcx.infcx.resolve_vars_if_possible(projected_term);
 
-            let mut result = if projected_term.has_projections() {
+            let mut result = if projected_term.has_aliases() {
                 let normalized_ty = normalize_with_depth_to(
                     selcx,
                     param_env,
@@ -596,7 +595,7 @@ pub fn normalize_inherent_projection<'a, 'b, 'tcx>(
     let ty = tcx.type_of(alias_ty.def_id).instantiate(tcx, args);
 
     let mut ty = selcx.infcx.resolve_vars_if_possible(ty);
-    if ty.has_projections() {
+    if ty.has_aliases() {
         ty = normalize_with_depth_to(selcx, param_env, cause.clone(), depth + 1, ty, obligations);
     }
 
@@ -2030,7 +2029,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
     } else {
         ty.map_bound(|ty| ty.into())
     };
-    if !check_args_compatible(tcx, assoc_ty.item, args) {
+    if !tcx.check_args_compatible(assoc_ty.item.def_id, args) {
         let err = Ty::new_error_with_message(
             tcx,
             obligation.cause.span,
diff --git a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
index 3b33f6e6144..279d96dec72 100644
--- a/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/type_op/normalize.rs
@@ -15,7 +15,7 @@ where
     type QueryResponse = T;
 
     fn try_fast_path(_tcx: TyCtxt<'tcx>, key: &ParamEnvAnd<'tcx, Self>) -> Option<T> {
-        if !key.value.value.has_projections() { Some(key.value.value) } else { None }
+        if !key.value.value.has_aliases() { Some(key.value.value) } else { None }
     }
 
     fn perform_query(
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index 3fbe8e39d1e..aa4ab9c7ee9 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -60,6 +60,20 @@ use rustc_middle::ty::print::with_no_trimmed_paths;
 mod candidate_assembly;
 mod confirmation;
 
+/// Whether to consider the binder of higher ranked goals for the `leak_check` when
+/// evaluating higher-ranked goals. See #119820 for more info.
+///
+/// While this is a bit hacky, it is necessary to match the behavior of the new solver:
+/// We eagerly instantiate binders in the new solver, outside of candidate selection, so
+/// the leak check inside of candidates does not consider any bound vars from the higher
+/// ranked goal. However, we do exit the binder once we're completely finished with a goal,
+/// so the leak-check can be used in evaluate by causing nested higher-ranked goals to fail.
+#[derive(Debug, Copy, Clone)]
+enum LeakCheckHigherRankedGoal {
+    No,
+    Yes,
+}
+
 #[derive(Clone, Debug, Eq, PartialEq, Hash)]
 pub enum IntercrateAmbiguityCause<'tcx> {
     DownstreamCrate { trait_ref: ty::TraitRef<'tcx>, self_ty: Option<Ty<'tcx>> },
@@ -384,7 +398,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     let mut no_candidates_apply = true;
 
                     for c in candidate_set.vec.iter() {
-                        if self.evaluate_candidate(stack, c)?.may_apply() {
+                        if self
+                            .evaluate_candidate(stack, c, LeakCheckHigherRankedGoal::No)?
+                            .may_apply()
+                        {
                             no_candidates_apply = false;
                             break;
                         }
@@ -455,7 +472,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         // is needed for specialization. Propagate overflow if it occurs.
         let mut candidates = candidates
             .into_iter()
-            .map(|c| match self.evaluate_candidate(stack, &c) {
+            .map(|c| match self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::No) {
                 Ok(eval) if eval.may_apply() => {
                     Ok(Some(EvaluatedCandidate { candidate: c, evaluation: eval }))
                 }
@@ -545,7 +562,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         obligation: &PredicateObligation<'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
         debug_assert!(!self.infcx.next_trait_solver());
-        self.evaluation_probe(|this| {
+        self.evaluation_probe(|this, _outer_universe| {
             let goal =
                 this.infcx.resolve_vars_if_possible((obligation.predicate, obligation.param_env));
             let mut result = this.evaluate_predicate_recursively(
@@ -561,13 +578,18 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         })
     }
 
+    /// Computes the evaluation result of `op`, discarding any constraints.
+    ///
+    /// This also runs for leak check to allow higher ranked region errors to impact
+    /// selection. By default it checks for leaks from all universes created inside of
+    /// `op`, but this can be overwritten if necessary.
     fn evaluation_probe(
         &mut self,
-        op: impl FnOnce(&mut Self) -> Result<EvaluationResult, OverflowError>,
+        op: impl FnOnce(&mut Self, &mut ty::UniverseIndex) -> Result<EvaluationResult, OverflowError>,
     ) -> Result<EvaluationResult, OverflowError> {
         self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
-            let outer_universe = self.infcx.universe();
-            let result = op(self)?;
+            let mut outer_universe = self.infcx.universe();
+            let result = op(self, &mut outer_universe)?;
 
             match self.infcx.leak_check(outer_universe, Some(snapshot)) {
                 Ok(()) => {}
@@ -586,9 +608,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         })
     }
 
-    /// Evaluates the predicates in `predicates` recursively. Note that
-    /// this applies projections in the predicates, and therefore
+    /// Evaluates the predicates in `predicates` recursively. This may
+    /// guide inference. If this is not desired, run it inside of a
     /// is run within an inference probe.
+    /// `probe`.
     #[instrument(skip(self, stack), level = "debug")]
     fn evaluate_predicates_recursively<'o, I>(
         &mut self,
@@ -883,7 +906,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                     .infcx
                                     .at(&obligation.cause, obligation.param_env)
                                     .trace(c1, c2)
-                                    .eq(DefineOpaqueTypes::No, a.args, b.args)
+                                    // Can define opaque types as this is only reachable with
+                                    // `generic_const_exprs`
+                                    .eq(DefineOpaqueTypes::Yes, a.args, b.args)
                                 {
                                     return self.evaluate_predicates_recursively(
                                         previous_stack,
@@ -896,7 +921,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                                 if let Ok(InferOk { obligations, value: () }) = self
                                     .infcx
                                     .at(&obligation.cause, obligation.param_env)
-                                    .eq(DefineOpaqueTypes::No, c1, c2)
+                                    // Can define opaque types as this is only reachable with
+                                    // `generic_const_exprs`
+                                    .eq(DefineOpaqueTypes::Yes, c1, c2)
                                 {
                                     return self.evaluate_predicates_recursively(
                                         previous_stack,
@@ -926,7 +953,9 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                     match (evaluate(c1), evaluate(c2)) {
                         (Ok(c1), Ok(c2)) => {
                             match self.infcx.at(&obligation.cause, obligation.param_env).eq(
-                                DefineOpaqueTypes::No,
+                                // Can define opaque types as this is only reachable with
+                                // `generic_const_exprs`
+                                DefineOpaqueTypes::Yes,
                                 c1,
                                 c2,
                             ) {
@@ -959,7 +988,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 ty::PredicateKind::Ambiguous => Ok(EvaluatedToAmbig),
                 ty::PredicateKind::Clause(ty::ClauseKind::ConstArgHasType(ct, ty)) => {
                     match self.infcx.at(&obligation.cause, obligation.param_env).eq(
-                        DefineOpaqueTypes::No,
+                        // Only really excercised by generic_const_exprs
+                        DefineOpaqueTypes::Yes,
                         ct.ty(),
                         ty,
                     ) {
@@ -1030,7 +1060,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             // so we will try to normalize the obligation and evaluate again.
             // we will replace it with new solver in the future.
             if EvaluationResult::EvaluatedToErr == result
-                && fresh_trait_pred.has_projections()
+                && fresh_trait_pred.has_aliases()
                 && fresh_trait_pred.is_global()
             {
                 let mut nested_obligations = Vec::new();
@@ -1194,7 +1224,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         }
 
         match self.candidate_from_obligation(stack) {
-            Ok(Some(c)) => self.evaluate_candidate(stack, &c),
+            Ok(Some(c)) => self.evaluate_candidate(stack, &c, LeakCheckHigherRankedGoal::Yes),
             Ok(None) => Ok(EvaluatedToAmbig),
             Err(Overflow(OverflowError::Canonical)) => Err(OverflowError::Canonical),
             Err(..) => Ok(EvaluatedToErr),
@@ -1219,6 +1249,10 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
     /// Further evaluates `candidate` to decide whether all type parameters match and whether nested
     /// obligations are met. Returns whether `candidate` remains viable after this further
     /// scrutiny.
+    ///
+    /// Depending on the value of [LeakCheckHigherRankedGoal], we may ignore the binder of the goal
+    /// when eagerly detecting higher ranked region errors via the `leak_check`. See that enum for
+    /// more info.
     #[instrument(
         level = "debug",
         skip(self, stack),
@@ -1229,10 +1263,25 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         &mut self,
         stack: &TraitObligationStack<'o, 'tcx>,
         candidate: &SelectionCandidate<'tcx>,
+        leak_check_higher_ranked_goal: LeakCheckHigherRankedGoal,
     ) -> Result<EvaluationResult, OverflowError> {
-        let mut result = self.evaluation_probe(|this| {
-            let candidate = (*candidate).clone();
-            match this.confirm_candidate(stack.obligation, candidate) {
+        let mut result = self.evaluation_probe(|this, outer_universe| {
+            // We eagerly instantiate higher ranked goals to prevent universe errors
+            // from impacting candidate selection. This matches the behavior of the new
+            // solver. This slightly weakens type inference.
+            //
+            // In case there are no unresolved type or const variables this
+            // should still not be necessary to select a unique impl as any overlap
+            // relying on a universe error from higher ranked goals should have resulted
+            // in an overlap error in coherence.
+            let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
+            let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
+            match leak_check_higher_ranked_goal {
+                LeakCheckHigherRankedGoal::No => *outer_universe = self.infcx.universe(),
+                LeakCheckHigherRankedGoal::Yes => {}
+            }
+
+            match this.confirm_candidate(&obligation, candidate.clone()) {
                 Ok(selection) => {
                     debug!(?selection);
                     this.evaluate_predicates_recursively(
@@ -1657,8 +1706,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
         stack: &TraitObligationStack<'o, 'tcx>,
         where_clause_trait_ref: ty::PolyTraitRef<'tcx>,
     ) -> Result<EvaluationResult, OverflowError> {
-        self.evaluation_probe(|this| {
-            match this.match_where_clause_trait_ref(stack.obligation, where_clause_trait_ref) {
+        self.evaluation_probe(|this, outer_universe| {
+            // Eagerly instantiate higher ranked goals.
+            //
+            // See the comment in `evaluate_candidate` to see why.
+            let p = self.infcx.enter_forall_and_leak_universe(stack.obligation.predicate);
+            let obligation = stack.obligation.with(this.tcx(), ty::Binder::dummy(p));
+            *outer_universe = self.infcx.universe();
+            match this.match_where_clause_trait_ref(&obligation, where_clause_trait_ref) {
                 Ok(obligations) => this.evaluate_predicates_recursively(stack.list(), obligations),
                 Err(()) => Ok(EvaluatedToErr),
             }
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
index 43c750ebbb5..46a0a4eb5ef 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/mod.rs
@@ -247,7 +247,12 @@ fn fulfill_implication<'tcx>(
     // do the impls unify? If not, no specialization.
     let Ok(InferOk { obligations: more_obligations, .. }) = infcx
         .at(&ObligationCause::dummy(), param_env)
-        .eq(DefineOpaqueTypes::No, source_trait, target_trait)
+        // Ok to use `Yes`, as all the generic params are already replaced by inference variables,
+        // which will match the opaque type no matter if it is defining or not.
+        // Any concrete type that would match the opaque would already be handled by coherence rules,
+        // and thus either be ok to match here and already have errored, or it won't match, in which
+        // case there is no issue anyway.
+        .eq(DefineOpaqueTypes::Yes, source_trait, target_trait)
     else {
         debug!("fulfill_implication: {:?} does not unify with {:?}", source_trait, target_trait);
         return Err(());
@@ -402,10 +407,6 @@ fn report_conflicting_impls<'tcx>(
         impl_span: Span,
         err: &mut Diag<'_, G>,
     ) {
-        if (overlap.trait_ref, overlap.self_ty).references_error() {
-            err.downgrade_to_delayed_bug();
-        }
-
         match tcx.span_of_impl(overlap.with_impl) {
             Ok(span) => {
                 err.span_label(span, "first implementation here");
@@ -458,6 +459,11 @@ fn report_conflicting_impls<'tcx>(
         )
     });
 
+    // Don't report overlap errors if the header references error
+    if let Err(err) = (overlap.trait_ref, overlap.self_ty).error_reported() {
+        return Err(err);
+    }
+
     match used_to_be_allowed {
         None => {
             let reported = if overlap.with_impl.is_local()
diff --git a/compiler/rustc_trait_selection/src/traits/util.rs b/compiler/rustc_trait_selection/src/traits/util.rs
index 466a53d8ce0..d29fc7921bc 100644
--- a/compiler/rustc_trait_selection/src/traits/util.rs
+++ b/compiler/rustc_trait_selection/src/traits/util.rs
@@ -344,48 +344,6 @@ pub enum TupleArgumentsFlag {
     No,
 }
 
-// Verify that the trait item and its implementation have compatible args lists
-pub fn check_args_compatible<'tcx>(
-    tcx: TyCtxt<'tcx>,
-    assoc_item: ty::AssocItem,
-    args: ty::GenericArgsRef<'tcx>,
-) -> bool {
-    fn check_args_compatible_inner<'tcx>(
-        tcx: TyCtxt<'tcx>,
-        generics: &'tcx ty::Generics,
-        args: &'tcx [ty::GenericArg<'tcx>],
-    ) -> bool {
-        if generics.count() != args.len() {
-            return false;
-        }
-
-        let (parent_args, own_args) = args.split_at(generics.parent_count);
-
-        if let Some(parent) = generics.parent
-            && let parent_generics = tcx.generics_of(parent)
-            && !check_args_compatible_inner(tcx, parent_generics, parent_args)
-        {
-            return false;
-        }
-
-        for (param, arg) in std::iter::zip(&generics.params, own_args) {
-            match (&param.kind, arg.unpack()) {
-                (ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
-                | (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
-                | (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
-                _ => return false,
-            }
-        }
-
-        true
-    }
-
-    let generics = tcx.generics_of(assoc_item.def_id);
-    // Chop off any additional args (RPITIT) args
-    let args = &args[0..generics.count().min(args.len())];
-    check_args_compatible_inner(tcx, generics, args)
-}
-
 /// Executes `f` on `value` after replacing all escaping bound variables with placeholders
 /// and then replaces these placeholders with the original bound variables in the result.
 ///
diff --git a/compiler/rustc_trait_selection/src/traits/wf.rs b/compiler/rustc_trait_selection/src/traits/wf.rs
index 7941a8fe95c..a44a5ae0e6b 100644
--- a/compiler/rustc_trait_selection/src/traits/wf.rs
+++ b/compiler/rustc_trait_selection/src/traits/wf.rs
@@ -647,6 +647,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
     fn visit_ty(&mut self, t: <TyCtxt<'tcx> as ty::Interner>::Ty) -> Self::Result {
         debug!("wf bounds for t={:?} t.kind={:#?}", t, t.kind());
 
+        let tcx = self.tcx();
+
         match *t.kind() {
             ty::Bool
             | ty::Char
@@ -707,6 +709,14 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
             }
 
             ty::FnDef(did, args) => {
+                // HACK: Check the return type of function definitions for
+                // well-formedness to mostly fix #84533. This is still not
+                // perfect and there may be ways to abuse the fact that we
+                // ignore requirements with escaping bound vars. That's a
+                // more general issue however.
+                let fn_sig = tcx.fn_sig(did).instantiate(tcx, args);
+                fn_sig.output().skip_binder().visit_with(self);
+
                 let obligations = self.nominal_obligations(did, args);
                 self.out.extend(obligations);
             }
@@ -716,7 +726,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 if !r.has_escaping_bound_vars() && !rty.has_escaping_bound_vars() {
                     let cause = self.cause(traits::ReferenceOutlivesReferent(t));
                     self.out.push(traits::Obligation::with_depth(
-                        self.tcx(),
+                        tcx,
                         cause,
                         self.recursion_depth,
                         self.param_env,
@@ -805,12 +815,12 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 // obligations that don't refer to Self and
                 // checking those
 
-                let defer_to_coercion = self.tcx().features().object_safe_for_dispatch;
+                let defer_to_coercion = tcx.features().object_safe_for_dispatch;
 
                 if !defer_to_coercion {
                     if let Some(principal) = data.principal_def_id() {
                         self.out.push(traits::Obligation::with_depth(
-                            self.tcx(),
+                            tcx,
                             self.cause(traits::WellFormed(None)),
                             self.recursion_depth,
                             self.param_env,
@@ -835,7 +845,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
             ty::Infer(_) => {
                 let cause = self.cause(traits::WellFormed(None));
                 self.out.push(traits::Obligation::with_depth(
-                    self.tcx(),
+                    tcx,
                     cause,
                     self.recursion_depth,
                     self.param_env,
@@ -850,6 +860,8 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
     }
 
     fn visit_const(&mut self, c: <TyCtxt<'tcx> as ty::Interner>::Const) -> Self::Result {
+        let tcx = self.tcx();
+
         match c.kind() {
             ty::ConstKind::Unevaluated(uv) => {
                 if !c.has_escaping_bound_vars() {
@@ -861,7 +873,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                     ));
                     let cause = self.cause(traits::WellFormed(None));
                     self.out.push(traits::Obligation::with_depth(
-                        self.tcx(),
+                        tcx,
                         cause,
                         self.recursion_depth,
                         self.param_env,
@@ -873,7 +885,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 let cause = self.cause(traits::WellFormed(None));
 
                 self.out.push(traits::Obligation::with_depth(
-                    self.tcx(),
+                    tcx,
                     cause,
                     self.recursion_depth,
                     self.param_env,
@@ -895,7 +907,7 @@ impl<'a, 'tcx> TypeVisitor<TyCtxt<'tcx>> for WfPredicates<'a, 'tcx> {
                 ));
                 let cause = self.cause(traits::WellFormed(None));
                 self.out.push(traits::Obligation::with_depth(
-                    self.tcx(),
+                    tcx,
                     cause,
                     self.recursion_depth,
                     self.param_env,
diff --git a/compiler/rustc_ty_utils/src/layout.rs b/compiler/rustc_ty_utils/src/layout.rs
index 331970ac362..509727cdeab 100644
--- a/compiler/rustc_ty_utils/src/layout.rs
+++ b/compiler/rustc_ty_utils/src/layout.rs
@@ -8,7 +8,9 @@ use rustc_middle::ty::layout::{
     IntegerExt, LayoutCx, LayoutError, LayoutOf, TyAndLayout, MAX_SIMD_LANES,
 };
 use rustc_middle::ty::print::with_no_trimmed_paths;
-use rustc_middle::ty::{self, AdtDef, EarlyBinder, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt};
+use rustc_middle::ty::{
+    self, AdtDef, EarlyBinder, FieldDef, GenericArgsRef, Ty, TyCtxt, TypeVisitableExt,
+};
 use rustc_session::{DataTypeKind, FieldInfo, FieldKind, SizeKind, VariantInfo};
 use rustc_span::sym;
 use rustc_span::symbol::Symbol;
@@ -239,9 +241,9 @@ fn layout_of_uncached<'tcx>(
 
         // Arrays and slices.
         ty::Array(element, mut count) => {
-            if count.has_projections() {
+            if count.has_aliases() {
                 count = tcx.normalize_erasing_regions(param_env, count);
-                if count.has_projections() {
+                if count.has_aliases() {
                     return Err(error(cx, LayoutError::Unknown(ty)));
                 }
             }
@@ -377,7 +379,7 @@ fn layout_of_uncached<'tcx>(
             }
 
             // Type of the first ADT field:
-            let f0_ty = fields[FieldIdx::from_u32(0)].ty(tcx, args);
+            let f0_ty = fields[FieldIdx::ZERO].ty(tcx, args);
 
             // Heterogeneous SIMD vectors are not supported:
             // (should be caught by typeck)
@@ -506,6 +508,40 @@ fn layout_of_uncached<'tcx>(
                 ));
             }
 
+            let err_if_unsized = |field: &FieldDef, err_msg: &str| {
+                let field_ty = tcx.type_of(field.did);
+                let is_unsized = tcx
+                    .try_instantiate_and_normalize_erasing_regions(args, cx.param_env, field_ty)
+                    .map(|f| !f.is_sized(tcx, cx.param_env))
+                    .map_err(|e| {
+                        error(
+                            cx,
+                            LayoutError::NormalizationFailure(field_ty.instantiate_identity(), e),
+                        )
+                    })?;
+
+                if is_unsized {
+                    cx.tcx.dcx().span_delayed_bug(tcx.def_span(def.did()), err_msg.to_owned());
+                    Err(error(cx, LayoutError::Unknown(ty)))
+                } else {
+                    Ok(())
+                }
+            };
+
+            if def.is_struct() {
+                if let Some((_, fields_except_last)) =
+                    def.non_enum_variant().fields.raw.split_last()
+                {
+                    for f in fields_except_last {
+                        err_if_unsized(f, "only the last field of a struct can be unsized")?;
+                    }
+                }
+            } else {
+                for f in def.all_fields() {
+                    err_if_unsized(f, &format!("{}s cannot have unsized fields", def.descr()))?;
+                }
+            }
+
             let get_discriminant_type =
                 |min, max| Integer::repr_discr(tcx, ty, &def.repr(), min, max);
 
diff --git a/compiler/rustc_ty_utils/src/opaque_types.rs b/compiler/rustc_ty_utils/src/opaque_types.rs
index fc16edc6d13..a652bb78116 100644
--- a/compiler/rustc_ty_utils/src/opaque_types.rs
+++ b/compiler/rustc_ty_utils/src/opaque_types.rs
@@ -7,7 +7,6 @@ use rustc_middle::ty::util::{CheckRegions, NotUniqueParam};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_middle::ty::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
 use rustc_span::Span;
-use rustc_trait_selection::traits::check_args_compatible;
 
 use crate::errors::{DuplicateArg, NotParam};
 
@@ -250,7 +249,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for OpaqueTypeCollector<'tcx> {
                                 ty::GenericArgs::identity_for_item(self.tcx, parent),
                             );
 
-                            if check_args_compatible(self.tcx, assoc, impl_args) {
+                            if self.tcx.check_args_compatible(assoc.def_id, impl_args) {
                                 self.tcx
                                     .type_of(assoc.def_id)
                                     .instantiate(self.tcx, impl_args)
diff --git a/compiler/rustc_ty_utils/src/sig_types.rs b/compiler/rustc_ty_utils/src/sig_types.rs
index 63654a453dd..19c092c5ddf 100644
--- a/compiler/rustc_ty_utils/src/sig_types.rs
+++ b/compiler/rustc_ty_utils/src/sig_types.rs
@@ -13,6 +13,7 @@ pub trait SpannedTypeVisitor<'tcx> {
     fn visit(&mut self, span: Span, value: impl TypeVisitable<TyCtxt<'tcx>>) -> Self::Result;
 }
 
+#[instrument(level = "trace", skip(tcx, visitor))]
 pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
     tcx: TyCtxt<'tcx>,
     item: LocalDefId,
@@ -36,7 +37,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
             for (hir, ty) in hir_sig.inputs.iter().zip(ty_sig.inputs().iter()) {
                 try_visit!(visitor.visit(hir.span, ty.map_bound(|x| *x)));
             }
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+            for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
                 try_visit!(visitor.visit(span, pred));
             }
         }
@@ -54,7 +55,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
                 // Associated types in traits don't necessarily have a type that we can visit
                 try_visit!(visitor.visit(ty.span, tcx.type_of(item).instantiate_identity()));
             }
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+            for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
                 try_visit!(visitor.visit(span, pred));
             }
         }
@@ -76,7 +77,7 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
                 let ty = field.ty(tcx, args);
                 try_visit!(visitor.visit(span, ty));
             }
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+            for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
                 try_visit!(visitor.visit(span, pred));
             }
         }
@@ -95,12 +96,12 @@ pub fn walk_types<'tcx, V: SpannedTypeVisitor<'tcx>>(
                 _ => tcx.def_span(item),
             };
             try_visit!(visitor.visit(span, tcx.type_of(item).instantiate_identity()));
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+            for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
                 try_visit!(visitor.visit(span, pred));
             }
         }
         DefKind::TraitAlias | DefKind::Trait => {
-            for (pred, span) in tcx.predicates_of(item).instantiate_identity(tcx) {
+            for (pred, span) in tcx.explicit_predicates_of(item).instantiate_identity(tcx) {
                 try_visit!(visitor.visit(span, pred));
             }
         }
diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs
index cd199222d90..997b410f819 100644
--- a/compiler/rustc_type_ir/src/flags.rs
+++ b/compiler/rustc_type_ir/src/flags.rs
@@ -78,8 +78,10 @@ bitflags! {
         /// Does this have `ConstKind::Unevaluated`?
         const HAS_CT_PROJECTION           = 1 << 14;
 
-        /// Could this type be normalized further?
-        const HAS_PROJECTION              = TypeFlags::HAS_TY_PROJECTION.bits()
+        /// Does this have `Alias` or `ConstKind::Unevaluated`?
+        ///
+        /// Rephrased, could this term be normalized further?
+        const HAS_ALIASES              = TypeFlags::HAS_TY_PROJECTION.bits()
                                           | TypeFlags::HAS_TY_WEAK.bits()
                                           | TypeFlags::HAS_TY_OPAQUE.bits()
                                           | TypeFlags::HAS_TY_INHERENT.bits()
diff --git a/compiler/rustc_type_ir/src/lib.rs b/compiler/rustc_type_ir/src/lib.rs
index c01baa58ae7..45e22b12a8b 100644
--- a/compiler/rustc_type_ir/src/lib.rs
+++ b/compiler/rustc_type_ir/src/lib.rs
@@ -314,7 +314,7 @@ rustc_index::newtype_index! {
 }
 
 impl UniverseIndex {
-    pub const ROOT: UniverseIndex = UniverseIndex::from_u32(0);
+    pub const ROOT: UniverseIndex = UniverseIndex::ZERO;
 
     /// Returns the "next" universe index in order -- this new index
     /// is considered to extend all previous universes. This
diff --git a/compiler/rustc_type_ir/src/visit.rs b/compiler/rustc_type_ir/src/visit.rs
index 839e75dba4c..d6a3f9f0749 100644
--- a/compiler/rustc_type_ir/src/visit.rs
+++ b/compiler/rustc_type_ir/src/visit.rs
@@ -223,8 +223,8 @@ pub trait TypeVisitableExt<I: Interner>: TypeVisitable<I> {
         self.has_vars_bound_at_or_above(ty::INNERMOST)
     }
 
-    fn has_projections(&self) -> bool {
-        self.has_type_flags(TypeFlags::HAS_PROJECTION)
+    fn has_aliases(&self) -> bool {
+        self.has_type_flags(TypeFlags::HAS_ALIASES)
     }
 
     fn has_inherent_projections(&self) -> bool {
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 0d866f27dad..8f77a19fc0e 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -971,6 +971,7 @@ pub enum PointerCoercion {
 
 #[derive(Copy, Clone, Debug, Eq, PartialEq)]
 pub enum CastKind {
+    // FIXME(smir-rename): rename this to PointerExposeProvenance
     PointerExposeAddress,
     PointerWithExposedProvenance,
     PointerCoercion(PointerCoercion),
diff --git a/library/alloc/benches/vec_deque_append.rs b/library/alloc/benches/vec_deque_append.rs
index 5825bdc355f..30b6e600e5a 100644
--- a/library/alloc/benches/vec_deque_append.rs
+++ b/library/alloc/benches/vec_deque_append.rs
@@ -5,6 +5,11 @@ const WARMUP_N: usize = 100;
 const BENCH_N: usize = 1000;
 
 fn main() {
+    if cfg!(miri) {
+        // Don't benchmark Miri...
+        // (Due to bootstrap quirks, this gets picked up by `x.py miri library/alloc --no-doc`.)
+        return;
+    }
     let a: VecDeque<i32> = (0..VECDEQUE_LEN).collect();
     let b: VecDeque<i32> = (0..VECDEQUE_LEN).collect();
 
diff --git a/library/alloc/src/lib.miri.rs b/library/alloc/src/lib.miri.rs
new file mode 100644
index 00000000000..89d7f49f55d
--- /dev/null
+++ b/library/alloc/src/lib.miri.rs
@@ -0,0 +1,4 @@
+//! Grep bootstrap for `MIRI_REPLACE_LIBRS_IF_NOT_TEST` to learn what this is about.
+#![no_std]
+extern crate alloc as realalloc;
+pub use realalloc::*;
diff --git a/library/core/src/clone.rs b/library/core/src/clone.rs
index d448c5338fc..44ae72bcd26 100644
--- a/library/core/src/clone.rs
+++ b/library/core/src/clone.rs
@@ -227,10 +227,13 @@ mod impls {
     impl_clone! {
         usize u8 u16 u32 u64 u128
         isize i8 i16 i32 i64 i128
-        f16 f32 f64 f128
+        f32 f64
         bool char
     }
 
+    #[cfg(not(bootstrap))]
+    impl_clone! { f16 f128 }
+
     #[unstable(feature = "never_type", issue = "35121")]
     impl Clone for ! {
         #[inline]
diff --git a/library/core/src/cmp.rs b/library/core/src/cmp.rs
index fa218600ed9..81bba927554 100644
--- a/library/core/src/cmp.rs
+++ b/library/core/src/cmp.rs
@@ -1497,9 +1497,12 @@ mod impls {
     }
 
     partial_eq_impl! {
-        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f16 f32 f64 f128
+        bool char usize u8 u16 u32 u64 u128 isize i8 i16 i32 i64 i128 f32 f64
     }
 
+    #[cfg(not(bootstrap))]
+    partial_eq_impl! { f16 f128 }
+
     macro_rules! eq_impl {
         ($($t:ty)*) => ($(
             #[stable(feature = "rust1", since = "1.0.0")]
@@ -1550,7 +1553,10 @@ mod impls {
         }
     }
 
-    partial_ord_impl! { f16 f32 f64 f128 }
+    partial_ord_impl! { f32 f64 }
+
+    #[cfg(not(bootstrap))]
+    partial_ord_impl! { f16 f128 }
 
     macro_rules! ord_impl {
         ($($t:ty)*) => ($(
diff --git a/library/core/src/fmt/mod.rs b/library/core/src/fmt/mod.rs
index e880d5758ec..287f6c23c89 100644
--- a/library/core/src/fmt/mod.rs
+++ b/library/core/src/fmt/mod.rs
@@ -2438,8 +2438,8 @@ impl Display for char {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<T: ?Sized> Pointer for *const T {
     fn fmt(&self, f: &mut Formatter<'_>) -> Result {
-        // Cast is needed here because `.expose_addr()` requires `T: Sized`.
-        pointer_fmt_inner((*self as *const ()).expose_addr(), f)
+        // Cast is needed here because `.expose_provenance()` requires `T: Sized`.
+        pointer_fmt_inner((*self as *const ()).expose_provenance(), f)
     }
 }
 
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index 614b4b589d3..eeff4ec609a 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -540,6 +540,10 @@ extern "rust-intrinsic" {
     /// `T` must be a vector of pointers.
     ///
     /// `U` must be a vector of `usize` with the same length as `T`.
+    #[cfg(not(bootstrap))]
+    #[rustc_nounwind]
+    pub fn simd_expose_provenance<T, U>(ptr: T) -> U;
+    #[cfg(bootstrap)]
     #[rustc_nounwind]
     pub fn simd_expose_addr<T, U>(ptr: T) -> U;
 
@@ -661,4 +665,6 @@ extern "rust-intrinsic" {
 }
 
 #[cfg(bootstrap)]
+pub use simd_expose_addr as simd_expose_provenance;
+#[cfg(bootstrap)]
 pub use simd_from_exposed_addr as simd_with_exposed_provenance;
diff --git a/library/core/src/lib.miri.rs b/library/core/src/lib.miri.rs
new file mode 100644
index 00000000000..5c1027f20ba
--- /dev/null
+++ b/library/core/src/lib.miri.rs
@@ -0,0 +1,4 @@
+//! Grep bootstrap for `MIRI_REPLACE_LIBRS_IF_NOT_TEST` to learn what this is about.
+#![no_std]
+extern crate core as realcore;
+pub use realcore::*;
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 0cc3ad1ead7..ba19ca1f45d 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -205,6 +205,8 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(not(bootstrap), feature(f128))]
+#![cfg_attr(not(bootstrap), feature(f16))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
@@ -229,8 +231,6 @@
 #![feature(doc_notable_trait)]
 #![feature(effects)]
 #![feature(extern_types)]
-#![feature(f128)]
-#![feature(f16)]
 #![feature(freeze_impls)]
 #![feature(fundamental)]
 #![feature(generic_arg_infer)]
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 1d073a6d649..fb97b3bfa09 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -422,11 +422,17 @@ marker_impls! {
     Copy for
         usize, u8, u16, u32, u64, u128,
         isize, i8, i16, i32, i64, i128,
-        f16, f32, f64, f128,
+        f32, f64,
         bool, char,
         {T: ?Sized} *const T,
         {T: ?Sized} *mut T,
+}
 
+#[cfg(not(bootstrap))]
+marker_impls! {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    Copy for
+        f16, f128,
 }
 
 #[unstable(feature = "never_type", issue = "35121")]
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index e5713ee89df..01db050e666 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -136,7 +136,7 @@ impl<T: ?Sized> *const T {
     #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
     #[deprecated(
         since = "1.67.0",
-        note = "replaced by the `expose_addr` method, or update your code \
+        note = "replaced by the `expose_provenance` method, or update your code \
             to follow the strict provenance rules using its APIs"
     )]
     #[inline(always)]
@@ -187,7 +187,7 @@ impl<T: ?Sized> *const T {
     ///
     /// If using those APIs is not possible because there is no way to preserve a pointer with the
     /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
-    /// or [`expose_addr`][pointer::expose_addr] and [`with_exposed_provenance`][with_exposed_provenance]
+    /// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
     /// instead. However, note that this makes your code less portable and less amenable to tools
     /// that check for compliance with the Rust memory model.
     ///
@@ -210,8 +210,8 @@ impl<T: ?Sized> *const T {
         unsafe { mem::transmute(self.cast::<()>()) }
     }
 
-    /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future
-    /// use in [`with_exposed_provenance`][].
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`with_exposed_provenance`][] and returns the "address" portion.
     ///
     /// This is equivalent to `self as usize`, which semantically discards *provenance* and
     /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
@@ -238,7 +238,7 @@ impl<T: ?Sized> *const T {
     #[must_use]
     #[inline(always)]
     #[unstable(feature = "exposed_provenance", issue = "95228")]
-    pub fn expose_addr(self) -> usize {
+    pub fn expose_provenance(self) -> usize {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         self.cast::<()>() as usize
     }
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index 9b5da935e07..25a06f121cd 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -2,6 +2,7 @@
 
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
+use crate::marker::Freeze;
 
 /// Provides the pointer metadata type of any pointed-to type.
 ///
@@ -57,7 +58,7 @@ pub trait Pointee {
     // NOTE: Keep trait bounds in `static_assert_expected_bounds_for_metadata`
     // in `library/core/src/ptr/metadata.rs`
     // in sync with those here:
-    type Metadata: fmt::Debug + Copy + Send + Sync + Ord + Hash + Unpin;
+    type Metadata: fmt::Debug + Copy + Send + Sync + Ord + Hash + Unpin + Freeze;
 }
 
 /// Pointers to types implementing this trait alias are “thin”.
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index 28df2b04c88..f12ab3d50cd 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -340,8 +340,8 @@
 //! clear where a satisfying unambiguous semantics can be defined for Exposed Provenance.
 //! Furthermore, Exposed Provenance will not work (well) with tools like [Miri] and [CHERI].
 //!
-//! Exposed Provenance is provided by the [`expose_addr`] and [`with_exposed_provenance`] methods, which
-//! are meant to replace `as` casts between pointers and integers. [`expose_addr`] is a lot like
+//! Exposed Provenance is provided by the [`expose_provenance`] and [`with_exposed_provenance`] methods,
+//! which are meant to replace `as` casts between pointers and integers. [`expose_provenance`] is a lot like
 //! [`addr`], but additionally adds the provenance of the pointer to a global list of 'exposed'
 //! provenances. (This list is purely conceptual, it exists for the purpose of specifying Rust but
 //! is not materialized in actual executions, except in tools like [Miri].) [`with_exposed_provenance`]
@@ -355,9 +355,9 @@
 //! there is *no* previously 'exposed' provenance that justifies the way the returned pointer will
 //! be used, the program has undefined behavior.
 //!
-//! Using [`expose_addr`] or [`with_exposed_provenance`] (or the `as` casts) means that code is
+//! Using [`expose_provenance`] or [`with_exposed_provenance`] (or the `as` casts) means that code is
 //! *not* following Strict Provenance rules. The goal of the Strict Provenance experiment is to
-//! determine how far one can get in Rust without the use of [`expose_addr`] and
+//! determine how far one can get in Rust without the use of [`expose_provenance`] and
 //! [`with_exposed_provenance`], and to encourage code to be written with Strict Provenance APIs only.
 //! Maximizing the amount of such code is a major win for avoiding specification complexity and to
 //! facilitate adoption of tools like [CHERI] and [Miri] that can be a big help in increasing the
@@ -374,7 +374,7 @@
 //! [`map_addr`]: pointer::map_addr
 //! [`addr`]: pointer::addr
 //! [`ptr::dangling`]: core::ptr::dangling
-//! [`expose_addr`]: pointer::expose_addr
+//! [`expose_provenance`]: pointer::expose_provenance
 //! [`with_exposed_provenance`]: with_exposed_provenance
 //! [Miri]: https://github.com/rust-lang/miri
 //! [CHERI]: https://www.cl.cam.ac.uk/research/security/ctsrd/cheri/
@@ -663,7 +663,7 @@ pub const fn dangling_mut<T>() -> *mut T {
 ///
 /// This is a more rigorously specified alternative to `addr as *const T`. The provenance of the
 /// returned pointer is that of *any* pointer that was previously exposed by passing it to
-/// [`expose_addr`][pointer::expose_addr], or a `ptr as usize` cast. In addition, memory which is
+/// [`expose_provenance`][pointer::expose_provenance], or a `ptr as usize` cast. In addition, memory which is
 /// outside the control of the Rust abstract machine (MMIO registers, for example) is always
 /// considered to be exposed, so long as this memory is disjoint from memory that will be used by
 /// the abstract machine such as the stack, heap, and statics.
@@ -711,7 +711,7 @@ where
 ///
 /// This is a more rigorously specified alternative to `addr as *mut T`. The provenance of the
 /// returned pointer is that of *any* pointer that was previously passed to
-/// [`expose_addr`][pointer::expose_addr] or a `ptr as usize` cast. If there is no previously
+/// [`expose_provenance`][pointer::expose_provenance] or a `ptr as usize` cast. If there is no previously
 /// 'exposed' provenance that justifies the way this pointer will be used, the program has undefined
 /// behavior. Note that there is no algorithm that decides which provenance will be used. You can
 /// think of this as "guessing" the right provenance, and the guess will be "maximally in your
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 042658fa35f..41e5ba67458 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -142,7 +142,7 @@ impl<T: ?Sized> *mut T {
     #[unstable(feature = "ptr_to_from_bits", issue = "91126")]
     #[deprecated(
         since = "1.67.0",
-        note = "replaced by the `expose_addr` method, or update your code \
+        note = "replaced by the `expose_provenance` method, or update your code \
             to follow the strict provenance rules using its APIs"
     )]
     #[inline(always)]
@@ -194,7 +194,7 @@ impl<T: ?Sized> *mut T {
     ///
     /// If using those APIs is not possible because there is no way to preserve a pointer with the
     /// required provenance, then Strict Provenance might not be for you. Use pointer-integer casts
-    /// or [`expose_addr`][pointer::expose_addr] and [`with_exposed_provenance`][with_exposed_provenance]
+    /// or [`expose_provenance`][pointer::expose_provenance] and [`with_exposed_provenance`][with_exposed_provenance]
     /// instead. However, note that this makes your code less portable and less amenable to tools
     /// that check for compliance with the Rust memory model.
     ///
@@ -217,8 +217,8 @@ impl<T: ?Sized> *mut T {
         unsafe { mem::transmute(self.cast::<()>()) }
     }
 
-    /// Gets the "address" portion of the pointer, and 'exposes' the "provenance" part for future
-    /// use in [`with_exposed_provenance`][].
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`with_exposed_provenance`][] and returns the "address" portion.
     ///
     /// This is equivalent to `self as usize`, which semantically discards *provenance* and
     /// *address-space* information. Furthermore, this (like the `as` cast) has the implicit
@@ -242,10 +242,9 @@ impl<T: ?Sized> *mut T {
     /// API and its claimed semantics are part of [Exposed Provenance][super#exposed-provenance].
     ///
     /// [`with_exposed_provenance_mut`]: with_exposed_provenance_mut
-    #[must_use]
     #[inline(always)]
     #[unstable(feature = "exposed_provenance", issue = "95228")]
-    pub fn expose_addr(self) -> usize {
+    pub fn expose_provenance(self) -> usize {
         // FIXME(strict_provenance_magic): I am magic and should be a compiler intrinsic.
         self.cast::<()>() as usize
     }
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 175c27662d0..8c5e5ecf5fe 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -38,6 +38,7 @@
 #![feature(duration_constructors)]
 #![feature(exact_size_is_empty)]
 #![feature(extern_types)]
+#![feature(freeze)]
 #![feature(flt2dec)]
 #![feature(fmt_internals)]
 #![feature(float_minimum_maximum)]
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index f0656f997fd..2c82eda9a58 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -1,4 +1,5 @@
 use core::cell::RefCell;
+use core::marker::Freeze;
 use core::mem::{self, MaybeUninit};
 use core::num::NonZero;
 use core::ptr;
@@ -841,7 +842,7 @@ fn ptr_metadata_bounds() {
     fn static_assert_expected_bounds_for_metadata<Meta>()
     where
         // Keep this in sync with the associated type in `library/core/src/ptr/metadata.rs`
-        Meta: Debug + Copy + Send + Sync + Ord + std::hash::Hash + Unpin,
+        Meta: Debug + Copy + Send + Sync + Ord + std::hash::Hash + Unpin + Freeze,
     {
     }
 }
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
index 4d2fe999ca6..0f1719206c9 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/const_ptr.rs
@@ -50,9 +50,9 @@ pub trait SimdConstPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::with_addr`] on each element.
     fn with_addr(self, addr: Self::Usize) -> Self;
 
-    /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
-    /// in [`Self::with_exposed_provenance`].
-    fn expose_addr(self) -> Self::Usize;
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`Self::with_exposed_provenance`] and returns the "address" portion.
+    fn expose_provenance(self) -> Self::Usize;
 
     /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
     ///
@@ -131,9 +131,9 @@ where
     }
 
     #[inline]
-    fn expose_addr(self) -> Self::Usize {
+    fn expose_provenance(self) -> Self::Usize {
         // Safety: `self` is a pointer vector
-        unsafe { core::intrinsics::simd::simd_expose_addr(self) }
+        unsafe { core::intrinsics::simd::simd_expose_provenance(self) }
     }
 
     #[inline]
diff --git a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
index b3437b9c499..7ba996d149c 100644
--- a/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
+++ b/library/portable-simd/crates/core_simd/src/simd/ptr/mut_ptr.rs
@@ -47,9 +47,9 @@ pub trait SimdMutPtr: Copy + Sealed {
     /// Equivalent to calling [`pointer::with_addr`] on each element.
     fn with_addr(self, addr: Self::Usize) -> Self;
 
-    /// Gets the "address" portion of the pointer, and "exposes" the provenance part for future use
-    /// in [`Self::with_exposed_provenance`].
-    fn expose_addr(self) -> Self::Usize;
+    /// Exposes the "provenance" part of the pointer for future use in
+    /// [`Self::with_exposed_provenance`] and returns the "address" portion.
+    fn expose_provenance(self) -> Self::Usize;
 
     /// Convert an address back to a pointer, picking up a previously "exposed" provenance.
     ///
@@ -128,9 +128,9 @@ where
     }
 
     #[inline]
-    fn expose_addr(self) -> Self::Usize {
+    fn expose_provenance(self) -> Self::Usize {
         // Safety: `self` is a pointer vector
-        unsafe { core::intrinsics::simd::simd_expose_addr(self) }
+        unsafe { core::intrinsics::simd::simd_expose_provenance(self) }
     }
 
     #[inline]
diff --git a/library/portable-simd/crates/core_simd/tests/pointers.rs b/library/portable-simd/crates/core_simd/tests/pointers.rs
index 5984fdae2f9..90bfc5d5fd6 100644
--- a/library/portable-simd/crates/core_simd/tests/pointers.rs
+++ b/library/portable-simd/crates/core_simd/tests/pointers.rs
@@ -32,10 +32,10 @@ macro_rules! common_tests {
                 );
             }
 
-            fn expose_addr<const LANES: usize>() {
+            fn expose_provenance<const LANES: usize>() {
                 test_helpers::test_unary_elementwise(
-                    &Simd::<*$constness u32, LANES>::expose_addr,
-                    &<*$constness u32>::expose_addr,
+                    &Simd::<*$constness u32, LANES>::expose_provenance,
+                    &<*$constness u32>::expose_provenance,
                     &|_| true,
                 );
             }
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index e04bf69ef51..01c449563ee 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1360,7 +1360,7 @@ impl Literal {
     }
 
     /// Byte character literal.
-    #[unstable(feature = "proc_macro_byte_character", issue = "115268")]
+    #[stable(feature = "proc_macro_byte_character", since = "CURRENT_RUSTC_VERSION")]
     pub fn byte_character(byte: u8) -> Literal {
         let string = [byte].escape_ascii().to_string();
         Literal::new(bridge::LitKind::Byte, &string, None)
@@ -1374,7 +1374,7 @@ impl Literal {
     }
 
     /// C string literal.
-    #[unstable(feature = "proc_macro_c_str_literals", issue = "119750")]
+    #[stable(feature = "proc_macro_c_str_literals", since = "CURRENT_RUSTC_VERSION")]
     pub fn c_string(string: &CStr) -> Literal {
         let string = string.to_bytes().escape_ascii().to_string();
         Literal::new(bridge::LitKind::CStr, &string, None)
diff --git a/library/std/build.rs b/library/std/build.rs
index ee3f3612d2e..7a47b52e8e4 100644
--- a/library/std/build.rs
+++ b/library/std/build.rs
@@ -22,6 +22,7 @@ fn main() {
         || target_os == "ios"
         || target_os == "tvos"
         || target_os == "watchos"
+        || target_os == "visionos"
         || target_os == "windows"
         || target_os == "fuchsia"
         || (target_vendor == "fortanix" && target_env == "sgx")
diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs
index 9017ba79714..b1102b440e0 100644
--- a/library/std/src/fs.rs
+++ b/library/std/src/fs.rs
@@ -37,7 +37,7 @@ use crate::time::SystemTime;
 ///
 /// # Examples
 ///
-/// Creates a new file and write bytes to it (you can also use [`write()`]):
+/// Creates a new file and write bytes to it (you can also use [`write`]):
 ///
 /// ```no_run
 /// use std::fs::File;
@@ -2018,7 +2018,7 @@ pub fn rename<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::Result<()>
 /// the length of the `to` file as reported by `metadata`.
 ///
 /// If you want to copy the contents of one file to another and you’re
-/// working with [`File`]s, see the [`io::copy()`] function.
+/// working with [`File`]s, see the [`io::copy`](io::copy()) function.
 ///
 /// # Platform-specific behavior
 ///
diff --git a/library/std/src/fs/tests.rs b/library/std/src/fs/tests.rs
index 65dec3863cc..6a92832fcdb 100644
--- a/library/std/src/fs/tests.rs
+++ b/library/std/src/fs/tests.rs
@@ -1644,8 +1644,8 @@ fn test_file_times() {
     use crate::os::macos::fs::FileTimesExt;
     #[cfg(target_os = "tvos")]
     use crate::os::tvos::fs::FileTimesExt;
-    #[cfg(target_os = "tvos")]
-    use crate::os::tvos::fs::FileTimesExt;
+    #[cfg(target_os = "visionos")]
+    use crate::os::visionos::fs::FileTimesExt;
     #[cfg(target_os = "watchos")]
     use crate::os::watchos::fs::FileTimesExt;
     #[cfg(windows)]
@@ -1662,6 +1662,7 @@ fn test_file_times() {
         target_os = "macos",
         target_os = "ios",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "tvos",
     ))]
     let created = SystemTime::UNIX_EPOCH + Duration::from_secs(32123);
@@ -1670,6 +1671,7 @@ fn test_file_times() {
         target_os = "macos",
         target_os = "ios",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "tvos",
     ))]
     {
@@ -1701,6 +1703,7 @@ fn test_file_times() {
         target_os = "macos",
         target_os = "ios",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "tvos",
     ))]
     {
@@ -1709,7 +1712,13 @@ fn test_file_times() {
 }
 
 #[test]
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    target_os = "tvos",
+    target_os = "watchos",
+    target_os = "visionos"
+))]
 fn test_file_times_pre_epoch_with_nanos() {
     #[cfg(target_os = "ios")]
     use crate::os::ios::fs::FileTimesExt;
@@ -1717,6 +1726,8 @@ fn test_file_times_pre_epoch_with_nanos() {
     use crate::os::macos::fs::FileTimesExt;
     #[cfg(target_os = "tvos")]
     use crate::os::tvos::fs::FileTimesExt;
+    #[cfg(target_os = "visionos")]
+    use crate::os::visionos::fs::FileTimesExt;
     #[cfg(target_os = "watchos")]
     use crate::os::watchos::fs::FileTimesExt;
 
diff --git a/library/std/src/lib.miri.rs b/library/std/src/lib.miri.rs
new file mode 100644
index 00000000000..1f9bfb5b1b5
--- /dev/null
+++ b/library/std/src/lib.miri.rs
@@ -0,0 +1,4 @@
+//! Grep bootstrap for `MIRI_REPLACE_LIBRS_IF_NOT_TEST` to learn what this is about.
+#![no_std]
+extern crate std as realstd;
+pub use realstd::*;
diff --git a/library/std/src/os/mod.rs b/library/std/src/os/mod.rs
index bebf3a797d8..ca3584e82f9 100644
--- a/library/std/src/os/mod.rs
+++ b/library/std/src/os/mod.rs
@@ -149,6 +149,8 @@ pub mod solid;
 pub(crate) mod tvos;
 #[cfg(target_os = "uefi")]
 pub mod uefi;
+#[cfg(target_os = "visionos")]
+pub(crate) mod visionos;
 #[cfg(target_os = "vita")]
 pub mod vita;
 #[cfg(target_os = "vxworks")]
diff --git a/library/std/src/os/unix/mod.rs b/library/std/src/os/unix/mod.rs
index b0633fd7bfc..d7a622012a5 100644
--- a/library/std/src/os/unix/mod.rs
+++ b/library/std/src/os/unix/mod.rs
@@ -79,6 +79,8 @@ mod platform {
     pub use crate::os::solaris::*;
     #[cfg(target_os = "tvos")]
     pub use crate::os::tvos::*;
+    #[cfg(target_os = "visionos")]
+    pub use crate::os::visionos::*;
     #[cfg(target_os = "vita")]
     pub use crate::os::vita::*;
     #[cfg(target_os = "vxworks")]
diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs
index 28c1188677b..16d9cd915ac 100644
--- a/library/std/src/os/unix/net/mod.rs
+++ b/library/std/src/os/unix/net/mod.rs
@@ -20,6 +20,7 @@ mod tests;
     target_os = "ios",
     target_os = "tvos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
@@ -46,6 +47,7 @@ pub use self::stream::*;
     target_os = "ios",
     target_os = "tvos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "macos",
     target_os = "netbsd",
     target_os = "openbsd",
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index 9b01d232611..82b24dca1c4 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -7,6 +7,7 @@
     target_os = "tvos",
     target_os = "macos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "netbsd",
     target_os = "openbsd",
     target_os = "nto"
@@ -234,6 +235,7 @@ impl UnixStream {
         target_os = "tvos",
         target_os = "macos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "netbsd",
         target_os = "openbsd",
         target_os = "nto"
diff --git a/library/std/src/os/unix/net/ucred.rs b/library/std/src/os/unix/net/ucred.rs
index 4c915c57906..3a752a53a50 100644
--- a/library/std/src/os/unix/net/ucred.rs
+++ b/library/std/src/os/unix/net/ucred.rs
@@ -35,7 +35,13 @@ pub(super) use self::impl_linux::peer_cred;
 ))]
 pub(super) use self::impl_bsd::peer_cred;
 
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    target_os = "tvos",
+    target_os = "watchos",
+    target_os = "visionos"
+))]
 pub(super) use self::impl_mac::peer_cred;
 
 #[cfg(any(target_os = "linux", target_os = "android"))]
@@ -97,7 +103,13 @@ mod impl_bsd {
     }
 }
 
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    target_os = "tvos",
+    target_os = "watchos",
+    target_os = "visionos"
+))]
 mod impl_mac {
     use super::UCred;
     use crate::os::unix::io::AsRawFd;
diff --git a/library/std/src/os/unix/net/ucred/tests.rs b/library/std/src/os/unix/net/ucred/tests.rs
index dd99ecdd819..2a0797877c6 100644
--- a/library/std/src/os/unix/net/ucred/tests.rs
+++ b/library/std/src/os/unix/net/ucred/tests.rs
@@ -11,6 +11,7 @@ use libc::{getegid, geteuid, getpid};
     target_os = "tvos",
     target_os = "macos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "openbsd"
 ))]
 fn test_socket_pair() {
@@ -32,6 +33,7 @@ fn test_socket_pair() {
     target_os = "ios",
     target_os = "macos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "tvos",
 ))]
 fn test_socket_pair_pids(arg: Type) -> RetType {
diff --git a/library/std/src/os/visionos/fs.rs b/library/std/src/os/visionos/fs.rs
new file mode 100644
index 00000000000..e5df4de0b7f
--- /dev/null
+++ b/library/std/src/os/visionos/fs.rs
@@ -0,0 +1,160 @@
+#![stable(feature = "metadata_ext", since = "1.1.0")]
+
+use crate::fs::{self, Metadata};
+use crate::sealed::Sealed;
+use crate::sys_common::{AsInner, AsInnerMut, IntoInner};
+use crate::time::SystemTime;
+
+#[allow(deprecated)]
+use super::raw;
+
+/// OS-specific extensions to [`fs::Metadata`].
+///
+/// [`fs::Metadata`]: crate::fs::Metadata
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+pub trait MetadataExt {
+    /// Gain a reference to the underlying `stat` structure which contains
+    /// the raw information returned by the OS.
+    ///
+    /// The contents of the returned `stat` are **not** consistent across
+    /// Unix platforms. The `os::unix::fs::MetadataExt` trait contains the
+    /// cross-Unix abstractions contained within the raw stat.
+    #[stable(feature = "metadata_ext", since = "1.1.0")]
+    #[deprecated(
+        since = "1.8.0",
+        note = "deprecated in favor of the accessor \
+                methods of this trait"
+    )]
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat;
+
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_dev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ino(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mode(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_nlink(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_uid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gid(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_rdev(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_size(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_atime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_mtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_ctime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_birthtime(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_birthtime_nsec(&self) -> i64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blksize(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_blocks(&self) -> u64;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_flags(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_gen(&self) -> u32;
+    #[stable(feature = "metadata_ext2", since = "1.8.0")]
+    fn st_lspare(&self) -> u32;
+}
+
+#[stable(feature = "metadata_ext", since = "1.1.0")]
+impl MetadataExt for Metadata {
+    #[allow(deprecated)]
+    fn as_raw_stat(&self) -> &raw::stat {
+        unsafe { &*(self.as_inner().as_inner() as *const libc::stat as *const raw::stat) }
+    }
+    fn st_dev(&self) -> u64 {
+        self.as_inner().as_inner().st_dev as u64
+    }
+    fn st_ino(&self) -> u64 {
+        self.as_inner().as_inner().st_ino as u64
+    }
+    fn st_mode(&self) -> u32 {
+        self.as_inner().as_inner().st_mode as u32
+    }
+    fn st_nlink(&self) -> u64 {
+        self.as_inner().as_inner().st_nlink as u64
+    }
+    fn st_uid(&self) -> u32 {
+        self.as_inner().as_inner().st_uid as u32
+    }
+    fn st_gid(&self) -> u32 {
+        self.as_inner().as_inner().st_gid as u32
+    }
+    fn st_rdev(&self) -> u64 {
+        self.as_inner().as_inner().st_rdev as u64
+    }
+    fn st_size(&self) -> u64 {
+        self.as_inner().as_inner().st_size as u64
+    }
+    fn st_atime(&self) -> i64 {
+        self.as_inner().as_inner().st_atime as i64
+    }
+    fn st_atime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_atime_nsec as i64
+    }
+    fn st_mtime(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime as i64
+    }
+    fn st_mtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_mtime_nsec as i64
+    }
+    fn st_ctime(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime as i64
+    }
+    fn st_ctime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_ctime_nsec as i64
+    }
+    fn st_birthtime(&self) -> i64 {
+        self.as_inner().as_inner().st_birthtime as i64
+    }
+    fn st_birthtime_nsec(&self) -> i64 {
+        self.as_inner().as_inner().st_birthtime_nsec as i64
+    }
+    fn st_blksize(&self) -> u64 {
+        self.as_inner().as_inner().st_blksize as u64
+    }
+    fn st_blocks(&self) -> u64 {
+        self.as_inner().as_inner().st_blocks as u64
+    }
+    fn st_gen(&self) -> u32 {
+        self.as_inner().as_inner().st_gen as u32
+    }
+    fn st_flags(&self) -> u32 {
+        self.as_inner().as_inner().st_flags as u32
+    }
+    fn st_lspare(&self) -> u32 {
+        self.as_inner().as_inner().st_lspare as u32
+    }
+}
+
+/// OS-specific extensions to [`fs::FileTimes`].
+#[stable(feature = "file_set_times", since = "1.75.0")]
+pub trait FileTimesExt: Sealed {
+    /// Set the creation time of a file.
+    #[stable(feature = "file_set_times", since = "1.75.0")]
+    fn set_created(self, t: SystemTime) -> Self;
+}
+
+#[stable(feature = "file_set_times", since = "1.75.0")]
+impl FileTimesExt for fs::FileTimes {
+    fn set_created(mut self, t: SystemTime) -> Self {
+        self.as_inner_mut().set_created(t.into_inner());
+        self
+    }
+}
diff --git a/library/std/src/os/visionos/mod.rs b/library/std/src/os/visionos/mod.rs
new file mode 100644
index 00000000000..f4b061ffda8
--- /dev/null
+++ b/library/std/src/os/visionos/mod.rs
@@ -0,0 +1,6 @@
+//! visionos-specific definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+
+pub mod fs;
+pub mod raw;
diff --git a/library/std/src/os/visionos/raw.rs b/library/std/src/os/visionos/raw.rs
new file mode 100644
index 00000000000..2b3eca6f493
--- /dev/null
+++ b/library/std/src/os/visionos/raw.rs
@@ -0,0 +1,83 @@
+//! visionos-specific raw type definitions
+
+#![stable(feature = "raw_ext", since = "1.1.0")]
+#![deprecated(
+    since = "1.8.0",
+    note = "these type aliases are no longer supported by \
+            the standard library, the `libc` crate on \
+            crates.io should be used instead for the correct \
+            definitions"
+)]
+#![allow(deprecated)]
+
+use crate::os::raw::c_long;
+
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blkcnt_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type blksize_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type dev_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type ino_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type mode_t = u32;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type nlink_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type off_t = u64;
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub type time_t = i64;
+
+#[stable(feature = "pthread_t", since = "1.8.0")]
+pub type pthread_t = usize;
+
+#[repr(C)]
+#[derive(Clone)]
+#[stable(feature = "raw_ext", since = "1.1.0")]
+pub struct stat {
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_dev: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mode: u16,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_nlink: u16,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ino: u64,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_uid: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gid: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_rdev: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_atime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_mtime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_ctime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_birthtime: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_birthtime_nsec: c_long,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_size: i64,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blocks: i64,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_blksize: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_flags: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_gen: u32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_lspare: i32,
+    #[stable(feature = "raw_ext", since = "1.1.0")]
+    pub st_qspare: [i64; 2],
+}
diff --git a/library/std/src/rt.rs b/library/std/src/rt.rs
index ff6e433ebce..59e118f81ab 100644
--- a/library/std/src/rt.rs
+++ b/library/std/src/rt.rs
@@ -16,8 +16,6 @@
 #![deny(unsafe_op_in_unsafe_fn)]
 #![allow(unused_macros)]
 
-use crate::ffi::CString;
-
 // Re-export some of our utilities which are expected by other crates.
 pub use crate::panicking::{begin_panic, panic_count};
 pub use core::panicking::{panic_display, panic_fmt};
@@ -96,7 +94,7 @@ unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
         sys::init(argc, argv, sigpipe);
 
         // Set up the current thread to give it the right name.
-        let thread = Thread::new(Some(rtunwrap!(Ok, CString::new("main"))));
+        let thread = Thread::new_main();
         thread::set_current(thread);
     }
 }
diff --git a/library/std/src/sys/pal/hermit/thread.rs b/library/std/src/sys/pal/hermit/thread.rs
index 62c76a74cd4..4fe6b12a95b 100644
--- a/library/std/src/sys/pal/hermit/thread.rs
+++ b/library/std/src/sys/pal/hermit/thread.rs
@@ -2,7 +2,7 @@
 
 use super::abi;
 use super::thread_local_dtor::run_dtors;
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::num::NonZero;
@@ -29,7 +29,7 @@ impl Thread {
         let p = Box::into_raw(Box::new(p));
         let tid = abi::spawn2(
             thread_start,
-            p.expose_addr(),
+            p.expose_provenance(),
             abi::Priority::into(abi::NORMAL_PRIO),
             stack,
             core_id,
@@ -71,10 +71,6 @@ impl Thread {
         // nope
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     #[inline]
     pub fn sleep(dur: Duration) {
         unsafe {
diff --git a/library/std/src/sys/pal/itron/thread.rs b/library/std/src/sys/pal/itron/thread.rs
index 1c66bd79ce4..205226ce1da 100644
--- a/library/std/src/sys/pal/itron/thread.rs
+++ b/library/std/src/sys/pal/itron/thread.rs
@@ -8,7 +8,7 @@ use super::{
 };
 use crate::{
     cell::UnsafeCell,
-    ffi::{CStr, CString},
+    ffi::CStr,
     hint, io,
     mem::ManuallyDrop,
     num::NonZero,
@@ -181,7 +181,7 @@ impl Thread {
             abi::acre_tsk(&abi::T_CTSK {
                 // Activate this task immediately
                 tskatr: abi::TA_ACT,
-                exinf: p_inner.as_ptr().expose_addr() as abi::EXINF,
+                exinf: p_inner.as_ptr().expose_provenance() as abi::EXINF,
                 // The entry point
                 task: Some(trampoline),
                 // Inherit the calling task's base priority
@@ -204,10 +204,6 @@ impl Thread {
         // nope
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     pub fn sleep(dur: Duration) {
         for timeout in dur2reltims(dur) {
             expect_success(unsafe { abi::dly_tsk(timeout) }, &"dly_tsk");
diff --git a/library/std/src/sys/pal/mod.rs b/library/std/src/sys/pal/mod.rs
index 7c87deed371..8c75ac65299 100644
--- a/library/std/src/sys/pal/mod.rs
+++ b/library/std/src/sys/pal/mod.rs
@@ -37,12 +37,12 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "hermit")] {
         mod hermit;
         pub use self::hermit::*;
-    } else if #[cfg(target_os = "wasi")] {
-        mod wasi;
-        pub use self::wasi::*;
     } else if #[cfg(all(target_os = "wasi", target_env = "p2"))] {
         mod wasip2;
         pub use self::wasip2::*;
+    } else if #[cfg(target_os = "wasi")] {
+        mod wasi;
+        pub use self::wasi::*;
     } else if #[cfg(target_family = "wasm")] {
         mod wasm;
         pub use self::wasm::*;
diff --git a/library/std/src/sys/pal/sgx/thread.rs b/library/std/src/sys/pal/sgx/thread.rs
index ef07f6e6a26..e2df57b1a1f 100644
--- a/library/std/src/sys/pal/sgx/thread.rs
+++ b/library/std/src/sys/pal/sgx/thread.rs
@@ -1,6 +1,6 @@
 #![cfg_attr(test, allow(dead_code))] // why is this necessary?
 use super::unsupported;
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::num::NonZero;
 use crate::time::Duration;
@@ -133,10 +133,6 @@ impl Thread {
         // which succeeds as-is with the SGX target.
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     pub fn sleep(dur: Duration) {
         usercalls::wait_timeout(0, dur, || true);
     }
diff --git a/library/std/src/sys/pal/teeos/thread.rs b/library/std/src/sys/pal/teeos/thread.rs
index fb4b74ba3c3..ae2f58ca08e 100644
--- a/library/std/src/sys/pal/teeos/thread.rs
+++ b/library/std/src/sys/pal/teeos/thread.rs
@@ -1,7 +1,7 @@
 use core::convert::TryInto;
 
 use crate::cmp;
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::num::NonZero;
@@ -101,10 +101,6 @@ impl Thread {
         // contact the teeos rustzone team.
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     /// only main thread could wait for sometime in teeos
     pub fn sleep(dur: Duration) {
         let sleep_millis = dur.as_millis();
diff --git a/library/std/src/sys/pal/uefi/thread.rs b/library/std/src/sys/pal/uefi/thread.rs
index ca7b1efc269..edc736978a1 100644
--- a/library/std/src/sys/pal/uefi/thread.rs
+++ b/library/std/src/sys/pal/uefi/thread.rs
@@ -1,5 +1,5 @@
 use super::unsupported;
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::num::NonZero;
 use crate::ptr::NonNull;
@@ -23,10 +23,6 @@ impl Thread {
         // nope
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     pub fn sleep(dur: Duration) {
         let boot_services: NonNull<r_efi::efi::BootServices> =
             crate::os::uefi::env::boot_services().expect("can't sleep").cast();
diff --git a/library/std/src/sys/pal/unix/args.rs b/library/std/src/sys/pal/unix/args.rs
index 78e82d9c194..acf8100d47f 100644
--- a/library/std/src/sys/pal/unix/args.rs
+++ b/library/std/src/sys/pal/unix/args.rs
@@ -170,7 +170,13 @@ mod imp {
     }
 }
 
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    target_os = "watchos",
+    target_os = "visionos",
+    target_os = "tvos"
+))]
 mod imp {
     use super::Args;
     use crate::ffi::CStr;
@@ -211,7 +217,12 @@ mod imp {
     // for i in (0..[args count])
     //      res.push([args objectAtIndex:i])
     // res
-    #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+    #[cfg(any(
+        target_os = "ios",
+        target_os = "tvos",
+        target_os = "watchos",
+        target_os = "visionos"
+    ))]
     pub fn args() -> Args {
         use crate::ffi::{c_char, c_void, OsString};
         use crate::mem;
diff --git a/library/std/src/sys/pal/unix/env.rs b/library/std/src/sys/pal/unix/env.rs
index 3d4ba509829..fb1f868644d 100644
--- a/library/std/src/sys/pal/unix/env.rs
+++ b/library/std/src/sys/pal/unix/env.rs
@@ -53,6 +53,17 @@ pub mod os {
     pub const EXE_EXTENSION: &str = "";
 }
 
+#[cfg(target_os = "visionos")]
+pub mod os {
+    pub const FAMILY: &str = "unix";
+    pub const OS: &str = "visionos";
+    pub const DLL_PREFIX: &str = "lib";
+    pub const DLL_SUFFIX: &str = ".dylib";
+    pub const DLL_EXTENSION: &str = "dylib";
+    pub const EXE_SUFFIX: &str = "";
+    pub const EXE_EXTENSION: &str = "";
+}
+
 #[cfg(target_os = "freebsd")]
 pub mod os {
     pub const FAMILY: &str = "unix";
diff --git a/library/std/src/sys/pal/unix/fd.rs b/library/std/src/sys/pal/unix/fd.rs
index 9d8cc18b838..48e83b04ef4 100644
--- a/library/std/src/sys/pal/unix/fd.rs
+++ b/library/std/src/sys/pal/unix/fd.rs
@@ -51,6 +51,7 @@ const READ_LIMIT: usize = libc::ssize_t::MAX as usize;
     target_os = "netbsd",
     target_os = "openbsd",
     target_os = "watchos",
+    target_os = "visionos",
 ))]
 const fn max_iov() -> usize {
     libc::IOV_MAX as usize
@@ -81,6 +82,7 @@ const fn max_iov() -> usize {
     target_os = "horizon",
     target_os = "vita",
     target_os = "watchos",
+    target_os = "visionos",
 )))]
 const fn max_iov() -> usize {
     16 // The minimum value required by POSIX.
diff --git a/library/std/src/sys/pal/unix/fs.rs b/library/std/src/sys/pal/unix/fs.rs
index 99b6da60c14..96f64051cda 100644
--- a/library/std/src/sys/pal/unix/fs.rs
+++ b/library/std/src/sys/pal/unix/fs.rs
@@ -23,6 +23,7 @@ use crate::sys_common::{AsInner, AsInnerMut, FromInner, IntoInner};
     target_os = "ios",
     target_os = "tvos",
     target_os = "watchos",
+    target_os = "visionos",
 ))]
 use crate::sys::weak::syscall;
 #[cfg(any(target_os = "android", target_os = "macos", target_os = "solaris"))]
@@ -35,6 +36,7 @@ use libc::{c_int, mode_t};
     target_os = "ios",
     target_os = "tvos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "solaris",
     all(target_os = "linux", target_env = "gnu")
 ))]
@@ -377,7 +379,13 @@ pub struct FilePermissions {
 pub struct FileTimes {
     accessed: Option<SystemTime>,
     modified: Option<SystemTime>,
-    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "tvos"))]
+    #[cfg(any(
+        target_os = "macos",
+        target_os = "ios",
+        target_os = "watchos",
+        target_os = "visionos",
+        target_os = "tvos"
+    ))]
     created: Option<SystemTime>,
 }
 
@@ -555,6 +563,7 @@ impl FileAttr {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
     ))]
     pub fn created(&self) -> io::Result<SystemTime> {
         SystemTime::new(self.stat.st_birthtime as i64, self.stat.st_birthtime_nsec as i64)
@@ -567,6 +576,7 @@ impl FileAttr {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "vita",
     )))]
     pub fn created(&self) -> io::Result<SystemTime> {
@@ -647,7 +657,13 @@ impl FileTimes {
         self.modified = Some(t);
     }
 
-    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "tvos"))]
+    #[cfg(any(
+        target_os = "macos",
+        target_os = "ios",
+        target_os = "watchos",
+        target_os = "visionos",
+        target_os = "tvos"
+    ))]
     pub fn set_created(&mut self, t: SystemTime) {
         self.created = Some(t);
     }
@@ -938,6 +954,7 @@ impl DirEntry {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "linux",
         target_os = "emscripten",
         target_os = "android",
@@ -974,6 +991,7 @@ impl DirEntry {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "netbsd",
         target_os = "openbsd",
         target_os = "freebsd",
@@ -993,6 +1011,7 @@ impl DirEntry {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "netbsd",
         target_os = "openbsd",
         target_os = "freebsd",
@@ -1162,6 +1181,7 @@ impl File {
             target_os = "ios",
             target_os = "tvos",
             target_os = "watchos",
+            target_os = "visionos",
         ))]
         unsafe fn os_fsync(fd: c_int) -> c_int {
             libc::fcntl(fd, libc::F_FULLFSYNC)
@@ -1171,6 +1191,7 @@ impl File {
             target_os = "ios",
             target_os = "tvos",
             target_os = "watchos",
+            target_os = "visionos",
         )))]
         unsafe fn os_fsync(fd: c_int) -> c_int {
             libc::fsync(fd)
@@ -1186,6 +1207,7 @@ impl File {
             target_os = "ios",
             target_os = "tvos",
             target_os = "watchos",
+            target_os = "visionos",
         ))]
         unsafe fn os_datasync(fd: c_int) -> c_int {
             libc::fcntl(fd, libc::F_FULLFSYNC)
@@ -1212,6 +1234,7 @@ impl File {
             target_os = "netbsd",
             target_os = "openbsd",
             target_os = "watchos",
+            target_os = "visionos",
             target_os = "nto",
             target_os = "hurd",
         )))]
@@ -1322,7 +1345,7 @@ impl File {
                     io::ErrorKind::Unsupported,
                     "setting file times not supported",
                 ))
-            } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))] {
+            } else if #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] {
                 let mut buf = [mem::MaybeUninit::<libc::timespec>::uninit(); 3];
                 let mut num_times = 0;
                 let mut attrlist: libc::attrlist = unsafe { mem::zeroed() };
@@ -1787,6 +1810,7 @@ fn open_to_and_set_permissions(
     target_os = "ios",
     target_os = "tvos",
     target_os = "watchos",
+    target_os = "visionos",
 )))]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     let (mut reader, reader_metadata) = open_from(from)?;
@@ -1813,7 +1837,13 @@ pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     }
 }
 
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    target_os = "watchos",
+    target_os = "visionos",
+    target_os = "tvos"
+))]
 pub fn copy(from: &Path, to: &Path) -> io::Result<u64> {
     use crate::sync::atomic::{AtomicBool, Ordering};
 
diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs
index f608ae47a21..4ae76518c4f 100644
--- a/library/std/src/sys/pal/unix/mod.rs
+++ b/library/std/src/sys/pal/unix/mod.rs
@@ -83,6 +83,7 @@ pub unsafe fn init(argc: isize, argv: *const *const u8, sigpipe: u8) {
             target_os = "ios",
             target_os = "tvos",
             target_os = "watchos",
+            target_os = "visionos",
             target_os = "redox",
             target_os = "l4re",
             target_os = "horizon",
@@ -405,7 +406,7 @@ cfg_if::cfg_if! {
     } else if #[cfg(target_os = "macos")] {
         #[link(name = "System")]
         extern "C" {}
-    } else if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos"))] {
+    } else if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos"))] {
         #[link(name = "System")]
         #[link(name = "objc")]
         #[link(name = "Foundation", kind = "framework")]
diff --git a/library/std/src/sys/pal/unix/os.rs b/library/std/src/sys/pal/unix/os.rs
index 0b9c8027e6f..96492fedece 100644
--- a/library/std/src/sys/pal/unix/os.rs
+++ b/library/std/src/sys/pal/unix/os.rs
@@ -69,7 +69,8 @@ extern "C" {
             target_os = "ios",
             target_os = "tvos",
             target_os = "freebsd",
-            target_os = "watchos"
+            target_os = "watchos",
+            target_os = "visionos",
         ),
         link_name = "__error"
     )]
@@ -430,7 +431,13 @@ pub fn current_exe() -> io::Result<PathBuf> {
     Ok(PathBuf::from(OsString::from_vec(e)))
 }
 
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    target_os = "watchos",
+    target_os = "visionos",
+    target_os = "tvos"
+))]
 pub fn current_exe() -> io::Result<PathBuf> {
     unsafe {
         let mut sz: u32 = 0;
@@ -699,6 +706,7 @@ pub fn home_dir() -> Option<PathBuf> {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "emscripten",
         target_os = "redox",
         target_os = "vxworks",
@@ -714,6 +722,7 @@ pub fn home_dir() -> Option<PathBuf> {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "emscripten",
         target_os = "redox",
         target_os = "vxworks",
diff --git a/library/std/src/sys/pal/unix/process/process_unix.rs b/library/std/src/sys/pal/unix/process/process_unix.rs
index f017d39d804..e798510f9e6 100644
--- a/library/std/src/sys/pal/unix/process/process_unix.rs
+++ b/library/std/src/sys/pal/unix/process/process_unix.rs
@@ -14,6 +14,7 @@ use crate::os::unix::io::AsRawFd;
 #[cfg(any(
     target_os = "macos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "tvos",
     target_os = "freebsd",
     all(target_os = "linux", target_env = "gnu"),
diff --git a/library/std/src/sys/pal/unix/rand.rs b/library/std/src/sys/pal/unix/rand.rs
index c9ed6825f6c..de087d98eb8 100644
--- a/library/std/src/sys/pal/unix/rand.rs
+++ b/library/std/src/sys/pal/unix/rand.rs
@@ -16,6 +16,7 @@ pub fn hashmap_random_keys() -> (u64, u64) {
     not(target_os = "ios"),
     not(target_os = "tvos"),
     not(target_os = "watchos"),
+    not(target_os = "visionos"),
     not(target_os = "openbsd"),
     not(target_os = "netbsd"),
     not(target_os = "fuchsia"),
@@ -62,17 +63,23 @@ mod imp {
         unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), libc::GRND_NONBLOCK) }
     }
 
-    #[cfg(any(
-        target_os = "espidf",
-        target_os = "horizon",
-        target_os = "freebsd",
-        target_os = "dragonfly",
-        netbsd10
-    ))]
+    #[cfg(any(target_os = "espidf", target_os = "horizon", target_os = "freebsd", netbsd10))]
     fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
         unsafe { libc::getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
     }
 
+    #[cfg(target_os = "dragonfly")]
+    fn getrandom(buf: &mut [u8]) -> libc::ssize_t {
+        extern "C" {
+            fn getrandom(
+                buf: *mut libc::c_void,
+                buflen: libc::size_t,
+                flags: libc::c_uint,
+            ) -> libc::ssize_t;
+        }
+        unsafe { getrandom(buf.as_mut_ptr().cast(), buf.len(), 0) }
+    }
+
     #[cfg(not(any(
         target_os = "linux",
         target_os = "android",
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7d25c974ed3..f56e64c3505 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -1,5 +1,5 @@
 use crate::cmp;
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::num::NonZero;
@@ -150,7 +150,13 @@ impl Thread {
         }
     }
 
-    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
+    #[cfg(any(
+        target_os = "macos",
+        target_os = "ios",
+        target_os = "watchos",
+        target_os = "visionos",
+        target_os = "tvos"
+    ))]
     pub fn set_name(name: &CStr) {
         unsafe {
             let name = truncate_cstr::<{ libc::MAXTHREADNAMESIZE }>(name);
@@ -228,78 +234,6 @@ impl Thread {
         // Newlib, Emscripten, and VxWorks have no way to set a thread name.
     }
 
-    #[cfg(any(
-        target_os = "linux",
-        target_os = "freebsd",
-        target_os = "netbsd",
-        target_os = "solaris",
-        target_os = "illumos"
-    ))]
-    pub fn get_name() -> Option<CString> {
-        #[cfg(target_os = "linux")]
-        const TASK_COMM_LEN: usize = 16;
-        #[cfg(target_os = "freebsd")]
-        const TASK_COMM_LEN: usize = libc::MAXCOMLEN + 1;
-        #[cfg(any(target_os = "netbsd", target_os = "solaris", target_os = "illumos"))]
-        const TASK_COMM_LEN: usize = 32;
-        let mut name = vec![0u8; TASK_COMM_LEN];
-        let res = unsafe {
-            libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
-        };
-        if res != 0 {
-            return None;
-        }
-        name.truncate(name.iter().position(|&c| c == 0)?);
-        CString::new(name).ok()
-    }
-
-    #[cfg(any(target_os = "macos", target_os = "ios", target_os = "tvos", target_os = "watchos"))]
-    pub fn get_name() -> Option<CString> {
-        let mut name = vec![0u8; libc::MAXTHREADNAMESIZE];
-        let res = unsafe {
-            libc::pthread_getname_np(libc::pthread_self(), name.as_mut_ptr().cast(), name.len())
-        };
-        if res != 0 {
-            return None;
-        }
-        name.truncate(name.iter().position(|&c| c == 0)?);
-        CString::new(name).ok()
-    }
-
-    #[cfg(target_os = "haiku")]
-    pub fn get_name() -> Option<CString> {
-        unsafe {
-            let mut tinfo = mem::MaybeUninit::<libc::thread_info>::uninit();
-            // See BeOS teams group and threads api.
-            // https://www.haiku-os.org/legacy-docs/bebook/TheKernelKit_ThreadsAndTeams_Overview.html
-            let thread_self = libc::find_thread(ptr::null_mut());
-            let res = libc::get_thread_info(thread_self, tinfo.as_mut_ptr());
-            if res != libc::B_OK {
-                return None;
-            }
-            let info = tinfo.assume_init();
-            let name =
-                core::slice::from_raw_parts(info.name.as_ptr() as *const u8, info.name.len());
-            CStr::from_bytes_until_nul(name).map(CStr::to_owned).ok()
-        }
-    }
-
-    #[cfg(not(any(
-        target_os = "linux",
-        target_os = "freebsd",
-        target_os = "netbsd",
-        target_os = "macos",
-        target_os = "ios",
-        target_os = "tvos",
-        target_os = "watchos",
-        target_os = "haiku",
-        target_os = "solaris",
-        target_os = "illumos"
-    )))]
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     #[cfg(not(target_os = "espidf"))]
     pub fn sleep(dur: Duration) {
         let mut secs = dur.as_secs();
@@ -371,6 +305,7 @@ impl Drop for Thread {
     target_os = "ios",
     target_os = "tvos",
     target_os = "watchos",
+    target_os = "visionos",
     target_os = "nto",
     target_os = "solaris",
     target_os = "illumos",
diff --git a/library/std/src/sys/pal/unix/thread_local_dtor.rs b/library/std/src/sys/pal/unix/thread_local_dtor.rs
index e367ce5f906..1164c1782f4 100644
--- a/library/std/src/sys/pal/unix/thread_local_dtor.rs
+++ b/library/std/src/sys/pal/unix/thread_local_dtor.rs
@@ -76,7 +76,13 @@ 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(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "tvos"))]
+#[cfg(any(
+    target_os = "macos",
+    target_os = "ios",
+    target_os = "watchos",
+    target_os = "visionos",
+    target_os = "tvos"
+))]
 pub unsafe fn register_dtor(t: *mut u8, dtor: unsafe extern "C" fn(*mut u8)) {
     use crate::cell::{Cell, RefCell};
     use crate::ptr;
diff --git a/library/std/src/sys/pal/unix/thread_parking/mod.rs b/library/std/src/sys/pal/unix/thread_parking/mod.rs
index 185333c072f..3348d4b366d 100644
--- a/library/std/src/sys/pal/unix/thread_parking/mod.rs
+++ b/library/std/src/sys/pal/unix/thread_parking/mod.rs
@@ -16,6 +16,7 @@ cfg_if::cfg_if! {
             target_os = "macos",
             target_os = "ios",
             target_os = "watchos",
+            target_os = "visionos",
             target_os = "tvos",
         ),
         not(miri),
diff --git a/library/std/src/sys/pal/unix/thread_parking/pthread.rs b/library/std/src/sys/pal/unix/thread_parking/pthread.rs
index bb79cf9548e..d0ad3e2ce3e 100644
--- a/library/std/src/sys/pal/unix/thread_parking/pthread.rs
+++ b/library/std/src/sys/pal/unix/thread_parking/pthread.rs
@@ -48,6 +48,7 @@ unsafe fn wait_timeout(
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "espidf",
         target_os = "horizon",
     ))]
@@ -76,6 +77,7 @@ unsafe fn wait_timeout(
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "espidf",
         target_os = "horizon",
     )))]
@@ -124,6 +126,7 @@ impl Parker {
                 target_os = "ios",
                 target_os = "tvos",
                 target_os = "watchos",
+                target_os = "visionos",
                 target_os = "l4re",
                 target_os = "android",
                 target_os = "redox",
diff --git a/library/std/src/sys/pal/unix/time.rs b/library/std/src/sys/pal/unix/time.rs
index 0440f33ded1..e69775be8cf 100644
--- a/library/std/src/sys/pal/unix/time.rs
+++ b/library/std/src/sys/pal/unix/time.rs
@@ -90,7 +90,8 @@ impl Timespec {
             target_os = "macos",
             target_os = "ios",
             target_os = "tvos",
-            target_os = "watchos"
+            target_os = "watchos",
+            target_os = "visionos",
         ))]
         let (tv_sec, tv_nsec) =
             if (tv_sec <= 0 && tv_sec > i64::MIN) && (tv_nsec < 0 && tv_nsec > -1_000_000_000) {
@@ -278,6 +279,7 @@ impl Instant {
             target_os = "macos",
             target_os = "ios",
             target_os = "watchos",
+            target_os = "visionos",
             target_os = "tvos"
         ))]
         const clock_id: libc::clockid_t = libc::CLOCK_UPTIME_RAW;
@@ -285,6 +287,7 @@ impl Instant {
             target_os = "macos",
             target_os = "ios",
             target_os = "watchos",
+            target_os = "visionos",
             target_os = "tvos"
         )))]
         const clock_id: libc::clockid_t = libc::CLOCK_MONOTONIC;
diff --git a/library/std/src/sys/pal/unsupported/thread.rs b/library/std/src/sys/pal/unsupported/thread.rs
index d3f2fa35b92..ea939247199 100644
--- a/library/std/src/sys/pal/unsupported/thread.rs
+++ b/library/std/src/sys/pal/unsupported/thread.rs
@@ -1,5 +1,5 @@
 use super::unsupported;
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::num::NonZero;
 use crate::time::Duration;
@@ -22,10 +22,6 @@ impl Thread {
         // nope
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     pub fn sleep(_dur: Duration) {
         panic!("can't sleep");
     }
diff --git a/library/std/src/sys/pal/wasi/thread.rs b/library/std/src/sys/pal/wasi/thread.rs
index 940f0c8423a..d45fb28b67e 100644
--- a/library/std/src/sys/pal/wasi/thread.rs
+++ b/library/std/src/sys/pal/wasi/thread.rs
@@ -1,4 +1,4 @@
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::mem;
 use crate::num::NonZero;
@@ -134,10 +134,6 @@ impl Thread {
         // nope
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     pub fn sleep(dur: Duration) {
         let nanos = dur.as_nanos();
         assert!(nanos <= u64::MAX as u128);
diff --git a/library/std/src/sys/pal/wasip2/cabi_realloc.rs b/library/std/src/sys/pal/wasip2/cabi_realloc.rs
new file mode 100644
index 00000000000..820063173d6
--- /dev/null
+++ b/library/std/src/sys/pal/wasip2/cabi_realloc.rs
@@ -0,0 +1,65 @@
+//! This module contains a canonical definition of the `cabi_realloc` function
+//! for the component model.
+//!
+//! The component model's canonical ABI for representing datatypes in memory
+//! makes use of this function when transferring lists and strings, for example.
+//! This function behaves like C's `realloc` but also takes alignment into
+//! account.
+//!
+//! Components are notably not required to export this function, but nearly
+//! all components end up doing so currently. This definition in the standard
+//! library removes the need for all compilations to define this themselves.
+//!
+//! More information about the canonical ABI can be found at
+//! <https://github.com/WebAssembly/component-model/blob/main/design/mvp/CanonicalABI.md>
+//!
+//! Note that the name of this function is not standardized in the canonical ABI
+//! at this time. Instead it's a convention of the "componentization process"
+//! where a core wasm module is converted to a component to use this name.
+//! Additionally this is not the only possible definition of this function, so
+//! this is defined as a "weak" symbol. This means that other definitions are
+//! allowed to overwrite it if they are present in a compilation.
+
+use crate::alloc::{self, Layout};
+use crate::ptr;
+
+#[used]
+static FORCE_CODEGEN_OF_CABI_REALLOC: unsafe extern "C" fn(
+    *mut u8,
+    usize,
+    usize,
+    usize,
+) -> *mut u8 = cabi_realloc;
+
+#[linkage = "weak"]
+#[no_mangle]
+pub unsafe extern "C" fn cabi_realloc(
+    old_ptr: *mut u8,
+    old_len: usize,
+    align: usize,
+    new_len: usize,
+) -> *mut u8 {
+    let layout;
+    let ptr = if old_len == 0 {
+        if new_len == 0 {
+            return ptr::without_provenance_mut(align);
+        }
+        layout = Layout::from_size_align_unchecked(new_len, align);
+        alloc::alloc(layout)
+    } else {
+        debug_assert_ne!(new_len, 0, "non-zero old_len requires non-zero new_len!");
+        layout = Layout::from_size_align_unchecked(old_len, align);
+        alloc::realloc(old_ptr, layout, new_len)
+    };
+    if ptr.is_null() {
+        // Print a nice message in debug mode, but in release mode don't
+        // pull in so many dependencies related to printing so just emit an
+        // `unreachable` instruction.
+        if cfg!(debug_assertions) {
+            alloc::handle_alloc_error(layout);
+        } else {
+            super::abort_internal();
+        }
+    }
+    return ptr;
+}
diff --git a/library/std/src/sys/pal/wasip2/mod.rs b/library/std/src/sys/pal/wasip2/mod.rs
index d1d444d7b79..94aa458d2f9 100644
--- a/library/std/src/sys/pal/wasip2/mod.rs
+++ b/library/std/src/sys/pal/wasip2/mod.rs
@@ -10,8 +10,6 @@
 pub mod alloc;
 #[path = "../wasi/args.rs"]
 pub mod args;
-#[path = "../unix/cmath.rs"]
-pub mod cmath;
 #[path = "../wasi/env.rs"]
 pub mod env;
 #[path = "../wasi/fd.rs"]
@@ -28,10 +26,6 @@ pub mod io;
 pub mod net;
 #[path = "../wasi/os.rs"]
 pub mod os;
-#[path = "../unix/os_str.rs"]
-pub mod os_str;
-#[path = "../unix/path.rs"]
-pub mod path;
 #[path = "../unsupported/pipe.rs"]
 pub mod pipe;
 #[path = "../unsupported/process.rs"]
@@ -72,3 +66,5 @@ pub use helpers::decode_error_kind;
 use helpers::err2io;
 pub use helpers::hashmap_random_keys;
 pub use helpers::is_interrupted;
+
+mod cabi_realloc;
diff --git a/library/std/src/sys/pal/wasm/atomics/thread.rs b/library/std/src/sys/pal/wasm/atomics/thread.rs
index 3923ff821d9..49f936f1449 100644
--- a/library/std/src/sys/pal/wasm/atomics/thread.rs
+++ b/library/std/src/sys/pal/wasm/atomics/thread.rs
@@ -1,5 +1,4 @@
 use crate::ffi::CStr;
-use crate::ffi::CString;
 use crate::io;
 use crate::num::NonZero;
 use crate::sys::unsupported;
@@ -18,9 +17,6 @@ impl Thread {
     pub fn yield_now() {}
 
     pub fn set_name(_name: &CStr) {}
-    pub fn get_name() -> Option<CString> {
-        None
-    }
 
     pub fn sleep(dur: Duration) {
         use crate::arch::wasm32;
diff --git a/library/std/src/sys/pal/windows/stack_overflow.rs b/library/std/src/sys/pal/windows/stack_overflow.rs
index 627763da856..f93f31026f8 100644
--- a/library/std/src/sys/pal/windows/stack_overflow.rs
+++ b/library/std/src/sys/pal/windows/stack_overflow.rs
@@ -3,21 +3,12 @@
 use crate::sys::c;
 use crate::thread;
 
-use super::api;
-
-pub struct Handler;
-
-impl Handler {
-    pub unsafe fn new() -> Handler {
-        // This API isn't available on XP, so don't panic in that case and just
-        // pray it works out ok.
-        if c::SetThreadStackGuarantee(&mut 0x5000) == 0
-            && api::get_last_error().code != c::ERROR_CALL_NOT_IMPLEMENTED
-        {
-            panic!("failed to reserve stack space for exception handling");
-        }
-        Handler
-    }
+/// Reserve stack space for use in stack overflow exceptions.
+pub unsafe fn reserve_stack() {
+    let result = c::SetThreadStackGuarantee(&mut 0x5000);
+    // Reserving stack space is not critical so we allow it to fail in the released build of libstd.
+    // We still use debug assert here so that CI will test that we haven't made a mistake calling the function.
+    debug_assert_ne!(result, 0, "failed to reserve stack space for exception handling");
 }
 
 unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POINTERS) -> c::LONG {
@@ -36,9 +27,10 @@ unsafe extern "system" fn vectored_handler(ExceptionInfo: *mut c::EXCEPTION_POIN
 }
 
 pub unsafe fn init() {
-    if c::AddVectoredExceptionHandler(0, Some(vectored_handler)).is_null() {
-        panic!("failed to install exception handler");
-    }
+    let result = c::AddVectoredExceptionHandler(0, Some(vectored_handler));
+    // Similar to the above, adding the stack overflow handler is allowed to fail
+    // but a debug assert is used so CI will still test that it normally works.
+    debug_assert!(!result.is_null(), "failed to install exception handler");
     // Set the thread stack guarantee for the main thread.
-    let _h = Handler::new();
+    reserve_stack();
 }
diff --git a/library/std/src/sys/pal/windows/stack_overflow_uwp.rs b/library/std/src/sys/pal/windows/stack_overflow_uwp.rs
index afdf7f566ae..9e9b3efaf1b 100644
--- a/library/std/src/sys/pal/windows/stack_overflow_uwp.rs
+++ b/library/std/src/sys/pal/windows/stack_overflow_uwp.rs
@@ -1,11 +1,4 @@
 #![cfg_attr(test, allow(dead_code))]
 
-pub struct Handler;
-
-impl Handler {
-    pub fn new() -> Handler {
-        Handler
-    }
-}
-
+pub unsafe fn reserve_stack() {}
 pub unsafe fn init() {}
diff --git a/library/std/src/sys/pal/windows/thread.rs b/library/std/src/sys/pal/windows/thread.rs
index 80eee4e078d..c0c63c3340f 100644
--- a/library/std/src/sys/pal/windows/thread.rs
+++ b/library/std/src/sys/pal/windows/thread.rs
@@ -9,7 +9,6 @@ use crate::sys::handle::Handle;
 use crate::sys::stack_overflow;
 use crate::sys_common::FromInner;
 use crate::time::Duration;
-use alloc::ffi::CString;
 use core::ffi::c_void;
 
 use super::time::WaitableTimer;
@@ -48,9 +47,8 @@ impl Thread {
 
         extern "system" fn thread_start(main: *mut c_void) -> c::DWORD {
             unsafe {
-                // Next, set up our stack overflow handler which may get triggered if we run
-                // out of stack.
-                let _handler = stack_overflow::Handler::new();
+                // Next, reserve some stack space for if we otherwise run out of stack.
+                stack_overflow::reserve_stack();
                 // Finally, let's run some code.
                 Box::from_raw(main as *mut Box<dyn FnOnce()>)();
             }
@@ -68,29 +66,6 @@ impl Thread {
         };
     }
 
-    pub fn get_name() -> Option<CString> {
-        unsafe {
-            let mut ptr = core::ptr::null_mut();
-            let result = c::GetThreadDescription(c::GetCurrentThread(), &mut ptr);
-            if result < 0 {
-                return None;
-            }
-            let name = String::from_utf16_lossy({
-                let mut len = 0;
-                while *ptr.add(len) != 0 {
-                    len += 1;
-                }
-                core::slice::from_raw_parts(ptr, len)
-            })
-            .into_bytes();
-            // Attempt to free the memory.
-            // This should never fail but if it does then there's not much we can do about it.
-            let result = c::LocalFree(ptr.cast::<c_void>());
-            debug_assert!(result.is_null());
-            if name.is_empty() { None } else { Some(CString::from_vec_unchecked(name)) }
-        }
-    }
-
     pub fn join(self) {
         let rc = unsafe { c::WaitForSingleObject(self.handle.as_raw_handle(), c::INFINITE) };
         if rc == c::WAIT_FAILED {
diff --git a/library/std/src/sys/pal/xous/thread.rs b/library/std/src/sys/pal/xous/thread.rs
index c1fd1c0d653..da7d722cc70 100644
--- a/library/std/src/sys/pal/xous/thread.rs
+++ b/library/std/src/sys/pal/xous/thread.rs
@@ -1,4 +1,4 @@
-use crate::ffi::{CStr, CString};
+use crate::ffi::CStr;
 use crate::io;
 use crate::num::NonZero;
 use crate::os::xous::ffi::{
@@ -113,10 +113,6 @@ impl Thread {
         // nope
     }
 
-    pub fn get_name() -> Option<CString> {
-        None
-    }
-
     pub fn sleep(dur: Duration) {
         // Because the sleep server works on units of `usized milliseconds`, split
         // the messages up into these chunks. This means we may run into issues
diff --git a/library/std/src/sys/personality/gcc.rs b/library/std/src/sys/personality/gcc.rs
index 6f317131145..b0f744dd966 100644
--- a/library/std/src/sys/personality/gcc.rs
+++ b/library/std/src/sys/personality/gcc.rs
@@ -92,7 +92,7 @@ const UNWIND_DATA_REG: (i32, i32) = (4, 5); // a0, a1
 // https://github.com/gcc-mirror/gcc/blob/trunk/libgcc/unwind-c.c
 
 cfg_if::cfg_if! {
-    if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "netbsd")))] {
+    if #[cfg(all(target_arch = "arm", not(target_os = "ios"), not(target_os = "tvos"), not(target_os = "watchos"), not(target_os = "visionos"), not(target_os = "netbsd")))] {
         // ARM EHABI personality routine.
         // https://web.archive.org/web/20190728160938/https://infocenter.arm.com/help/topic/com.arm.doc.ihi0038b/IHI0038B_ehabi.pdf
         //
diff --git a/library/std/src/sys/sync/condvar/pthread.rs b/library/std/src/sys/sync/condvar/pthread.rs
index 728371685ee..0475f985078 100644
--- a/library/std/src/sys/sync/condvar/pthread.rs
+++ b/library/std/src/sys/sync/condvar/pthread.rs
@@ -34,6 +34,7 @@ impl LazyInit for AllocatedCondvar {
                 target_os = "ios",
                 target_os = "tvos",
                 target_os = "watchos",
+                target_os = "visionos",
                 target_os = "l4re",
                 target_os = "android",
                 target_os = "redox"
@@ -127,6 +128,7 @@ impl Condvar {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "android",
         target_os = "espidf",
         target_os = "horizon"
@@ -162,6 +164,7 @@ impl Condvar {
         target_os = "ios",
         target_os = "tvos",
         target_os = "watchos",
+        target_os = "visionos",
         target_os = "android",
         target_os = "espidf",
         target_os = "horizon"
diff --git a/library/std/src/sys_common/net.rs b/library/std/src/sys_common/net.rs
index 2d785064245..8c9885974b4 100644
--- a/library/std/src/sys_common/net.rs
+++ b/library/std/src/sys_common/net.rs
@@ -18,7 +18,7 @@ use crate::ffi::{c_int, c_void};
 cfg_if::cfg_if! {
     if #[cfg(any(
         target_os = "dragonfly", target_os = "freebsd",
-        target_os = "ios", target_os = "tvos", target_os = "macos", target_os = "watchos",
+        target_os = "ios", target_os = "tvos", target_os = "macos", target_os = "watchos", target_os = "visionos",
         target_os = "openbsd", target_os = "netbsd", target_os = "illumos",
         target_os = "solaris", target_os = "haiku", target_os = "l4re", target_os = "nto"))] {
         use crate::sys::net::netc::IPV6_JOIN_GROUP as IPV6_ADD_MEMBERSHIP;
diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs
index f7eb92bc61e..f792a27dd69 100644
--- a/library/std/src/thread/mod.rs
+++ b/library/std/src/thread/mod.rs
@@ -694,9 +694,7 @@ pub(crate) fn set_current(thread: Thread) {
 /// In contrast to the public `current` function, this will not panic if called
 /// from inside a TLS destructor.
 pub(crate) fn try_current() -> Option<Thread> {
-    CURRENT
-        .try_with(|current| current.get_or_init(|| Thread::new(imp::Thread::get_name())).clone())
-        .ok()
+    CURRENT.try_with(|current| current.get_or_init(|| Thread::new(None)).clone()).ok()
 }
 
 /// Gets a handle to the thread that invokes it.
@@ -1247,9 +1245,16 @@ impl ThreadId {
 // Thread
 ////////////////////////////////////////////////////////////////////////////////
 
+/// The internal representation of a `Thread`'s name.
+enum ThreadName {
+    Main,
+    Other(CString),
+    Unnamed,
+}
+
 /// The internal representation of a `Thread` handle
 struct Inner {
-    name: Option<CString>, // Guaranteed to be UTF-8
+    name: ThreadName, // Guaranteed to be UTF-8
     id: ThreadId,
     parker: Parker,
 }
@@ -1286,8 +1291,20 @@ pub struct Thread {
 
 impl Thread {
     // Used only internally to construct a thread object without spawning
-    // Panics if the name contains nuls.
     pub(crate) fn new(name: Option<CString>) -> Thread {
+        if let Some(name) = name {
+            Self::new_inner(ThreadName::Other(name))
+        } else {
+            Self::new_inner(ThreadName::Unnamed)
+        }
+    }
+
+    // Used in runtime to construct main thread
+    pub(crate) fn new_main() -> Thread {
+        Self::new_inner(ThreadName::Main)
+    }
+
+    fn new_inner(name: ThreadName) -> Thread {
         // We have to use `unsafe` here to construct the `Parker` in-place,
         // which is required for the UNIX implementation.
         //
@@ -1414,7 +1431,11 @@ impl Thread {
     }
 
     fn cname(&self) -> Option<&CStr> {
-        self.inner.name.as_deref()
+        match &self.inner.name {
+            ThreadName::Main => Some(c"main"),
+            ThreadName::Other(other) => Some(&other),
+            ThreadName::Unnamed => None,
+        }
     }
 }
 
diff --git a/library/std/src/thread/tests.rs b/library/std/src/thread/tests.rs
index 589a5fdad1d..494513f2c75 100644
--- a/library/std/src/thread/tests.rs
+++ b/library/std/src/thread/tests.rs
@@ -43,7 +43,8 @@ fn test_named_thread() {
     target_os = "macos",
     target_os = "ios",
     target_os = "tvos",
-    target_os = "watchos"
+    target_os = "watchos",
+    target_os = "visionos",
 ))]
 #[test]
 fn test_named_thread_truncation() {
@@ -69,26 +70,6 @@ fn test_named_thread_truncation() {
     result.unwrap().join().unwrap();
 }
 
-#[cfg(any(
-    all(target_os = "windows", not(target_vendor = "win7")),
-    target_os = "linux",
-    target_os = "macos",
-    target_os = "ios",
-    target_os = "tvos",
-    target_os = "watchos"
-))]
-#[test]
-fn test_get_os_named_thread() {
-    use crate::sys::thread::Thread;
-    // Spawn a new thread to avoid interfering with other tests running on this thread.
-    let handler = thread::spawn(|| {
-        let name = c"test me please";
-        Thread::set_name(name);
-        assert_eq!(name, Thread::get_name().unwrap().as_c_str());
-    });
-    handler.join().unwrap();
-}
-
 #[test]
 #[should_panic]
 fn test_invalid_named_thread() {
diff --git a/library/unwind/src/libunwind.rs b/library/unwind/src/libunwind.rs
index 0a0dc9438b3..57ce3d0fa5c 100644
--- a/library/unwind/src/libunwind.rs
+++ b/library/unwind/src/libunwind.rs
@@ -123,7 +123,7 @@ extern "C" {
 }
 
 cfg_if::cfg_if! {
-if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "netbsd", not(target_arch = "arm")))] {
+if #[cfg(any(target_os = "ios", target_os = "tvos", target_os = "watchos", target_os = "visionos", target_os = "netbsd", not(target_arch = "arm")))] {
     // Not ARM EHABI
     #[repr(C)]
     #[derive(Copy, Clone, PartialEq)]
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 30d728aa230..39add60e705 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -1038,6 +1038,7 @@ class RustBuild(object):
                 sync_dirs = "--sync ./src/tools/cargo/Cargo.toml " \
                             "--sync ./src/tools/rust-analyzer/Cargo.toml " \
                             "--sync ./compiler/rustc_codegen_cranelift/Cargo.toml " \
+                            "--sync ./compiler/rustc_codegen_gcc/Cargo.toml " \
                             "--sync ./src/bootstrap/Cargo.toml "
                 eprint('ERROR: vendoring required, but vendor directory does not exist.')
                 eprint('       Run `cargo vendor {}` to initialize the '
diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs
index ecea62140a2..b51d3e15788 100644
--- a/src/bootstrap/src/core/build_steps/dist.rs
+++ b/src/bootstrap/src/core/build_steps/dist.rs
@@ -1011,6 +1011,8 @@ impl Step for PlainSourceTarball {
                 .arg("--sync")
                 .arg(builder.src.join("./compiler/rustc_codegen_cranelift/Cargo.toml"))
                 .arg("--sync")
+                .arg(builder.src.join("./compiler/rustc_codegen_gcc/Cargo.toml"))
+                .arg("--sync")
                 .arg(builder.src.join("./src/bootstrap/Cargo.toml"))
                 // Will read the libstd Cargo.toml
                 // which uses the unstable `public-dependency` feature.
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index e461e11677f..420336fee14 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -365,10 +365,11 @@ impl Step for Llvm {
             cfg.define("LLVM_ENABLE_ZLIB", "OFF");
         }
 
-        // Are we compiling for iOS/tvOS/watchOS?
+        // Are we compiling for iOS/tvOS/watchOS/visionOS?
         if target.contains("apple-ios")
             || target.contains("apple-tvos")
             || target.contains("apple-watchos")
+            || target.contains("apple-visionos")
         {
             // These two defines prevent CMake from automatically trying to add a MacOSX sysroot, which leads to a compiler error.
             cfg.define("CMAKE_OSX_SYSROOT", "/");
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 8a79c28fc6c..bacf5f0d33c 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -595,7 +595,7 @@ impl Step for Miri {
         // This is for the tests so everything is done with the target compiler.
         let miri_sysroot = Miri::build_miri_sysroot(builder, target_compiler, target);
         builder.ensure(compile::Std::new(target_compiler, host));
-        let sysroot = builder.sysroot(target_compiler);
+        let host_sysroot = builder.sysroot(target_compiler);
 
         // # Run `cargo test`.
         // This is with the Miri crate, so it uses the host compiler.
@@ -618,7 +618,7 @@ impl Step for Miri {
 
         // miri tests need to know about the stage sysroot
         cargo.env("MIRI_SYSROOT", &miri_sysroot);
-        cargo.env("MIRI_HOST_SYSROOT", &sysroot);
+        cargo.env("MIRI_HOST_SYSROOT", &host_sysroot);
         cargo.env("MIRI", &miri);
 
         // Set the target.
@@ -681,10 +681,6 @@ impl Step for Miri {
             }
         }
 
-        // Tell `cargo miri` where to find the sysroots.
-        cargo.env("MIRI_SYSROOT", &miri_sysroot);
-        cargo.env("MIRI_HOST_SYSROOT", sysroot);
-
         // Finally, pass test-args and run everything.
         cargo.arg("--").args(builder.config.test_args());
         let mut cargo = Command::from(cargo);
@@ -2540,9 +2536,14 @@ fn prepare_cargo_test(
     //
     // Note that to run the compiler we need to run with the *host* libraries,
     // but our wrapper scripts arrange for that to be the case anyway.
-    let mut dylib_path = dylib_path();
-    dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
-    cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
+    //
+    // We skip everything on Miri as then this overwrites the libdir set up
+    // by `Cargo::new` and that actually makes things go wrong.
+    if builder.kind != Kind::Miri {
+        let mut dylib_path = dylib_path();
+        dylib_path.insert(0, PathBuf::from(&*builder.sysroot_libdir(compiler, target)));
+        cargo.env(dylib_path_var(), env::join_paths(&dylib_path).unwrap());
+    }
 
     if builder.remote_tested(target) {
         cargo.env(
@@ -2598,28 +2599,62 @@ impl Step for Crate {
         let target = self.target;
         let mode = self.mode;
 
+        // Prepare sysroot
         // See [field@compile::Std::force_recompile].
         builder.ensure(compile::Std::force_recompile(compiler, compiler.host));
 
-        if builder.config.build != target {
-            builder.ensure(compile::Std::force_recompile(compiler, target));
-            builder.ensure(RemoteCopyLibs { compiler, target });
-        }
-
         // If we're not doing a full bootstrap but we're testing a stage2
         // version of libstd, then what we're actually testing is the libstd
         // produced in stage1. Reflect that here by updating the compiler that
         // we're working with automatically.
         let compiler = builder.compiler_for(compiler.stage, compiler.host, target);
 
-        let mut cargo = builder::Cargo::new(
-            builder,
-            compiler,
-            mode,
-            SourceType::InTree,
-            target,
-            builder.kind.as_str(),
-        );
+        let mut cargo = if builder.kind == Kind::Miri {
+            if builder.top_stage == 0 {
+                eprintln!("ERROR: `x.py miri` requires stage 1 or higher");
+                std::process::exit(1);
+            }
+
+            // Build `cargo miri test` command
+            // (Implicitly prepares target sysroot)
+            let mut cargo = builder::Cargo::new(
+                builder,
+                compiler,
+                mode,
+                SourceType::InTree,
+                target,
+                "miri-test",
+            );
+            // This hack helps bootstrap run standard library tests in Miri. The issue is as
+            // follows: when running `cargo miri test` on libcore, cargo builds a local copy of core
+            // and makes it a dependency of the integration test crate. This copy duplicates all the
+            // lang items, so the build fails. (Regular testing avoids this because the sysroot is a
+            // literal copy of what `cargo build` produces, but since Miri builds its own sysroot
+            // this does not work for us.) So we need to make it so that the locally built libcore
+            // contains all the items from `core`, but does not re-define them -- we want to replace
+            // the entire crate but a re-export of the sysroot crate. We do this by swapping out the
+            // source file: if `MIRI_REPLACE_LIBRS_IF_NOT_TEST` is set and we are building a
+            // `lib.rs` file, and a `lib.miri.rs` file exists in the same folder, we build that
+            // instead. But crucially we only do that for the library, not the test builds.
+            cargo.env("MIRI_REPLACE_LIBRS_IF_NOT_TEST", "1");
+            cargo
+        } else {
+            // Also prepare a sysroot for the target.
+            if builder.config.build != target {
+                builder.ensure(compile::Std::force_recompile(compiler, target));
+                builder.ensure(RemoteCopyLibs { compiler, target });
+            }
+
+            // Build `cargo test` command
+            builder::Cargo::new(
+                builder,
+                compiler,
+                mode,
+                SourceType::InTree,
+                target,
+                builder.kind.as_str(),
+            )
+        };
 
         match mode {
             Mode::Std => {
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index c051b818328..9555be481e6 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -631,6 +631,7 @@ pub enum Kind {
     Format,
     #[value(alias = "t")]
     Test,
+    Miri,
     Bench,
     #[value(alias = "d")]
     Doc,
@@ -673,6 +674,7 @@ impl Kind {
             Kind::Fix => "fix",
             Kind::Format => "fmt",
             Kind::Test => "test",
+            Kind::Miri => "miri",
             Kind::Bench => "bench",
             Kind::Doc => "doc",
             Kind::Clean => "clean",
@@ -822,6 +824,7 @@ impl<'a> Builder<'a> {
                 // Run run-make last, since these won't pass without make on Windows
                 test::RunMake,
             ),
+            Kind::Miri => describe!(test::Crate),
             Kind::Bench => describe!(test::Crate, test::CrateLibrustc),
             Kind::Doc => describe!(
                 doc::UnstableBook,
@@ -970,6 +973,7 @@ impl<'a> Builder<'a> {
             Subcommand::Fix => (Kind::Fix, &paths[..]),
             Subcommand::Doc { .. } => (Kind::Doc, &paths[..]),
             Subcommand::Test { .. } => (Kind::Test, &paths[..]),
+            Subcommand::Miri { .. } => (Kind::Miri, &paths[..]),
             Subcommand::Bench { .. } => (Kind::Bench, &paths[..]),
             Subcommand::Dist => (Kind::Dist, &paths[..]),
             Subcommand::Install => (Kind::Install, &paths[..]),
@@ -1194,20 +1198,11 @@ impl<'a> Builder<'a> {
     }
 
     pub fn cargo_clippy_cmd(&self, run_compiler: Compiler) -> Command {
-        let initial_sysroot_bin = self.initial_rustc.parent().unwrap();
-        // Set PATH to include the sysroot bin dir so clippy can find cargo.
-        // FIXME: once rust-clippy#11944 lands on beta, set `CARGO` directly instead.
-        let path = t!(env::join_paths(
-            // The sysroot comes first in PATH to avoid using rustup's cargo.
-            std::iter::once(PathBuf::from(initial_sysroot_bin))
-                .chain(env::split_paths(&t!(env::var("PATH"))))
-        ));
-
         if run_compiler.stage == 0 {
             // `ensure(Clippy { stage: 0 })` *builds* clippy with stage0, it doesn't use the beta clippy.
             let cargo_clippy = self.build.config.download_clippy();
             let mut cmd = Command::new(cargo_clippy);
-            cmd.env("PATH", &path);
+            cmd.env("CARGO", &self.initial_cargo);
             return cmd;
         }
 
@@ -1227,7 +1222,7 @@ impl<'a> Builder<'a> {
 
         let mut cmd = Command::new(cargo_clippy);
         cmd.env(helpers::dylib_path_var(), env::join_paths(&dylib_path).unwrap());
-        cmd.env("PATH", path);
+        cmd.env("CARGO", &self.initial_cargo);
         cmd
     }
 
@@ -1235,6 +1230,7 @@ impl<'a> Builder<'a> {
         assert!(run_compiler.stage > 0, "miri can not be invoked at stage 0");
         let build_compiler = self.compiler(run_compiler.stage - 1, self.build.build);
 
+        // Prepare the tools
         let miri = self.ensure(tool::Miri {
             compiler: build_compiler,
             target: self.build.build,
@@ -1245,7 +1241,7 @@ impl<'a> Builder<'a> {
             target: self.build.build,
             extra_features: Vec::new(),
         });
-        // Invoke cargo-miri, make sure we can find miri and cargo.
+        // Invoke cargo-miri, make sure it can find miri and cargo.
         let mut cmd = Command::new(cargo_miri);
         cmd.env("MIRI", &miri);
         cmd.env("CARGO", &self.initial_cargo);
@@ -1308,7 +1304,11 @@ impl<'a> Builder<'a> {
         if cmd == "clippy" {
             cargo = self.cargo_clippy_cmd(compiler);
             cargo.arg(cmd);
-        } else if let Some(subcmd) = cmd.strip_prefix("miri-") {
+        } else if let Some(subcmd) = cmd.strip_prefix("miri") {
+            // Command must be "miri-X".
+            let subcmd = subcmd
+                .strip_prefix("-")
+                .unwrap_or_else(|| panic!("expected `miri-$subcommand`, but got {}", cmd));
             cargo = self.cargo_miri_cmd(compiler);
             cargo.arg("miri").arg(subcmd);
         } else {
@@ -1711,6 +1711,15 @@ impl<'a> Builder<'a> {
             cargo.env("RUSTC_WRAPPER_REAL", existing_wrapper);
         }
 
+        // If this is for `miri-test`, prepare the sysroots.
+        if cmd == "miri-test" {
+            self.ensure(compile::Std::new(compiler, compiler.host));
+            let host_sysroot = self.sysroot(compiler);
+            let miri_sysroot = test::Miri::build_miri_sysroot(self, compiler, target);
+            cargo.env("MIRI_SYSROOT", &miri_sysroot);
+            cargo.env("MIRI_HOST_SYSROOT", &host_sysroot);
+        }
+
         cargo.env(profile_var("STRIP"), self.config.rust_strip.to_string());
 
         if let Some(stack_protector) = &self.config.rust_stack_protector {
@@ -2093,12 +2102,10 @@ impl<'a> Builder<'a> {
             rustdocflags.arg("--cfg=parallel_compiler");
         }
 
-        // set rustc args passed from command line
-        let rustc_args =
-            self.config.cmd.rustc_args().iter().map(|s| s.to_string()).collect::<Vec<_>>();
-        if !rustc_args.is_empty() {
-            cargo.env("RUSTFLAGS", &rustc_args.join(" "));
-        }
+        // Pass the value of `--rustc-args` from test command. If it's not a test command, this won't set anything.
+        self.config.cmd.rustc_args().iter().for_each(|v| {
+            rustflags.arg(v);
+        });
 
         Cargo {
             command: cargo,
diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs
index 0f977640559..178df633cec 100644
--- a/src/bootstrap/src/core/builder/tests.rs
+++ b/src/bootstrap/src/core/builder/tests.rs
@@ -599,7 +599,6 @@ mod dist {
             pass: None,
             run: None,
             only_modified: false,
-            skip: vec![],
             extra_checks: None,
         };
 
@@ -664,7 +663,6 @@ mod dist {
             no_fail_fast: false,
             doc: true,
             no_doc: false,
-            skip: vec![],
             bless: false,
             force_rerun: false,
             compare_mode: None,
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index 67cde01ccdb..96dec975250 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -2022,7 +2022,7 @@ impl Config {
             Subcommand::Build { .. } => {
                 flags.stage.or(build_stage).unwrap_or(if download_rustc { 2 } else { 1 })
             }
-            Subcommand::Test { .. } => {
+            Subcommand::Test { .. } | Subcommand::Miri { .. } => {
                 flags.stage.or(test_stage).unwrap_or(if download_rustc { 2 } else { 1 })
             }
             Subcommand::Bench { .. } => flags.stage.or(bench_stage).unwrap_or(2),
@@ -2044,6 +2044,7 @@ impl Config {
         if flags.stage.is_none() && crate::CiEnv::current() != crate::CiEnv::None {
             match config.cmd {
                 Subcommand::Test { .. }
+                | Subcommand::Miri { .. }
                 | Subcommand::Doc { .. }
                 | Subcommand::Build { .. }
                 | Subcommand::Bench { .. }
@@ -2099,7 +2100,9 @@ impl Config {
 
     pub(crate) fn test_args(&self) -> Vec<&str> {
         let mut test_args = match self.cmd {
-            Subcommand::Test { ref test_args, .. } | Subcommand::Bench { ref test_args, .. } => {
+            Subcommand::Test { ref test_args, .. }
+            | Subcommand::Bench { ref test_args, .. }
+            | Subcommand::Miri { ref test_args, .. } => {
                 test_args.iter().flat_map(|s| s.split_whitespace()).collect()
             }
             _ => vec![],
diff --git a/src/bootstrap/src/core/config/flags.rs b/src/bootstrap/src/core/config/flags.rs
index 7262b785ee0..aaa2a2c47e0 100644
--- a/src/bootstrap/src/core/config/flags.rs
+++ b/src/bootstrap/src/core/config/flags.rs
@@ -339,9 +339,6 @@ pub enum Subcommand {
         #[arg(long)]
         /// run all tests regardless of failure
         no_fail_fast: bool,
-        #[arg(long, value_name = "SUBSTRING")]
-        /// skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times
-        skip: Vec<PathBuf>,
         #[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
         /// extra arguments to be passed for the test tool being used
         /// (e.g. libtest, compiletest or rustdoc)
@@ -382,6 +379,25 @@ pub enum Subcommand {
         /// `/<build_base>/rustfix_missing_coverage.txt`
         rustfix_coverage: bool,
     },
+    /// Build and run some test suites *in Miri*
+    Miri {
+        #[arg(long)]
+        /// run all tests regardless of failure
+        no_fail_fast: bool,
+        #[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
+        /// extra arguments to be passed for the test tool being used
+        /// (e.g. libtest, compiletest or rustdoc)
+        test_args: Vec<String>,
+        /// extra options to pass the compiler when running tests
+        #[arg(long, value_name = "ARGS", allow_hyphen_values(true))]
+        rustc_args: Vec<String>,
+        #[arg(long)]
+        /// do not run doc tests
+        no_doc: bool,
+        #[arg(long)]
+        /// only run doc tests
+        doc: bool,
+    },
     /// Build and run some benchmarks
     Bench {
         #[arg(long, allow_hyphen_values(true))]
@@ -453,6 +469,7 @@ impl Subcommand {
             Subcommand::Fix { .. } => Kind::Fix,
             Subcommand::Format { .. } => Kind::Format,
             Subcommand::Test { .. } => Kind::Test,
+            Subcommand::Miri { .. } => Kind::Miri,
             Subcommand::Clean { .. } => Kind::Clean,
             Subcommand::Dist { .. } => Kind::Dist,
             Subcommand::Install { .. } => Kind::Install,
@@ -464,7 +481,7 @@ impl Subcommand {
 
     pub fn rustc_args(&self) -> Vec<&str> {
         match *self {
-            Subcommand::Test { ref rustc_args, .. } => {
+            Subcommand::Test { ref rustc_args, .. } | Subcommand::Miri { ref rustc_args, .. } => {
                 rustc_args.iter().flat_map(|s| s.split_whitespace()).collect()
             }
             _ => vec![],
@@ -473,14 +490,16 @@ impl Subcommand {
 
     pub fn fail_fast(&self) -> bool {
         match *self {
-            Subcommand::Test { no_fail_fast, .. } => !no_fail_fast,
+            Subcommand::Test { no_fail_fast, .. } | Subcommand::Miri { no_fail_fast, .. } => {
+                !no_fail_fast
+            }
             _ => false,
         }
     }
 
     pub fn doc_tests(&self) -> DocTests {
         match *self {
-            Subcommand::Test { doc, no_doc, .. } => {
+            Subcommand::Test { doc, no_doc, .. } | Subcommand::Miri { no_doc, doc, .. } => {
                 if doc {
                     DocTests::Only
                 } else if no_doc {
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 44452446eb8..bcb8260b15a 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -92,8 +92,9 @@ const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (Some(Mode::Std), "backtrace_in_libstd", None),
     /* Extra values not defined in the built-in targets yet, but used in std */
     (Some(Mode::Std), "target_env", Some(&["libnx", "p2"])),
-    // (Some(Mode::Std), "target_os", Some(&[])),
+    (Some(Mode::Std), "target_os", Some(&["visionos"])),
     (Some(Mode::Std), "target_arch", Some(&["arm64ec", "spirv", "nvptx", "xtensa"])),
+    (Some(Mode::ToolStd), "target_os", Some(&["visionos"])),
     /* Extra names used by dependencies */
     // FIXME: Used by serde_json, but we should not be triggering on external dependencies.
     (Some(Mode::Rustc), "no_btreemap_remove_entry", None),
diff --git a/src/bootstrap/src/utils/render_tests.rs b/src/bootstrap/src/utils/render_tests.rs
index 70f25b2cc87..95cd55c9a3d 100644
--- a/src/bootstrap/src/utils/render_tests.rs
+++ b/src/bootstrap/src/utils/render_tests.rs
@@ -231,14 +231,16 @@ impl<'a> Renderer<'a> {
         print!("\ntest result: ");
         self.builder.colored_stdout(|stdout| outcome.write_long(stdout)).unwrap();
         println!(
-            ". {} passed; {} failed; {} ignored; {} measured; {} filtered out; \
-             finished in {:.2?}\n",
+            ". {} passed; {} failed; {} ignored; {} measured; {} filtered out{time}\n",
             suite.passed,
             suite.failed,
             suite.ignored,
             suite.measured,
             suite.filtered_out,
-            Duration::from_secs_f64(suite.exec_time)
+            time = match suite.exec_time {
+                Some(t) => format!("; finished in {:.2?}", Duration::from_secs_f64(t)),
+                None => format!(""),
+            }
         );
     }
 
@@ -374,7 +376,9 @@ struct SuiteOutcome {
     ignored: usize,
     measured: usize,
     filtered_out: usize,
-    exec_time: f64,
+    /// The time it took to execute this test suite, or `None` if time measurement was not possible
+    /// (e.g. due to running inside Miri).
+    exec_time: Option<f64>,
 }
 
 #[derive(serde_derive::Deserialize)]
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
index 07feb823492..14a8c245756 100644
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version
@@ -1 +1 @@
-0.17.0
\ No newline at end of file
+0.17.1
\ No newline at end of file
diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
index 10ae7f17db7..38c5b173ae3 100755
--- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
+++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh
@@ -62,3 +62,8 @@ case $HOST_TARGET in
     exit 1
     ;;
 esac
+# Also smoke-test `x.py miri`. This doesn't run any actual tests (that would take too long),
+# but it ensures that the crates build properly when tested with Miri.
+python3 "$X_PY" miri --stage 2 library/core --test-args notest
+python3 "$X_PY" miri --stage 2 library/alloc --test-args notest
+python3 "$X_PY" miri --stage 2 library/std --test-args notest
diff --git a/src/ci/scripts/upload-artifacts.sh b/src/ci/scripts/upload-artifacts.sh
index 9755edb6dce..c9c85ec20b4 100755
--- a/src/ci/scripts/upload-artifacts.sh
+++ b/src/ci/scripts/upload-artifacts.sh
@@ -45,3 +45,17 @@ deploy_url="s3://${DEPLOY_BUCKET}/${deploy_dir}/$(ciCommit)"
 
 retry aws s3 cp --storage-class INTELLIGENT_TIERING \
     --no-progress --recursive --acl public-read "${upload_dir}" "${deploy_url}"
+
+access_url="https://ci-artifacts.rust-lang.org/${deploy_dir}/$(ciCommit)"
+
+# Output URLs to the uploaded artifacts to GitHub summary (if it is available)
+# to make them easily accessible.
+if [ -n "${GITHUB_STEP_SUMMARY}" ]
+then
+  echo "# CI artifacts" >> "${GITHUB_STEP_SUMMARY}"
+
+  for filename in "${upload_dir}"/*.xz; do
+    filename=`basename "${filename}"`
+    echo "- [${filename}](${access_url}/${filename})" >> "${GITHUB_STEP_SUMMARY}"
+  done
+fi
diff --git a/src/doc/rustc/src/SUMMARY.md b/src/doc/rustc/src/SUMMARY.md
index 83acce80f96..db85753145d 100644
--- a/src/doc/rustc/src/SUMMARY.md
+++ b/src/doc/rustc/src/SUMMARY.md
@@ -21,6 +21,7 @@
     - [arm64ec-pc-windows-msvc](platform-support/arm64ec-pc-windows-msvc.md)
     - [\*-apple-tvos](platform-support/apple-tvos.md)
     - [\*-apple-watchos\*](platform-support/apple-watchos.md)
+    - [aarch64-apple-visionos\*](platform-support/apple-visionos.md)
     - [aarch64-nintendo-switch-freestanding](platform-support/aarch64-nintendo-switch-freestanding.md)
     - [armeb-unknown-linux-gnueabi](platform-support/armeb-unknown-linux-gnueabi.md)
     - [arm-none-eabi](platform-support/arm-none-eabi.md)
diff --git a/src/doc/rustc/src/platform-support.md b/src/doc/rustc/src/platform-support.md
index aa982a44503..f7836f18cf9 100644
--- a/src/doc/rustc/src/platform-support.md
+++ b/src/doc/rustc/src/platform-support.md
@@ -243,6 +243,8 @@ target | std | host | notes
 [`aarch64-apple-tvos-sim`](platform-support/apple-tvos.md) | ? |  | ARM64 tvOS Simulator
 [`aarch64-apple-watchos`](platform-support/apple-watchos.md) | ✓ |  | ARM64 Apple WatchOS
 [`aarch64-apple-watchos-sim`](platform-support/apple-watchos.md) | ✓ |  | ARM64 Apple WatchOS Simulator
+[`aarch64-apple-visionos`](platform-support/apple-visionos.md) | ✓ |  | ARM64 Apple visionOS
+[`aarch64-apple-visionos-sim`](platform-support/apple-visionos.md) | ✓ |  | ARM64 Apple visionOS Simulator
 [`aarch64-kmc-solid_asp3`](platform-support/kmc-solid.md) | ✓ |  | ARM64 SOLID with TOPPERS/ASP3
 [`aarch64-nintendo-switch-freestanding`](platform-support/aarch64-nintendo-switch-freestanding.md) | * |  | ARM64 Nintendo Switch, Horizon
 [`aarch64-pc-windows-gnullvm`](platform-support/pc-windows-gnullvm.md) | ✓ | ✓ |
diff --git a/src/doc/rustc/src/platform-support/apple-visionos.md b/src/doc/rustc/src/platform-support/apple-visionos.md
new file mode 100644
index 00000000000..9874126e42f
--- /dev/null
+++ b/src/doc/rustc/src/platform-support/apple-visionos.md
@@ -0,0 +1,53 @@
+# aarch64-apple-visionos\*
+
+-   aarch64-apple-visionos
+-   aarch64-apple-visionos-sim
+
+**Tier: 3**
+
+Apple visionOS targets:
+
+-   Apple visionOS on arm64
+-   Apple visionOS Simulator on arm64
+
+## Target maintainers
+
+-   [@agg23](https://github.com/agg23)
+-   [@madsmtm](https://github.com/madsmtm)
+
+## Requirements
+
+These targets are cross-compiled.
+To build these targets Xcode 15 or higher on macOS is required, along with LLVM 18.
+
+## Building the target
+
+The targets can be built by enabling them for a `rustc` build, for example:
+
+```toml
+[build]
+build-stage = 1
+target = ["aarch64-apple-visionos-sim"]
+```
+
+## Building Rust programs
+
+_Note: Building for this target requires the corresponding visionOS SDK, as provided by Xcode 15+._
+
+Rust programs can be built for these targets, if `rustc` has been built with support for them, for example:
+
+```text
+rustc --target aarch64-apple-visionos-sim your-code.rs
+```
+
+## Testing
+
+There is no support for running the Rust testsuite on visionOS or the simulators.
+
+There is no easy way to run simple programs on visionOS or the visionOS simulators. Static library builds can be embedded into visionOS applications.
+
+## Cross-compilation toolchains and C code
+
+This target can be cross-compiled from x86_64 or aarch64 macOS hosts.
+
+Other hosts are not supported for cross-compilation, but might work when also providing the required Xcode SDK.
diff --git a/src/doc/rustc/src/platform-support/netbsd.md b/src/doc/rustc/src/platform-support/netbsd.md
index 3891d6d3148..ef9337befa6 100644
--- a/src/doc/rustc/src/platform-support/netbsd.md
+++ b/src/doc/rustc/src/platform-support/netbsd.md
@@ -13,7 +13,7 @@ are currently defined running NetBSD:
 
 |          Target name           | NetBSD Platform |
 |--------------------------------|-----------------|
-| `amd64-unknown-netbsd`         | [amd64 / x86_64 systems](https://wiki.netbsd.org/ports/amd64/) |
+| `x86_64-unknown-netbsd`        | [amd64 / x86_64 systems](https://wiki.netbsd.org/ports/amd64/) |
 | `armv7-unknown-netbsd-eabihf`  | [32-bit ARMv7 systems with hard-float](https://wiki.netbsd.org/ports/evbarm/) |
 | `armv6-unknown-netbsd-eabihf`  | [32-bit ARMv6 systems with hard-float](https://wiki.netbsd.org/ports/evbarm/) |
 | `aarch64-unknown-netbsd`       | [64-bit ARM systems, little-endian](https://wiki.netbsd.org/ports/evbarm/) |
@@ -22,7 +22,7 @@ are currently defined running NetBSD:
 | `i686-unknown-netbsd`          | [32-bit i386 with SSE](https://wiki.netbsd.org/ports/i386/) |
 | `mipsel-unknown-netbsd`        | [32-bit mips, requires mips32 cpu support](https://wiki.netbsd.org/ports/evbmips/) |
 | `powerpc-unknown-netbsd`       | [Various 32-bit PowerPC systems, e.g. MacPPC](https://wiki.netbsd.org/ports/macppc/) |
-| `riscv64gc-unknown-netbsd`     | [64-bit RISC-V](https://wiki.netbsd.org/ports/riscv/)
+| `riscv64gc-unknown-netbsd`     | [64-bit RISC-V](https://wiki.netbsd.org/ports/riscv/) |
 | `sparc64-unknown-netbsd`       | [Sun UltraSPARC systems](https://wiki.netbsd.org/ports/sparc64/) |
 
 All use the "native" `stdc++` library which goes along with the natively
@@ -43,7 +43,7 @@ bug reporting system.
 
 ## Requirements
 
-The `amd64-unknown-netbsd` artifacts is being distributed by the
+The `x86_64-unknown-netbsd` artifacts is being distributed by the
 rust project.
 
 The other targets are built by the designated developers (see above),
@@ -95,7 +95,7 @@ capable systems we build and test `firefox` (amd64, i386, aarch64).
 
 ## Building Rust programs
 
-Rust ships pre-compiled artifacts for the `amd64-unknown-netbsd`
+Rust ships pre-compiled artifacts for the `x86_64-unknown-netbsd`
 target.
 
 For the other systems mentioned above, using the `pkgsrc` route is
diff --git a/src/doc/rustdoc/src/what-is-rustdoc.md b/src/doc/rustdoc/src/what-is-rustdoc.md
index 7179ee0cf03..cb4ec51caf2 100644
--- a/src/doc/rustdoc/src/what-is-rustdoc.md
+++ b/src/doc/rustdoc/src/what-is-rustdoc.md
@@ -34,6 +34,9 @@ the main page is located in `doc/lib/index.html`. If you open that up in
 a web browser, you will see a page with a search bar, and "Crate lib" at the
 top, with no contents.
 
+You can also use `cargo doc` to generate documentation for the whole project.
+See [Using rustdoc with Cargo](#using-rustdoc-with-cargo).
+
 ## Configuring rustdoc
 
 There are two problems with this: first, why does it
@@ -79,7 +82,13 @@ docs. Instead of the `rustdoc` command, we could have done this:
 $ cargo doc
 ```
 
-Internally, this calls out to `rustdoc` like this:
+If you want `cargo` to automatically open the generated documentation, you can use:
+
+```bash
+$ cargo doc --open
+```
+
+Internally, `cargo doc` calls out to `rustdoc` like this:
 
 ```bash
 $ rustdoc --crate-name docs src/lib.rs -o <path>/docs/target/doc -L
diff --git a/src/doc/unstable-book/src/compiler-flags/external-clangrt.md b/src/doc/unstable-book/src/compiler-flags/external-clangrt.md
new file mode 100644
index 00000000000..76b78d733e5
--- /dev/null
+++ b/src/doc/unstable-book/src/compiler-flags/external-clangrt.md
@@ -0,0 +1,6 @@
+# `external-clangrt`
+
+This option controls whether the compiler links in its own runtime library for
+[sanitizers](./sanitizer.md). Passing this flag makes the compiler *not* link
+its own library. For more information, see the section in the sanitizers doc on
+[working with other languages.](./sanitizer.md#working-with-other-languages)
diff --git a/src/doc/unstable-book/src/compiler-flags/sanitizer.md b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
index c8fd154a00e..72b44e002b4 100644
--- a/src/doc/unstable-book/src/compiler-flags/sanitizer.md
+++ b/src/doc/unstable-book/src/compiler-flags/sanitizer.md
@@ -45,6 +45,9 @@ To enable a sanitizer compile with `-Zsanitizer=address`, `-Zsanitizer=cfi`,
 `-Zsanitizer=dataflow`,`-Zsanitizer=hwaddress`, `-Zsanitizer=leak`,
 `-Zsanitizer=memory`, `-Zsanitizer=memtag`, `-Zsanitizer=shadow-call-stack`, or
 `-Zsanitizer=thread`. You might also need the `--target` and `build-std` flags.
+If you're working with other languages that are also instrumented with sanitizers,
+you might need the `external-clangrt` flag. See the section on
+[working with other languages](#working-with-other-languages).
 
 Example:
 ```shell
@@ -853,6 +856,18 @@ functionality][build-std].
 
 [build-std]: ../../cargo/reference/unstable.html#build-std
 
+# Working with other languages
+
+Sanitizers rely on compiler runtime libraries to function properly. Rust links
+in its own compiler runtime which might conflict with runtimes required by
+languages such as C++. Since Rust's runtime doesn't always contain the symbols
+required by C++ instrumented code, you might need to skip linking it so another
+runtime can be linked instead.
+
+A separate unstable option `-Zexternal-clangrt` can be used to make rustc skip
+linking the compiler runtime for the sanitizer. This will require you to link
+in an external runtime, such as from clang instead.
+
 # Build scripts and procedural macros
 
 Use of sanitizers together with build scripts and procedural macros is
diff --git a/src/etc/completions/x.py.fish b/src/etc/completions/x.py.fish
index 9fc95fd09ba..5ae27bc8c91 100644
--- a/src/etc/completions/x.py.fish
+++ b/src/etc/completions/x.py.fish
@@ -39,6 +39,7 @@ complete -c x.py -n "__fish_use_subcommand" -f -a "fix" -d 'Run cargo fix'
 complete -c x.py -n "__fish_use_subcommand" -f -a "fmt" -d 'Run rustfmt'
 complete -c x.py -n "__fish_use_subcommand" -f -a "doc" -d 'Build documentation'
 complete -c x.py -n "__fish_use_subcommand" -f -a "test" -d 'Build and run some test suites'
+complete -c x.py -n "__fish_use_subcommand" -f -a "miri" -d 'Build and run some test suites *in Miri*'
 complete -c x.py -n "__fish_use_subcommand" -f -a "bench" -d 'Build and run some benchmarks'
 complete -c x.py -n "__fish_use_subcommand" -f -a "clean" -d 'Clean out build directories'
 complete -c x.py -n "__fish_use_subcommand" -f -a "dist" -d 'Build distribution artifacts'
@@ -261,7 +262,6 @@ complete -c x.py -n "__fish_seen_subcommand_from doc" -l llvm-profile-generate -
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x.py -n "__fish_seen_subcommand_from doc" -s h -l help -d 'Print help (see more with \'--help\')'
-complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from test" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
 complete -c x.py -n "__fish_seen_subcommand_from test" -l extra-checks -d 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)' -r
@@ -274,6 +274,7 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l build -d 'build target
 complete -c x.py -n "__fish_seen_subcommand_from test" -l host -d 'host targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from test" -l target -d 'target targets to build' -r -f
 complete -c x.py -n "__fish_seen_subcommand_from test" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from test" -l skip -d 'build paths to skip' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from test" -l rustc-error-format -r -f
 complete -c x.py -n "__fish_seen_subcommand_from test" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
 complete -c x.py -n "__fish_seen_subcommand_from test" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
@@ -308,6 +309,45 @@ complete -c x.py -n "__fish_seen_subcommand_from test" -l llvm-profile-generate
 complete -c x.py -n "__fish_seen_subcommand_from test" -l enable-bolt-settings -d 'Enable BOLT link flags'
 complete -c x.py -n "__fish_seen_subcommand_from test" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
 complete -c x.py -n "__fish_seen_subcommand_from test" -s h -l help -d 'Print help (see more with \'--help\')'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l test-args -d 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)' -r
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l rustc-args -d 'extra options to pass the compiler when running tests' -r
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l config -d 'TOML configuration file for build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l build -d 'build target of the stage0 compiler' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l host -d 'host targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l target -d 'target targets to build' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l exclude -d 'build paths to exclude' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l skip -d 'build paths to skip' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l rustc-error-format -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l on-fail -d 'command to run on failure' -r -f -a "(__fish_complete_command)"
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l stage -d 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l keep-stage -d 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l keep-stage-std -d 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l src -d 'path to the root of the rust checkout' -r -f -a "(__fish_complete_directories)"
+complete -c x.py -n "__fish_seen_subcommand_from miri" -s j -l jobs -d 'number of jobs to run in parallel' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l warnings -d 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour' -r -f -a "{deny	'',warn	'',default	''}"
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l error-format -d 'rustc error format' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l color -d 'whether to use color in cargo and rustc output' -r -f -a "{always	'',never	'',auto	''}"
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l llvm-skip-rebuild -d 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml' -r -f -a "{true	'',false	''}"
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l rust-profile-generate -d 'generate PGO profile with rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l rust-profile-use -d 'use PGO profile for rustc build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l llvm-profile-use -d 'use PGO profile for LLVM build' -r -F
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l reproducible-artifact -d 'Additional reproducible artifacts that should be added to the reproducible artifacts archive' -r
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l set -d 'override options in config.toml' -r -f
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l no-fail-fast -d 'run all tests regardless of failure'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l no-doc -d 'do not run doc tests'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l doc -d 'only run doc tests'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -s v -l verbose -d 'use verbose output (-vv for very verbose)'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -s i -l incremental -d 'use incremental compilation'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l include-default-paths -d 'include default paths in addition to the provided ones'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l dry-run -d 'dry run; don\'t build anything'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l dump-bootstrap-shims -d 'Indicates whether to dump the work done from bootstrap shims'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l json-output -d 'use message-format=json'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l bypass-bootstrap-lock -d 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l llvm-profile-generate -d 'generate PGO profile with llvm built for rustc'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l enable-bolt-settings -d 'Enable BOLT link flags'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -l skip-stage0-validation -d 'Skip stage0 compiler validation'
+complete -c x.py -n "__fish_seen_subcommand_from miri" -s h -l help -d 'Print help (see more with \'--help\')'
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l test-args -r
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l config -d 'TOML configuration file for build' -r -F
 complete -c x.py -n "__fish_seen_subcommand_from bench" -l build-dir -d 'Build directory, overrides `build.build-dir` in `config.toml`' -r -f -a "(__fish_complete_directories)"
diff --git a/src/etc/completions/x.py.ps1 b/src/etc/completions/x.py.ps1
index 6359b7ff086..d39639a1f91 100644
--- a/src/etc/completions/x.py.ps1
+++ b/src/etc/completions/x.py.ps1
@@ -66,6 +66,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('fmt', 'fmt', [CompletionResultType]::ParameterValue, 'Run rustfmt')
             [CompletionResult]::new('doc', 'doc', [CompletionResultType]::ParameterValue, 'Build documentation')
             [CompletionResult]::new('test', 'test', [CompletionResultType]::ParameterValue, 'Build and run some test suites')
+            [CompletionResult]::new('miri', 'miri', [CompletionResultType]::ParameterValue, 'Build and run some test suites *in Miri*')
             [CompletionResult]::new('bench', 'bench', [CompletionResultType]::ParameterValue, 'Build and run some benchmarks')
             [CompletionResult]::new('clean', 'clean', [CompletionResultType]::ParameterValue, 'Clean out build directories')
             [CompletionResult]::new('dist', 'dist', [CompletionResultType]::ParameterValue, 'Build distribution artifacts')
@@ -333,7 +334,6 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             break
         }
         'x.py;test' {
-            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times')
             [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
             [CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
             [CompletionResult]::new('--extra-checks', 'extra-checks', [CompletionResultType]::ParameterName, 'comma-separated list of other files types to check (accepts py, py:lint, py:fmt, shell)')
@@ -346,6 +346,7 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
             [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
             [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
             [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
             [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
             [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
@@ -386,6 +387,52 @@ Register-ArgumentCompleter -Native -CommandName 'x.py' -ScriptBlock {
             [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
             break
         }
+        'x.py;miri' {
+            [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)')
+            [CompletionResult]::new('--rustc-args', 'rustc-args', [CompletionResultType]::ParameterName, 'extra options to pass the compiler when running tests')
+            [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
+            [CompletionResult]::new('--build-dir', 'build-dir', [CompletionResultType]::ParameterName, 'Build directory, overrides `build.build-dir` in `config.toml`')
+            [CompletionResult]::new('--build', 'build', [CompletionResultType]::ParameterName, 'build target of the stage0 compiler')
+            [CompletionResult]::new('--host', 'host', [CompletionResultType]::ParameterName, 'host targets to build')
+            [CompletionResult]::new('--target', 'target', [CompletionResultType]::ParameterName, 'target targets to build')
+            [CompletionResult]::new('--exclude', 'exclude', [CompletionResultType]::ParameterName, 'build paths to exclude')
+            [CompletionResult]::new('--skip', 'skip', [CompletionResultType]::ParameterName, 'build paths to skip')
+            [CompletionResult]::new('--rustc-error-format', 'rustc-error-format', [CompletionResultType]::ParameterName, 'rustc-error-format')
+            [CompletionResult]::new('--on-fail', 'on-fail', [CompletionResultType]::ParameterName, 'command to run on failure')
+            [CompletionResult]::new('--stage', 'stage', [CompletionResultType]::ParameterName, 'stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)')
+            [CompletionResult]::new('--keep-stage', 'keep-stage', [CompletionResultType]::ParameterName, 'stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--keep-stage-std', 'keep-stage-std', [CompletionResultType]::ParameterName, 'stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)')
+            [CompletionResult]::new('--src', 'src', [CompletionResultType]::ParameterName, 'path to the root of the rust checkout')
+            [CompletionResult]::new('-j', 'j', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--jobs', 'jobs', [CompletionResultType]::ParameterName, 'number of jobs to run in parallel')
+            [CompletionResult]::new('--warnings', 'warnings', [CompletionResultType]::ParameterName, 'if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour')
+            [CompletionResult]::new('--error-format', 'error-format', [CompletionResultType]::ParameterName, 'rustc error format')
+            [CompletionResult]::new('--color', 'color', [CompletionResultType]::ParameterName, 'whether to use color in cargo and rustc output')
+            [CompletionResult]::new('--llvm-skip-rebuild', 'llvm-skip-rebuild', [CompletionResultType]::ParameterName, 'whether rebuilding llvm should be skipped, overriding `skip-rebuld` in config.toml')
+            [CompletionResult]::new('--rust-profile-generate', 'rust-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with rustc build')
+            [CompletionResult]::new('--rust-profile-use', 'rust-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for rustc build')
+            [CompletionResult]::new('--llvm-profile-use', 'llvm-profile-use', [CompletionResultType]::ParameterName, 'use PGO profile for LLVM build')
+            [CompletionResult]::new('--reproducible-artifact', 'reproducible-artifact', [CompletionResultType]::ParameterName, 'Additional reproducible artifacts that should be added to the reproducible artifacts archive')
+            [CompletionResult]::new('--set', 'set', [CompletionResultType]::ParameterName, 'override options in config.toml')
+            [CompletionResult]::new('--no-fail-fast', 'no-fail-fast', [CompletionResultType]::ParameterName, 'run all tests regardless of failure')
+            [CompletionResult]::new('--no-doc', 'no-doc', [CompletionResultType]::ParameterName, 'do not run doc tests')
+            [CompletionResult]::new('--doc', 'doc', [CompletionResultType]::ParameterName, 'only run doc tests')
+            [CompletionResult]::new('-v', 'v', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('--verbose', 'verbose', [CompletionResultType]::ParameterName, 'use verbose output (-vv for very verbose)')
+            [CompletionResult]::new('-i', 'i', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--incremental', 'incremental', [CompletionResultType]::ParameterName, 'use incremental compilation')
+            [CompletionResult]::new('--include-default-paths', 'include-default-paths', [CompletionResultType]::ParameterName, 'include default paths in addition to the provided ones')
+            [CompletionResult]::new('--dry-run', 'dry-run', [CompletionResultType]::ParameterName, 'dry run; don''t build anything')
+            [CompletionResult]::new('--dump-bootstrap-shims', 'dump-bootstrap-shims', [CompletionResultType]::ParameterName, 'Indicates whether to dump the work done from bootstrap shims')
+            [CompletionResult]::new('--json-output', 'json-output', [CompletionResultType]::ParameterName, 'use message-format=json')
+            [CompletionResult]::new('--bypass-bootstrap-lock', 'bypass-bootstrap-lock', [CompletionResultType]::ParameterName, 'Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)')
+            [CompletionResult]::new('--llvm-profile-generate', 'llvm-profile-generate', [CompletionResultType]::ParameterName, 'generate PGO profile with llvm built for rustc')
+            [CompletionResult]::new('--enable-bolt-settings', 'enable-bolt-settings', [CompletionResultType]::ParameterName, 'Enable BOLT link flags')
+            [CompletionResult]::new('--skip-stage0-validation', 'skip-stage0-validation', [CompletionResultType]::ParameterName, 'Skip stage0 compiler validation')
+            [CompletionResult]::new('-h', 'h', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            [CompletionResult]::new('--help', 'help', [CompletionResultType]::ParameterName, 'Print help (see more with ''--help'')')
+            break
+        }
         'x.py;bench' {
             [CompletionResult]::new('--test-args', 'test-args', [CompletionResultType]::ParameterName, 'test-args')
             [CompletionResult]::new('--config', 'config', [CompletionResultType]::ParameterName, 'TOML configuration file for build')
diff --git a/src/etc/completions/x.py.sh b/src/etc/completions/x.py.sh
index e1436dcde67..1f1a9a70767 100644
--- a/src/etc/completions/x.py.sh
+++ b/src/etc/completions/x.py.sh
@@ -42,6 +42,9 @@ _x.py() {
             bootstrap,install)
                 cmd="bootstrap__install"
                 ;;
+            bootstrap,miri)
+                cmd="bootstrap__miri"
+                ;;
             bootstrap,run)
                 cmd="bootstrap__run"
                 ;;
@@ -61,7 +64,7 @@ _x.py() {
 
     case "${cmd}" in
         x.py)
-            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test bench clean dist install run setup suggest"
+            opts="-v -i -j -h --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]... build check clippy fix fmt doc test miri bench clean dist install run setup suggest"
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 1 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
@@ -1290,6 +1293,124 @@ _x.py() {
             COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
             return 0
             ;;
+        x.py__miri)
+            opts="-v -i -j -h --no-fail-fast --test-args --rustc-args --no-doc --doc --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
+                COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+                return 0
+            fi
+            case "${prev}" in
+                --test-args)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-args)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --config)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --build-dir)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --build)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --host)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --target)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --exclude)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rustc-error-format)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --on-fail)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --stage)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --keep-stage)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --keep-stage-std)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --src)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --jobs)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                -j)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --warnings)
+                    COMPREPLY=($(compgen -W "deny warn default" -- "${cur}"))
+                    return 0
+                    ;;
+                --error-format)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                --color)
+                    COMPREPLY=($(compgen -W "always never auto" -- "${cur}"))
+                    return 0
+                    ;;
+                --llvm-skip-rebuild)
+                    COMPREPLY=($(compgen -W "true false" -- "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-generate)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --rust-profile-use)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --llvm-profile-use)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --reproducible-artifact)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
+                --set)
+                    COMPREPLY=("${cur}")
+                    return 0
+                    ;;
+                *)
+                    COMPREPLY=()
+                    ;;
+            esac
+            COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
+            return 0
+            ;;
         x.py__run)
             opts="-v -i -j -h --args --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
@@ -1625,16 +1746,12 @@ _x.py() {
             return 0
             ;;
         x.py__test)
-            opts="-v -i -j -h --no-fail-fast --skip --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
+            opts="-v -i -j -h --no-fail-fast --test-args --rustc-args --no-doc --doc --bless --extra-checks --force-rerun --only-modified --compare-mode --pass --run --rustfix-coverage --verbose --incremental --config --build-dir --build --host --target --exclude --skip --include-default-paths --rustc-error-format --on-fail --dry-run --dump-bootstrap-shims --stage --keep-stage --keep-stage-std --src --jobs --warnings --error-format --json-output --color --bypass-bootstrap-lock --llvm-skip-rebuild --rust-profile-generate --rust-profile-use --llvm-profile-use --llvm-profile-generate --enable-bolt-settings --skip-stage0-validation --reproducible-artifact --set --help [PATHS]... [ARGS]..."
             if [[ ${cur} == -* || ${COMP_CWORD} -eq 2 ]] ; then
                 COMPREPLY=( $(compgen -W "${opts}" -- "${cur}") )
                 return 0
             fi
             case "${prev}" in
-                --skip)
-                    COMPREPLY=($(compgen -f "${cur}"))
-                    return 0
-                    ;;
                 --test-args)
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
@@ -1683,6 +1800,10 @@ _x.py() {
                     COMPREPLY=($(compgen -f "${cur}"))
                     return 0
                     ;;
+                --skip)
+                    COMPREPLY=($(compgen -f "${cur}"))
+                    return 0
+                    ;;
                 --rustc-error-format)
                     COMPREPLY=("${cur}")
                     return 0
diff --git a/src/etc/completions/x.py.zsh b/src/etc/completions/x.py.zsh
index ea7e4ba6758..b920309ac2c 100644
--- a/src/etc/completions/x.py.zsh
+++ b/src/etc/completions/x.py.zsh
@@ -335,7 +335,6 @@ _arguments "${_arguments_options[@]}" \
 ;;
 (test)
 _arguments "${_arguments_options[@]}" \
-'*--skip=[skips tests matching SUBSTRING, if supported by test tool. May be passed multiple times]:SUBSTRING:_files' \
 '*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
 '*--rustc-args=[extra options to pass the compiler when running tests]:ARGS: ' \
 '--extra-checks=[comma-separated list of other files types to check (accepts py, py\:lint, py\:fmt, shell)]:EXTRA_CHECKS: ' \
@@ -348,6 +347,7 @@ _arguments "${_arguments_options[@]}" \
 '--host=[host targets to build]:HOST:( )' \
 '--target=[target targets to build]:TARGET:( )' \
 '*--exclude=[build paths to exclude]:PATH:_files' \
+'*--skip=[build paths to skip]:PATH:_files' \
 '--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
 '--on-fail=[command to run on failure]:CMD:_cmdstring' \
 '--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
@@ -389,6 +389,54 @@ _arguments "${_arguments_options[@]}" \
 '*::paths -- paths for the subcommand:_files' \
 && ret=0
 ;;
+(miri)
+_arguments "${_arguments_options[@]}" \
+'*--test-args=[extra arguments to be passed for the test tool being used (e.g. libtest, compiletest or rustdoc)]:ARGS: ' \
+'*--rustc-args=[extra options to pass the compiler when running tests]:ARGS: ' \
+'--config=[TOML configuration file for build]:FILE:_files' \
+'--build-dir=[Build directory, overrides \`build.build-dir\` in \`config.toml\`]:DIR:_files -/' \
+'--build=[build target of the stage0 compiler]:BUILD:( )' \
+'--host=[host targets to build]:HOST:( )' \
+'--target=[target targets to build]:TARGET:( )' \
+'*--exclude=[build paths to exclude]:PATH:_files' \
+'*--skip=[build paths to skip]:PATH:_files' \
+'--rustc-error-format=[]:RUSTC_ERROR_FORMAT:( )' \
+'--on-fail=[command to run on failure]:CMD:_cmdstring' \
+'--stage=[stage to build (indicates compiler to use/test, e.g., stage 0 uses the bootstrap compiler, stage 1 the stage 0 rustc artifacts, etc.)]:N:( )' \
+'*--keep-stage=[stage(s) to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'*--keep-stage-std=[stage(s) of the standard library to keep without recompiling (pass multiple times to keep e.g., both stages 0 and 1)]:N:( )' \
+'--src=[path to the root of the rust checkout]:DIR:_files -/' \
+'-j+[number of jobs to run in parallel]:JOBS:( )' \
+'--jobs=[number of jobs to run in parallel]:JOBS:( )' \
+'--warnings=[if value is deny, will deny warnings if value is warn, will emit warnings otherwise, use the default configured behaviour]:deny|warn:(deny warn default)' \
+'--error-format=[rustc error format]:FORMAT:( )' \
+'--color=[whether to use color in cargo and rustc output]:STYLE:(always never auto)' \
+'--llvm-skip-rebuild=[whether rebuilding llvm should be skipped, overriding \`skip-rebuld\` in config.toml]:VALUE:(true false)' \
+'--rust-profile-generate=[generate PGO profile with rustc build]:PROFILE:_files' \
+'--rust-profile-use=[use PGO profile for rustc build]:PROFILE:_files' \
+'--llvm-profile-use=[use PGO profile for LLVM build]:PROFILE:_files' \
+'*--reproducible-artifact=[Additional reproducible artifacts that should be added to the reproducible artifacts archive]:REPRODUCIBLE_ARTIFACT: ' \
+'*--set=[override options in config.toml]:section.option=value:( )' \
+'--no-fail-fast[run all tests regardless of failure]' \
+'--no-doc[do not run doc tests]' \
+'--doc[only run doc tests]' \
+'*-v[use verbose output (-vv for very verbose)]' \
+'*--verbose[use verbose output (-vv for very verbose)]' \
+'-i[use incremental compilation]' \
+'--incremental[use incremental compilation]' \
+'--include-default-paths[include default paths in addition to the provided ones]' \
+'--dry-run[dry run; don'\''t build anything]' \
+'--dump-bootstrap-shims[Indicates whether to dump the work done from bootstrap shims]' \
+'--json-output[use message-format=json]' \
+'--bypass-bootstrap-lock[Bootstrap uses this value to decide whether it should bypass locking the build process. This is rarely needed (e.g., compiling the std library for different targets in parallel)]' \
+'--llvm-profile-generate[generate PGO profile with llvm built for rustc]' \
+'--enable-bolt-settings[Enable BOLT link flags]' \
+'--skip-stage0-validation[Skip stage0 compiler validation]' \
+'-h[Print help (see more with '\''--help'\'')]' \
+'--help[Print help (see more with '\''--help'\'')]' \
+'*::paths -- paths for the subcommand:_files' \
+&& ret=0
+;;
 (bench)
 _arguments "${_arguments_options[@]}" \
 '*--test-args=[]:TEST_ARGS: ' \
@@ -710,6 +758,7 @@ _x.py_commands() {
 'fmt:Run rustfmt' \
 'doc:Build documentation' \
 'test:Build and run some test suites' \
+'miri:Build and run some test suites *in Miri*' \
 'bench:Build and run some benchmarks' \
 'clean:Clean out build directories' \
 'dist:Build distribution artifacts' \
@@ -770,6 +819,11 @@ _x.py__install_commands() {
     local commands; commands=()
     _describe -t commands 'x.py install commands' commands "$@"
 }
+(( $+functions[_x.py__miri_commands] )) ||
+_x.py__miri_commands() {
+    local commands; commands=()
+    _describe -t commands 'x.py miri commands' commands "$@"
+}
 (( $+functions[_x.py__run_commands] )) ||
 _x.py__run_commands() {
     local commands; commands=()
diff --git a/src/librustdoc/clean/blanket_impl.rs b/src/librustdoc/clean/blanket_impl.rs
index 47cfe651e31..72d4cc7c465 100644
--- a/src/librustdoc/clean/blanket_impl.rs
+++ b/src/librustdoc/clean/blanket_impl.rs
@@ -47,7 +47,7 @@ impl<'a, 'tcx> BlanketImplFinder<'a, 'tcx> {
                 // Require the type the impl is implemented on to match
                 // our type, and ignore the impl if there was a mismatch.
                 let Ok(eq_result) = infcx.at(&traits::ObligationCause::dummy(), param_env).eq(
-                    DefineOpaqueTypes::No,
+                    DefineOpaqueTypes::Yes,
                     impl_trait_ref.self_ty(),
                     impl_ty,
                 ) else {
diff --git a/src/librustdoc/clean/cfg.rs b/src/librustdoc/clean/cfg.rs
index 277db90df9a..2814e83dcd7 100644
--- a/src/librustdoc/clean/cfg.rs
+++ b/src/librustdoc/clean/cfg.rs
@@ -511,6 +511,7 @@ impl<'a> fmt::Display for Display<'a> {
                         "wasi" => "WASI",
                         "watchos" => "watchOS",
                         "windows" => "Windows",
+                        "visionos" => "visionOS",
                         _ => "",
                     },
                     (sym::target_arch, Some(arch)) => match arch.as_str() {
diff --git a/src/librustdoc/html/static/css/noscript.css b/src/librustdoc/html/static/css/noscript.css
index f425f3ec95c..ccb97d7df4c 100644
--- a/src/librustdoc/html/static/css/noscript.css
+++ b/src/librustdoc/html/static/css/noscript.css
@@ -34,7 +34,7 @@ nav.sub {
 	in rustdoc.css */
 
 /* Begin theme: light */
-:root {
+:root, :root:not([data-theme]) {
 	--main-background-color: white;
 	--main-color: black;
 	--settings-input-color: #2196f3;
@@ -140,7 +140,7 @@ nav.sub {
 
 @media (prefers-color-scheme: dark) {
 	/* Begin theme: dark */
-	:root {
+	:root, :root:not([data-theme]) {
 		--main-background-color: #353535;
 		--main-color: #ddd;
 		--settings-input-color: #2196f3;
diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css
index 9993dfb1d8c..0bb073b1cea 100644
--- a/src/librustdoc/html/static/css/rustdoc.css
+++ b/src/librustdoc/html/static/css/rustdoc.css
@@ -2315,8 +2315,14 @@ in src-script.js and main.js
 	tooling to ensure different themes all define all the variables. Do not
 	alter their formatting. */
 
+/*
+About `:root:not([data-theme])`: if for any reason the JS is enabled but cannot be loaded,
+`noscript` won't be enabled and the doc will have no color applied. To do around this, we
+add a selector check that if `data-theme` is not defined, then we apply the light theme
+by default.
+*/
 /* Begin theme: light */
-:root[data-theme="light"] {
+:root[data-theme="light"], :root:not([data-theme]) {
 	--main-background-color: white;
 	--main-color: black;
 	--settings-input-color: #2196f3;
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject 0637083df5bbdcc951845f0d2eff6999cdb6d30
+Subproject 28e7b2bc0a812f90126be30f48a00a4ada990ea
diff --git a/src/tools/clippy/.gitignore b/src/tools/clippy/.gitignore
index 503ae3c5090..181b71a658b 100644
--- a/src/tools/clippy/.gitignore
+++ b/src/tools/clippy/.gitignore
@@ -1,3 +1,6 @@
+# Generated by ui-test
+rustc-ice-*
+
 # Used by CI to be able to push:
 /.github/deploy_key
 out
diff --git a/src/tools/clippy/CHANGELOG.md b/src/tools/clippy/CHANGELOG.md
index 76ef84a48b8..f7e7ed86eed 100644
--- a/src/tools/clippy/CHANGELOG.md
+++ b/src/tools/clippy/CHANGELOG.md
@@ -5379,6 +5379,7 @@ Released 2018-09-13
 [`large_stack_arrays`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_arrays
 [`large_stack_frames`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_stack_frames
 [`large_types_passed_by_value`]: https://rust-lang.github.io/rust-clippy/master/index.html#large_types_passed_by_value
+[`legacy_numeric_constants`]: https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants
 [`len_without_is_empty`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_without_is_empty
 [`len_zero`]: https://rust-lang.github.io/rust-clippy/master/index.html#len_zero
 [`let_and_return`]: https://rust-lang.github.io/rust-clippy/master/index.html#let_and_return
@@ -5481,6 +5482,7 @@ Released 2018-09-13
 [`missing_safety_doc`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_safety_doc
 [`missing_spin_loop`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_spin_loop
 [`missing_trait_methods`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_trait_methods
+[`missing_transmute_annotations`]: https://rust-lang.github.io/rust-clippy/master/index.html#missing_transmute_annotations
 [`mistyped_literal_suffixes`]: https://rust-lang.github.io/rust-clippy/master/index.html#mistyped_literal_suffixes
 [`mixed_attributes_style`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_attributes_style
 [`mixed_case_hex_literals`]: https://rust-lang.github.io/rust-clippy/master/index.html#mixed_case_hex_literals
diff --git a/src/tools/clippy/Cargo.toml b/src/tools/clippy/Cargo.toml
index 2b37b54c004..43f20ecedc2 100644
--- a/src/tools/clippy/Cargo.toml
+++ b/src/tools/clippy/Cargo.toml
@@ -31,7 +31,6 @@ anstream = "0.6.0"
 
 [dev-dependencies]
 ui_test = "0.22.2"
-tester = "0.9"
 regex = "1.5.5"
 toml = "0.7.3"
 walkdir = "2.3"
diff --git a/src/tools/clippy/book/src/SUMMARY.md b/src/tools/clippy/book/src/SUMMARY.md
index a048fbbd8ac..be13fcbe260 100644
--- a/src/tools/clippy/book/src/SUMMARY.md
+++ b/src/tools/clippy/book/src/SUMMARY.md
@@ -32,3 +32,4 @@
     - [Proposals](development/proposals/README.md)
         - [Roadmap 2021](development/proposals/roadmap-2021.md)
         - [Syntax Tree Patterns](development/proposals/syntax-tree-patterns.md)
+    - [The Team](development/the_team.md)
diff --git a/src/tools/clippy/book/src/development/defining_lints.md b/src/tools/clippy/book/src/development/defining_lints.md
index 54f77b00190..806ed0845f0 100644
--- a/src/tools/clippy/book/src/development/defining_lints.md
+++ b/src/tools/clippy/book/src/development/defining_lints.md
@@ -62,9 +62,8 @@ $ cargo dev new_lint --name=lint_name --pass=late --category=pedantic
 There are two things to note here:
 
 1. `--pass`: We set `--pass=late` in this command to do a late lint pass. The
-   alternative is an `early` lint pass. We will discuss this difference in a
-   later chapter.
-   <!-- FIXME: Link that "later chapter" when lint_passes.md is merged -->
+   alternative is an `early` lint pass. We will discuss this difference in the
+   [Lint Passes] chapter.
 2. `--category`: If not provided, the `category` of this new lint will default
    to `nursery`.
 
@@ -194,8 +193,7 @@ store.register_late_pass(|_| Box::new(foo_functions::FooFunctions));
 
 As you might have guessed, where there's something late, there is something
 early: in Clippy there is a `register_early_pass` method as well. More on early
-vs. late passes in a later chapter.
-<!-- FIXME: Link that "later chapter" when lint_passes.md is merged -->
+vs. late passes in the [Lint Passes] chapter.
 
 Without a call to one of `register_early_pass` or `register_late_pass`, the lint
 pass in question will not be run.
@@ -203,3 +201,4 @@ pass in question will not be run.
 
 [all_lints]: https://rust-lang.github.io/rust-clippy/master/
 [lint_naming]: https://rust-lang.github.io/rfcs/0344-conventions-galore.html#lints
+[Lint Passes]: lint_passes.md
diff --git a/src/tools/clippy/book/src/development/lint_passes.md b/src/tools/clippy/book/src/development/lint_passes.md
index 621fc20972e..dde9e1a273b 100644
--- a/src/tools/clippy/book/src/development/lint_passes.md
+++ b/src/tools/clippy/book/src/development/lint_passes.md
@@ -50,7 +50,7 @@ questions already, but the parser is okay with it. This is what we
 mean when we say `EarlyLintPass` deals with only syntax on the AST level.
 
 Alternatively, think of the `foo_functions` lint we mentioned in
-define new lints <!-- FIXME: add link --> chapter.
+the [Define New Lints](defining_lints.md) chapter.
 
 We want the `foo_functions` lint to detect functions with `foo` as their name.
 Writing a lint that only checks for the name of a function means that we only
diff --git a/src/tools/clippy/book/src/development/the_team.md b/src/tools/clippy/book/src/development/the_team.md
new file mode 100644
index 00000000000..10341791cec
--- /dev/null
+++ b/src/tools/clippy/book/src/development/the_team.md
@@ -0,0 +1,130 @@
+# The team
+
+Everyone who contributes to Clippy makes the project what it is. Collaboration
+and discussions are the lifeblood of every open-source project. Clippy has a
+very flat hierarchy. The teams mainly have additional access rights to the repo.
+
+This document outlines the onboarding process, as well as duties, and access
+rights for members of a group.
+
+All regular events mentioned in this chapter are tracked in the [calendar repository].
+The calendar file is also available for download: [clippy.ics]
+
+## Everyone
+
+Everyone, including you, is welcome to join discussions and contribute in other
+ways, like PRs.
+
+You also have some triage rights, using `@rustbot` to add labels and claim
+issues. See [labeling with @rustbot].
+
+A rule for everyone should be to keep a healthy work-life balance. Take a break
+when you need one.
+
+## Clippy-Contributors
+
+This is a group of regular contributors to Clippy to help with triaging.
+
+### Duties
+
+This team exists to make contributing easier for regular members. It doesn't
+carry any duties that need to be done. However, we want to encourage members of
+this group to help with triaging, which can include:
+
+1. **Labeling issues**
+
+    For the `good-first-issue` label, it can still be good to use `@rustbot` to
+    subscribe to the issue and help interested parties, if they post questions
+    in the comments. 
+
+2. **Closing duplicate or resolved issues**
+
+    When you manually close an issue, it's often a good idea, to add a short
+    comment explaining the reason.
+
+3. **Ping people after two weeks of inactivity**
+
+    We try to keep issue assignments and PRs fairly up-to-date. After two weeks,
+    it can be good to send a friendly ping to the delaying party.
+
+    You might close a PR with the `I-inactive-closed` label if the author is
+    busy or wants to abandon it. If the reviewer is busy, the PR can be
+    reassigned to someone else.
+
+    Checkout: https://triage.rust-lang.org/triage/rust-lang/rust-clippy to
+    monitor PRs.
+
+While not part of their duties, contributors are encouraged to review PRs
+and help on Zulip. The team always appreciates help!
+
+### Membership
+
+If you have been contributing to Clippy for some time, we'll probably ask you if
+you want to join this team. Members of this team are also welcome to suggest
+people who they think would make a great addition to this group.
+
+For this group, there is no direct onboarding process. You're welcome to just
+continue what you've been doing. If you like, you can ask for someone to mentor
+you, either in the Clippy stream on Zulip or privately via a PM.
+
+If you have been inactive in Clippy for over three months, we'll probably move
+you to the alumni group. You're always welcome to come back.
+
+## The Clippy Team
+
+[The Clippy team](https://www.rust-lang.org/governance/teams/dev-tools#Clippy%20team)
+is responsible for maintaining Clippy.
+
+### Duties
+
+1. **Respond to PRs in a timely manner**
+
+    It's totally fine, if you don't have the time for reviews right now.
+    You can reassign the PR to a random member by commenting `r? clippy`.
+
+2. **Take a break when you need one**
+
+    You are valuable! Clippy wouldn't be what it is without you. So take a break
+    early and recharge some energy when you need to.
+
+3. **Be responsive on Zulip**
+
+    This means in a reasonable time frame, so responding within one or two days
+    is totally fine.
+
+    It's also good, if you answer threads on Zulip and take part in our Clippy
+    meetings, every two weeks. The meeting dates are tracked in the [calendar repository].
+    
+
+4. **Sync Clippy with the rust-lang/rust repo**
+
+    This is done every two weeks, usually by @flip1995.
+
+5. **Update the changelog**
+
+    This needs to be done for every release, every six weeks. This is usually
+    done by @xFrednet.
+
+### Membership
+
+If you have been active for some time, we'll probably reach out and ask
+if you want to help with reviews and eventually join the Clippy team.
+
+During the onboarding process, you'll be assigned pull requests to review.
+You'll also have an active team member as a mentor who'll stay in contact via
+Zulip DMs to provide advice and feedback. If you have questions, you're always
+welcome to ask, that is the best way to learn. Once you're done with the review,
+you can ping your mentor for a full review and to r+ the PR in both of your names.
+
+When your mentor is confident that you can handle reviews on your own, they'll
+start an informal vote among the active team members to officially add you to
+the team. This vote is usually accepted unanimously. Then you'll be added to
+the team once you've confirmed that you're still interested in joining. The
+onboarding phase typically takes a couple of weeks to a few months.
+
+If you have been inactive in Clippy for over three months, we'll probably move
+you to the alumni group. You're always welcome to come back.
+
+[calendar repository]: https://github.com/rust-lang/calendar/blob/main/clippy.toml
+[clippy.ics]: https://rust-lang.github.io/calendar/clippy.ics
+[labeling with @rustbot]: https://forge.rust-lang.org/triagebot/labeling.html
diff --git a/src/tools/clippy/book/src/lint_configuration.md b/src/tools/clippy/book/src/lint_configuration.md
index a9234899746..4a2727c5197 100644
--- a/src/tools/clippy/book/src/lint_configuration.md
+++ b/src/tools/clippy/book/src/lint_configuration.md
@@ -616,6 +616,7 @@ The minimum rust version that the project supports. Defaults to the `rust-versio
 * [`if_then_some_else_none`](https://rust-lang.github.io/rust-clippy/master/index.html#if_then_some_else_none)
 * [`index_refutable_slice`](https://rust-lang.github.io/rust-clippy/master/index.html#index_refutable_slice)
 * [`iter_kv_map`](https://rust-lang.github.io/rust-clippy/master/index.html#iter_kv_map)
+* [`legacy_numeric_constants`](https://rust-lang.github.io/rust-clippy/master/index.html#legacy_numeric_constants)
 * [`manual_bits`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_bits)
 * [`manual_c_str_literals`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_c_str_literals)
 * [`manual_clamp`](https://rust-lang.github.io/rust-clippy/master/index.html#manual_clamp)
diff --git a/src/tools/clippy/clippy_config/src/conf.rs b/src/tools/clippy/clippy_config/src/conf.rs
index 3218fe7f456..53c10f7cee8 100644
--- a/src/tools/clippy/clippy_config/src/conf.rs
+++ b/src/tools/clippy/clippy_config/src/conf.rs
@@ -262,7 +262,7 @@ define_Conf! {
     ///
     /// Suppress lints whenever the suggested change would cause breakage for other crates.
     (avoid_breaking_exported_api: bool = true),
-    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES.
+    /// Lint: MANUAL_SPLIT_ONCE, MANUAL_STR_REPEAT, CLONED_INSTEAD_OF_COPIED, REDUNDANT_FIELD_NAMES, OPTION_MAP_UNWRAP_OR, REDUNDANT_STATIC_LIFETIMES, FILTER_MAP_NEXT, CHECKED_CONVERSIONS, MANUAL_RANGE_CONTAINS, USE_SELF, MEM_REPLACE_WITH_DEFAULT, MANUAL_NON_EXHAUSTIVE, OPTION_AS_REF_DEREF, MAP_UNWRAP_OR, MATCH_LIKE_MATCHES_MACRO, MANUAL_STRIP, MISSING_CONST_FOR_FN, UNNESTED_OR_PATTERNS, FROM_OVER_INTO, PTR_AS_PTR, IF_THEN_SOME_ELSE_NONE, APPROX_CONSTANT, DEPRECATED_CFG_ATTR, INDEX_REFUTABLE_SLICE, MAP_CLONE, BORROW_AS_PTR, MANUAL_BITS, ERR_EXPECT, CAST_ABS_TO_UNSIGNED, UNINLINED_FORMAT_ARGS, MANUAL_CLAMP, MANUAL_LET_ELSE, UNCHECKED_DURATION_SUBTRACTION, COLLAPSIBLE_STR_REPLACE, SEEK_FROM_CURRENT, SEEK_REWIND, UNNECESSARY_LAZY_EVALUATIONS, TRANSMUTE_PTR_TO_REF, ALMOST_COMPLETE_RANGE, NEEDLESS_BORROW, DERIVABLE_IMPLS, MANUAL_IS_ASCII_CHECK, MANUAL_REM_EUCLID, MANUAL_RETAIN, TYPE_REPETITION_IN_BOUNDS, TUPLE_ARRAY_CONVERSIONS, MANUAL_TRY_FOLD, MANUAL_HASH_ONE, ITER_KV_MAP, MANUAL_C_STR_LITERALS, ASSIGNING_CLONES, LEGACY_NUMERIC_CONSTANTS.
     ///
     /// The minimum rust version that the project supports. Defaults to the `rust-version` field in `Cargo.toml`
     #[default_text = ""]
@@ -857,11 +857,6 @@ mod tests {
         }
 
         assert!(
-            names.remove("allow-one-hash-in-raw-strings"),
-            "remove this when #11481 is fixed"
-        );
-
-        assert!(
             names.is_empty(),
             "Configuration variable lacks test: {names:?}\nAdd a test to `tests/ui-toml`"
         );
diff --git a/src/tools/clippy/clippy_config/src/lib.rs b/src/tools/clippy/clippy_config/src/lib.rs
index 01e2aa6e0a6..ff7fa7241cb 100644
--- a/src/tools/clippy/clippy_config/src/lib.rs
+++ b/src/tools/clippy/clippy_config/src/lib.rs
@@ -1,6 +1,12 @@
 #![feature(rustc_private, let_chains)]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
-#![warn(rust_2018_idioms, unused_lifetimes)]
+#![warn(
+    trivial_casts,
+    trivial_numeric_casts,
+    rust_2018_idioms,
+    unused_lifetimes,
+    unused_qualifications
+)]
 #![allow(
     clippy::must_use_candidate,
     clippy::missing_panics_doc,
diff --git a/src/tools/clippy/clippy_config/src/msrvs.rs b/src/tools/clippy/clippy_config/src/msrvs.rs
index 149c4776dc9..59dd5b334b8 100644
--- a/src/tools/clippy/clippy_config/src/msrvs.rs
+++ b/src/tools/clippy/clippy_config/src/msrvs.rs
@@ -36,7 +36,7 @@ msrv_aliases! {
     1,47,0 { TAU, IS_ASCII_DIGIT_CONST, ARRAY_IMPL_ANY_LEN }
     1,46,0 { CONST_IF_MATCH }
     1,45,0 { STR_STRIP_PREFIX }
-    1,43,0 { LOG2_10, LOG10_2 }
+    1,43,0 { LOG2_10, LOG10_2, NUMERIC_ASSOCIATED_CONSTANTS }
     1,42,0 { MATCHES_MACRO, SLICE_PATTERNS, PTR_SLICE_RAW_PARTS }
     1,41,0 { RE_REBALANCING_COHERENCE, RESULT_MAP_OR_ELSE }
     1,40,0 { MEM_TAKE, NON_EXHAUSTIVE, OPTION_AS_DEREF }
diff --git a/src/tools/clippy/clippy_dev/src/lib.rs b/src/tools/clippy/clippy_dev/src/lib.rs
index c4ae4f0e2bd..bb62e902cd5 100644
--- a/src/tools/clippy/clippy_dev/src/lib.rs
+++ b/src/tools/clippy/clippy_dev/src/lib.rs
@@ -2,8 +2,13 @@
 #![feature(let_chains)]
 #![feature(rustc_private)]
 #![cfg_attr(feature = "deny-warnings", deny(warnings))]
-// warn on lints, that are included in `rust-lang/rust`s bootstrap
-#![warn(rust_2018_idioms, unused_lifetimes)]
+#![warn(
+    trivial_casts,
+    trivial_numeric_casts,
+    rust_2018_idioms,
+    unused_lifetimes,
+    unused_qualifications
+)]
 
 // The `rustc_driver` crate seems to be required in order to use the `rust_lexer` crate.
 #[allow(unused_extern_crates)]
diff --git a/src/tools/clippy/clippy_dev/src/lint.rs b/src/tools/clippy/clippy_dev/src/lint.rs
index 906a9727810..f308f5dfdfd 100644
--- a/src/tools/clippy/clippy_dev/src/lint.rs
+++ b/src/tools/clippy/clippy_dev/src/lint.rs
@@ -20,6 +20,8 @@ pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
                 .args(["--edition", "2021"])
                 .arg(path)
                 .args(args)
+                // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
+                .env("RUSTC_ICE", "0")
                 .status(),
         );
     } else {
@@ -32,6 +34,8 @@ pub fn run<'a>(path: &str, args: impl Iterator<Item = &'a String>) {
         let status = Command::new(cargo_clippy_path())
             .arg("clippy")
             .args(args)
+            // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
+            .env("RUSTC_ICE", "0")
             .current_dir(path)
             .status();
 
diff --git a/src/tools/clippy/clippy_dev/src/update_lints.rs b/src/tools/clippy/clippy_dev/src/update_lints.rs
index 76ae26dddf4..625b1339591 100644
--- a/src/tools/clippy/clippy_dev/src/update_lints.rs
+++ b/src/tools/clippy/clippy_dev/src/update_lints.rs
@@ -992,7 +992,7 @@ fn replace_region_in_text<'a>(
 }
 
 fn try_rename_file(old_name: &Path, new_name: &Path) -> bool {
-    match fs::OpenOptions::new().create_new(true).write(true).open(new_name) {
+    match OpenOptions::new().create_new(true).write(true).open(new_name) {
         Ok(file) => drop(file),
         Err(e) if matches!(e.kind(), io::ErrorKind::AlreadyExists | io::ErrorKind::NotFound) => return false,
         Err(e) => panic_file(e, new_name, "create"),
@@ -1016,7 +1016,7 @@ fn panic_file(error: io::Error, name: &Path, action: &str) -> ! {
 }
 
 fn rewrite_file(path: &Path, f: impl FnOnce(&str) -> Option<String>) {
-    let mut file = fs::OpenOptions::new()
+    let mut file = OpenOptions::new()
         .write(true)
         .read(true)
         .open(path)
diff --git a/src/tools/clippy/clippy_lints/src/approx_const.rs b/src/tools/clippy/clippy_lints/src/approx_const.rs
index 25606f4253e..ec28fd46111 100644
--- a/src/tools/clippy/clippy_lints/src/approx_const.rs
+++ b/src/tools/clippy/clippy_lints/src/approx_const.rs
@@ -95,7 +95,7 @@ impl ApproxConstant {
                         cx,
                         APPROX_CONSTANT,
                         e.span,
-                        &format!("approximate value of `{module}::consts::{}` found", &name),
+                        format!("approximate value of `{module}::consts::{}` found", &name),
                         None,
                         "consider using the constant directly",
                     );
diff --git a/src/tools/clippy/clippy_lints/src/asm_syntax.rs b/src/tools/clippy/clippy_lints/src/asm_syntax.rs
index c2fa56e1360..7c88bfc97ca 100644
--- a/src/tools/clippy/clippy_lints/src/asm_syntax.rs
+++ b/src/tools/clippy/clippy_lints/src/asm_syntax.rs
@@ -53,9 +53,9 @@ fn check_asm_syntax(
                 cx,
                 lint,
                 span,
-                &format!("{style} x86 assembly syntax used"),
+                format!("{style} x86 assembly syntax used"),
                 None,
-                &format!("use {} x86 assembly syntax", !style),
+                format!("use {} x86 assembly syntax", !style),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
index 9365fbfaed0..2003dd1fb0e 100644
--- a/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
+++ b/src/tools/clippy/clippy_lints/src/assertions_on_constants.rs
@@ -58,7 +58,7 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
                 cx,
                 ASSERTIONS_ON_CONSTANTS,
                 macro_call.span,
-                &format!(
+                format!(
                     "`{}!(true)` will be optimized out by the compiler",
                     cx.tcx.item_name(macro_call.def_id)
                 ),
@@ -74,9 +74,9 @@ impl<'tcx> LateLintPass<'tcx> for AssertionsOnConstants {
                 cx,
                 ASSERTIONS_ON_CONSTANTS,
                 macro_call.span,
-                &format!("`assert!(false{assert_arg})` should probably be replaced"),
+                format!("`assert!(false{assert_arg})` should probably be replaced"),
                 None,
-                &format!("use `panic!({panic_arg})` or `unreachable!({panic_arg})`"),
+                format!("use `panic!({panic_arg})` or `unreachable!({panic_arg})`"),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/assigning_clones.rs b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
index 8e27b3ccefd..dc7f44af2b7 100644
--- a/src/tools/clippy/clippy_lints/src/assigning_clones.rs
+++ b/src/tools/clippy/clippy_lints/src/assigning_clones.rs
@@ -65,7 +65,7 @@ impl AssigningClones {
 impl_lint_pass!(AssigningClones => [ASSIGNING_CLONES]);
 
 impl<'tcx> LateLintPass<'tcx> for AssigningClones {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, assign_expr: &'tcx hir::Expr<'_>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, assign_expr: &'tcx Expr<'_>) {
         // Do not fire the lint in macros
         let expn_data = assign_expr.span().ctxt().outer_expn_data();
         match expn_data.kind {
@@ -181,6 +181,23 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC
         return false;
     }
 
+    // If the call expression is inside an impl block that contains the method invoked by the
+    // call expression, we bail out to avoid suggesting something that could result in endless
+    // recursion.
+    if let Some(local_block_id) = impl_block.as_local()
+        && let Some(block) = cx.tcx.hir_node_by_def_id(local_block_id).as_owner()
+    {
+        let impl_block_owner = block.def_id();
+        if cx
+            .tcx
+            .hir()
+            .parent_id_iter(lhs.hir_id)
+            .any(|parent| parent.owner == impl_block_owner)
+        {
+            return false;
+        }
+    }
+
     // Find the function for which we want to check that it is implemented.
     let provided_fn = match call.target {
         TargetTrait::Clone => cx.tcx.get_diagnostic_item(sym::Clone).and_then(|clone| {
@@ -205,14 +222,9 @@ fn is_ok_to_suggest<'tcx>(cx: &LateContext<'tcx>, lhs: &Expr<'tcx>, call: &CallC
     implemented_fns.contains_key(&provided_fn.def_id)
 }
 
-fn suggest<'tcx>(
-    cx: &LateContext<'tcx>,
-    assign_expr: &hir::Expr<'tcx>,
-    lhs: &hir::Expr<'tcx>,
-    call: &CallCandidate<'tcx>,
-) {
+fn suggest<'tcx>(cx: &LateContext<'tcx>, assign_expr: &Expr<'tcx>, lhs: &Expr<'tcx>, call: &CallCandidate<'tcx>) {
     span_lint_and_then(cx, ASSIGNING_CLONES, assign_expr.span, call.message(), |diag| {
-        let mut applicability = Applicability::MachineApplicable;
+        let mut applicability = Applicability::Unspecified;
 
         diag.span_suggestion(
             assign_expr.span,
@@ -263,7 +275,7 @@ impl<'tcx> CallCandidate<'tcx> {
     fn suggested_replacement(
         &self,
         cx: &LateContext<'tcx>,
-        lhs: &hir::Expr<'tcx>,
+        lhs: &Expr<'tcx>,
         applicability: &mut Applicability,
     ) -> String {
         match self.target {
diff --git a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
index df00f23e37e..4a22e17463f 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/allow_attributes_without_reason.rs
@@ -30,7 +30,7 @@ pub(super) fn check<'cx>(cx: &LateContext<'cx>, name: Symbol, items: &[NestedMet
         cx,
         ALLOW_ATTRIBUTES_WITHOUT_REASON,
         attr.span,
-        &format!("`{}` attribute without specifying a reason", name.as_str()),
+        format!("`{}` attribute without specifying a reason", name.as_str()),
         None,
         "try adding a reason at the end with `, reason = \"..\"`",
     );
diff --git a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
index 3c5ac597fd5..3a8844d0754 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/duplicated_attributes.rs
@@ -31,6 +31,9 @@ fn check_duplicated_attr(
     attr_paths: &mut FxHashMap<String, Span>,
     parent: &mut Vec<String>,
 ) {
+    if attr.span.from_expansion() {
+        return;
+    }
     let Some(ident) = attr.ident() else { return };
     let name = ident.name;
     if name == sym::doc || name == sym::cfg_attr {
@@ -38,6 +41,14 @@ fn check_duplicated_attr(
         // conditions are the same.
         return;
     }
+    if let Some(direct_parent) = parent.last()
+        && ["cfg", "cfg_attr"].contains(&direct_parent.as_str())
+        && [sym::all, sym::not, sym::any].contains(&name)
+    {
+        // FIXME: We don't correctly check `cfg`s for now, so if it's more complex than just a one
+        // level `cfg`, we leave.
+        return;
+    }
     if let Some(value) = attr.value_str() {
         emit_if_duplicated(cx, attr, attr_paths, format!("{}:{name}={value}", parent.join(":")));
     } else if let Some(sub_attrs) = attr.meta_item_list() {
diff --git a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
index cfcd2cc6a00..3b5b80ffefa 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/inline_always.rs
@@ -21,7 +21,7 @@ pub(super) fn check(cx: &LateContext<'_>, span: Span, name: Symbol, attrs: &[Att
                     cx,
                     INLINE_ALWAYS,
                     attr.span,
-                    &format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
+                    format!("you have declared `#[inline(always)]` on `{name}`. This is usually a bad idea"),
                 );
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs
index 5a70866eda5..e6b2e835be8 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/maybe_misused_cfg.rs
@@ -40,7 +40,7 @@ fn check_nested_misused_cfg(cx: &EarlyContext<'_>, items: &[NestedMetaItem]) {
                     cx,
                     MAYBE_MISUSED_CFG,
                     meta.span,
-                    &format!("'test' may be misspelled as '{}'", ident.name.as_str()),
+                    format!("'test' may be misspelled as '{}'", ident.name.as_str()),
                     "did you mean",
                     "test".to_string(),
                     Applicability::MaybeIncorrect,
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
index c2e21cfd330..5d2ea36b366 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mixed_attributes_style.rs
@@ -1,30 +1,85 @@
 use super::MIXED_ATTRIBUTES_STYLE;
 use clippy_utils::diagnostics::span_lint;
-use rustc_ast::AttrStyle;
-use rustc_lint::EarlyContext;
+use rustc_ast::{AttrKind, AttrStyle, Attribute};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::sync::Lrc;
+use rustc_lint::{LateContext, LintContext};
+use rustc_span::source_map::SourceMap;
+use rustc_span::{SourceFile, Span, Symbol};
 
-pub(super) fn check(cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
-    let mut has_outer = false;
-    let mut has_inner = false;
+#[derive(Hash, PartialEq, Eq)]
+enum SimpleAttrKind {
+    Doc,
+    /// A normal attribute, with its name symbols.
+    Normal(Vec<Symbol>),
+}
+
+impl From<&AttrKind> for SimpleAttrKind {
+    fn from(value: &AttrKind) -> Self {
+        match value {
+            AttrKind::Normal(attr) => {
+                let path_symbols = attr
+                    .item
+                    .path
+                    .segments
+                    .iter()
+                    .map(|seg| seg.ident.name)
+                    .collect::<Vec<_>>();
+                Self::Normal(path_symbols)
+            },
+            AttrKind::DocComment(..) => Self::Doc,
+        }
+    }
+}
+
+pub(super) fn check(cx: &LateContext<'_>, item_span: Span, attrs: &[Attribute]) {
+    let mut inner_attr_kind: FxHashSet<SimpleAttrKind> = FxHashSet::default();
+    let mut outer_attr_kind: FxHashSet<SimpleAttrKind> = FxHashSet::default();
+
+    let source_map = cx.sess().source_map();
+    let item_src = source_map.lookup_source_file(item_span.lo());
 
-    for attr in &item.attrs {
-        if attr.span.from_expansion() {
+    for attr in attrs {
+        if attr.span.from_expansion() || !attr_in_same_src_as_item(source_map, &item_src, attr.span) {
             continue;
         }
+
+        let kind: SimpleAttrKind = (&attr.kind).into();
         match attr.style {
-            AttrStyle::Inner => has_inner = true,
-            AttrStyle::Outer => has_outer = true,
-        }
+            AttrStyle::Inner => {
+                if outer_attr_kind.contains(&kind) {
+                    lint_mixed_attrs(cx, attrs);
+                    return;
+                }
+                inner_attr_kind.insert(kind);
+            },
+            AttrStyle::Outer => {
+                if inner_attr_kind.contains(&kind) {
+                    lint_mixed_attrs(cx, attrs);
+                    return;
+                }
+                outer_attr_kind.insert(kind);
+            },
+        };
     }
-    if !has_outer || !has_inner {
+}
+
+fn lint_mixed_attrs(cx: &LateContext<'_>, attrs: &[Attribute]) {
+    let mut attrs_iter = attrs.iter().filter(|attr| !attr.span.from_expansion());
+    let span = if let (Some(first), Some(last)) = (attrs_iter.next(), attrs_iter.last()) {
+        first.span.with_hi(last.span.hi())
+    } else {
         return;
-    }
-    let mut attrs_iter = item.attrs.iter().filter(|attr| !attr.span.from_expansion());
-    let span = attrs_iter.next().unwrap().span;
+    };
     span_lint(
         cx,
         MIXED_ATTRIBUTES_STYLE,
-        span.with_hi(attrs_iter.last().unwrap().span.hi()),
+        span,
         "item has both inner and outer attributes",
     );
 }
+
+fn attr_in_same_src_as_item(source_map: &SourceMap, item_src: &Lrc<SourceFile>, attr_span: Span) -> bool {
+    let attr_src = source_map.lookup_source_file(attr_span.lo());
+    Lrc::ptr_eq(item_src, &attr_src)
+}
diff --git a/src/tools/clippy/clippy_lints/src/attrs/mod.rs b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
index 675c428948f..684ad7de2f0 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/mod.rs
@@ -465,10 +465,20 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Checks that an item has only one kind of attributes.
+    /// Checks for items that have the same kind of attributes with mixed styles (inner/outer).
     ///
     /// ### Why is this bad?
-    /// Having both kinds of attributes makes it more complicated to read code.
+    /// Having both style of said attributes makes it more complicated to read code.
+    ///
+    /// ### Known problems
+    /// This lint currently has false-negatives when mixing same attributes
+    /// but they have different path symbols, for example:
+    /// ```ignore
+    /// #[custom_attribute]
+    /// pub fn foo() {
+    ///     #![my_crate::custom_attribute]
+    /// }
+    /// ```
     ///
     /// ### Example
     /// ```no_run
@@ -486,7 +496,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.78.0"]
     pub MIXED_ATTRIBUTES_STYLE,
-    suspicious,
+    style,
     "item has both inner and outer attributes"
 }
 
@@ -523,6 +533,7 @@ declare_lint_pass!(Attributes => [
     USELESS_ATTRIBUTE,
     BLANKET_CLIPPY_RESTRICTION_LINTS,
     SHOULD_PANIC_WITHOUT_EXPECT,
+    MIXED_ATTRIBUTES_STYLE,
 ]);
 
 impl<'tcx> LateLintPass<'tcx> for Attributes {
@@ -566,6 +577,7 @@ impl<'tcx> LateLintPass<'tcx> for Attributes {
             ItemKind::ExternCrate(..) | ItemKind::Use(..) => useless_attribute::check(cx, item, attrs),
             _ => {},
         }
+        mixed_attributes_style::check(cx, item.span, attrs);
     }
 
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx ImplItem<'_>) {
@@ -594,7 +606,6 @@ impl_lint_pass!(EarlyAttributes => [
     MAYBE_MISUSED_CFG,
     DEPRECATED_CLIPPY_CFG_ATTR,
     UNNECESSARY_CLIPPY_CFG,
-    MIXED_ATTRIBUTES_STYLE,
     DUPLICATED_ATTRIBUTES,
 ]);
 
@@ -605,7 +616,6 @@ impl EarlyLintPass for EarlyAttributes {
 
     fn check_item(&mut self, cx: &EarlyContext<'_>, item: &rustc_ast::Item) {
         empty_line_after::check(cx, item);
-        mixed_attributes_style::check(cx, item);
         duplicated_attributes::check(cx, &item.attrs);
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
index 05da69636c6..486e7c6ec4f 100644
--- a/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
+++ b/src/tools/clippy/clippy_lints/src/attrs/unnecessary_clippy_cfg.rs
@@ -58,7 +58,7 @@ pub(super) fn check(
                 clippy_lints,
                 "no need to put clippy lints behind a `clippy` cfg",
                 None,
-                &format!(
+                format!(
                     "write instead: `#{}[{}({})]`",
                     if attr.style == AttrStyle::Inner { "!" } else { "" },
                     ident.name,
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 765cc7c0a54..f25a474d9bb 100644
--- a/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
+++ b/src/tools/clippy/clippy_lints/src/await_holding_invalid.rs
@@ -267,7 +267,7 @@ fn emit_invalid_type(cx: &LateContext<'_>, span: Span, disallowed: &DisallowedPa
         cx,
         AWAIT_HOLDING_INVALID_TYPE,
         span,
-        &format!(
+        format!(
             "`{}` may not be held across an `await` point per `clippy.toml`",
             disallowed.path()
         ),
diff --git a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
index 2eb0dac9742..171f3031860 100644
--- a/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
+++ b/src/tools/clippy/clippy_lints/src/blocks_in_conditions.rs
@@ -72,7 +72,7 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
         else {
             return;
         };
-        let complex_block_message = &format!(
+        let complex_block_message = format!(
             "in {desc}, avoid complex blocks or closures with blocks; \
             instead, move the block or closure higher and bind it with a `let`",
         );
@@ -141,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for BlocksInConditions {
                     let ex = &body.value;
                     if let ExprKind::Block(block, _) = ex.kind {
                         if !body.value.span.from_expansion() && !block.stmts.is_empty() {
-                            span_lint(cx, BLOCKS_IN_CONDITIONS, ex.span, complex_block_message);
+                            span_lint(cx, BLOCKS_IN_CONDITIONS, ex.span, complex_block_message.clone());
                             return ControlFlow::Continue(Descend::No);
                         }
                     }
diff --git a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
index 74201e9cc30..58c1a2f2706 100644
--- a/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
+++ b/src/tools/clippy/clippy_lints/src/bool_assert_comparison.rs
@@ -121,7 +121,7 @@ impl<'tcx> LateLintPass<'tcx> for BoolAssertComparison {
             cx,
             BOOL_ASSERT_COMPARISON,
             macro_call.span,
-            &format!("used `{macro_name}!` with a literal bool"),
+            format!("used `{macro_name}!` with a literal bool"),
             |diag| {
                 // assert_eq!(...)
                 // ^^^^^^^^^
diff --git a/src/tools/clippy/clippy_lints/src/booleans.rs b/src/tools/clippy/clippy_lints/src/booleans.rs
index a474356608f..6edfebb5534 100644
--- a/src/tools/clippy/clippy_lints/src/booleans.rs
+++ b/src/tools/clippy/clippy_lints/src/booleans.rs
@@ -392,13 +392,13 @@ fn simple_negate(b: Bool) -> Bool {
         t @ Term(_) => Not(Box::new(t)),
         And(mut v) => {
             for el in &mut v {
-                *el = simple_negate(::std::mem::replace(el, True));
+                *el = simple_negate(std::mem::replace(el, True));
             }
             Or(v)
         },
         Or(mut v) => {
             for el in &mut v {
-                *el = simple_negate(::std::mem::replace(el, True));
+                *el = simple_negate(std::mem::replace(el, True));
             }
             And(v)
         },
diff --git a/src/tools/clippy/clippy_lints/src/box_default.rs b/src/tools/clippy/clippy_lints/src/box_default.rs
index 8683cb86e8a..4062212f408 100644
--- a/src/tools/clippy/clippy_lints/src/box_default.rs
+++ b/src/tools/clippy/clippy_lints/src/box_default.rs
@@ -1,6 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::macros::macro_backtrace;
-use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::expr_sig;
 use clippy_utils::{is_default_equivalent, path_def_id};
 use rustc_errors::Applicability;
@@ -9,20 +8,16 @@ use rustc_hir::intravisit::{walk_ty, Visitor};
 use rustc_hir::{Block, Expr, ExprKind, LetStmt, Node, QPath, Ty, TyKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::print::with_forced_trimmed_paths;
-use rustc_middle::ty::IsSuggestable;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
 declare_clippy_lint! {
     /// ### What it does
-    /// checks for `Box::new(T::default())`, which is better written as
-    /// `Box::<T>::default()`.
+    /// checks for `Box::new(Default::default())`, which can be written as
+    /// `Box::default()`.
     ///
     /// ### Why is this bad?
-    /// First, it's more complex, involving two calls instead of one.
-    /// Second, `Box::default()` can be faster
-    /// [in certain cases](https://nnethercote.github.io/perf-book/standard-library-types.html#box).
+    /// `Box::default()` is equivalent and more concise.
     ///
     /// ### Example
     /// ```no_run
@@ -34,7 +29,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.66.0"]
     pub BOX_DEFAULT,
-    perf,
+    style,
     "Using Box::new(T::default()) instead of Box::default()"
 }
 
@@ -53,14 +48,14 @@ impl LateLintPass<'_> for BoxDefault {
             && path_def_id(cx, ty).map_or(false, |id| Some(id) == cx.tcx.lang_items().owned_box())
             // And the single argument to the call is another function call
             // This is the `T::default()` of `Box::new(T::default())`
-            && let ExprKind::Call(arg_path, inner_call_args) = arg.kind
+            && let ExprKind::Call(arg_path, _) = arg.kind
             // And we are not in a foreign crate's macro
             && !in_external_macro(cx.sess(), expr.span)
             // And the argument expression has the same context as the outer call expression
             // or that we are inside a `vec!` macro expansion
             && (expr.span.eq_ctxt(arg.span) || is_local_vec_expn(cx, arg, expr))
-            // And the argument is equivalent to `Default::default()`
-            && is_default_equivalent(cx, arg)
+            // And the argument is `Default::default()` or the type is specified
+            && (is_plain_default(cx, arg_path) || (given_type(cx, expr) && is_default_equivalent(cx, arg)))
         {
             span_lint_and_sugg(
                 cx,
@@ -68,25 +63,7 @@ impl LateLintPass<'_> for BoxDefault {
                 expr.span,
                 "`Box::new(_)` of default value",
                 "try",
-                if is_plain_default(cx, arg_path) || given_type(cx, expr) {
-                    "Box::default()".into()
-                } else if let Some(arg_ty) =
-                    cx.typeck_results().expr_ty(arg).make_suggestable(cx.tcx, true, None)
-                {
-                    // Check if we can copy from the source expression in the replacement.
-                    // We need the call to have no argument (see `explicit_default_type`).
-                    if inner_call_args.is_empty()
-                        && let Some(ty) = explicit_default_type(arg_path)
-                        && let Some(s) = snippet_opt(cx, ty.span)
-                    {
-                        format!("Box::<{s}>::default()")
-                    } else {
-                        // Otherwise, use the inferred type's formatting.
-                        with_forced_trimmed_paths!(format!("Box::<{arg_ty}>::default()"))
-                    }
-                } else {
-                    return;
-                },
+                "Box::default()".into(),
                 Applicability::MachineApplicable,
             );
         }
@@ -105,20 +82,6 @@ fn is_plain_default(cx: &LateContext<'_>, arg_path: &Expr<'_>) -> bool {
     }
 }
 
-// Checks whether the call is of the form `A::B::f()`. Returns `A::B` if it is.
-//
-// In the event we have this kind of construct, it's easy to use `A::B` as a replacement in the
-// quickfix. `f` must however have no parameter. Should `f` have some, then some of the type of
-// `A::B` may be inferred from the arguments. This would be the case for `Vec::from([0; false])`,
-// where the argument to `from` allows inferring this is a `Vec<bool>`
-fn explicit_default_type<'a>(arg_path: &'a Expr<'_>) -> Option<&'a Ty<'a>> {
-    if let ExprKind::Path(QPath::TypeRelative(ty, _)) = &arg_path.kind {
-        Some(ty)
-    } else {
-        None
-    }
-}
-
 fn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>) -> bool {
     macro_backtrace(expr.span).next().map_or(false, |call| {
         cx.tcx.is_diagnostic_item(sym::vec_macro, call.def_id) && call.span.eq_ctxt(ref_expr.span)
@@ -129,7 +92,7 @@ fn is_local_vec_expn(cx: &LateContext<'_>, expr: &Expr<'_>, ref_expr: &Expr<'_>)
 struct InferVisitor(bool);
 
 impl<'tcx> Visitor<'tcx> for InferVisitor {
-    fn visit_ty(&mut self, t: &rustc_hir::Ty<'_>) {
+    fn visit_ty(&mut self, t: &Ty<'_>) {
         self.0 |= matches!(t.kind, TyKind::Infer | TyKind::OpaqueDef(..) | TyKind::TraitObject(..));
         if !self.0 {
             walk_ty(self, t);
diff --git a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
index 99fe6c1e790..3af2d8c0256 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/common_metadata.rs
@@ -41,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, ignore_publish: b
 
 fn missing_warning(cx: &LateContext<'_>, package: &cargo_metadata::Package, field: &str) {
     let message = format!("package `{}` is missing `{field}` metadata", package.name);
-    span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, &message);
+    span_lint(cx, CARGO_COMMON_METADATA, DUMMY_SP, message);
 }
 
 fn is_empty_str<T: AsRef<std::ffi::OsStr>>(value: &Option<T>) -> bool {
diff --git a/src/tools/clippy/clippy_lints/src/cargo/feature_name.rs b/src/tools/clippy/clippy_lints/src/cargo/feature_name.rs
index 9e69919c727..6982b96dd3b 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/feature_name.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/feature_name.rs
@@ -56,13 +56,13 @@ fn lint(cx: &LateContext<'_>, feature: &str, substring: &str, is_prefix: bool) {
             REDUNDANT_FEATURE_NAMES
         },
         DUMMY_SP,
-        &format!(
+        format!(
             "the \"{substring}\" {} in the feature name \"{feature}\" is {}",
             if is_prefix { "prefix" } else { "suffix" },
             if is_negative { "negative" } else { "redundant" }
         ),
         None,
-        &format!(
+        format!(
             "consider renaming the feature to \"{}\"{}",
             if is_prefix {
                 feature.strip_prefix(substring)
diff --git a/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs b/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
index a39b972b56a..a3291c9da10 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/lint_groups_priority.rs
@@ -102,7 +102,7 @@ fn check_table(cx: &LateContext<'_>, table: LintTable, groups: &FxHashSet<&str>,
                 cx,
                 LINT_GROUPS_PRIORITY,
                 toml_span(group.span(), file),
-                &format!(
+                format!(
                     "lint group `{}` has the same priority ({priority}) as a lint",
                     group.as_ref()
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/cargo/mod.rs b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
index 95d5449781b..ca7fa4e5a41 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/mod.rs
@@ -241,7 +241,7 @@ impl LateLintPass<'_> for Cargo {
                 },
                 Err(e) => {
                     for lint in NO_DEPS_LINTS {
-                        span_lint(cx, lint, DUMMY_SP, &format!("could not read cargo metadata: {e}"));
+                        span_lint(cx, lint, DUMMY_SP, format!("could not read cargo metadata: {e}"));
                     }
                 },
             }
@@ -257,7 +257,7 @@ impl LateLintPass<'_> for Cargo {
                 },
                 Err(e) => {
                     for lint in WITH_DEPS_LINTS {
-                        span_lint(cx, lint, DUMMY_SP, &format!("could not read cargo metadata: {e}"));
+                        span_lint(cx, lint, DUMMY_SP, format!("could not read cargo metadata: {e}"));
                     }
                 },
             }
diff --git a/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs b/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
index 3f30a77fcfe..2769463c8a5 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/multiple_crate_versions.rs
@@ -52,7 +52,7 @@ pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata, allowed_duplicate
                     cx,
                     MULTIPLE_CRATE_VERSIONS,
                     DUMMY_SP,
-                    &format!("multiple versions for dependency `{name}`: {versions}"),
+                    format!("multiple versions for dependency `{name}`: {versions}"),
                 );
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/cargo/wildcard_dependencies.rs b/src/tools/clippy/clippy_lints/src/cargo/wildcard_dependencies.rs
index 244e98eb666..0cf687d0192 100644
--- a/src/tools/clippy/clippy_lints/src/cargo/wildcard_dependencies.rs
+++ b/src/tools/clippy/clippy_lints/src/cargo/wildcard_dependencies.rs
@@ -17,7 +17,7 @@ pub(super) fn check(cx: &LateContext<'_>, metadata: &Metadata) {
                 cx,
                 WILDCARD_DEPENDENCIES,
                 DUMMY_SP,
-                &format!("wildcard dependency for `{}`", dep.name),
+                format!("wildcard dependency for `{}`", dep.name),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
index a667ea04af0..f05fd3fcde5 100644
--- a/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/as_ptr_cast_mut.rs
@@ -28,7 +28,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
             cx,
             AS_PTR_CAST_MUT,
             expr.span,
-            &format!("casting the result of `as_ptr` to *mut {ptrty}"),
+            format!("casting the result of `as_ptr` to *mut {ptrty}"),
             "replace with",
             format!("{recv}.as_mut_ptr()"),
             applicability,
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
index c1663348321..d4d5ee37bcc 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_abs_to_unsigned.rs
@@ -34,7 +34,7 @@ pub(super) fn check(
             cx,
             CAST_ABS_TO_UNSIGNED,
             span,
-            &format!("casting the result of `{cast_from}::abs()` to {cast_to}"),
+            format!("casting the result of `{cast_from}::abs()` to {cast_to}"),
             "replace with",
             format!("{}.unsigned_abs()", Sugg::hir(cx, receiver, "..").maybe_par()),
             Applicability::MachineApplicable,
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 86f4332d05a..d52ad1c6f23 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_lossless.rs
@@ -68,7 +68,7 @@ pub(super) fn check(
         cx,
         CAST_LOSSLESS,
         expr.span,
-        &message,
+        message,
         "try",
         format!("{cast_to_fmt}::from({sugg})"),
         app,
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_nan_to_int.rs b/src/tools/clippy/clippy_lints/src/casts/cast_nan_to_int.rs
index da756129db3..1743ce71add 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_nan_to_int.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_nan_to_int.rs
@@ -12,7 +12,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
             cx,
             CAST_NAN_TO_INT,
             expr.span,
-            &format!("casting a known NaN to {to_ty}"),
+            format!("casting a known NaN to {to_ty}"),
             None,
             "this always evaluates to 0",
         );
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 2c0a3d48296..dbfa8e1ee91 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
@@ -41,7 +41,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
                 })
             },
             BinOpKind::Rem | BinOpKind::BitAnd => get_constant_bits(cx, right)
-                .unwrap_or(u64::max_value())
+                .unwrap_or(u64::MAX)
                 .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).unwrap_or_default())),
@@ -56,7 +56,7 @@ fn apply_reductions(cx: &LateContext<'_>, nbits: u64, expr: &Expr<'_>, signed: b
             } else {
                 None
             };
-            apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::max_value()))
+            apply_reductions(cx, nbits, left, signed).min(max_bits.unwrap_or(u64::MAX))
         },
         ExprKind::MethodCall(method, _, [lo, hi], _) => {
             if method.ident.as_str() == "clamp" {
@@ -142,7 +142,7 @@ pub(super) fn check(
                     cx,
                     CAST_ENUM_TRUNCATION,
                     expr.span,
-                    &format!(
+                    format!(
                         "casting `{cast_from}::{}` to `{cast_to}` will truncate the value{suffix}",
                         variant.name,
                     ),
@@ -163,7 +163,7 @@ pub(super) fn check(
         _ => return,
     };
 
-    span_lint_and_then(cx, CAST_POSSIBLE_TRUNCATION, expr.span, &msg, |diag| {
+    span_lint_and_then(cx, CAST_POSSIBLE_TRUNCATION, expr.span, msg, |diag| {
         diag.help("if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...");
         if !cast_from.is_floating_point() {
             offer_suggestion(cx, expr, cast_expr, cast_to_span, diag);
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs b/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs
index 2ddb0f00ecd..11274383595 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_possible_wrap.rs
@@ -79,7 +79,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca
         ),
     };
 
-    span_lint_and_then(cx, CAST_POSSIBLE_WRAP, expr.span, &message, |diag| {
+    span_lint_and_then(cx, CAST_POSSIBLE_WRAP, expr.span, message, |diag| {
         if let EmitState::LintOnPtrSize(16) = should_lint {
             diag
                 .note("`usize` and `isize` may be as small as 16 bits on some platforms")
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs b/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs
index 334e1646cd4..035666e4d4c 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_precision_loss.rs
@@ -38,7 +38,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_from: Ty<'_>, ca
         cx,
         CAST_PRECISION_LOSS,
         expr.span,
-        &format!(
+        format!(
             "casting `{0}` to `{1}` causes a loss of precision {2}(`{0}` is {3} bits wide, \
              but `{1}`'s mantissa is only {4} bits wide)",
             cast_from,
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
index 4d1a0f678f4..960c81045e3 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_ptr_alignment.rs
@@ -48,7 +48,7 @@ fn lint_cast_ptr_alignment<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, cast_f
             cx,
             CAST_PTR_ALIGNMENT,
             expr.span,
-            &format!(
+            format!(
                 "casting from `{cast_from}` to a more-strictly-aligned pointer (`{cast_to}`) ({} < {} bytes)",
                 from_layout.align.abi.bytes(),
                 to_layout.align.abi.bytes(),
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs b/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
index 8fd95d9654c..2b6e17dc103 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_sign_loss.rs
@@ -47,7 +47,7 @@ pub(super) fn check<'cx>(
             cx,
             CAST_SIGN_LOSS,
             expr.span,
-            &format!("casting `{cast_from}` to `{cast_to}` may lose the sign of the value"),
+            format!("casting `{cast_from}` to `{cast_to}` may lose the sign of the value"),
         );
     }
 }
@@ -118,7 +118,7 @@ enum Sign {
     Uncertain,
 }
 
-fn expr_sign<'cx>(cx: &LateContext<'cx>, expr: &Expr<'_>, ty: impl Into<Option<Ty<'cx>>>) -> Sign {
+fn expr_sign<'cx, 'tcx>(cx: &LateContext<'cx>, mut expr: &'tcx Expr<'tcx>, ty: impl Into<Option<Ty<'cx>>>) -> Sign {
     // Try evaluate this expr first to see if it's positive
     if let Some(val) = get_const_signed_int_eval(cx, expr, ty) {
         return if val >= 0 { Sign::ZeroOrPositive } else { Sign::Negative };
@@ -134,11 +134,12 @@ fn expr_sign<'cx>(cx: &LateContext<'cx>, expr: &Expr<'_>, ty: impl Into<Option<T
         // Peel unwrap(), expect(), etc.
         while let Some(&found_name) = METHODS_UNWRAP.iter().find(|&name| &method_name == name)
             && let Some(arglist) = method_chain_args(expr, &[found_name])
-            && let ExprKind::MethodCall(inner_path, ..) = &arglist[0].0.kind
+            && let ExprKind::MethodCall(inner_path, recv, ..) = &arglist[0].0.kind
         {
             // The original type has changed, but we can't use `ty` here anyway, because it has been
             // moved.
             method_name = inner_path.ident.name.as_str();
+            expr = recv;
         }
 
         if METHODS_POW.iter().any(|&name| method_name == name)
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
index 76d5c329179..285f0357112 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_different_sizes.rs
@@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, msrv: &Msrv
                     cx,
                     CAST_SLICE_DIFFERENT_SIZES,
                     expr.span,
-                    &format!(
+                    format!(
                         "casting between raw pointers to `[{}]` (element size {from_size}) and `[{}]` (element size {to_size}) does not adjust the count",
                         start_ty.ty, end_ty.ty,
                     ),
diff --git a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
index 48629b6c5cc..1d89f6c75e1 100644
--- a/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/cast_slice_from_raw_parts.rs
@@ -46,7 +46,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
             cx,
             CAST_SLICE_FROM_RAW_PARTS,
             span,
-            &format!("casting the result of `{func}` to {cast_to}"),
+            format!("casting the result of `{func}` to {cast_to}"),
             "replace with",
             format!("core::ptr::slice_{func}({ptr}, {len})"),
             applicability,
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
index a26bfab4e7c..f263bec1576 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast.rs
@@ -25,7 +25,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
                     cx,
                     FN_TO_NUMERIC_CAST,
                     expr.span,
-                    &format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
+                    format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
                     "try",
                     format!("{from_snippet} as usize"),
                     applicability,
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
index 75654129408..826589bf303 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_any.rs
@@ -23,7 +23,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
                 cx,
                 FN_TO_NUMERIC_CAST_ANY,
                 expr.span,
-                &format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
+                format!("casting function pointer `{from_snippet}` to `{cast_to}`"),
                 "did you mean to invoke the function?",
                 format!("{from_snippet}() as {cast_to}"),
                 applicability,
diff --git a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
index 556be1d1506..0e11bcfb8ec 100644
--- a/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/fn_to_numeric_cast_with_truncation.rs
@@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, cast_expr: &Expr<'_>,
                     cx,
                     FN_TO_NUMERIC_CAST_WITH_TRUNCATION,
                     expr.span,
-                    &format!("casting function pointer `{from_snippet}` to `{cast_to}`, which truncates the value"),
+                    format!("casting function pointer `{from_snippet}` to `{cast_to}`, which truncates the value"),
                     "try",
                     format!("{from_snippet} as usize"),
                     applicability,
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
index 5a121e6a7eb..68841076f77 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_as_ptr.rs
@@ -62,8 +62,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, msrv: &Msrv) {
         // we omit following `cast`:
         let omit_cast = if let ExprKind::Call(func, []) = cast_expr.kind
             && let ExprKind::Path(ref qpath @ QPath::Resolved(None, path)) = func.kind
+            && let Some(method_defid) = path.res.opt_def_id()
         {
-            let method_defid = path.res.def_id();
             if cx.tcx.is_diagnostic_item(sym::ptr_null, method_defid) {
                 OmitFollowedCastReason::Null(qpath)
             } else if cx.tcx.is_diagnostic_item(sym::ptr_null_mut, method_defid) {
diff --git a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
index e88146331ca..921693567fc 100644
--- a/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/ptr_cast_constness.rs
@@ -36,7 +36,7 @@ pub(super) fn check<'tcx>(
             PTR_CAST_CONSTNESS,
             expr.span,
             "`as` casting between raw pointers while changing only its constness",
-            &format!("try `pointer::cast_{constness}`, a safer alternative"),
+            format!("try `pointer::cast_{constness}`, a safer alternative"),
             format!("{}.cast_{constness}()", sugg.maybe_par()),
             Applicability::MachineApplicable,
         );
diff --git a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
index 148d52cb5dd..a7f7bf7854e 100644
--- a/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/casts/unnecessary_cast.rs
@@ -51,7 +51,7 @@ pub(super) fn check<'tcx>(
             cx,
             UNNECESSARY_CAST,
             expr.span,
-            &format!(
+            format!(
                 "casting raw pointers to the same type and constness is unnecessary (`{cast_from}` -> `{cast_to}`)"
             ),
             "try",
@@ -166,7 +166,7 @@ pub(super) fn check<'tcx>(
             cx,
             UNNECESSARY_CAST,
             expr.span,
-            &format!("casting to the same type is unnecessary (`{cast_from}` -> `{cast_to}`)"),
+            format!("casting to the same type is unnecessary (`{cast_from}` -> `{cast_to}`)"),
             "try",
             if needs_block {
                 format!("{{ {cast_str} }}")
@@ -209,7 +209,7 @@ fn lint_unnecessary_cast(
         cx,
         UNNECESSARY_CAST,
         expr.span,
-        &format!("casting {literal_kind_name} literal to `{cast_to}` is unnecessary"),
+        format!("casting {literal_kind_name} literal to `{cast_to}` is unnecessary"),
         "try",
         sugg,
         Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
index 7dac3c5d9da..ee1bb63b50d 100644
--- a/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
+++ b/src/tools/clippy/clippy_lints/src/cognitive_complexity.rs
@@ -121,7 +121,7 @@ impl CognitiveComplexity {
                 cx,
                 COGNITIVE_COMPLEXITY,
                 fn_span,
-                &format!(
+                format!(
                     "the function has a cognitive complexity of ({cc}/{})",
                     self.limit.limit()
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
index e921b9b46a6..6942ca53640 100644
--- a/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
+++ b/src/tools/clippy/clippy_lints/src/collection_is_never_read.rs
@@ -70,7 +70,7 @@ impl<'tcx> LateLintPass<'tcx> for CollectionIsNeverRead {
     }
 }
 
-fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections: &[rustc_span::Symbol]) -> bool {
+fn match_acceptable_type(cx: &LateContext<'_>, local: &LetStmt<'_>, collections: &[Symbol]) -> bool {
     let ty = cx.typeck_results().pat_ty(local.pat);
     collections.iter().any(|&sym| is_type_diagnostic_item(cx, ty, sym))
     // String type is a lang item but not a diagnostic item for now so we need a separate check
diff --git a/src/tools/clippy/clippy_lints/src/declared_lints.rs b/src/tools/clippy/clippy_lints/src/declared_lints.rs
index c8e148598a2..5ff7d8e5134 100644
--- a/src/tools/clippy/clippy_lints/src/declared_lints.rs
+++ b/src/tools/clippy/clippy_lints/src/declared_lints.rs
@@ -254,6 +254,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::large_include_file::LARGE_INCLUDE_FILE_INFO,
     crate::large_stack_arrays::LARGE_STACK_ARRAYS_INFO,
     crate::large_stack_frames::LARGE_STACK_FRAMES_INFO,
+    crate::legacy_numeric_constants::LEGACY_NUMERIC_CONSTANTS_INFO,
     crate::len_zero::COMPARISON_TO_EMPTY_INFO,
     crate::len_zero::LEN_WITHOUT_IS_EMPTY_INFO,
     crate::len_zero::LEN_ZERO_INFO,
@@ -678,6 +679,7 @@ pub(crate) static LINTS: &[&crate::LintInfo] = &[
     crate::trait_bounds::TYPE_REPETITION_IN_BOUNDS_INFO,
     crate::transmute::CROSSPOINTER_TRANSMUTE_INFO,
     crate::transmute::EAGER_TRANSMUTE_INFO,
+    crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS_INFO,
     crate::transmute::TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS_INFO,
     crate::transmute::TRANSMUTE_BYTES_TO_STR_INFO,
     crate::transmute::TRANSMUTE_FLOAT_TO_INT_INFO,
diff --git a/src/tools/clippy/clippy_lints/src/default.rs b/src/tools/clippy/clippy_lints/src/default.rs
index 98a6d9370c3..2b3f4854255 100644
--- a/src/tools/clippy/clippy_lints/src/default.rs
+++ b/src/tools/clippy/clippy_lints/src/default.rs
@@ -100,7 +100,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
                 cx,
                 DEFAULT_TRAIT_ACCESS,
                 expr.span,
-                &format!("calling `{replacement}` is more clear than this expression"),
+                format!("calling `{replacement}` is more clear than this expression"),
                 "try",
                 replacement,
                 Applicability::Unspecified, // First resolve the TODO above
@@ -243,7 +243,7 @@ impl<'tcx> LateLintPass<'tcx> for Default {
                     first_assign.unwrap().span,
                     "field assignment outside of initializer for an instance created with Default::default()",
                     Some(local.span),
-                    &format!("consider initializing the variable with `{sugg}` and removing relevant reassignments"),
+                    format!("consider initializing the variable with `{sugg}` and removing relevant reassignments"),
                 );
                 self.reassigned_linted.insert(span);
             }
diff --git a/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs
index 71e1a25c2bc..13778175496 100644
--- a/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs
+++ b/src/tools/clippy/clippy_lints/src/default_constructed_unit_structs.rs
@@ -56,7 +56,7 @@ fn is_alias(ty: hir::Ty<'_>) -> bool {
 
 impl LateLintPass<'_> for DefaultConstructedUnitStructs {
     fn check_expr<'tcx>(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>) {
-        if let hir::ExprKind::Call(fn_expr, &[]) = expr.kind
+        if let ExprKind::Call(fn_expr, &[]) = expr.kind
             // make sure we have a call to `Default::default`
             && let ExprKind::Path(ref qpath @ hir::QPath::TypeRelative(base, _)) = fn_expr.kind
             // make sure this isn't a type alias:
diff --git a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
index e617c19eff0..ac49e6f1a48 100644
--- a/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
+++ b/src/tools/clippy/clippy_lints/src/default_instead_of_iter_empty.rs
@@ -49,7 +49,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
                 cx,
                 DEFAULT_INSTEAD_OF_ITER_EMPTY,
                 expr.span,
-                &format!("`{path}()` is the more idiomatic way"),
+                format!("`{path}()` is the more idiomatic way"),
                 "try",
                 sugg,
                 applicability,
@@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultIterEmpty {
 
 fn make_sugg(
     cx: &LateContext<'_>,
-    ty_path: &rustc_hir::QPath<'_>,
+    ty_path: &QPath<'_>,
     ctxt: SyntaxContext,
     applicability: &mut Applicability,
     path: &str,
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 bfd89bfd2c7..3f87ed8df2b 100644
--- a/src/tools/clippy/clippy_lints/src/default_union_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/default_union_representation.rs
@@ -62,7 +62,7 @@ impl<'tcx> LateLintPass<'tcx> for DefaultUnionRepresentation {
                 item.span,
                 "this union has the default representation",
                 None,
-                &format!(
+                format!(
                     "consider annotating `{}` with `#[repr(C)]` to explicitly specify memory layout",
                     cx.tcx.def_path_str(item.owner_id)
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/derivable_impls.rs b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
index b0f46f5c646..80327586fed 100644
--- a/src/tools/clippy/clippy_lints/src/derivable_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/derivable_impls.rs
@@ -79,7 +79,7 @@ fn is_path_self(e: &Expr<'_>) -> bool {
 fn contains_trait_object(ty: Ty<'_>) -> bool {
     match ty.kind() {
         ty::Ref(_, ty, _) => contains_trait_object(*ty),
-        ty::Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object),
+        Adt(def, args) => def.is_box() && args[0].as_type().map_or(false, contains_trait_object),
         ty::Dynamic(..) => true,
         _ => false,
     }
diff --git a/src/tools/clippy/clippy_lints/src/derive.rs b/src/tools/clippy/clippy_lints/src/derive.rs
index c554edc8fce..5f9700b76d9 100644
--- a/src/tools/clippy/clippy_lints/src/derive.rs
+++ b/src/tools/clippy/clippy_lints/src/derive.rs
@@ -11,8 +11,7 @@ use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::hir::nested_filter;
 use rustc_middle::traits::Reveal;
 use rustc_middle::ty::{
-    self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, ToPredicate, TraitPredicate, Ty,
-    TyCtxt,
+    self, ClauseKind, GenericArgKind, GenericParamDefKind, ParamEnv, ToPredicate, TraitPredicate, Ty, TyCtxt,
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::def_id::LocalDefId;
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
index 4a617ba34d5..871f529da6c 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_macros.rs
@@ -102,11 +102,11 @@ impl DisallowedMacros {
                         DISALLOWED_MACROS,
                         cx.tcx.local_def_id_to_hir_id(derive_src.def_id),
                         mac.span,
-                        &msg,
+                        msg,
                         add_note,
                     );
                 } else {
-                    span_lint_and_then(cx, DISALLOWED_MACROS, mac.span, &msg, add_note);
+                    span_lint_and_then(cx, DISALLOWED_MACROS, mac.span, msg, add_note);
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
index 1868d3cd391..9de879604e2 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_methods.rs
@@ -99,7 +99,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedMethods {
             None => return,
         };
         let msg = format!("use of a disallowed method `{}`", conf.path());
-        span_lint_and_then(cx, DISALLOWED_METHODS, expr.span, &msg, |diag| {
+        span_lint_and_then(cx, DISALLOWED_METHODS, expr.span, msg, |diag| {
             if let Some(reason) = conf.reason() {
                 diag.note(reason);
             }
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_names.rs b/src/tools/clippy/clippy_lints/src/disallowed_names.rs
index 09dad5554ad..2afbf184117 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_names.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_names.rs
@@ -64,7 +64,7 @@ impl<'tcx> LateLintPass<'tcx> for DisallowedNames {
                     cx,
                     DISALLOWED_NAMES,
                     ident.span,
-                    &format!("use of a disallowed/placeholder name `{}`", ident.name),
+                    format!("use of a disallowed/placeholder name `{}`", ident.name),
                 );
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
index 0c1bb2da7e8..def4b5932b4 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_script_idents.rs
@@ -98,7 +98,7 @@ impl EarlyLintPass for DisallowedScriptIdents {
                         cx,
                         DISALLOWED_SCRIPT_IDENTS,
                         span,
-                        &format!(
+                        format!(
                             "identifier `{symbol_str}` has a Unicode script that is not allowed by configuration: {}",
                             script.full_name()
                         ),
diff --git a/src/tools/clippy/clippy_lints/src/disallowed_types.rs b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
index 130f56b698f..4196309a22a 100644
--- a/src/tools/clippy/clippy_lints/src/disallowed_types.rs
+++ b/src/tools/clippy/clippy_lints/src/disallowed_types.rs
@@ -127,7 +127,7 @@ fn emit(cx: &LateContext<'_>, name: &str, span: Span, conf: &DisallowedPath) {
         cx,
         DISALLOWED_TYPES,
         span,
-        &format!("`{name}` is not allowed according to config"),
+        format!("`{name}` is not allowed according to config"),
         |diag| {
             if let Some(reason) = conf.reason() {
                 diag.note(reason);
diff --git a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
index bf6f54c1e72..119473c2454 100644
--- a/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/drop_forget_ref.rs
@@ -129,9 +129,9 @@ impl<'tcx> LateLintPass<'tcx> for DropForgetRef {
                 cx,
                 lint,
                 expr.span,
-                &msg,
+                msg,
                 note_span,
-                &format!("argument has type `{arg_ty}`"),
+                format!("argument has type `{arg_ty}`"),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
index 471335c098f..ed27e38ef2d 100644
--- a/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
+++ b/src/tools/clippy/clippy_lints/src/duplicate_mod.rs
@@ -119,7 +119,7 @@ impl EarlyLintPass for DuplicateMod {
                 cx,
                 DUPLICATE_MOD,
                 multi_span,
-                &format!("file is loaded as a module multiple times: `{}`", local_path.display()),
+                format!("file is loaded as a module multiple times: `{}`", local_path.display()),
                 None,
                 "replace all but one `mod` item with `use` items",
             );
diff --git a/src/tools/clippy/clippy_lints/src/endian_bytes.rs b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
index b8a817e21b1..dd03df797de 100644
--- a/src/tools/clippy/clippy_lints/src/endian_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/endian_bytes.rs
@@ -197,7 +197,7 @@ fn maybe_lint_endian_bytes(cx: &LateContext<'_>, expr: &Expr<'_>, prefix: Prefix
         cx,
         lint.as_lint(),
         expr.span,
-        &format!(
+        format!(
             "usage of the {}`{ty}::{}`{}",
             if prefix == Prefix::From { "function " } else { "" },
             lint.as_name(prefix),
diff --git a/src/tools/clippy/clippy_lints/src/entry.rs b/src/tools/clippy/clippy_lints/src/entry.rs
index dafbf6c8846..b7c9d3d0385 100644
--- a/src/tools/clippy/clippy_lints/src/entry.rs
+++ b/src/tools/clippy/clippy_lints/src/entry.rs
@@ -186,7 +186,7 @@ impl<'tcx> LateLintPass<'tcx> for HashMapPass {
             cx,
             MAP_ENTRY,
             expr.span,
-            &format!("usage of `contains_key` followed by `insert` on a `{}`", map_ty.name()),
+            format!("usage of `contains_key` followed by `insert` on a `{}`", map_ty.name()),
             "try",
             sugg,
             app,
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index ad589dad350..386d4c3c317 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -177,7 +177,7 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
         }
     }
 
-    fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
+    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
 impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
diff --git a/src/tools/clippy/clippy_lints/src/eta_reduction.rs b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
index eccfc31fdd3..850a4f0eec8 100644
--- a/src/tools/clippy/clippy_lints/src/eta_reduction.rs
+++ b/src/tools/clippy/clippy_lints/src/eta_reduction.rs
@@ -3,14 +3,14 @@ use clippy_utils::higher::VecArgs;
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::type_diagnostic_name;
 use clippy_utils::usage::{local_used_after_expr, local_used_in};
-use clippy_utils::{get_path_from_caller_to_method_type, higher, is_adjusted, path_to_local, path_to_local_id};
+use clippy_utils::{get_path_from_caller_to_method_type, is_adjusted, path_to_local, path_to_local_id};
 use rustc_errors::Applicability;
 use rustc_hir::{BindingAnnotation, Expr, ExprKind, FnRetTy, Param, PatKind, QPath, TyKind, Unsafety};
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::{
-    self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, RegionKind,
-    Ty, TypeVisitableExt, TypeckResults,
+    self, Binder, ClosureArgs, ClosureKind, FnSig, GenericArg, GenericArgKind, List, Region, RegionKind, Ty,
+    TypeVisitableExt, TypeckResults,
 };
 use rustc_session::declare_lint_pass;
 use rustc_span::symbol::sym;
@@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for EtaReduction {
 
         if body.value.span.from_expansion() {
             if body.params.is_empty() {
-                if let Some(VecArgs::Vec(&[])) = higher::VecArgs::hir(cx, body.value) {
+                if let Some(VecArgs::Vec(&[])) = VecArgs::hir(cx, body.value) {
                     // replace `|| vec![]` with `Vec::new`
                     span_lint_and_sugg(
                         cx,
diff --git a/src/tools/clippy/clippy_lints/src/excessive_bools.rs b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
index c5f7212c4c0..62d5ce24d40 100644
--- a/src/tools/clippy/clippy_lints/src/excessive_bools.rs
+++ b/src/tools/clippy/clippy_lints/src/excessive_bools.rs
@@ -120,7 +120,7 @@ impl ExcessiveBools {
                 cx,
                 FN_PARAMS_EXCESSIVE_BOOLS,
                 span,
-                &format!("more than {} bools in function parameters", self.max_fn_params_bools),
+                format!("more than {} bools in function parameters", self.max_fn_params_bools),
                 None,
                 "consider refactoring bools into two-variant enums",
             );
@@ -145,7 +145,7 @@ impl<'tcx> LateLintPass<'tcx> for ExcessiveBools {
                     cx,
                     STRUCT_EXCESSIVE_BOOLS,
                     item.span,
-                    &format!("more than {} bools in a struct", self.max_struct_bools),
+                    format!("more than {} bools in a struct", self.max_struct_bools),
                     None,
                     "consider using a state machine or refactoring bools into two-variant enums",
                 );
diff --git a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
index 3a621d967f4..9ffda645742 100644
--- a/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
+++ b/src/tools/clippy/clippy_lints/src/exhaustive_items.rs
@@ -38,7 +38,7 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Warns on any exported `structs`s that are not tagged `#[non_exhaustive]`
+    /// Warns on any exported `struct`s that are not tagged `#[non_exhaustive]`
     ///
     /// ### Why is this bad?
     /// Exhaustive structs are typically fine, but a project which does
diff --git a/src/tools/clippy/clippy_lints/src/explicit_write.rs b/src/tools/clippy/clippy_lints/src/explicit_write.rs
index 2e9bec6a7b0..33bd5a5a9d3 100644
--- a/src/tools/clippy/clippy_lints/src/explicit_write.rs
+++ b/src/tools/clippy/clippy_lints/src/explicit_write.rs
@@ -88,7 +88,7 @@ impl<'tcx> LateLintPass<'tcx> for ExplicitWrite {
                 cx,
                 EXPLICIT_WRITE,
                 expr.span,
-                &format!("use of `{used}.unwrap()`"),
+                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 538d29eb43d..7484f772e08 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
@@ -110,11 +110,11 @@ impl<'cx, 'tcx> TypeWalker<'cx, 'tcx> {
             .map_or(param.span, |bound_span| param.span.with_hi(bound_span.hi()))
     }
 
-    fn emit_help(&self, spans: Vec<Span>, msg: &str, help: &'static str) {
+    fn emit_help(&self, spans: Vec<Span>, msg: String, help: &'static str) {
         span_lint_and_help(self.cx, EXTRA_UNUSED_TYPE_PARAMETERS, spans, msg, None, help);
     }
 
-    fn emit_sugg(&self, spans: Vec<Span>, msg: &str, help: &'static str) {
+    fn emit_sugg(&self, spans: Vec<Span>, msg: String, help: &'static str) {
         let suggestions: Vec<(Span, String)> = spans.iter().copied().zip(std::iter::repeat(String::new())).collect();
         span_lint_and_then(self.cx, EXTRA_UNUSED_TYPE_PARAMETERS, spans, msg, |diag| {
             diag.multipart_suggestion(help, suggestions, Applicability::MachineApplicable);
@@ -167,7 +167,7 @@ impl<'cx, 'tcx> TypeWalker<'cx, 'tcx> {
                 .iter()
                 .map(|(_, param)| self.get_bound_span(param))
                 .collect::<Vec<_>>();
-            self.emit_help(spans, &msg, help);
+            self.emit_help(spans, msg, help);
         } else {
             let spans = if explicit_params.len() == extra_params.len() {
                 vec![self.generics.span] // Remove the entire list of generics
@@ -196,7 +196,7 @@ impl<'cx, 'tcx> TypeWalker<'cx, 'tcx> {
                     })
                     .collect()
             };
-            self.emit_sugg(spans, &msg, help);
+            self.emit_sugg(spans, msg, help);
         };
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/float_literal.rs b/src/tools/clippy/clippy_lints/src/float_literal.rs
index 981a76d683d..2cd4e9e99a5 100644
--- a/src/tools/clippy/clippy_lints/src/float_literal.rs
+++ b/src/tools/clippy/clippy_lints/src/float_literal.rs
@@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
                 LitFloatType::Unsuffixed => None,
             };
             let (is_whole, is_inf, mut float_str) = match fty {
-                FloatTy::F16 => {
+                FloatTy::F16 | FloatTy::F128 => {
                     // FIXME(f16_f128): do a check like the others when parsing is available
                     return;
                 },
@@ -97,10 +97,6 @@ impl<'tcx> LateLintPass<'tcx> for FloatLiteral {
 
                     (value.fract() == 0.0, value.is_infinite(), formatter.format(value))
                 },
-                FloatTy::F128 => {
-                    // FIXME(f16_f128): do a check like the others when parsing is available
-                    return;
-                },
             };
 
             if is_inf {
diff --git a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
index c8b87e510ed..46d47e217b0 100644
--- a/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/floating_point_arithmetic.rs
@@ -552,9 +552,9 @@ fn is_testing_negative(cx: &LateContext<'_>, expr: &Expr<'_>, test: &Expr<'_>) -
 /// Returns true iff expr is some zero literal
 fn is_zero(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     match constant_simple(cx, cx.typeck_results(), expr) {
-        Some(Constant::Int(i)) => i == 0,
-        Some(Constant::F32(f)) => f == 0.0,
-        Some(Constant::F64(f)) => f == 0.0,
+        Some(Int(i)) => i == 0,
+        Some(F32(f)) => f == 0.0,
+        Some(F64(f)) => f == 0.0,
         _ => false,
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/format_args.rs b/src/tools/clippy/clippy_lints/src/format_args.rs
index 61f550ce0be..80db617c639 100644
--- a/src/tools/clippy/clippy_lints/src/format_args.rs
+++ b/src/tools/clippy/clippy_lints/src/format_args.rs
@@ -401,7 +401,7 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
             self.cx,
             FORMAT_IN_FORMAT_ARGS,
             self.macro_call.span,
-            &format!("`format!` in `{name}!` args"),
+            format!("`format!` in `{name}!` args"),
             |diag| {
                 diag.help(format!(
                     "combine the `format!(..)` arguments with the outer `{name}!(..)` call"
@@ -431,7 +431,7 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
                     cx,
                     TO_STRING_IN_FORMAT_ARGS,
                     to_string_span.with_lo(receiver.span.hi()),
-                    &format!("`to_string` applied to a type that implements `Display` in `{name}!` args"),
+                    format!("`to_string` applied to a type that implements `Display` in `{name}!` args"),
                     "remove this",
                     String::new(),
                     Applicability::MachineApplicable,
@@ -441,7 +441,7 @@ impl<'a, 'tcx> FormatArgsExpr<'a, 'tcx> {
                     cx,
                     TO_STRING_IN_FORMAT_ARGS,
                     value.span,
-                    &format!("`to_string` applied to a type that implements `Display` in `{name}!` args"),
+                    format!("`to_string` applied to a type that implements `Display` in `{name}!` args"),
                     "use this",
                     format!(
                         "{}{:*>n_needed_derefs$}{receiver_snippet}",
diff --git a/src/tools/clippy/clippy_lints/src/format_impl.rs b/src/tools/clippy/clippy_lints/src/format_impl.rs
index 93517076cda..0a52347940a 100644
--- a/src/tools/clippy/clippy_lints/src/format_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/format_impl.rs
@@ -214,7 +214,7 @@ impl<'a, 'tcx> FormatImplExpr<'a, 'tcx> {
                 self.cx,
                 RECURSIVE_FORMAT_IMPL,
                 self.expr.span,
-                &format!("using `self` as `{name}` in `impl {name}` will cause infinite recursion"),
+                format!("using `self` as `{name}` in `impl {name}` will cause infinite recursion"),
             );
         }
     }
@@ -235,7 +235,7 @@ impl<'a, 'tcx> FormatImplExpr<'a, 'tcx> {
                 self.cx,
                 PRINT_IN_FORMAT_IMPL,
                 macro_call.span,
-                &format!("use of `{name}!` in `{}` impl", self.format_trait_impl.name),
+                format!("use of `{name}!` in `{}` impl", self.format_trait_impl.name),
                 "replace with",
                 if let Some(formatter_name) = self.format_trait_impl.formatter_name {
                     format!("{replacement}!({formatter_name}, ..)")
diff --git a/src/tools/clippy/clippy_lints/src/formatting.rs b/src/tools/clippy/clippy_lints/src/formatting.rs
index c3ef6f180c9..34e93bdb9b9 100644
--- a/src/tools/clippy/clippy_lints/src/formatting.rs
+++ b/src/tools/clippy/clippy_lints/src/formatting.rs
@@ -151,12 +151,12 @@ fn check_assign(cx: &EarlyContext<'_>, expr: &Expr) {
                             cx,
                             SUSPICIOUS_ASSIGNMENT_FORMATTING,
                             eqop_span,
-                            &format!(
+                            format!(
                                 "this looks like you are trying to use `.. {op}= ..`, but you \
                                  really are doing `.. = ({op} ..)`"
                             ),
                             None,
-                            &format!("to remove this lint, use either `{op}=` or `= {op}`"),
+                            format!("to remove this lint, use either `{op}=` or `= {op}`"),
                         );
                     }
                 }
@@ -187,12 +187,12 @@ fn check_unop(cx: &EarlyContext<'_>, expr: &Expr) {
             cx,
             SUSPICIOUS_UNARY_OP_FORMATTING,
             eqop_span,
-            &format!(
+            format!(
                 "by not having a space between `{binop_str}` and `{unop_str}` it looks like \
                  `{binop_str}{unop_str}` is a single operator"
             ),
             None,
-            &format!("put a space between `{binop_str}` and `{unop_str}` and remove the space after `{unop_str}`"),
+            format!("put a space between `{binop_str}` and `{unop_str}` and remove the space after `{unop_str}`"),
         );
     }
 }
@@ -215,6 +215,7 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
         // it’s bad when there is a ‘\n’ after the “else”
         && let Some(else_snippet) = snippet_opt(cx, else_span)
         && let Some((pre_else, post_else)) = else_snippet.split_once("else")
+        && !else_snippet.contains('/')
         && let Some((_, post_else_post_eol)) = post_else.split_once('\n')
     {
         // Allow allman style braces `} \n else \n {`
@@ -238,9 +239,9 @@ fn check_else(cx: &EarlyContext<'_>, expr: &Expr) {
             cx,
             SUSPICIOUS_ELSE_FORMATTING,
             else_span,
-            &format!("this is an `else {else_desc}` but the formatting might hide it"),
+            format!("this is an `else {else_desc}` but the formatting might hide it"),
             None,
-            &format!(
+            format!(
                 "to remove this lint, remove the `else` or remove the new line between \
                  `else` and `{else_desc}`",
             ),
@@ -308,9 +309,9 @@ fn check_missing_else(cx: &EarlyContext<'_>, first: &Expr, second: &Expr) {
             cx,
             SUSPICIOUS_ELSE_FORMATTING,
             else_span,
-            &format!("this looks like {looks_like} but the `else` is missing"),
+            format!("this looks like {looks_like} but the `else` is missing"),
             None,
-            &format!("to remove this lint, add the missing `else` or add a new line before {next_thing}",),
+            format!("to remove this lint, add the missing `else` or add a new line before {next_thing}",),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
index 286ba2306c9..ba2495c17a2 100644
--- a/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/from_raw_with_void_ptr.rs
@@ -4,7 +4,7 @@ use clippy_utils::ty::is_c_void;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{Expr, ExprKind, QPath};
 use rustc_lint::{LateContext, LateLintPass};
-use rustc_middle::ty::{RawPtr};
+use rustc_middle::ty::RawPtr;
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
@@ -52,7 +52,7 @@ impl LateLintPass<'_> for FromRawWithVoidPtr {
                 cx,
                 FROM_RAW_WITH_VOID_PTR,
                 expr.span,
-                &msg,
+                msg,
                 Some(arg.span),
                 "cast this to a pointer of the appropriate type",
             );
diff --git a/src/tools/clippy/clippy_lints/src/functions/must_use.rs b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
index d752d010f9f..d0c66900c00 100644
--- a/src/tools/clippy/clippy_lints/src/functions/must_use.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/must_use.rs
@@ -142,7 +142,7 @@ fn check_must_use_candidate<'tcx>(
     item_span: Span,
     item_id: hir::OwnerId,
     fn_span: Span,
-    msg: &str,
+    msg: &'static str,
 ) {
     if has_mutable_arg(cx, body)
         || mutates_static(cx, body)
@@ -207,9 +207,7 @@ fn is_mutable_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>, tys: &mut DefIdSet)
         },
         ty::Tuple(args) => args.iter().any(|ty| is_mutable_ty(cx, ty, tys)),
         ty::Array(ty, _) | ty::Slice(ty) => is_mutable_ty(cx, ty, tys),
-        ty::RawPtr(ty, mutbl) | ty::Ref(_, ty, mutbl) => {
-            mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys)
-        },
+        ty::RawPtr(ty, mutbl) | ty::Ref(_, ty, mutbl) => mutbl == hir::Mutability::Mut || is_mutable_ty(cx, ty, tys),
         // calling something constitutes a side effect, so return true on all callables
         // also never calls need not be used, so return true for them, too
         _ => true,
diff --git a/src/tools/clippy/clippy_lints/src/functions/result.rs b/src/tools/clippy/clippy_lints/src/functions/result.rs
index 37fbf2c7d59..93f088d3e33 100644
--- a/src/tools/clippy/clippy_lints/src/functions/result.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/result.rs
@@ -2,7 +2,7 @@ use rustc_errors::Diag;
 use rustc_hir as hir;
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::in_external_macro;
-use rustc_middle::ty::{self, Adt, Ty};
+use rustc_middle::ty::{Adt, Ty};
 use rustc_span::{sym, Span};
 
 use clippy_utils::diagnostics::{span_lint_and_help, span_lint_and_then};
@@ -25,7 +25,7 @@ fn result_err_ty<'tcx>(
             .tcx
             .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(id).instantiate_identity().output())
         && is_type_diagnostic_item(cx, ty, sym::Result)
-        && let ty::Adt(_, args) = ty.kind()
+        && let Adt(_, args) = ty.kind()
     {
         let err_ty = args.type_at(1);
         Some((hir_ty, err_ty))
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
index 1e08922a616..e72a2ad49d8 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_arguments.rs
@@ -59,7 +59,7 @@ fn check_arg_number(cx: &LateContext<'_>, decl: &hir::FnDecl<'_>, fn_span: Span,
             cx,
             TOO_MANY_ARGUMENTS,
             fn_span,
-            &format!("this function has too many arguments ({args}/{too_many_arguments_threshold})"),
+            format!("this function has too many arguments ({args}/{too_many_arguments_threshold})"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
index 34f1bf3b2b1..586ca58d60d 100644
--- a/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
+++ b/src/tools/clippy/clippy_lints/src/functions/too_many_lines.rs
@@ -77,7 +77,7 @@ pub(super) fn check_fn(
             cx,
             TOO_MANY_LINES,
             span,
-            &format!("this function has too many lines ({line_count}/{too_many_lines_threshold})"),
+            format!("this function has too many lines ({line_count}/{too_many_lines_threshold})"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
index 8f48941c4a9..f5ba62ae432 100644
--- a/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
+++ b/src/tools/clippy/clippy_lints/src/if_then_some_else_none.rs
@@ -117,9 +117,9 @@ impl<'tcx> LateLintPass<'tcx> for IfThenSomeElseNone {
                 cx,
                 IF_THEN_SOME_ELSE_NONE,
                 expr.span,
-                &format!("this could be simplified with `bool::{method_name}`"),
+                format!("this could be simplified with `bool::{method_name}`"),
                 None,
-                &help,
+                help,
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
index 8acb138332c..a46aae36d5c 100644
--- a/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
+++ b/src/tools/clippy/clippy_lints/src/implicit_hasher.rs
@@ -141,7 +141,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                         cx,
                         IMPLICIT_HASHER,
                         target.span(),
-                        &format!(
+                        format!(
                             "impl for `{}` should be generalized over different hashers",
                             target.type_name()
                         ),
@@ -187,7 +187,7 @@ impl<'tcx> LateLintPass<'tcx> for ImplicitHasher {
                             cx,
                             IMPLICIT_HASHER,
                             target.span(),
-                            &format!(
+                            format!(
                                 "parameter of type `{}` should be generalized over different hashers",
                                 target.type_name()
                             ),
diff --git a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
index 9f4d7b51271..7b97fc15caa 100644
--- a/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
+++ b/src/tools/clippy/clippy_lints/src/implied_bounds_in_impls.rs
@@ -56,7 +56,7 @@ fn emit_lint(
     index: usize,
     // The bindings that were implied, used for suggestion purposes since removing a bound with associated types
     // means we might need to then move it to a different bound
-    implied_bindings: &[rustc_hir::TypeBinding<'_>],
+    implied_bindings: &[TypeBinding<'_>],
     bound: &ImplTraitBound<'_>,
 ) {
     let implied_by = snippet(cx, bound.span, "..");
@@ -65,7 +65,7 @@ fn emit_lint(
         cx,
         IMPLIED_BOUNDS_IN_IMPLS,
         poly_trait.span,
-        &format!("this bound is already specified as the supertrait of `{implied_by}`"),
+        format!("this bound is already specified as the supertrait of `{implied_by}`"),
         |diag| {
             // If we suggest removing a bound, we may also need to extend the span
             // to include the `+` token that is ahead or behind,
diff --git a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
index cd000fcd184..35b4481bfee 100644
--- a/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
+++ b/src/tools/clippy/clippy_lints/src/incompatible_msrv.rs
@@ -33,7 +33,7 @@ declare_clippy_lint! {
     ///
     /// To fix this problem, either increase your MSRV or use another item
     /// available in your current MSRV.
-    #[clippy::version = "1.77.0"]
+    #[clippy::version = "1.78.0"]
     pub INCOMPATIBLE_MSRV,
     suspicious,
     "ensures that all items used in the crate are available for the current MSRV"
@@ -104,7 +104,7 @@ impl IncompatibleMsrv {
             cx,
             INCOMPATIBLE_MSRV,
             span,
-            &format!(
+            format!(
                 "current MSRV (Minimum Supported Rust Version) is `{}` but this item is stable since `{version}`",
                 self.msrv
             ),
diff --git a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
index ca2ac60306b..157f6105984 100644
--- a/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/inherent_to_string.rs
@@ -132,20 +132,20 @@ fn show_lint(cx: &LateContext<'_>, item: &ImplItem<'_>) {
             cx,
             INHERENT_TO_STRING_SHADOW_DISPLAY,
             item.span,
-            &format!(
+            format!(
                 "type `{self_type}` implements inherent method `to_string(&self) -> String` which shadows the implementation of `Display`"
             ),
             None,
-            &format!("remove the inherent method from type `{self_type}`"),
+            format!("remove the inherent method from type `{self_type}`"),
         );
     } else {
         span_lint_and_help(
             cx,
             INHERENT_TO_STRING,
             item.span,
-            &format!("implementation of inherent method `to_string(&self) -> String` for type `{self_type}`"),
+            format!("implementation of inherent method `to_string(&self) -> String` for type `{self_type}`"),
             None,
-            &format!("implement trait `Display` for type `{self_type}` instead"),
+            format!("implement trait `Display` for type `{self_type}` instead"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
index 83ecaeef982..860258fd030 100644
--- a/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
+++ b/src/tools/clippy/clippy_lints/src/inline_fn_without_body.rs
@@ -51,7 +51,7 @@ fn check_attrs(cx: &LateContext<'_>, name: Symbol, attrs: &[Attribute]) {
             cx,
             INLINE_FN_WITHOUT_BODY,
             attr.span,
-            &format!("use of `#[inline]` on trait method `{name}` which has no body"),
+            format!("use of `#[inline]` on trait method `{name}` which has no body"),
             |diag| {
                 diag.suggest_remove_item(cx, attr.span, "remove", Applicability::MachineApplicable);
             },
diff --git a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
index 17b6256f982..10b00f632bb 100644
--- a/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
+++ b/src/tools/clippy/clippy_lints/src/instant_subtraction.rs
@@ -1,5 +1,5 @@
 use clippy_config::msrvs::{self, Msrv};
-use clippy_utils::diagnostics::{self, span_lint_and_sugg};
+use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_context;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty;
@@ -149,7 +149,7 @@ fn print_unchecked_duration_subtraction_sugg(
     let left_expr = snippet_with_context(cx, left_expr.span, ctxt, "<instant>", &mut applicability).0;
     let right_expr = snippet_with_context(cx, right_expr.span, ctxt, "<duration>", &mut applicability).0;
 
-    diagnostics::span_lint_and_sugg(
+    span_lint_and_sugg(
         cx,
         UNCHECKED_DURATION_SUBTRACTION,
         expr.span,
diff --git a/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs b/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs
index 36dc45ca788..a3577b765c0 100644
--- a/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs
+++ b/src/tools/clippy/clippy_lints/src/integer_division_remainder_used.rs
@@ -43,7 +43,7 @@ impl LateLintPass<'_> for IntegerDivisionRemainderUsed {
                 cx,
                 INTEGER_DIVISION_REMAINDER_USED,
                 expr.span.source_callsite(),
-                &format!("use of {} has been disallowed in this context", op.node.as_str()),
+                format!("use of {} has been disallowed in this context", op.node.as_str()),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs
index 8bcd9b532bd..30f2285bdd2 100644
--- a/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/invalid_upcast_comparisons.rs
@@ -76,7 +76,7 @@ fn err_upcast_comparison(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, alwa
             cx,
             INVALID_UPCAST_COMPARISONS,
             span,
-            &format!(
+            format!(
                 "because of the numeric bounds on `{}` prior to casting, this expression is always {}",
                 snippet(cx, cast_val.span, "the expression"),
                 if always { "true" } else { "false" },
@@ -88,7 +88,7 @@ fn err_upcast_comparison(cx: &LateContext<'_>, span: Span, expr: &Expr<'_>, alwa
 fn upcast_comparison_bounds_err<'tcx>(
     cx: &LateContext<'tcx>,
     span: Span,
-    rel: comparisons::Rel,
+    rel: Rel,
     lhs_bounds: Option<(FullInt, FullInt)>,
     lhs: &'tcx Expr<'_>,
     rhs: &'tcx Expr<'_>,
diff --git a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
index 0b4c416d94d..6615122567d 100644
--- a/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
+++ b/src/tools/clippy/clippy_lints/src/item_name_repetitions.rs
@@ -240,9 +240,9 @@ fn check_fields(cx: &LateContext<'_>, threshold: u64, item: &Item<'_>, fields: &
             cx,
             STRUCT_FIELD_NAMES,
             item.span,
-            &format!("all fields have the same {what}fix: `{value}`"),
+            format!("all fields have the same {what}fix: `{value}`"),
             None,
-            &format!("remove the {what}fixes"),
+            format!("remove the {what}fixes"),
         );
     }
 }
@@ -370,9 +370,9 @@ fn check_variant(cx: &LateContext<'_>, threshold: u64, def: &EnumDef<'_>, item_n
         cx,
         ENUM_VARIANT_NAMES,
         span,
-        &format!("all variants have the same {what}fix: `{value}`"),
+        format!("all variants have the same {what}fix: `{value}`"),
         None,
-        &format!(
+        format!(
             "remove the {what}fixes and use full paths to \
              the variants instead of glob imports"
         ),
diff --git a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
index 32ae6be5687..1b5f1b49947 100644
--- a/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_not_returning_iterator.rs
@@ -84,7 +84,7 @@ fn check_sig(cx: &LateContext<'_>, name: &str, sig: &FnSig<'_>, fn_id: LocalDefI
                 cx,
                 ITER_NOT_RETURNING_ITERATOR,
                 sig.span,
-                &format!("this method is named `{name}` but its return type does not implement `Iterator`"),
+                format!("this method is named `{name}` but its return type does not implement `Iterator`"),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
index cf0ab88032c..c749a712330 100644
--- a/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
+++ b/src/tools/clippy/clippy_lints/src/iter_without_into_iter.rs
@@ -182,7 +182,7 @@ impl LateLintPass<'_> for IterWithoutIntoIter {
                 cx,
                 INTO_ITER_WITHOUT_ITER,
                 item.span,
-                &format!("`IntoIterator` implemented for a reference type without an `{expected_method_name}` method"),
+                format!("`IntoIterator` implemented for a reference type without an `{expected_method_name}` method"),
                 |diag| {
                     // The suggestion forwards to the `IntoIterator` impl and uses a form of UFCS
                     // to avoid name ambiguities, as there might be an inherent into_iter method
@@ -258,7 +258,7 @@ impl {self_ty_without_ref} {{
                 cx,
                 ITER_WITHOUT_INTO_ITER,
                 item.span,
-                &format!(
+                format!(
                     "`{}` method without an `IntoIterator` impl for `{self_ty_snippet}`",
                     item.ident
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/large_futures.rs b/src/tools/clippy/clippy_lints/src/large_futures.rs
index eb7570e9b44..07488a512a3 100644
--- a/src/tools/clippy/clippy_lints/src/large_futures.rs
+++ b/src/tools/clippy/clippy_lints/src/large_futures.rs
@@ -71,7 +71,7 @@ impl<'tcx> LateLintPass<'tcx> for LargeFuture {
                     cx,
                     LARGE_FUTURES,
                     expr.span,
-                    &format!("large future with a size of {} bytes", size.bytes()),
+                    format!("large future with a size of {} bytes", size.bytes()),
                     "consider `Box::pin` on it",
                     format!("Box::pin({})", snippet(cx, expr.span, "..")),
                     Applicability::Unspecified,
diff --git a/src/tools/clippy/clippy_lints/src/large_include_file.rs b/src/tools/clippy/clippy_lints/src/large_include_file.rs
index 1b5981ecc28..0599afca09f 100644
--- a/src/tools/clippy/clippy_lints/src/large_include_file.rs
+++ b/src/tools/clippy/clippy_lints/src/large_include_file.rs
@@ -74,7 +74,7 @@ impl LateLintPass<'_> for LargeIncludeFile {
                 expr.span,
                 "attempted to include a large file",
                 None,
-                &format!(
+                format!(
                     "the configuration allows a maximum size of {} bytes",
                     self.max_file_size
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
index fd33ba91bfd..afcb6745947 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_arrays.rs
@@ -58,12 +58,12 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackArrays {
                 cx,
                 LARGE_STACK_ARRAYS,
                 expr.span,
-                &format!(
+                format!(
                     "allocating a local array larger than {} bytes",
                     self.maximum_allowed_size
                 ),
                 None,
-                &format!(
+                format!(
                     "consider allocating on the heap with `vec!{}.into_boxed_slice()`",
                     snippet(cx, expr.span, "[...]")
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
index b397180a69c..49408d7e243 100644
--- a/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
+++ b/src/tools/clippy/clippy_lints/src/large_stack_frames.rs
@@ -1,10 +1,12 @@
-use std::ops::AddAssign;
+use std::{fmt, ops};
 
-use clippy_utils::diagnostics::span_lint_and_note;
+use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::fn_has_unsatisfiable_preds;
+use clippy_utils::source::snippet_opt;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::FnKind;
 use rustc_hir::{Body, FnDecl};
+use rustc_lexer::is_ident;
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::impl_lint_pass;
 use rustc_span::Span;
@@ -108,13 +110,25 @@ impl Space {
     }
 }
 
-impl AddAssign<u64> for Space {
-    fn add_assign(&mut self, rhs: u64) {
-        if let Self::Used(lhs) = self {
-            match lhs.checked_add(rhs) {
-                Some(sum) => *self = Self::Used(sum),
-                None => *self = Self::Overflow,
-            }
+impl fmt::Display for Space {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+        match self {
+            Space::Used(1) => write!(f, "1 byte"),
+            Space::Used(n) => write!(f, "{n} bytes"),
+            Space::Overflow => write!(f, "over 2⁶⁴-1 bytes"),
+        }
+    }
+}
+
+impl ops::Add<u64> for Space {
+    type Output = Self;
+    fn add(self, rhs: u64) -> Self {
+        match self {
+            Self::Used(lhs) => match lhs.checked_add(rhs) {
+                Some(sum) => Self::Used(sum),
+                None => Self::Overflow,
+            },
+            Self::Overflow => self,
         }
     }
 }
@@ -123,10 +137,10 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackFrames {
     fn check_fn(
         &mut self,
         cx: &LateContext<'tcx>,
-        _: FnKind<'tcx>,
+        fn_kind: FnKind<'tcx>,
         _: &'tcx FnDecl<'tcx>,
         _: &'tcx Body<'tcx>,
-        span: Span,
+        entire_fn_span: Span,
         local_def_id: LocalDefId,
     ) {
         let def_id = local_def_id.to_def_id();
@@ -138,22 +152,68 @@ impl<'tcx> LateLintPass<'tcx> for LargeStackFrames {
         let mir = cx.tcx.optimized_mir(def_id);
         let param_env = cx.tcx.param_env(def_id);
 
-        let mut frame_size = Space::Used(0);
+        let sizes_of_locals = || {
+            mir.local_decls.iter().filter_map(|local| {
+                let layout = cx.tcx.layout_of(param_env.and(local.ty)).ok()?;
+                Some((local, layout.size.bytes()))
+            })
+        };
 
-        for local in &mir.local_decls {
-            if let Ok(layout) = cx.tcx.layout_of(param_env.and(local.ty)) {
-                frame_size += layout.size.bytes();
-            }
-        }
+        let frame_size = sizes_of_locals().fold(Space::Used(0), |sum, (_, size)| sum + size);
+
+        let limit = self.maximum_allowed_size;
+        if frame_size.exceeds_limit(limit) {
+            // Point at just the function name if possible, because lints that span
+            // the entire body and don't have to are less legible.
+            let fn_span = match fn_kind {
+                FnKind::ItemFn(ident, _, _) | FnKind::Method(ident, _) => ident.span,
+                FnKind::Closure => entire_fn_span,
+            };
 
-        if frame_size.exceeds_limit(self.maximum_allowed_size) {
-            span_lint_and_note(
+            span_lint_and_then(
                 cx,
                 LARGE_STACK_FRAMES,
-                span,
-                "this function allocates a large amount of stack space",
-                None,
-                "allocating large amounts of stack space can overflow the stack",
+                fn_span,
+                format!("this function may allocate {frame_size} on the stack"),
+                |diag| {
+                    // Point out the largest individual contribution to this size, because
+                    // it is the most likely to be unintentionally large.
+                    if let Some((local, size)) = sizes_of_locals().max_by_key(|&(_, size)| size) {
+                        let local_span: Span = local.source_info.span;
+                        let size = Space::Used(size); // pluralizes for us
+                        let ty = local.ty;
+
+                        // TODO: Is there a cleaner, robust way to ask this question?
+                        // The obvious `LocalDecl::is_user_variable()` panics on "unwrapping cross-crate data",
+                        // and that doesn't get us the true name in scope rather than the span text either.
+                        if let Some(name) = snippet_opt(cx, local_span)
+                            && is_ident(&name)
+                        {
+                            // If the local is an ordinary named variable,
+                            // print its name rather than relying solely on the span.
+                            diag.span_label(
+                                local_span,
+                                format!("`{name}` is the largest part, at {size} for type `{ty}`"),
+                            );
+                        } else {
+                            diag.span_label(
+                                local_span,
+                                format!("this is the largest part, at {size} for type `{ty}`"),
+                            );
+                        }
+                    }
+
+                    // Explain why we are linting this and not other functions.
+                    diag.note(format!(
+                        "{frame_size} is larger than Clippy's configured `stack-size-threshold` of {limit}"
+                    ));
+
+                    // Explain why the user should care, briefly.
+                    diag.note_once(
+                        "allocating large amounts of stack space can overflow the stack \
+                        and cause the program to abort",
+                    );
+                },
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
new file mode 100644
index 00000000000..c5f1afe68c3
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/legacy_numeric_constants.rs
@@ -0,0 +1,293 @@
+use clippy_config::msrvs::{Msrv, NUMERIC_ASSOCIATED_CONSTANTS};
+use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
+use clippy_utils::{get_parent_expr, is_from_proc_macro};
+use hir::def_id::DefId;
+use rustc_errors::{Applicability, SuggestionStyle};
+use rustc_hir as hir;
+use rustc_hir::{ExprKind, Item, ItemKind, QPath, UseKind};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
+use rustc_middle::lint::in_external_macro;
+use rustc_session::impl_lint_pass;
+use rustc_span::symbol::kw;
+use rustc_span::{sym, Symbol};
+
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks for usage of `<integer>::max_value()`, `std::<integer>::MAX`,
+    /// `std::<float>::EPSILON`, etc.
+    ///
+    /// ### Why is this bad?
+    /// All of these have been superceded by the associated constants on their respective types,
+    /// such as `i128::MAX`. These legacy items may be deprecated in a future version of rust.
+    ///
+    /// ### Example
+    /// ```rust
+    /// let eps = std::f32::EPSILON;
+    /// ```
+    /// Use instead:
+    /// ```rust
+    /// let eps = f32::EPSILON;
+    /// ```
+    #[clippy::version = "1.72.0"]
+    pub LEGACY_NUMERIC_CONSTANTS,
+    style,
+    "checks for usage of legacy std numeric constants and methods"
+}
+pub struct LegacyNumericConstants {
+    msrv: Msrv,
+}
+
+impl LegacyNumericConstants {
+    #[must_use]
+    pub fn new(msrv: Msrv) -> Self {
+        Self { msrv }
+    }
+}
+
+impl_lint_pass!(LegacyNumericConstants => [LEGACY_NUMERIC_CONSTANTS]);
+
+impl<'tcx> LateLintPass<'tcx> for LegacyNumericConstants {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
+        let Self { msrv } = self;
+
+        if !msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS) || in_external_macro(cx.sess(), item.span) {
+            return;
+        }
+
+        // Integer modules are "TBD" deprecated, and the contents are too,
+        // so lint on the `use` statement directly.
+        if let ItemKind::Use(path, kind @ (UseKind::Single | UseKind::Glob)) = item.kind
+            && let Some(def_id) = path.res[0].opt_def_id()
+        {
+            let module = if is_integer_module(cx, def_id) {
+                true
+            } else if is_numeric_const(cx, def_id) {
+                false
+            } else {
+                return;
+            };
+
+            span_lint_and_then(
+                cx,
+                LEGACY_NUMERIC_CONSTANTS,
+                path.span,
+                if module {
+                    "importing legacy numeric constants"
+                } else {
+                    "importing a legacy numeric constant"
+                },
+                |diag| {
+                    if item.ident.name == kw::Underscore {
+                        diag.help("remove this import");
+                        return;
+                    }
+
+                    let def_path = cx.get_def_path(def_id);
+
+                    if module && let [.., module_name] = &*def_path {
+                        if kind == UseKind::Glob {
+                            diag.help(format!("remove this import and use associated constants `{module_name}::<CONST>` from the primitive type instead"));
+                        } else {
+                            diag.help("remove this import").note(format!(
+                                "then `{module_name}::<CONST>` will resolve to the respective associated constant"
+                            ));
+                        }
+                    } else if let [.., module_name, name] = &*def_path {
+                        diag.help(
+                            format!("remove this import and use the associated constant `{module_name}::{name}` from the primitive type instead")
+                        );
+                    }
+                },
+            );
+        }
+    }
+
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+        let Self { msrv } = self;
+
+        if !msrv.meets(NUMERIC_ASSOCIATED_CONSTANTS) || in_external_macro(cx.sess(), expr.span) {
+            return;
+        }
+        let ExprKind::Path(qpath) = expr.kind else {
+            return;
+        };
+
+        // `std::<integer>::<CONST>` check
+        let (span, sugg, msg) = if let QPath::Resolved(None, path) = qpath
+            && let Some(def_id) = path.res.opt_def_id()
+            && is_numeric_const(cx, def_id)
+            && let def_path = cx.get_def_path(def_id)
+            && let [.., mod_name, name] = &*def_path
+            // Skip linting if this usage looks identical to the associated constant,
+            // since this would only require removing a `use` import (which is already linted).
+            && !is_numeric_const_path_canonical(path, [*mod_name, *name])
+        {
+            (
+                expr.span,
+                format!("{mod_name}::{name}"),
+                "usage of a legacy numeric constant",
+            )
+        // `<integer>::xxx_value` check
+        } else if let QPath::TypeRelative(_, last_segment) = qpath
+            && let Some(def_id) = cx.qpath_res(&qpath, expr.hir_id).opt_def_id()
+            && is_integer_method(cx, def_id)
+            && let Some(par_expr) = get_parent_expr(cx, expr)
+            && let ExprKind::Call(_, _) = par_expr.kind
+        {
+            let name = last_segment.ident.name.as_str();
+
+            (
+                last_segment.ident.span.with_hi(par_expr.span.hi()),
+                name[..=2].to_ascii_uppercase(),
+                "usage of a legacy numeric method",
+            )
+        } else {
+            return;
+        };
+
+        if is_from_proc_macro(cx, expr) {
+            return;
+        }
+
+        span_lint_hir_and_then(cx, LEGACY_NUMERIC_CONSTANTS, expr.hir_id, span, msg, |diag| {
+            diag.span_suggestion_with_style(
+                span,
+                "use the associated constant instead",
+                sugg,
+                Applicability::MaybeIncorrect,
+                SuggestionStyle::ShowAlways,
+            );
+        });
+    }
+
+    extract_msrv_attr!(LateContext);
+}
+
+fn is_integer_module(cx: &LateContext<'_>, did: DefId) -> bool {
+    matches!(
+        cx.tcx.get_diagnostic_name(did),
+        Some(
+            sym::isize_legacy_mod
+                | sym::i128_legacy_mod
+                | sym::i64_legacy_mod
+                | sym::i32_legacy_mod
+                | sym::i16_legacy_mod
+                | sym::i8_legacy_mod
+                | sym::usize_legacy_mod
+                | sym::u128_legacy_mod
+                | sym::u64_legacy_mod
+                | sym::u32_legacy_mod
+                | sym::u16_legacy_mod
+                | sym::u8_legacy_mod
+        )
+    )
+}
+
+fn is_numeric_const(cx: &LateContext<'_>, did: DefId) -> bool {
+    matches!(
+        cx.tcx.get_diagnostic_name(did),
+        Some(
+            sym::isize_legacy_const_max
+                | sym::isize_legacy_const_min
+                | sym::i128_legacy_const_max
+                | sym::i128_legacy_const_min
+                | sym::i16_legacy_const_max
+                | sym::i16_legacy_const_min
+                | sym::i32_legacy_const_max
+                | sym::i32_legacy_const_min
+                | sym::i64_legacy_const_max
+                | sym::i64_legacy_const_min
+                | sym::i8_legacy_const_max
+                | sym::i8_legacy_const_min
+                | sym::usize_legacy_const_max
+                | sym::usize_legacy_const_min
+                | sym::u128_legacy_const_max
+                | sym::u128_legacy_const_min
+                | sym::u16_legacy_const_max
+                | sym::u16_legacy_const_min
+                | sym::u32_legacy_const_max
+                | sym::u32_legacy_const_min
+                | sym::u64_legacy_const_max
+                | sym::u64_legacy_const_min
+                | sym::u8_legacy_const_max
+                | sym::u8_legacy_const_min
+                | sym::f32_legacy_const_digits
+                | sym::f32_legacy_const_epsilon
+                | sym::f32_legacy_const_infinity
+                | sym::f32_legacy_const_mantissa_dig
+                | sym::f32_legacy_const_max
+                | sym::f32_legacy_const_max_10_exp
+                | sym::f32_legacy_const_max_exp
+                | sym::f32_legacy_const_min
+                | sym::f32_legacy_const_min_10_exp
+                | sym::f32_legacy_const_min_exp
+                | sym::f32_legacy_const_min_positive
+                | sym::f32_legacy_const_nan
+                | sym::f32_legacy_const_neg_infinity
+                | sym::f32_legacy_const_radix
+                | sym::f64_legacy_const_digits
+                | sym::f64_legacy_const_epsilon
+                | sym::f64_legacy_const_infinity
+                | sym::f64_legacy_const_mantissa_dig
+                | sym::f64_legacy_const_max
+                | sym::f64_legacy_const_max_10_exp
+                | sym::f64_legacy_const_max_exp
+                | sym::f64_legacy_const_min
+                | sym::f64_legacy_const_min_10_exp
+                | sym::f64_legacy_const_min_exp
+                | sym::f64_legacy_const_min_positive
+                | sym::f64_legacy_const_nan
+                | sym::f64_legacy_const_neg_infinity
+                | sym::f64_legacy_const_radix
+        )
+    )
+}
+
+// Whether path expression looks like `i32::MAX`
+fn is_numeric_const_path_canonical(expr_path: &hir::Path<'_>, [mod_name, name]: [Symbol; 2]) -> bool {
+    let [
+        hir::PathSegment {
+            ident: one, args: None, ..
+        },
+        hir::PathSegment {
+            ident: two, args: None, ..
+        },
+    ] = expr_path.segments
+    else {
+        return false;
+    };
+
+    one.name == mod_name && two.name == name
+}
+
+fn is_integer_method(cx: &LateContext<'_>, did: DefId) -> bool {
+    matches!(
+        cx.tcx.get_diagnostic_name(did),
+        Some(
+            sym::isize_legacy_fn_max_value
+                | sym::isize_legacy_fn_min_value
+                | sym::i128_legacy_fn_max_value
+                | sym::i128_legacy_fn_min_value
+                | sym::i16_legacy_fn_max_value
+                | sym::i16_legacy_fn_min_value
+                | sym::i32_legacy_fn_max_value
+                | sym::i32_legacy_fn_min_value
+                | sym::i64_legacy_fn_max_value
+                | sym::i64_legacy_fn_min_value
+                | sym::i8_legacy_fn_max_value
+                | sym::i8_legacy_fn_min_value
+                | sym::usize_legacy_fn_max_value
+                | sym::usize_legacy_fn_min_value
+                | sym::u128_legacy_fn_max_value
+                | sym::u128_legacy_fn_min_value
+                | sym::u16_legacy_fn_max_value
+                | sym::u16_legacy_fn_min_value
+                | sym::u32_legacy_fn_max_value
+                | sym::u32_legacy_fn_min_value
+                | sym::u64_legacy_fn_max_value
+                | sym::u64_legacy_fn_min_value
+                | sym::u8_legacy_fn_max_value
+                | sym::u8_legacy_fn_min_value
+        )
+    )
+}
diff --git a/src/tools/clippy/clippy_lints/src/len_zero.rs b/src/tools/clippy/clippy_lints/src/len_zero.rs
index cae9ada5a33..97a245b76d4 100644
--- a/src/tools/clippy/clippy_lints/src/len_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/len_zero.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::snippet_with_context;
-use clippy_utils::sugg::Sugg;
+use clippy_utils::source::{snippet_opt, snippet_with_context};
+use clippy_utils::sugg::{has_enclosing_paren, Sugg};
 use clippy_utils::{get_item_name, get_parent_as_impl, is_lint_allowed, peel_ref_operators};
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
@@ -192,7 +192,7 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
 
         if let ExprKind::Binary(Spanned { node: cmp, .. }, left, right) = expr.kind {
             // expr.span might contains parenthesis, see issue #10529
-            let actual_span = left.span.with_hi(right.span.hi());
+            let actual_span = span_without_enclosing_paren(cx, expr.span);
             match cmp {
                 BinOpKind::Eq => {
                     check_cmp(cx, actual_span, left, right, "", 0); // len == 0
@@ -218,6 +218,20 @@ impl<'tcx> LateLintPass<'tcx> for LenZero {
     }
 }
 
+fn span_without_enclosing_paren(cx: &LateContext<'_>, span: Span) -> Span {
+    let Some(snippet) = snippet_opt(cx, span) else {
+        return span;
+    };
+    if has_enclosing_paren(snippet) {
+        let source_map = cx.tcx.sess.source_map();
+        let left_paren = source_map.start_point(span);
+        let right_parent = source_map.end_point(span);
+        left_paren.between(right_parent)
+    } else {
+        span
+    }
+}
+
 fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items: &[TraitItemRef]) {
     fn is_named_self(cx: &LateContext<'_>, item: &TraitItemRef, name: Symbol) -> bool {
         item.ident.name == name
@@ -256,7 +270,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
             .items()
             .flat_map(|&i| cx.tcx.associated_items(i).filter_by_name_unhygienic(is_empty))
             .any(|i| {
-                i.kind == ty::AssocKind::Fn
+                i.kind == AssocKind::Fn
                     && i.fn_has_self_parameter
                     && cx.tcx.fn_sig(i.def_id).skip_binder().inputs().skip_binder().len() == 1
             });
@@ -266,7 +280,7 @@ fn check_trait_items(cx: &LateContext<'_>, visited_trait: &Item<'_>, trait_items
                 cx,
                 LEN_WITHOUT_IS_EMPTY,
                 visited_trait.span,
-                &format!(
+                format!(
                     "trait `{}` has a `len` method but no (possibly inherited) `is_empty` method",
                     visited_trait.ident.name
                 ),
@@ -484,7 +498,7 @@ fn check_for_is_empty(
         Some(_) => return,
     };
 
-    span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, span, &msg, |db| {
+    span_lint_and_then(cx, LEN_WITHOUT_IS_EMPTY, span, msg, |db| {
         if let Some(span) = is_empty_span {
             db.span_note(span, "`is_empty` defined here");
         }
@@ -495,6 +509,10 @@ fn check_for_is_empty(
 }
 
 fn check_cmp(cx: &LateContext<'_>, span: Span, method: &Expr<'_>, lit: &Expr<'_>, op: &str, compare_to: u32) {
+    if method.span.from_expansion() {
+        return;
+    }
+
     if let (&ExprKind::MethodCall(method_path, receiver, args, _), ExprKind::Lit(lit)) = (&method.kind, &lit.kind) {
         // check if we are in an is_empty() method
         if let Some(name) = get_item_name(cx, method) {
@@ -542,8 +560,8 @@ fn check_len(
                 cx,
                 LEN_ZERO,
                 span,
-                &format!("length comparison to {}", if compare_to == 0 { "zero" } else { "one" }),
-                &format!("using `{op}is_empty` is clearer and more explicit"),
+                format!("length comparison to {}", if compare_to == 0 { "zero" } else { "one" }),
+                format!("using `{op}is_empty` is clearer and more explicit"),
                 format!(
                     "{op}{}.is_empty()",
                     snippet_with_context(cx, receiver.span, span.ctxt(), "_", &mut applicability).0,
@@ -566,7 +584,7 @@ fn check_empty_expr(cx: &LateContext<'_>, span: Span, lit1: &Expr<'_>, lit2: &Ex
             COMPARISON_TO_EMPTY,
             span,
             "comparison to empty slice",
-            &format!("using `{op}is_empty` is clearer and more explicit"),
+            format!("using `{op}is_empty` is clearer and more explicit"),
             format!("{op}{lit_str}.is_empty()"),
             applicability,
         );
@@ -594,7 +612,7 @@ fn is_empty_array(expr: &Expr<'_>) -> bool {
 fn has_is_empty(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     /// Gets an `AssocItem` and return true if it matches `is_empty(self)`.
     fn is_is_empty(cx: &LateContext<'_>, item: &ty::AssocItem) -> bool {
-        if item.kind == ty::AssocKind::Fn {
+        if item.kind == AssocKind::Fn {
             let sig = cx.tcx.fn_sig(item.def_id).skip_binder();
             let ty = sig.skip_binder();
             ty.inputs().len() == 1
diff --git a/src/tools/clippy/clippy_lints/src/lib.rs b/src/tools/clippy/clippy_lints/src/lib.rs
index 57fac351042..b92364a9d14 100644
--- a/src/tools/clippy/clippy_lints/src/lib.rs
+++ b/src/tools/clippy/clippy_lints/src/lib.rs
@@ -16,11 +16,14 @@
     rustc::diagnostic_outside_of_impl,
     rustc::untranslatable_diagnostic
 )]
-#![warn(trivial_casts, trivial_numeric_casts)]
-// warn on lints, that are included in `rust-lang/rust`s bootstrap
-#![warn(rust_2018_idioms, unused_lifetimes)]
-// warn on rustc internal lints
-#![warn(rustc::internal)]
+#![warn(
+    trivial_casts,
+    trivial_numeric_casts,
+    rust_2018_idioms,
+    unused_lifetimes,
+    unused_qualifications,
+    rustc::internal
+)]
 // Disable this rustc lint for now, as it was also done in rustc
 #![allow(rustc::potential_query_instability)]
 
@@ -186,6 +189,7 @@ mod large_futures;
 mod large_include_file;
 mod large_stack_arrays;
 mod large_stack_frames;
+mod legacy_numeric_constants;
 mod len_zero;
 mod let_if_seq;
 mod let_underscore;
@@ -1080,6 +1084,7 @@ pub fn register_lints(store: &mut rustc_lint::LintStore, conf: &'static Conf) {
             allow_one_hash_in_raw_strings,
         })
     });
+    store.register_late_pass(move |_| Box::new(legacy_numeric_constants::LegacyNumericConstants::new(msrv())));
     store.register_late_pass(|_| Box::new(manual_range_patterns::ManualRangePatterns));
     store.register_early_pass(|| Box::new(visibility::Visibility));
     store.register_late_pass(move |_| Box::new(tuple_array_conversions::TupleArrayConversions { msrv: msrv() }));
diff --git a/src/tools/clippy/clippy_lints/src/lifetimes.rs b/src/tools/clippy/clippy_lints/src/lifetimes.rs
index 2b73663d229..a60a40a2a47 100644
--- a/src/tools/clippy/clippy_lints/src/lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/lifetimes.rs
@@ -216,7 +216,7 @@ fn check_fn_inner<'tcx>(
                     None
                 }))
                 .collect_vec(),
-            &format!("the following explicit lifetimes could be elided: {lts}"),
+            format!("the following explicit lifetimes could be elided: {lts}"),
             |diag| {
                 if sig.header.is_async() {
                     // async functions have usages whose spans point at the lifetime declaration which messes up
diff --git a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs
index 29957e423b0..3d1c666dfea 100644
--- a/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs
+++ b/src/tools/clippy/clippy_lints/src/lines_filter_map_ok.rs
@@ -70,7 +70,7 @@ impl LateLintPass<'_> for LinesFilterMapOk {
                 cx,
                 LINES_FILTER_MAP_OK,
                 fm_span,
-                &format!("`{fm_method_str}()` will run forever if the iterator repeatedly produces an `Err`",),
+                format!("`{fm_method_str}()` will run forever if the iterator repeatedly produces an `Err`",),
                 |diag| {
                     diag.span_note(
                         fm_receiver.span,
diff --git a/src/tools/clippy/clippy_lints/src/literal_representation.rs b/src/tools/clippy/clippy_lints/src/literal_representation.rs
index f33151cf4c5..2348dd18220 100644
--- a/src/tools/clippy/clippy_lints/src/literal_representation.rs
+++ b/src/tools/clippy/clippy_lints/src/literal_representation.rs
@@ -158,7 +158,7 @@ enum WarningType {
 }
 
 impl WarningType {
-    fn display(&self, suggested_format: String, cx: &EarlyContext<'_>, span: rustc_span::Span) {
+    fn display(&self, suggested_format: String, cx: &EarlyContext<'_>, span: Span) {
         match self {
             Self::MistypedLiteralSuffix => span_lint_and_sugg(
                 cx,
@@ -302,11 +302,7 @@ impl LiteralDigitGrouping {
     }
 
     // Returns `false` if the check fails
-    fn check_for_mistyped_suffix(
-        cx: &EarlyContext<'_>,
-        span: rustc_span::Span,
-        num_lit: &mut NumericLiteral<'_>,
-    ) -> bool {
+    fn check_for_mistyped_suffix(cx: &EarlyContext<'_>, span: Span, num_lit: &mut NumericLiteral<'_>) -> bool {
         if num_lit.suffix.is_some() {
             return true;
         }
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs
index 277062a8490..f0ee64d714e 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_counter_loop.rs
@@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(
                             cx,
                             EXPLICIT_COUNTER_LOOP,
                             span,
-                            &format!("the variable `{name}` is used as a loop counter"),
+                            format!("the variable `{name}` is used as a loop counter"),
                             "consider using",
                             format!(
                                 "for ({name}, {}) in {}.enumerate()",
@@ -62,7 +62,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     EXPLICIT_COUNTER_LOOP,
                     span,
-                    &format!("the variable `{name}` is used as a loop counter"),
+                    format!("the variable `{name}` is used as a loop counter"),
                     |diag| {
                         diag.span_suggestion(
                             span,
diff --git a/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs b/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs
index 94c951fc10a..6922533fbe9 100644
--- a/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/for_kv_map.rs
@@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, pat: &'tcx Pat<'_>, arg: &'tcx
                     cx,
                     FOR_KV_MAP,
                     arg_span,
-                    &format!("you seem to want to iterate on a map's {kind}s"),
+                    format!("you seem to want to iterate on a map's {kind}s"),
                     |diag| {
                         let map = sugg::Sugg::hir(cx, arg, "map");
                         multispan_sugg(
diff --git a/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs b/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs
index 36de9021f49..dbc094a6d73 100644
--- a/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/manual_flatten.rs
@@ -62,7 +62,7 @@ pub(super) fn check<'tcx>(
             "...and remove the `if let` statement in the for loop"
         };
 
-        span_lint_and_then(cx, MANUAL_FLATTEN, span, &msg, |diag| {
+        span_lint_and_then(cx, MANUAL_FLATTEN, span, msg, |diag| {
             diag.span_suggestion(arg.span, "try", sugg, applicability);
             diag.span_help(inner_expr.span, help_msg);
         });
diff --git a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
index c4e60e98ad4..94330001e4f 100644
--- a/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/mut_range_bound.rs
@@ -109,7 +109,7 @@ impl<'tcx> Delegate<'tcx> for MutatePairDelegate<'_, 'tcx> {
         }
     }
 
-    fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
+    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
 impl MutatePairDelegate<'_, '_> {
@@ -141,7 +141,7 @@ impl BreakAfterExprVisitor {
     }
 }
 
-impl<'tcx> intravisit::Visitor<'tcx> for BreakAfterExprVisitor {
+impl<'tcx> Visitor<'tcx> for BreakAfterExprVisitor {
     fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         if self.past_candidate {
             return;
diff --git a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
index cf34c904dfe..de7ec81bc01 100644
--- a/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/needless_range_loop.rs
@@ -143,7 +143,7 @@ pub(super) fn check<'tcx>(
                         cx,
                         NEEDLESS_RANGE_LOOP,
                         arg.span,
-                        &format!("the loop variable `{}` is used to index `{indexed}`", ident.name),
+                        format!("the loop variable `{}` is used to index `{indexed}`", ident.name),
                         |diag| {
                             multispan_sugg(
                                 diag,
@@ -169,7 +169,7 @@ pub(super) fn check<'tcx>(
                         cx,
                         NEEDLESS_RANGE_LOOP,
                         arg.span,
-                        &format!("the loop variable `{}` is only used to index `{indexed}`", ident.name),
+                        format!("the loop variable `{}` is only used to index `{indexed}`", ident.name),
                         |diag| {
                             multispan_sugg(
                                 diag,
@@ -357,7 +357,7 @@ impl<'a, 'tcx> Visitor<'tcx> for VarVisitor<'a, 'tcx> {
                 let def_id = self.cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
                 for (ty, expr) in iter::zip(
                     self.cx.tcx.fn_sig(def_id).instantiate_identity().inputs().skip_binder(),
-                    std::iter::once(receiver).chain(args.iter()),
+                    iter::once(receiver).chain(args.iter()),
                 ) {
                     self.prefer_mutable = false;
                     if let ty::Ref(_, _, mutbl) = *ty.kind() {
diff --git a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
index 8aae7be4593..313a5bfefbc 100644
--- a/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/never_loop.rs
@@ -159,12 +159,9 @@ fn never_loop_expr<'tcx>(
         | ExprKind::DropTemps(e) => never_loop_expr(cx, e, local_labels, main_loop_id),
         ExprKind::Let(let_expr) => never_loop_expr(cx, let_expr.init, local_labels, main_loop_id),
         ExprKind::Array(es) | ExprKind::Tup(es) => never_loop_expr_all(cx, es.iter(), local_labels, main_loop_id),
-        ExprKind::MethodCall(_, receiver, es, _) => never_loop_expr_all(
-            cx,
-            std::iter::once(receiver).chain(es.iter()),
-            local_labels,
-            main_loop_id,
-        ),
+        ExprKind::MethodCall(_, receiver, es, _) => {
+            never_loop_expr_all(cx, once(receiver).chain(es.iter()), local_labels, main_loop_id)
+        },
         ExprKind::Struct(_, fields, base) => {
             let fields = never_loop_expr_all(cx, fields.iter().map(|f| f.expr), local_labels, main_loop_id);
             if let Some(base) = base {
diff --git a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
index 670a78d58c3..1d90d4a58f5 100644
--- a/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/same_item_push.rs
@@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(
             vec.span,
             "it looks like the same item is being pushed into this Vec",
             None,
-            &format!("consider using vec![{item_str};SIZE] or {vec_str}.resize(NEW_SIZE, {item_str})"),
+            format!("consider using vec![{item_str};SIZE] or {vec_str}.resize(NEW_SIZE, {item_str})"),
         );
     }
 
diff --git a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
index 4773a1454b7..108fdb69775 100644
--- a/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/single_element_loop.rs
@@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(
             },
             [],
             _,
-        ) if method.ident.name == rustc_span::sym::iter => (arg, "&"),
+        ) if method.ident.name == sym::iter => (arg, "&"),
         ExprKind::MethodCall(
             method,
             Expr {
@@ -60,7 +60,7 @@ pub(super) fn check<'tcx>(
             },
             [],
             _,
-        ) if method.ident.name == rustc_span::sym::into_iter => (arg, ""),
+        ) if method.ident.name == sym::into_iter => (arg, ""),
         // Only check for arrays edition 2021 or later, as this case will trigger a compiler error otherwise.
         ExprKind::Array([arg]) if cx.tcx.sess.edition() >= Edition::Edition2021 => (arg, ""),
         _ => return,
@@ -95,7 +95,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 SINGLE_ELEMENT_LOOP,
                 arg.span,
-                format!("this loops only once with `{pat_snip}` being `{range_expr}`").as_str(),
+                format!("this loops only once with `{pat_snip}` being `{range_expr}`"),
                 "did you mean to iterate over the range instead?",
                 sugg.to_string(),
                 Applicability::Unspecified,
diff --git a/src/tools/clippy/clippy_lints/src/main_recursion.rs b/src/tools/clippy/clippy_lints/src/main_recursion.rs
index a381b35cf2e..72807b4b284 100644
--- a/src/tools/clippy/clippy_lints/src/main_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/main_recursion.rs
@@ -51,7 +51,7 @@ impl LateLintPass<'_> for MainRecursion {
                 cx,
                 MAIN_RECURSION,
                 func.span,
-                &format!("recursing into entrypoint `{}`", snippet(cx, func.span, "main")),
+                format!("recursing into entrypoint `{}`", snippet(cx, func.span, "main")),
                 None,
                 "consider using another function for this recursion",
             );
diff --git a/src/tools/clippy/clippy_lints/src/manual_assert.rs b/src/tools/clippy/clippy_lints/src/manual_assert.rs
index 4f6a2cf017c..76edbe8b755 100644
--- a/src/tools/clippy/clippy_lints/src/manual_assert.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_assert.rs
@@ -1,7 +1,7 @@
 use crate::rustc_lint::LintContext;
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::macros::root_macro_call;
-use clippy_utils::{is_else_clause, peel_blocks_with_stmt, span_extract_comment, sugg};
+use clippy_utils::{is_else_clause, is_parent_stmt, peel_blocks_with_stmt, span_extract_comment, sugg};
 use rustc_errors::Applicability;
 use rustc_hir::{Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
@@ -63,7 +63,8 @@ impl<'tcx> LateLintPass<'tcx> for ManualAssert {
                 _ => (cond, "!"),
             };
             let cond_sugg = sugg::Sugg::hir_with_applicability(cx, cond, "..", &mut applicability).maybe_par();
-            let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip});");
+            let semicolon = if is_parent_stmt(cx, expr.hir_id) { ";" } else { "" };
+            let sugg = format!("assert!({not}{cond_sugg}, {format_args_snip}){semicolon}");
             // we show to the user the suggestion without the comments, but when applying the fix, include the
             // comments in the block
             span_lint_and_then(
diff --git a/src/tools/clippy/clippy_lints/src/manual_bits.rs b/src/tools/clippy/clippy_lints/src/manual_bits.rs
index aa02e4e7a43..24fc2b4faea 100644
--- a/src/tools/clippy/clippy_lints/src/manual_bits.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_bits.rs
@@ -139,7 +139,7 @@ fn is_ty_conversion(expr: &Expr<'_>) -> bool {
     if let ExprKind::Cast(..) = expr.kind {
         true
     } else if let ExprKind::MethodCall(path, _, [], _) = expr.kind
-        && path.ident.name == rustc_span::sym::try_into
+        && path.ident.name == sym::try_into
     {
         // This is only called for `usize` which implements `TryInto`. Therefore,
         // we don't have to check here if `self` implements the `TryInto` trait.
diff --git a/src/tools/clippy/clippy_lints/src/manual_clamp.rs b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
index 830af77968c..1eadc200bed 100644
--- a/src/tools/clippy/clippy_lints/src/manual_clamp.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_clamp.rs
@@ -1,4 +1,5 @@
 use clippy_config::msrvs::{self, Msrv};
+use clippy_utils::consts::{constant, Constant};
 use clippy_utils::diagnostics::{span_lint_and_then, span_lint_hir_and_then};
 use clippy_utils::higher::If;
 use clippy_utils::sugg::Sugg;
@@ -17,6 +18,7 @@ use rustc_middle::ty::Ty;
 use rustc_session::impl_lint_pass;
 use rustc_span::symbol::sym;
 use rustc_span::Span;
+use std::cmp::Ordering;
 use std::ops::Deref;
 
 declare_clippy_lint! {
@@ -26,6 +28,11 @@ declare_clippy_lint! {
     /// ### Why is this bad?
     /// clamp is much shorter, easier to read, and doesn't use any control flow.
     ///
+    /// ### Limitations
+    ///
+    /// This lint will only trigger if max and min are known at compile time, and max is
+    /// greater than min.
+    ///
     /// ### Known issue(s)
     /// If the clamped variable is NaN this suggestion will cause the code to propagate NaN
     /// rather than returning either `max` or `min`.
@@ -80,7 +87,7 @@ declare_clippy_lint! {
     /// ```
     #[clippy::version = "1.66.0"]
     pub MANUAL_CLAMP,
-    nursery,
+    complexity,
     "using a clamp pattern instead of the clamp function"
 }
 impl_lint_pass!(ManualClamp => [MANUAL_CLAMP]);
@@ -103,6 +110,26 @@ struct ClampSuggestion<'tcx> {
     hir_with_ignore_attr: Option<HirId>,
 }
 
+impl<'tcx> ClampSuggestion<'tcx> {
+    /// This function will return true if and only if you can demonstrate at compile time that min
+    /// is less than max.
+    fn min_less_than_max(&self, cx: &LateContext<'tcx>) -> bool {
+        let max_type = cx.typeck_results().expr_ty(self.params.max);
+        let min_type = cx.typeck_results().expr_ty(self.params.min);
+        if max_type != min_type {
+            return false;
+        }
+        if let Some(max) = constant(cx, cx.typeck_results(), self.params.max)
+            && let Some(min) = constant(cx, cx.typeck_results(), self.params.min)
+            && let Some(ord) = Constant::partial_cmp(cx.tcx, max_type, &min, &max)
+        {
+            ord != Ordering::Greater
+        } else {
+            false
+        }
+    }
+}
+
 #[derive(Debug)]
 struct InputMinMax<'tcx> {
     input: &'tcx Expr<'tcx>,
@@ -123,7 +150,7 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp {
                 .or_else(|| is_match_pattern(cx, expr))
                 .or_else(|| is_if_elseif_pattern(cx, expr));
             if let Some(suggestion) = suggestion {
-                emit_suggestion(cx, &suggestion);
+                maybe_emit_suggestion(cx, &suggestion);
             }
         }
     }
@@ -133,13 +160,16 @@ impl<'tcx> LateLintPass<'tcx> for ManualClamp {
             return;
         }
         for suggestion in is_two_if_pattern(cx, block) {
-            emit_suggestion(cx, &suggestion);
+            maybe_emit_suggestion(cx, &suggestion);
         }
     }
     extract_msrv_attr!(LateContext);
 }
 
-fn emit_suggestion<'tcx>(cx: &LateContext<'tcx>, suggestion: &ClampSuggestion<'tcx>) {
+fn maybe_emit_suggestion<'tcx>(cx: &LateContext<'tcx>, suggestion: &ClampSuggestion<'tcx>) {
+    if !suggestion.min_less_than_max(cx) {
+        return;
+    }
     let ClampSuggestion {
         params: InputMinMax {
             input,
diff --git a/src/tools/clippy/clippy_lints/src/manual_strip.rs b/src/tools/clippy/clippy_lints/src/manual_strip.rs
index bcd02436002..45af9f07718 100644
--- a/src/tools/clippy/clippy_lints/src/manual_strip.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_strip.rs
@@ -106,12 +106,12 @@ impl<'tcx> LateLintPass<'tcx> for ManualStrip {
                     cx,
                     MANUAL_STRIP,
                     strippings[0],
-                    &format!("stripping a {kind_word} manually"),
+                    format!("stripping a {kind_word} manually"),
                     |diag| {
                         diag.span_note(test_span, format!("the {kind_word} was tested here"));
                         multispan_sugg(
                             diag,
-                            &format!("try using the `strip_{kind_word}` method"),
+                            format!("try using the `strip_{kind_word}` method"),
                             vec![(
                                 test_span,
                                 format!(
diff --git a/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs b/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs
index ddaf97c463a..c562ceb5bce 100644
--- a/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs
+++ b/src/tools/clippy/clippy_lints/src/manual_unwrap_or_default.rs
@@ -1,14 +1,15 @@
+use clippy_utils::sugg::Sugg;
 use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::{Arm, Expr, ExprKind, HirId, LangItem, MatchSource, Pat, PatKind, QPath};
-use rustc_lint::{LateContext, LateLintPass};
+use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_session::declare_lint_pass;
 use rustc_span::sym;
 
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::is_default_equivalent;
 use clippy_utils::source::snippet_opt;
 use clippy_utils::ty::implements_trait;
+use clippy_utils::{in_constant, is_default_equivalent, peel_blocks, span_contains_comment};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -118,22 +119,27 @@ fn handle_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) -> bool {
         // We now get the bodies for both the `Some` and `None` arms.
         && let Some(((body_some, binding_id), body_none)) = get_some_and_none_bodies(cx, arm1, arm2)
         // We check that the `Some(x) => x` doesn't do anything apart "returning" the value in `Some`.
-        && let ExprKind::Path(QPath::Resolved(_, path)) = body_some.peel_blocks().kind
+        && let ExprKind::Path(QPath::Resolved(_, path)) = peel_blocks(body_some).kind
         && let Res::Local(local_id) = path.res
         && local_id == binding_id
         // We now check the `None` arm is calling a method equivalent to `Default::default`.
-        && let body_none = body_none.peel_blocks()
+        && let body_none = peel_blocks(body_none)
         && is_default_equivalent(cx, body_none)
-        && let Some(match_expr_snippet) = snippet_opt(cx, match_expr.span)
+        && let Some(receiver) = Sugg::hir_opt(cx, match_expr).map(Sugg::maybe_par)
     {
+        let applicability = if span_contains_comment(cx.sess().source_map(), expr.span) {
+            Applicability::MaybeIncorrect
+        } else {
+            Applicability::MachineApplicable
+        };
         span_lint_and_sugg(
             cx,
             MANUAL_UNWRAP_OR_DEFAULT,
             expr.span,
             "match can be simplified with `.unwrap_or_default()`",
             "replace it with",
-            format!("{match_expr_snippet}.unwrap_or_default()"),
-            Applicability::MachineApplicable,
+            format!("{receiver}.unwrap_or_default()"),
+            applicability,
         );
     }
     true
@@ -149,14 +155,19 @@ fn handle_if_let<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         && implements_trait(cx, match_ty, default_trait_id, &[])
         && let Some(binding_id) = get_some(cx, let_.pat)
         // We check that the `Some(x) => x` doesn't do anything apart "returning" the value in `Some`.
-        && let ExprKind::Path(QPath::Resolved(_, path)) = if_block.peel_blocks().kind
+        && let ExprKind::Path(QPath::Resolved(_, path)) = peel_blocks(if_block).kind
         && let Res::Local(local_id) = path.res
         && local_id == binding_id
         // We now check the `None` arm is calling a method equivalent to `Default::default`.
-        && let body_else = else_expr.peel_blocks()
+        && let body_else = peel_blocks(else_expr)
         && is_default_equivalent(cx, body_else)
         && let Some(if_let_expr_snippet) = snippet_opt(cx, let_.init.span)
     {
+        let applicability = if span_contains_comment(cx.sess().source_map(), expr.span) {
+            Applicability::MaybeIncorrect
+        } else {
+            Applicability::MachineApplicable
+        };
         span_lint_and_sugg(
             cx,
             MANUAL_UNWRAP_OR_DEFAULT,
@@ -164,14 +175,14 @@ fn handle_if_let<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
             "if let can be simplified with `.unwrap_or_default()`",
             "replace it with",
             format!("{if_let_expr_snippet}.unwrap_or_default()"),
-            Applicability::MachineApplicable,
+            applicability,
         );
     }
 }
 
 impl<'tcx> LateLintPass<'tcx> for ManualUnwrapOrDefault {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
-        if expr.span.from_expansion() {
+        if expr.span.from_expansion() || in_constant(cx, expr.hir_id) {
             return;
         }
         if !handle_match(cx, expr) {
diff --git a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
index c9eab7109eb..9db04b615be 100644
--- a/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
+++ b/src/tools/clippy/clippy_lints/src/map_unit_fn.rs
@@ -221,13 +221,13 @@ fn lint_map_unit_fn(
             binding = let_binding_name(cx, var_arg)
         );
 
-        span_lint_and_then(cx, lint, expr.span, &msg, |diag| {
+        span_lint_and_then(cx, lint, expr.span, msg, |diag| {
             diag.span_suggestion(stmt.span, "try", suggestion, applicability);
         });
     } else if let Some((binding, closure_expr)) = unit_closure(cx, fn_arg) {
         let msg = suggestion_msg("closure", map_type);
 
-        span_lint_and_then(cx, lint, expr.span, &msg, |diag| {
+        span_lint_and_then(cx, lint, expr.span, msg, |diag| {
             if let Some(reduced_expr_span) = reduce_unit_expression(cx, closure_expr) {
                 let mut applicability = Applicability::MachineApplicable;
                 let suggestion = format!(
diff --git a/src/tools/clippy/clippy_lints/src/match_result_ok.rs b/src/tools/clippy/clippy_lints/src/match_result_ok.rs
index 62cedc8847b..2a5fc8b6609 100644
--- a/src/tools/clippy/clippy_lints/src/match_result_ok.rs
+++ b/src/tools/clippy/clippy_lints/src/match_result_ok.rs
@@ -76,7 +76,7 @@ impl<'tcx> LateLintPass<'tcx> for MatchResultOk {
                 MATCH_RESULT_OK,
                 expr.span.with_hi(let_expr.span.hi()),
                 "matching on `Some` with `ok()` is redundant",
-                &format!("consider matching on `Ok({some_expr_string})` and removing the call to `ok` instead"),
+                format!("consider matching on `Ok({some_expr_string})` and removing the call to `ok` instead"),
                 sugg,
                 applicability,
             );
diff --git a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
index 5fef5930fab..6746920edc5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/collapsible_match.rs
@@ -97,7 +97,7 @@ fn check_arm<'tcx>(
         } else {
             String::new()
         };
-        span_lint_and_then(cx, COLLAPSIBLE_MATCH, inner_expr.span, &msg, |diag| {
+        span_lint_and_then(cx, COLLAPSIBLE_MATCH, inner_expr.span, msg, |diag| {
             let mut help_span = MultiSpan::from_spans(vec![binding_span, inner_then_pat.span]);
             help_span.push_span_label(binding_span, "replace this binding");
             help_span.push_span_label(inner_then_pat.span, format!("with this pattern{replace_msg}"));
diff --git a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
index 3e79cabd795..9edd6c95404 100644
--- a/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/manual_unwrap_or.rs
@@ -34,7 +34,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'tcx>, scrutinee:
             cx,
             MANUAL_UNWRAP_OR,
             expr.span,
-            &format!("this pattern reimplements `{ty_name}::unwrap_or`"),
+            format!("this pattern reimplements `{ty_name}::unwrap_or`"),
             "replace with",
             format!("{suggestion}.unwrap_or({reindented_or_body})",),
             app,
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
index 6b484ff2749..f5da8ec6187 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_as_ref.rs
@@ -43,7 +43,7 @@ pub(crate) fn check(cx: &LateContext<'_>, ex: &Expr<'_>, arms: &[Arm<'_>], expr:
                 cx,
                 MATCH_AS_REF,
                 expr.span,
-                &format!("use `{suggestion}()` instead"),
+                format!("use `{suggestion}()` instead"),
                 "try",
                 format!(
                     "{}.{suggestion}(){cast}",
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
index b062e81cefd..64cb7a06ce9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_like_matches.rs
@@ -122,7 +122,7 @@ where
             cx,
             MATCH_LIKE_MATCHES_MACRO,
             expr.span,
-            &format!(
+            format!(
                 "{} expression looks like `matches!` macro",
                 if is_if_let { "if let .. else" } else { "match" }
             ),
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
index bd38648bcf1..322e9c3ebe5 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_str_case_mismatch.rs
@@ -111,7 +111,7 @@ fn lint(cx: &LateContext<'_>, case_method: &CaseMethod, bad_case_span: Span, bad
         MATCH_STR_CASE_MISMATCH,
         bad_case_span,
         "this `match` arm has a differing case than its expression",
-        &format!("consider changing the case of this arm to respect `{method_str}`"),
+        format!("consider changing the case of this arm to respect `{method_str}`"),
         format!("\"{suggestion}\""),
         Applicability::MachineApplicable,
     );
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs
index 8a4c0ab9062..d1f637ec78c 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_wild_err_arm.rs
@@ -43,7 +43,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, ex: &Expr<'tcx>, arms: &[Arm<'
                             cx,
                             MATCH_WILD_ERR_ARM,
                             arm.pat.span,
-                            &format!("`Err({ident_bind_name})` matches all errors"),
+                            format!("`Err({ident_bind_name})` matches all errors"),
                             None,
                             "match each error separately or use the error output, or use `.expect(msg)` if the error case is unreachable",
                         );
diff --git a/src/tools/clippy/clippy_lints/src/matches/mod.rs b/src/tools/clippy/clippy_lints/src/matches/mod.rs
index 580d4a64296..fae2c4e4af9 100644
--- a/src/tools/clippy/clippy_lints/src/matches/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/mod.rs
@@ -25,14 +25,13 @@ mod try_err;
 mod wild_in_or_pats;
 
 use clippy_config::msrvs::{self, Msrv};
-use clippy_utils::source::{snippet_opt, walk_span_to_context};
-use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, tokenize_with_text};
+use clippy_utils::source::walk_span_to_context;
+use clippy_utils::{higher, in_constant, is_direct_expn_of, is_span_match, span_contains_cfg};
 use rustc_hir::{Arm, Expr, ExprKind, LetStmt, MatchSource, Pat};
-use rustc_lexer::TokenKind;
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_session::impl_lint_pass;
-use rustc_span::{Span, SpanData, SyntaxContext};
+use rustc_span::{SpanData, SyntaxContext};
 
 declare_clippy_lint! {
     /// ### What it does
@@ -1196,28 +1195,3 @@ fn contains_cfg_arm(cx: &LateContext<'_>, e: &Expr<'_>, scrutinee: &Expr<'_>, ar
         Err(()) => true,
     }
 }
-
-/// Checks if the given span contains a `#[cfg(..)]` attribute
-fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
-    let Some(snip) = snippet_opt(cx, s) else {
-        // Assume true. This would require either an invalid span, or one which crosses file boundaries.
-        return true;
-    };
-    let mut iter = tokenize_with_text(&snip);
-
-    // Search for the token sequence [`#`, `[`, `cfg`]
-    while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
-        let mut iter = iter.by_ref().skip_while(|(t, _)| {
-            matches!(
-                t,
-                TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
-            )
-        });
-        if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
-            && matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
-        {
-            return true;
-        }
-    }
-    false
-}
diff --git a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
index b5870d94d99..78973984fb0 100644
--- a/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/redundant_pattern_match.rs
@@ -72,7 +72,7 @@ fn find_match_true<'tcx>(
     pat: &'tcx Pat<'_>,
     scrutinee: &'tcx Expr<'_>,
     span: Span,
-    message: &str,
+    message: &'static str,
 ) {
     if let PatKind::Lit(lit) = pat.kind
         && let ExprKind::Lit(lit) = lit.kind
@@ -98,7 +98,7 @@ fn find_match_true<'tcx>(
             span,
             message,
             "consider using the condition directly",
-            sugg.to_string(),
+            sugg.into_string(),
             applicability,
         );
     }
@@ -227,7 +227,7 @@ fn find_method_sugg_for_if_let<'tcx>(
         cx,
         REDUNDANT_PATTERN_MATCHING,
         let_pat.span,
-        &format!("redundant pattern matching, consider using `{good_method}`"),
+        format!("redundant pattern matching, consider using `{good_method}`"),
         |diag| {
             // if/while let ... = ... { ... }
             // ^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -304,7 +304,7 @@ pub(super) fn check_match<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, op
                 cx,
                 REDUNDANT_PATTERN_MATCHING,
                 span,
-                &format!("redundant pattern matching, consider using `{good_method}`"),
+                format!("redundant pattern matching, consider using `{good_method}`"),
                 "try",
                 sugg,
                 Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/mem_replace.rs b/src/tools/clippy/clippy_lints/src/mem_replace.rs
index 1cdb7921f81..578aa7989e7 100644
--- a/src/tools/clippy/clippy_lints/src/mem_replace.rs
+++ b/src/tools/clippy/clippy_lints/src/mem_replace.rs
@@ -193,7 +193,7 @@ fn check_replace_with_default(cx: &LateContext<'_>, src: &Expr<'_>, dest: &Expr<
             cx,
             MEM_REPLACE_WITH_DEFAULT,
             expr_span,
-            &format!(
+            format!(
                 "replacing a value of type `T` with `T::default()` is better expressed using `{top_crate}::mem::take`"
             ),
             |diag| {
diff --git a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
index 08bfa2e009b..fb440ce656e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bind_instead_of_map.rs
@@ -84,7 +84,7 @@ pub(crate) trait BindInsteadOfMap {
                 "{option_snip}.{}({closure_args_snip} {some_inner_snip})",
                 Self::GOOD_METHOD_NAME
             );
-            span_lint_and_sugg(cx, BIND_INSTEAD_OF_MAP, expr.span, &msg, "try", note, app);
+            span_lint_and_sugg(cx, BIND_INSTEAD_OF_MAP, expr.span, msg, "try", note, app);
             true
         } else {
             false
@@ -114,7 +114,7 @@ pub(crate) trait BindInsteadOfMap {
         } else {
             return false;
         };
-        span_lint_and_then(cx, BIND_INSTEAD_OF_MAP, expr.span, &msg, |diag| {
+        span_lint_and_then(cx, BIND_INSTEAD_OF_MAP, expr.span, msg, |diag| {
             multispan_sugg_with_applicability(
                 diag,
                 "try",
@@ -157,7 +157,7 @@ pub(crate) trait BindInsteadOfMap {
                         cx,
                         BIND_INSTEAD_OF_MAP,
                         expr.span,
-                        &msg,
+                        msg,
                         "use the expression directly",
                         snippet(cx, recv.span, "..").into(),
                         Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
index baafb7030aa..a82abc79f2a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/bytes_nth.rs
@@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
             cx,
             BYTES_NTH,
             parent.span,
-            &format!("called `.bytes().nth().unwrap()` on a `{caller_type}`"),
+            format!("called `.bytes().nth().unwrap()` on a `{caller_type}`"),
             "try",
             format!("{receiver}.as_bytes()[{n}]",),
             applicability,
@@ -41,7 +41,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
             cx,
             BYTES_NTH,
             expr.span,
-            &format!("called `.bytes().nth()` on a `{caller_type}`"),
+            format!("called `.bytes().nth()` on a `{caller_type}`"),
             "try",
             format!("{receiver}.as_bytes().get({n}).copied()"),
             applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs
index c99cec067bf..4ae0aeea2d1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp.rs
@@ -30,7 +30,7 @@ pub(super) fn check(
             cx,
             lint,
             info.expr.span,
-            &format!("you should use the `{suggest}` method"),
+            format!("you should use the `{suggest}` method"),
             "like this",
             format!(
                 "{}{}.{suggest}({})",
diff --git a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
index d07e45434a7..9c45ec2e56c 100644
--- a/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/chars_cmp_with_unwrap.rs
@@ -23,7 +23,7 @@ pub(super) fn check(
             cx,
             lint,
             info.expr.span,
-            &format!("you should use the `{suggest}` method"),
+            format!("you should use the `{suggest}` method"),
             "like this",
             format!(
                 "{}{}.{suggest}('{}')",
diff --git a/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs b/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs
index 67ad58d5a8c..5389861245a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clear_with_drain.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::is_range_full;
 use clippy_utils::ty::{is_type_diagnostic_item, is_type_lang_item};
 use rustc_errors::Applicability;
-use rustc_hir as hir;
 use rustc_hir::{Expr, ExprKind, LangItem, QPath};
 use rustc_lint::LateContext;
 use rustc_span::symbol::sym;
@@ -28,7 +27,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span
     }
 }
 
-fn match_acceptable_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>, types: &[rustc_span::Symbol]) -> bool {
+fn match_acceptable_type(cx: &LateContext<'_>, expr: &Expr<'_>, types: &[rustc_span::Symbol]) -> bool {
     let expr_ty = cx.typeck_results().expr_ty(expr).peel_refs();
     types.iter().any(|&ty| is_type_diagnostic_item(cx, expr_ty, ty))
     // String type is a lang item but not a diagnostic item for now so we need a separate check
@@ -44,7 +43,7 @@ fn suggest(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span: Span) {
             cx,
             CLEAR_WITH_DRAIN,
             span.with_hi(expr.span.hi()),
-            &format!("`drain` used to clear a `{ty_name}`"),
+            format!("`drain` used to clear a `{ty_name}`"),
             "try",
             "clear()".to_string(),
             Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
index 3e099004c47..4e6823e8220 100644
--- a/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/clone_on_copy.rs
@@ -94,7 +94,7 @@ pub(super) fn check(
             cx,
             CLONE_ON_COPY,
             expr.span,
-            &with_forced_trimmed_paths!(format!(
+            with_forced_trimmed_paths!(format!(
                 "using `clone` on type `{ty}` which implements the `Copy` trait"
             )),
             help,
diff --git a/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs b/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
index 3a8ca37610a..56171a13452 100644
--- a/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/drain_collect.rs
@@ -70,7 +70,7 @@ pub(super) fn check(cx: &LateContext<'_>, args: &[Expr<'_>], expr: &Expr<'_>, re
             cx,
             DRAIN_COLLECT,
             expr.span,
-            &format!("you seem to be trying to move all elements into a new `{typename}`"),
+            format!("you seem to be trying to move all elements into a new `{typename}`"),
             "consider using `mem::take`",
             sugg,
             Applicability::MachineApplicable,
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 4d8fb217f7f..fba76852344 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
@@ -142,7 +142,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 EXPECT_FUN_CALL,
                 span_replace_word,
-                &format!("use of `{name}` followed by a function call"),
+                format!("use of `{name}` followed by a function call"),
                 "try",
                 format!("unwrap_or_else({closure_args} panic!({sugg}))"),
                 applicability,
@@ -160,7 +160,7 @@ pub(super) fn check<'tcx>(
         cx,
         EXPECT_FUN_CALL,
         span_replace_word,
-        &format!("use of `{name}` followed by a function call"),
+        format!("use of `{name}` followed by a function call"),
         "try",
         format!("unwrap_or_else({closure_args} {{ panic!(\"{{}}\", {arg_root_snippet}) }})"),
         applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs b/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs
index b05361ab212..eab536b88a5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filetype_is_file.rs
@@ -34,5 +34,5 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr
     }
     let lint_msg = format!("`{lint_unary}FileType::is_file()` only {verb} regular files");
     let help_msg = format!("use `{help_unary}FileType::is_dir()` instead");
-    span_lint_and_help(cx, FILETYPE_IS_FILE, span, &lint_msg, None, &help_msg);
+    span_lint_and_help(cx, FILETYPE_IS_FILE, span, lint_msg, None, help_msg);
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
index 9b656531957..581e3b308c3 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map.rs
@@ -16,20 +16,18 @@ use std::borrow::Cow;
 
 use super::{MANUAL_FILTER_MAP, MANUAL_FIND_MAP, OPTION_FILTER_MAP, RESULT_FILTER_MAP};
 
-fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) -> bool {
+fn is_method(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symbol) -> bool {
     match &expr.kind {
-        hir::ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name,
-        hir::ExprKind::Path(QPath::Resolved(_, segments)) => {
-            segments.segments.last().unwrap().ident.name == method_name
-        },
-        hir::ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name,
-        hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
+        ExprKind::Path(QPath::TypeRelative(_, mname)) => mname.ident.name == method_name,
+        ExprKind::Path(QPath::Resolved(_, segments)) => segments.segments.last().unwrap().ident.name == method_name,
+        ExprKind::MethodCall(segment, _, _, _) => segment.ident.name == method_name,
+        ExprKind::Closure(&Closure { body, .. }) => {
             let body = cx.tcx.hir().body(body);
             let closure_expr = peel_blocks(body.value);
             match closure_expr.kind {
-                hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, receiver, ..) => {
+                ExprKind::MethodCall(PathSegment { ident, .. }, receiver, ..) => {
                     if ident.name == method_name
-                        && let hir::ExprKind::Path(path) = &receiver.kind
+                        && let ExprKind::Path(path) = &receiver.kind
                         && let Res::Local(ref local) = cx.qpath_res(path, receiver.hir_id)
                         && !body.params.is_empty()
                     {
@@ -45,10 +43,10 @@ fn is_method(cx: &LateContext<'_>, expr: &hir::Expr<'_>, method_name: Symbol) ->
     }
 }
 
-fn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool {
+fn is_option_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
     is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_some))
 }
-fn is_ok_filter_map(cx: &LateContext<'_>, filter_arg: &hir::Expr<'_>, map_arg: &hir::Expr<'_>) -> bool {
+fn is_ok_filter_map(cx: &LateContext<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
     is_method(cx, map_arg, sym::unwrap) && is_method(cx, filter_arg, sym!(is_ok))
 }
 
@@ -267,10 +265,10 @@ impl<'tcx> OffendingFilterExpr<'tcx> {
 /// is `filter(|x| x.is_some()).map(|x| x.unwrap())`
 fn is_filter_some_map_unwrap(
     cx: &LateContext<'_>,
-    expr: &hir::Expr<'_>,
-    filter_recv: &hir::Expr<'_>,
-    filter_arg: &hir::Expr<'_>,
-    map_arg: &hir::Expr<'_>,
+    expr: &Expr<'_>,
+    filter_recv: &Expr<'_>,
+    filter_arg: &Expr<'_>,
+    map_arg: &Expr<'_>,
 ) -> bool {
     let iterator = is_trait_method(cx, expr, sym::Iterator);
     let option = is_type_diagnostic_item(cx, cx.typeck_results().expr_ty(filter_recv), sym::Option);
@@ -279,12 +277,7 @@ fn is_filter_some_map_unwrap(
 }
 
 /// is `filter(|x| x.is_ok()).map(|x| x.unwrap())`
-fn is_filter_ok_map_unwrap(
-    cx: &LateContext<'_>,
-    expr: &hir::Expr<'_>,
-    filter_arg: &hir::Expr<'_>,
-    map_arg: &hir::Expr<'_>,
-) -> bool {
+fn is_filter_ok_map_unwrap(cx: &LateContext<'_>, expr: &Expr<'_>, filter_arg: &Expr<'_>, map_arg: &Expr<'_>) -> bool {
     // result has no filter, so we only check for iterators
     let iterator = is_trait_method(cx, expr, sym::Iterator);
     iterator && is_ok_filter_map(cx, filter_arg, map_arg)
@@ -294,12 +287,12 @@ fn is_filter_ok_map_unwrap(
 #[allow(clippy::too_many_arguments)]
 pub(super) fn check(
     cx: &LateContext<'_>,
-    expr: &hir::Expr<'_>,
-    filter_recv: &hir::Expr<'_>,
-    filter_arg: &hir::Expr<'_>,
+    expr: &Expr<'_>,
+    filter_recv: &Expr<'_>,
+    filter_arg: &Expr<'_>,
     filter_span: Span,
-    map_recv: &hir::Expr<'_>,
-    map_arg: &hir::Expr<'_>,
+    map_recv: &Expr<'_>,
+    map_arg: &Expr<'_>,
     map_span: Span,
     is_find: bool,
 ) {
@@ -393,7 +386,7 @@ pub(super) fn check(
                 )
             },
         };
-        span_lint_and_then(cx, lint, span, &msg, |diag| {
+        span_lint_and_then(cx, lint, span, msg, |diag| {
             diag.span_suggestion(span, "try", sugg, applicability);
 
             if let Some((note, span)) = note_and_span {
@@ -405,9 +398,9 @@ pub(super) fn check(
 
 fn is_find_or_filter<'a>(
     cx: &LateContext<'a>,
-    map_recv: &hir::Expr<'_>,
-    filter_arg: &hir::Expr<'_>,
-    map_arg: &hir::Expr<'_>,
+    map_recv: &Expr<'_>,
+    filter_arg: &Expr<'_>,
+    map_arg: &Expr<'_>,
 ) -> Option<(Ident, CheckResult<'a>)> {
     if is_trait_method(cx, map_recv, sym::Iterator)
         // filter(|x| ...is_some())...
diff --git a/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
index 8291c373f37..999df875c75 100644
--- a/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/filter_map_identity.rs
@@ -1,5 +1,5 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
-use clippy_utils::{is_expr_untyped_identity_function, is_trait_method};
+use clippy_utils::{is_expr_identity_function, is_expr_untyped_identity_function, is_trait_method};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
 use rustc_lint::LateContext;
@@ -7,8 +7,20 @@ use rustc_span::{sym, Span};
 
 use super::FILTER_MAP_IDENTITY;
 
+fn is_identity(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Applicability> {
+    if is_expr_untyped_identity_function(cx, expr) {
+        return Some(Applicability::MachineApplicable);
+    }
+    if is_expr_identity_function(cx, expr) {
+        return Some(Applicability::Unspecified);
+    }
+    None
+}
+
 pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg: &hir::Expr<'_>, filter_map_span: Span) {
-    if is_trait_method(cx, expr, sym::Iterator) && is_expr_untyped_identity_function(cx, filter_map_arg) {
+    if is_trait_method(cx, expr, sym::Iterator)
+        && let Some(applicability) = is_identity(cx, filter_map_arg)
+    {
         span_lint_and_sugg(
             cx,
             FILTER_MAP_IDENTITY,
@@ -16,7 +28,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, filter_map_arg:
             "use of `filter_map` with an identity function",
             "try",
             "flatten()".to_string(),
-            Applicability::MachineApplicable,
+            applicability,
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/get_first.rs b/src/tools/clippy/clippy_lints/src/methods/get_first.rs
index 55fcf372894..f4465e654c2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/get_first.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/get_first.rs
@@ -32,7 +32,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 GET_FIRST,
                 expr.span,
-                &format!("accessing first element with `{slice_name}.get(0)`"),
+                format!("accessing first element with `{slice_name}.get(0)`"),
                 "try",
                 format!("{slice_name}.first()"),
                 app,
@@ -44,7 +44,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 GET_FIRST,
                 expr.span,
-                &format!("accessing first element with `{slice_name}.get(0)`"),
+                format!("accessing first element with `{slice_name}.get(0)`"),
                 "try",
                 format!("{slice_name}.front()"),
                 app,
diff --git a/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs b/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
index 3bdc154df04..62037651134 100644
--- a/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/get_last_with_len.rs
@@ -44,7 +44,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, arg:
             cx,
             GET_LAST_WITH_LEN,
             expr.span,
-            &format!("accessing last element with `{recv_snippet}.get({recv_snippet}.len() - 1)`"),
+            format!("accessing last element with `{recv_snippet}.get({recv_snippet}.len() - 1)`"),
             "try",
             format!("{recv_snippet}.{method}()"),
             applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs
index afdcb3b6549..455274a4428 100644
--- a/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/get_unwrap.rs
@@ -70,7 +70,7 @@ pub(super) fn check<'tcx>(
         cx,
         GET_UNWRAP,
         span,
-        &format!("called `.get{mut_str}().unwrap()` on a {caller_type}. Using `[]` is more clear and more concise"),
+        format!("called `.get{mut_str}().unwrap()` on a {caller_type}. Using `[]` is more clear and more concise"),
         "try",
         format!(
             "{borrow_str}{}[{get_args_str}]",
diff --git a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
index 78a553eb8c0..c510cd915d0 100644
--- a/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/implicit_clone.rs
@@ -27,7 +27,7 @@ pub fn check(cx: &LateContext<'_>, method_name: &str, expr: &hir::Expr<'_>, recv
             cx,
             IMPLICIT_CLONE,
             expr.span,
-            &format!("implicitly cloning a `{ty_name}` by calling `{method_name}` on its dereferenced type"),
+            format!("implicitly cloning a `{ty_name}` by calling `{method_name}` on its dereferenced type"),
             "consider using",
             if ref_count > 1 {
                 format!("({}{recv_snip}).clone()", "*".repeat(ref_count - 1))
diff --git a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
index efc3ddd20b4..230a8eb2ec4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/inefficient_to_string.rs
@@ -32,7 +32,7 @@ pub fn check(
             cx,
             INEFFICIENT_TO_STRING,
             expr.span,
-            &format!("calling `to_string` on `{arg_ty}`"),
+            format!("calling `to_string` on `{arg_ty}`"),
             |diag| {
                 diag.help(format!(
                     "`{self_ty}` implements `ToString` through a slower blanket impl, but `{deref_self_ty}` has a fast specialization of `ToString`"
diff --git a/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs b/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
index 80160d17c82..bbc7ce8d78a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/into_iter_on_ref.rs
@@ -27,7 +27,7 @@ pub(super) fn check(
             cx,
             INTO_ITER_ON_REF,
             method_span,
-            &format!("this `.into_iter()` call is equivalent to `.{method_name}()` and will not consume the `{kind}`",),
+            format!("this `.into_iter()` call is equivalent to `.{method_name}()` and will not consume the `{kind}`",),
             "call directly",
             method_name.to_string(),
             Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
index e963950960a..210e4ae0a7b 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_digit_ascii_radix.rs
@@ -36,7 +36,7 @@ pub(super) fn check<'tcx>(
             cx,
             IS_DIGIT_ASCII_RADIX,
             expr.span,
-            &format!("use of `char::is_digit` with literal radix of {num}"),
+            format!("use of `char::is_digit` with literal radix of {num}"),
             "try",
             format!(
                 "{}.{replacement}()",
diff --git a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
index 7fe66062251..d921b7ea14f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/is_empty.rs
@@ -23,7 +23,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &'_ Expr<'_>, receiver: &Expr<'_
             cx,
             CONST_IS_EMPTY,
             expr.span,
-            &format!("this expression always evaluates to {init_is_empty:?}"),
+            format!("this expression always evaluates to {init_is_empty:?}"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_cloned_collect.rs b/src/tools/clippy/clippy_lints/src/methods/iter_cloned_collect.rs
index dd741cd43f9..49de83885a1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_cloned_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_cloned_collect.rs
@@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, method_name: &str, expr: &hir:
             cx,
             ITER_CLONED_COLLECT,
             to_replace,
-            &format!(
+            format!(
                 "called `iter().{method_name}().collect()` on a slice to create a `Vec`. Calling `to_vec()` is both faster and \
             more readable"
             ),
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_count.rs b/src/tools/clippy/clippy_lints/src/methods/iter_count.rs
index bcddc7c786a..209cf2fcc0a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_count.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_count.rs
@@ -37,7 +37,7 @@ pub(crate) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>, recv: &'tcx E
         cx,
         ITER_COUNT,
         expr.span,
-        &format!("called `.{iter_method}().count()` on a `{caller_type}`"),
+        format!("called `.{iter_method}().count()` on a `{caller_type}`"),
         "try",
         format!(
             "{}.len()",
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs
index 9f84321ced4..12647ea1ffc 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_filter.rs
@@ -55,7 +55,7 @@ fn is_method(
         }
     }
     match expr.kind {
-        hir::ExprKind::MethodCall(hir::PathSegment { ident, .. }, recv, ..) => {
+        ExprKind::MethodCall(hir::PathSegment { ident, .. }, recv, ..) => {
             // compare the identifier of the receiver to the parameter
             // we are in a filter => closure has a single parameter and a single, non-block
             // expression, this means that the parameter shadows all outside variables with
@@ -73,7 +73,7 @@ fn is_method(
         // This is used to check for complete paths via `|a| std::option::Option::is_some(a)`
         // this then unwraps to a path with `QPath::TypeRelative`
         // we pass the params as they've been passed to the current call through the closure
-        hir::ExprKind::Call(expr, [param]) => {
+        ExprKind::Call(expr, [param]) => {
             // this will hit the `QPath::TypeRelative` case and check that the method name is correct
             if is_method(cx, expr, type_symbol, method_name, params)
                 // we then check that this is indeed passing the parameter of the closure
@@ -85,7 +85,7 @@ fn is_method(
             }
             false
         },
-        hir::ExprKind::Path(QPath::TypeRelative(ty, mname)) => {
+        ExprKind::Path(QPath::TypeRelative(ty, mname)) => {
             let ty = cx.typeck_results().node_type(ty.hir_id);
             if let Some(did) = cx.tcx.get_diagnostic_item(type_symbol)
                 && ty.ty_adt_def() == cx.tcx.type_of(did).skip_binder().ty_adt_def()
@@ -94,7 +94,7 @@ fn is_method(
             }
             false
         },
-        hir::ExprKind::Closure(&hir::Closure { body, .. }) => {
+        ExprKind::Closure(&hir::Closure { body, .. }) => {
             let body = cx.tcx.hir().body(body);
             let closure_expr = peel_blocks(body.value);
             let params = body.params.iter().map(|param| param.pat).collect::<Vec<_>>();
@@ -107,8 +107,8 @@ fn is_method(
 fn parent_is_map(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
     if let Some(expr) = get_parent_expr(cx, expr)
         && is_trait_method(cx, expr, sym::Iterator)
-        && let hir::ExprKind::MethodCall(path, _, _, _) = expr.kind
-        && path.ident.name == rustc_span::sym::map
+        && let ExprKind::MethodCall(path, _, _, _) = expr.kind
+        && path.ident.name == sym::map
     {
         return true;
     }
@@ -148,7 +148,7 @@ fn expression_type(
     {
         return None;
     }
-    if let hir::ExprKind::MethodCall(_, receiver, _, _) = expr.kind
+    if let ExprKind::MethodCall(_, receiver, _, _) = expr.kind
         && let receiver_ty = cx.typeck_results().expr_ty(receiver)
         && let Some(iter_item_ty) = get_iterator_item_ty(cx, receiver_ty)
     {
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
index 1431a5db2d9..b9fec0c4f80 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_kv_map.rs
@@ -54,7 +54,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 ITER_KV_MAP,
                 expr.span,
-                &format!("iterating on a map's {replacement_kind}s"),
+                format!("iterating on a map's {replacement_kind}s"),
                 "try",
                 format!("{recv_snippet}.{into_prefix}{replacement_kind}s()"),
                 applicability,
@@ -64,7 +64,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 ITER_KV_MAP,
                 expr.span,
-                &format!("iterating on a map's {replacement_kind}s"),
+                format!("iterating on a map's {replacement_kind}s"),
                 "try",
                 format!(
                     "{recv_snippet}.{into_prefix}{replacement_kind}s().map(|{}{bound_ident}| {})",
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs b/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs
index 5b0b70b4b96..e31fa2f777d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_nth.rs
@@ -28,7 +28,7 @@ pub(super) fn check<'tcx>(
         cx,
         ITER_NTH,
         expr.span,
-        &format!("called `.{iter_method}().nth()` on a {caller_type}"),
+        format!("called `.{iter_method}().nth()` on a {caller_type}"),
         |diag| {
             let get_method = if iter_method == "iter_mut" { "get_mut" } else { "get" };
             diag.span_suggestion_verbose(
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
index 19b7e97339d..6c9bdcff826 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_on_single_or_empty_collections.rs
@@ -69,7 +69,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
             cx,
             ITER_ON_SINGLE_ITEMS,
             expr.span,
-            &format!("`{method_name}` call on a collection with only one item"),
+            format!("`{method_name}` call on a collection with only one item"),
             "try",
             sugg,
             Applicability::MaybeIncorrect,
@@ -79,7 +79,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: &str, re
             cx,
             ITER_ON_EMPTY_COLLECTIONS,
             expr.span,
-            &format!("`{method_name}` call on an empty collection"),
+            format!("`{method_name}` call on an empty collection"),
             "try",
             format!("{top_crate}::iter::empty()"),
             Applicability::MaybeIncorrect,
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
index b2fe129cd95..4729481320e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_overeager_cloned.rs
@@ -60,7 +60,7 @@ pub(super) fn check<'tcx>(
         }
 
         if let Op::NeedlessMove(expr) = op {
-            let rustc_hir::ExprKind::Closure(closure) = expr.kind else {
+            let ExprKind::Closure(closure) = expr.kind else {
                 return;
             };
             let body @ Body { params: [p], .. } = cx.tcx.hir().body(closure.body) else {
diff --git a/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs b/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
index 2ab721ace84..1378a07cbc4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/iter_with_drain.rs
@@ -20,7 +20,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, span
             cx,
             ITER_WITH_DRAIN,
             span.with_hi(expr.span.hi()),
-            &format!("`drain(..)` used on a `{ty_name}`"),
+            format!("`drain(..)` used on a `{ty_name}`"),
             "try",
             "into_iter()".to_string(),
             Applicability::MaybeIncorrect,
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
index bf437db7e72..9e3b313156e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_saturating_arithmetic.rs
@@ -50,7 +50,7 @@ pub fn check(
         super::MANUAL_SATURATING_ARITHMETIC,
         expr.span,
         "manual saturating arithmetic",
-        &format!("consider using `saturating_{arith}`"),
+        format!("consider using `saturating_{arith}`"),
         format!(
             "{}.saturating_{arith}({})",
             snippet_with_applicability(cx, arith_lhs.span, "..", &mut applicability),
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
index c3c7a3a0033..0901268e9bd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_clone.rs
@@ -1,7 +1,7 @@
 use clippy_config::msrvs::{self, Msrv};
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::{is_copy, is_type_diagnostic_item};
+use clippy_utils::ty::{is_copy, is_type_diagnostic_item, should_call_clone_as_function};
 use clippy_utils::{is_diag_trait_item, match_def_path, paths, peel_blocks};
 use rustc_errors::Applicability;
 use rustc_hir as hir;
@@ -50,7 +50,7 @@ pub(super) fn check(cx: &LateContext<'_>, e: &hir::Expr<'_>, recv: &hir::Expr<'_
                 let closure_body = cx.tcx.hir().body(body);
                 let closure_expr = peel_blocks(closure_body.value);
                 match closure_body.params[0].pat.kind {
-                    hir::PatKind::Ref(inner, hir::Mutability::Not) => {
+                    hir::PatKind::Ref(inner, Mutability::Not) => {
                         if let hir::PatKind::Binding(hir::BindingAnnotation::NONE, .., name, None) = inner.kind {
                             if ident_eq(name, closure_expr) {
                                 lint_explicit_closure(cx, e.span, recv.span, true, msrv);
@@ -124,6 +124,7 @@ fn handle_path(
             && let ty::Ref(_, ty, Mutability::Not) = ty.kind()
             && let ty::FnDef(_, lst) = cx.typeck_results().expr_ty(arg).kind()
             && lst.iter().all(|l| l.as_type() == Some(*ty))
+            && !should_call_clone_as_function(cx, *ty)
         {
             lint_path(cx, e.span, recv.span, is_copy(cx, ty.peel_refs()));
         }
@@ -160,7 +161,7 @@ fn lint_path(cx: &LateContext<'_>, replace: Span, root: Span, is_copy: bool) {
         MAP_CLONE,
         replace,
         "you are explicitly cloning with `.map()`",
-        &format!("consider calling the dedicated `{replacement}` method"),
+        format!("consider calling the dedicated `{replacement}` method"),
         format!(
             "{}.{replacement}()",
             snippet_with_applicability(cx, root, "..", &mut applicability),
@@ -183,7 +184,7 @@ fn lint_explicit_closure(cx: &LateContext<'_>, replace: Span, root: Span, is_cop
         MAP_CLONE,
         replace,
         message,
-        &format!("consider calling the dedicated `{sugg_method}` method"),
+        format!("consider calling the dedicated `{sugg_method}` method"),
         format!(
             "{}.{sugg_method}()",
             snippet_with_applicability(cx, root, "..", &mut applicability),
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
index 26ef0d10fed..def8be2ef73 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_flatten.rs
@@ -21,8 +21,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>, map_
             cx,
             MAP_FLATTEN,
             expr.span.with_lo(map_span.lo()),
-            &format!("called `map(..).flatten()` on `{caller_ty_name}`"),
-            &format!("try replacing `map` with `{method_to_use}` and remove the `.flatten()`"),
+            format!("called `map(..).flatten()` on `{caller_ty_name}`"),
+            format!("try replacing `map` with `{method_to_use}` and remove the `.flatten()`"),
             format!("{method_to_use}({closure_snippet})"),
             applicability,
         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
index 6da9a87f5ee..5dd7b1b02ad 100644
--- a/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/map_identity.rs
@@ -29,7 +29,7 @@ pub(super) fn check(
             MAP_IDENTITY,
             sugg_span,
             "unnecessary map of the identity function",
-            &format!("remove the call to `{name}`"),
+            format!("remove the call to `{name}`"),
             String::new(),
             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 b6c474212cd..2fb317c8c68 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -231,8 +231,12 @@ declare_clippy_lint! {
     /// used instead.
     ///
     /// ### Why is this bad?
-    /// When applicable, `filter_map()` is more clear since it shows that
-    /// `Option` is used to produce 0 or 1 items.
+    /// `filter_map()` is known to always produce 0 or 1 output items per input item,
+    /// rather than however many the inner iterator type produces.
+    /// Therefore, it maintains the upper bound in `Iterator::size_hint()`,
+    /// and communicates to the reader that the input items are not being expanded into
+    /// multiple output items without their having to notice that the mapping function
+    /// returns an `Option`.
     ///
     /// ### Example
     /// ```no_run
@@ -2998,13 +3002,22 @@ declare_clippy_lint! {
 
 declare_clippy_lint! {
     /// ### What it does
-    /// Looks for calls to `<Box<dyn Any> as Any>::type_id`.
+    /// Looks for calls to `.type_id()` on a `Box<dyn _>`.
     ///
     /// ### Why is this bad?
-    /// This most certainly does not do what the user expects and is very easy to miss.
-    /// Calling `type_id` on a `Box<dyn Any>` calls `type_id` on the `Box<..>` itself,
-    /// so this will return the `TypeId` of the `Box<dyn Any>` type (not the type id
-    /// of the value referenced by the box!).
+    /// This almost certainly does not do what the user expects and can lead to subtle bugs.
+    /// Calling `.type_id()` on a `Box<dyn Trait>` returns a fixed `TypeId` of the `Box` itself,
+    /// rather than returning the `TypeId` of the underlying type behind the trait object.
+    ///
+    /// For `Box<dyn Any>` specifically (and trait objects that have `Any` as its supertrait),
+    /// this lint will provide a suggestion, which is to dereference the receiver explicitly
+    /// to go from `Box<dyn Any>` to `dyn Any`.
+    /// This makes sure that `.type_id()` resolves to a dynamic call on the trait object
+    /// and not on the box.
+    ///
+    /// If the fixed `TypeId` of the `Box` is the intended behavior, it's better to be explicit about it
+    /// and write `TypeId::of::<Box<dyn Trait>>()`:
+    /// this makes it clear that a fixed `TypeId` is returned and not the `TypeId` of the implementor.
     ///
     /// ### Example
     /// ```rust,ignore
@@ -3024,7 +3037,7 @@ declare_clippy_lint! {
     #[clippy::version = "1.73.0"]
     pub TYPE_ID_ON_BOX,
     suspicious,
-    "calling `.type_id()` on `Box<dyn Any>`"
+    "calling `.type_id()` on a boxed trait object"
 }
 
 declare_clippy_lint! {
@@ -4236,8 +4249,8 @@ impl_lint_pass!(Methods => [
 
 /// Extracts a method call name, args, and `Span` of the method name.
 pub fn method_call<'tcx>(
-    recv: &'tcx hir::Expr<'tcx>,
-) -> Option<(&'tcx str, &'tcx hir::Expr<'tcx>, &'tcx [hir::Expr<'tcx>], Span, Span)> {
+    recv: &'tcx Expr<'tcx>,
+) -> Option<(&'tcx str, &'tcx Expr<'tcx>, &'tcx [Expr<'tcx>], Span, Span)> {
     if let ExprKind::MethodCall(path, receiver, args, call_span) = recv.kind {
         if !args.iter().any(|e| e.span.from_expansion()) && !receiver.span.from_expansion() {
             let name = path.ident.name.as_str();
@@ -4248,7 +4261,7 @@ pub fn method_call<'tcx>(
 }
 
 impl<'tcx> LateLintPass<'tcx> for Methods {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if expr.span.from_expansion() {
             return;
         }
@@ -4256,12 +4269,12 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
         self.check_methods(cx, expr);
 
         match expr.kind {
-            hir::ExprKind::Call(func, args) => {
+            ExprKind::Call(func, args) => {
                 from_iter_instead_of_collect::check(cx, expr, args, func);
                 unnecessary_fallible_conversions::check_function(cx, expr, func);
                 manual_c_str_literals::check(cx, expr, func, args, &self.msrv);
             },
-            hir::ExprKind::MethodCall(method_call, receiver, args, _) => {
+            ExprKind::MethodCall(method_call, receiver, args, _) => {
                 let method_span = method_call.ident.span;
                 or_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
                 expect_fun_call::check(cx, expr, method_span, method_call.ident.as_str(), receiver, args);
@@ -4273,7 +4286,7 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                 single_char_pattern::check(cx, expr, method_call.ident.name, receiver, args);
                 unnecessary_to_owned::check(cx, expr, method_call.ident.name, receiver, args, &self.msrv);
             },
-            hir::ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
+            ExprKind::Binary(op, lhs, rhs) if op.node == hir::BinOpKind::Eq || op.node == hir::BinOpKind::Ne => {
                 let mut info = BinaryExprInfo {
                     expr,
                     chain: lhs,
@@ -4320,12 +4333,12 @@ impl<'tcx> LateLintPass<'tcx> for Methods {
                             cx,
                             SHOULD_IMPLEMENT_TRAIT,
                             impl_item.span,
-                            &format!(
+                            format!(
                                 "method `{}` can be confused for the standard trait method `{}::{}`",
                                 method_config.method_name, method_config.trait_name, method_config.method_name
                             ),
                             None,
-                            &format!(
+                            format!(
                                 "consider implementing the trait `{}` or choosing a less ambiguous method name",
                                 method_config.trait_name
                             ),
@@ -4995,9 +5008,9 @@ fn check_is_some_is_none(cx: &LateContext<'_>, expr: &Expr<'_>, recv: &Expr<'_>,
 /// Used for `lint_binary_expr_with_method_call`.
 #[derive(Copy, Clone)]
 struct BinaryExprInfo<'a> {
-    expr: &'a hir::Expr<'a>,
-    chain: &'a hir::Expr<'a>,
-    other: &'a hir::Expr<'a>,
+    expr: &'a Expr<'a>,
+    chain: &'a Expr<'a>,
+    other: &'a Expr<'a>,
     eq: bool,
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
index 9e2fd92255e..662e7746496 100644
--- a/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/needless_collect.rs
@@ -107,7 +107,7 @@ pub(super) fn check<'tcx>(
                 span.push_span_label(iter_call.span, "the iterator could be used here instead");
                 span_lint_hir_and_then(
                     cx,
-                    super::NEEDLESS_COLLECT,
+                    NEEDLESS_COLLECT,
                     collect_expr.hir_id,
                     span,
                     NEEDLESS_COLLECT_MSG,
diff --git a/src/tools/clippy/clippy_lints/src/methods/open_options.rs b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
index 77484ab91a9..d425b505a76 100644
--- a/src/tools/clippy/clippy_lints/src/methods/open_options.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/open_options.rs
@@ -151,7 +151,7 @@ fn check_open_options(cx: &LateContext<'_>, settings: &[(OpenOption, Argument, S
                 cx,
                 NONSENSICAL_OPEN_OPTIONS,
                 prev_span,
-                &format!("the method `{}` is called more than once", &option),
+                format!("the method `{}` is called more than once", &option),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs
index d7fec360fa2..ba167f9d9c2 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_cloned.rs
@@ -15,7 +15,7 @@ pub(super) fn check(cx: &LateContext<'_>, cloned_recv: &Expr<'_>, cloned_ident_s
             cx,
             OPTION_AS_REF_CLONED,
             as_ref_ident_span.to(cloned_ident_span),
-            &format!("cloning an `Option<_>` using `.{method}().cloned()`"),
+            format!("cloning an `Option<_>` using `.{method}().cloned()`"),
             "this can be written more concisely by cloning the `Option<_>` directly",
             "clone".into(),
             Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
index 88e2af15658..cb57689b0c4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_as_ref_deref.rs
@@ -104,8 +104,8 @@ pub(super) fn check(
             cx,
             OPTION_AS_REF_DEREF,
             expr.span,
-            &msg,
-            &suggestion,
+            msg,
+            suggestion,
             hint,
             Applicability::MachineApplicable,
         );
diff --git a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
index ab36f854fcb..efec9dd716d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/option_map_unwrap_or.rs
@@ -97,7 +97,7 @@ pub(super) fn check<'tcx>(
         } else {
             "map_or(<a>, <f>)"
         };
-        let msg = &format!("called `map(<f>).unwrap_or({arg})` on an `Option` value");
+        let msg = format!("called `map(<f>).unwrap_or({arg})` on an `Option` value");
 
         span_lint_and_then(cx, MAP_UNWRAP_OR, expr.span, msg, |diag| {
             let map_arg_span = map_arg.span;
diff --git a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
index 0602eeaa704..583e04fb4b1 100644
--- a/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/or_fun_call.rs
@@ -97,7 +97,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 UNWRAP_OR_DEFAULT,
                 method_span.with_hi(span.hi()),
-                &format!("use of `{name}` to construct default value"),
+                format!("use of `{name}` to construct default value"),
                 "try",
                 format!("{sugg}()"),
                 Applicability::MachineApplicable,
@@ -167,7 +167,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 OR_FUN_CALL,
                 span_replace_word,
-                &format!("use of `{name}` followed by a function call"),
+                format!("use of `{name}` followed by a function call"),
                 "try",
                 format!("{name}_{suffix}({sugg})"),
                 app,
diff --git a/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs b/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
index 1148628b084..28ca76832eb 100644
--- a/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/range_zip_with_len.rs
@@ -24,7 +24,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, recv: &'
             cx,
             RANGE_ZIP_WITH_LEN,
             expr.span,
-            &format!(
+            format!(
                 "it is more idiomatic to use `{}.iter().enumerate()`",
                 snippet(cx, recv.span, "_")
             ),
diff --git a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
index ef1baa6c988..ac5cc2f01e5 100644
--- a/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/search_is_some.rs
@@ -39,7 +39,7 @@ pub(super) fn check<'tcx>(
                 && let closure_body = cx.tcx.hir().body(body)
                 && let Some(closure_arg) = closure_body.params.first()
             {
-                if let hir::PatKind::Ref(..) = closure_arg.pat.kind {
+                if let PatKind::Ref(..) = closure_arg.pat.kind {
                     Some(search_snippet.replacen('&', "", 1))
                 } else if let PatKind::Binding(..) = strip_pat_refs(closure_arg.pat).kind {
                     // `find()` provides a reference to the item, but `any` does not,
@@ -62,7 +62,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     SEARCH_IS_SOME,
                     method_span.with_hi(expr.span.hi()),
-                    &msg,
+                    msg,
                     "consider using",
                     format!(
                         "any({})",
@@ -76,7 +76,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     SEARCH_IS_SOME,
                     expr.span,
-                    &msg,
+                    msg,
                     "consider using",
                     format!(
                         "!{iter}.any({})",
@@ -94,7 +94,7 @@ pub(super) fn check<'tcx>(
                     ""
                 }
             );
-            span_lint_and_help(cx, SEARCH_IS_SOME, expr.span, &msg, None, &hint);
+            span_lint_and_help(cx, SEARCH_IS_SOME, expr.span, msg, None, hint);
         }
     }
     // lint if `find()` is called by `String` or `&str`
@@ -117,7 +117,7 @@ pub(super) fn check<'tcx>(
                         cx,
                         SEARCH_IS_SOME,
                         method_span.with_hi(expr.span.hi()),
-                        &msg,
+                        msg,
                         "consider using",
                         format!("contains({find_arg})"),
                         applicability,
@@ -131,7 +131,7 @@ pub(super) fn check<'tcx>(
                         cx,
                         SEARCH_IS_SOME,
                         expr.span,
-                        &msg,
+                        msg,
                         "consider using",
                         format!("!{string}.contains({find_arg})"),
                         applicability,
diff --git a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs
index 0f4c97022db..aef14435d8a 100644
--- a/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/stable_sort_primitive.rs
@@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, recv: &'tcx
             cx,
             STABLE_SORT_PRIMITIVE,
             e.span,
-            &format!("used `sort` on primitive type `{slice_type}`"),
+            format!("used `sort` on primitive type `{slice_type}`"),
             |diag| {
                 let mut app = Applicability::MachineApplicable;
                 let recv_snip = snippet_with_context(cx, recv.span, e.span.ctxt(), "..", &mut app).0;
diff --git a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
index 946cdb49d27..55ae9746298 100644
--- a/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/str_splitn.rs
@@ -53,7 +53,7 @@ fn lint_needless(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, self_
         cx,
         NEEDLESS_SPLITN,
         expr.span,
-        &format!("unnecessary use of `{r}splitn`"),
+        format!("unnecessary use of `{r}splitn`"),
         "try",
         format!(
             "{}.{r}split({})",
@@ -154,7 +154,7 @@ fn check_manual_split_once_indirect(
         let self_snip = snippet_with_context(cx, self_arg.span, ctxt, "..", &mut app).0;
         let pat_snip = snippet_with_context(cx, pat_arg.span, ctxt, "..", &mut app).0;
 
-        span_lint_and_then(cx, MANUAL_SPLIT_ONCE, local.span, &msg, |diag| {
+        span_lint_and_then(cx, MANUAL_SPLIT_ONCE, local.span, msg, |diag| {
             diag.span_label(first.span, "first usage here");
             diag.span_label(second.span, "second usage here");
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs
index c45212581ee..ff5c1d1a401 100644
--- a/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_splitn.rs
@@ -37,6 +37,6 @@ pub(super) fn check(cx: &LateContext<'_>, method_name: &str, expr: &Expr<'_>, se
             )
         };
 
-        span_lint_and_note(cx, SUSPICIOUS_SPLITN, expr.span, &msg, None, note_msg);
+        span_lint_and_note(cx, SUSPICIOUS_SPLITN, expr.span, msg, None, note_msg);
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs b/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
index 60864902a48..ce7aefed01f 100644
--- a/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/suspicious_to_owned.rs
@@ -23,7 +23,7 @@ pub fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, recv: &hir::Expr<'_>) -
             cx,
             SUSPICIOUS_TO_OWNED,
             expr.span,
-            &with_forced_trimmed_paths!(format!(
+            with_forced_trimmed_paths!(format!(
                 "this `to_owned` call clones the {input_type} itself and does not cause the {input_type} contents to become owned"
             )),
             |diag| {
diff --git a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs
index 4917936a932..6f9b38fcf83 100644
--- a/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/type_id_on_box.rs
@@ -5,13 +5,33 @@ use rustc_errors::Applicability;
 use rustc_hir::Expr;
 use rustc_lint::LateContext;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment};
+use rustc_middle::ty::print::with_forced_trimmed_paths;
 use rustc_middle::ty::{self, ExistentialPredicate, Ty};
 use rustc_span::{sym, Span};
 
-fn is_dyn_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
+/// Checks if the given type is `dyn Any`, or a trait object that has `Any` as a supertrait.
+/// Only in those cases will its vtable have a `type_id` method that returns the implementor's
+/// `TypeId`, and only in those cases can we give a proper suggestion to dereference the box.
+///
+/// If this returns false, then `.type_id()` likely (this may have FNs) will not be what the user
+/// expects in any case and dereferencing it won't help either. It will likely require some
+/// other changes, but it is still worth emitting a lint.
+/// See <https://github.com/rust-lang/rust-clippy/pull/11350#discussion_r1544863005> for more details.
+fn is_subtrait_of_any(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     if let ty::Dynamic(preds, ..) = ty.kind() {
         preds.iter().any(|p| match p.skip_binder() {
-            ExistentialPredicate::Trait(tr) => cx.tcx.is_diagnostic_item(sym::Any, tr.def_id),
+            ExistentialPredicate::Trait(tr) => {
+                cx.tcx.is_diagnostic_item(sym::Any, tr.def_id)
+                    || cx
+                        .tcx
+                        .super_predicates_of(tr.def_id)
+                        .predicates
+                        .iter()
+                        .any(|(clause, _)| {
+                            matches!(clause.kind().skip_binder(), ty::ClauseKind::Trait(super_tr)
+                            if cx.tcx.is_diagnostic_item(sym::Any, super_tr.def_id()))
+                        })
+            },
             _ => false,
         })
     } else {
@@ -26,36 +46,42 @@ pub(super) fn check(cx: &LateContext<'_>, receiver: &Expr<'_>, call_span: Span)
         && let ty::Ref(_, ty, _) = recv_ty.kind()
         && let ty::Adt(adt, args) = ty.kind()
         && adt.is_box()
-        && is_dyn_any(cx, args.type_at(0))
+        && let inner_box_ty = args.type_at(0)
+        && let ty::Dynamic(..) = inner_box_ty.kind()
     {
+        let ty_name = with_forced_trimmed_paths!(ty.to_string());
+
         span_lint_and_then(
             cx,
             TYPE_ID_ON_BOX,
             call_span,
-            "calling `.type_id()` on a `Box<dyn Any>`",
+            format!("calling `.type_id()` on `{ty_name}`"),
             |diag| {
                 let derefs = recv_adjusts
                     .iter()
                     .filter(|adj| matches!(adj.kind, Adjust::Deref(None)))
                     .count();
 
-                let mut sugg = "*".repeat(derefs + 1);
-                sugg += &snippet(cx, receiver.span, "<expr>");
-
                 diag.note(
-                    "this returns the type id of the literal type `Box<dyn Any>` instead of the \
+                    "this returns the type id of the literal type `Box<_>` instead of the \
                     type id of the boxed value, which is most likely not what you want",
                 )
-                .note(
-                    "if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, \
-                    which makes it more clear",
-                )
-                .span_suggestion(
-                    receiver.span,
-                    "consider dereferencing first",
-                    format!("({sugg})"),
-                    Applicability::MaybeIncorrect,
-                );
+                .note(format!(
+                    "if this is intentional, use `TypeId::of::<{ty_name}>()` instead, \
+                    which makes it more clear"
+                ));
+
+                if is_subtrait_of_any(cx, inner_box_ty) {
+                    let mut sugg = "*".repeat(derefs + 1);
+                    sugg += &snippet(cx, receiver.span, "<expr>");
+
+                    diag.span_suggestion(
+                        receiver.span,
+                        "consider dereferencing first",
+                        format!("({sugg})"),
+                        Applicability::MaybeIncorrect,
+                    );
+                }
             },
         );
     }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
index fabf3fa0c0c..daf99d98614 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_filter_map.rs
@@ -60,7 +60,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'tcx>, a
                 UNNECESSARY_FIND_MAP
             },
             expr.span,
-            &format!("this `.{name}` can be written more simply using `.{sugg}`"),
+            format!("this `.{name}` can be written more simply using `.{sugg}`"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
index cc8053ef507..f6184222d8e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_get_then_check.rs
@@ -58,7 +58,7 @@ pub(super) fn check(
                 cx,
                 UNNECESSARY_GET_THEN_CHECK,
                 both_calls_span,
-                &format!("unnecessary use of `{snippet}`"),
+                format!("unnecessary use of `{snippet}`"),
                 "replace it with",
                 suggestion,
                 Applicability::MaybeIncorrect,
@@ -70,7 +70,7 @@ pub(super) fn check(
                 cx,
                 UNNECESSARY_GET_THEN_CHECK,
                 both_calls_span,
-                &format!("unnecessary use of `{snippet}`"),
+                format!("unnecessary use of `{snippet}`"),
                 |diag| {
                     diag.span_suggestion(
                         full_span,
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
index 36497d59a5a..520dcb2d52d 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_iter_cloned.rs
@@ -61,7 +61,7 @@ pub fn check_for_loop_iter(
             cx,
             UNNECESSARY_TO_OWNED,
             expr.span,
-            &format!("unnecessary use of `{method_name}`"),
+            format!("unnecessary use of `{method_name}`"),
             |diag| {
                 // If `check_into_iter_call_arg` called `check_for_loop_iter` because a call to
                 // a `to_owned`-like function was removed, then the next suggestion may be
diff --git a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
index 1b2bfbf4090..494d71fc053 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unnecessary_literal_unwrap.rs
@@ -63,7 +63,7 @@ pub(super) fn check(
     let help_message = format!("used `{method}()` on `{constructor}` value");
     let suggestion_message = format!("remove the `{constructor}` and `{method}()`");
 
-    span_lint_and_then(cx, UNNECESSARY_LITERAL_UNWRAP, expr.span, &help_message, |diag| {
+    span_lint_and_then(cx, UNNECESSARY_LITERAL_UNWRAP, expr.span, help_message, |diag| {
         let suggestions = match (constructor, method, ty) {
             ("None", "unwrap", _) => Some(vec![(expr.span, "panic!()".to_string())]),
             ("None", "expect", _) => Some(vec![
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 e58d4776427..23fc323446e 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
@@ -18,8 +18,7 @@ use rustc_lint::LateContext;
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, OverloadedDeref};
 use rustc_middle::ty::{
-    self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate,
-    TraitPredicate, Ty,
+    self, ClauseKind, GenericArg, GenericArgKind, GenericArgsRef, ParamTy, ProjectionPredicate, TraitPredicate, Ty,
 };
 use rustc_span::{sym, Symbol};
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt as _;
@@ -138,7 +137,7 @@ fn check_addr_of_expr(
                 cx,
                 UNNECESSARY_TO_OWNED,
                 parent.span,
-                &format!("unnecessary use of `{method_name}`"),
+                format!("unnecessary use of `{method_name}`"),
                 "use",
                 format!(
                     "{:&>width$}{receiver_snippet}",
@@ -163,7 +162,7 @@ fn check_addr_of_expr(
                     cx,
                     UNNECESSARY_TO_OWNED,
                     parent.span,
-                    &format!("unnecessary use of `{method_name}`"),
+                    format!("unnecessary use of `{method_name}`"),
                     "use",
                     receiver_snippet,
                     Applicability::MachineApplicable,
@@ -173,7 +172,7 @@ fn check_addr_of_expr(
                     cx,
                     UNNECESSARY_TO_OWNED,
                     expr.span.with_lo(receiver.span.hi()),
-                    &format!("unnecessary use of `{method_name}`"),
+                    format!("unnecessary use of `{method_name}`"),
                     "remove this",
                     String::new(),
                     Applicability::MachineApplicable,
@@ -188,7 +187,7 @@ fn check_addr_of_expr(
                 cx,
                 UNNECESSARY_TO_OWNED,
                 parent.span,
-                &format!("unnecessary use of `{method_name}`"),
+                format!("unnecessary use of `{method_name}`"),
                 "use",
                 format!("{receiver_snippet}.as_ref()"),
                 Applicability::MachineApplicable,
@@ -232,7 +231,7 @@ fn check_into_iter_call_arg(
             cx,
             UNNECESSARY_TO_OWNED,
             parent.span,
-            &format!("unnecessary use of `{method_name}`"),
+            format!("unnecessary use of `{method_name}`"),
             "use",
             format!("{receiver_snippet}.iter().{cloned_or_copied}()"),
             Applicability::MaybeIncorrect,
@@ -271,7 +270,7 @@ fn check_split_call_arg(cx: &LateContext<'_>, expr: &Expr<'_>, method_name: Symb
             cx,
             UNNECESSARY_TO_OWNED,
             parent.span,
-            &format!("unnecessary use of `{method_name}`"),
+            format!("unnecessary use of `{method_name}`"),
             "use",
             format!("{receiver_snippet}{as_ref}.split({arg_snippet})"),
             Applicability::MaybeIncorrect,
@@ -350,7 +349,7 @@ fn check_other_call_arg<'tcx>(
             cx,
             UNNECESSARY_TO_OWNED,
             maybe_arg.span,
-            &format!("unnecessary use of `{method_name}`"),
+            format!("unnecessary use of `{method_name}`"),
             "use",
             format!("{:&>n_refs$}{receiver_snippet}", ""),
             Applicability::MachineApplicable,
@@ -642,7 +641,7 @@ fn check_if_applicable_to_argument<'tcx>(cx: &LateContext<'tcx>, arg: &Expr<'tcx
             cx,
             UNNECESSARY_TO_OWNED,
             arg.span,
-            &format!("unnecessary use of `{method_name}`"),
+            format!("unnecessary use of `{method_name}`"),
             "replace it with",
             if original_arg_ty.is_array() {
                 format!("{snippet}.as_slice()")
diff --git a/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs b/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs
index 7bd16b473ce..516b8984ad7 100644
--- a/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/unwrap_expect_used.rs
@@ -69,7 +69,7 @@ pub(super) fn check(
         cx,
         variant.lint(),
         expr.span,
-        &format!("used `{}()` on {kind} value", variant.method_name(is_err)),
+        format!("used `{}()` on {kind} value", variant.method_name(is_err)),
         |diag| {
             diag.note(format!("if this value is {none_prefix}`{none_value}`, it will panic"));
 
diff --git a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
index b8baad18cc8..ae2b6e6347e 100644
--- a/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/useless_asref.rs
@@ -1,6 +1,6 @@
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::walk_ptrs_ty_depth;
+use clippy_utils::ty::{should_call_clone_as_function, walk_ptrs_ty_depth};
 use clippy_utils::{
     get_parent_expr, is_diag_trait_item, match_def_path, path_to_local_id, paths, peel_blocks, strip_pat_refs,
 };
@@ -68,7 +68,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
                 cx,
                 USELESS_ASREF,
                 expr.span,
-                &format!("this call to `{call_name}` does nothing"),
+                format!("this call to `{call_name}` does nothing"),
                 "try",
                 snippet_with_applicability(cx, recvr.span, "..", &mut applicability).to_string(),
                 applicability,
@@ -93,6 +93,8 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &hir::Expr<'_>, call_name: &str,
             // And that it only has one argument.
             && let [arg] = args
             && is_calling_clone(cx, arg)
+            // And that we are not recommending recv.clone() over Arc::clone() or similar
+            && !should_call_clone_as_function(cx, rcv_ty)
         {
             lint_as_ref_clone(cx, expr.span.with_hi(parent.span.hi()), recvr, call_name);
         }
@@ -157,7 +159,7 @@ fn lint_as_ref_clone(cx: &LateContext<'_>, span: Span, recvr: &hir::Expr<'_>, ca
         cx,
         USELESS_ASREF,
         span,
-        &format!("this call to `{call_name}.map(...)` does nothing"),
+        format!("this call to `{call_name}.map(...)` does nothing"),
         "try",
         format!(
             "{}.clone()",
diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs
index 3a0305b4d55..ef00c812d51 100644
--- a/src/tools/clippy/clippy_lints/src/methods/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs
@@ -3,7 +3,6 @@ use clippy_utils::ty::is_type_diagnostic_item;
 use clippy_utils::{get_parent_expr, path_to_local_id, usage};
 use rustc_ast::ast;
 use rustc_errors::Applicability;
-use rustc_hir as hir;
 use rustc_hir::intravisit::{walk_expr, Visitor};
 use rustc_hir::{BorrowKind, Expr, ExprKind, HirId, Mutability, Pat};
 use rustc_lint::LateContext;
@@ -13,9 +12,9 @@ use rustc_span::symbol::sym;
 
 pub(super) fn derefs_to_slice<'tcx>(
     cx: &LateContext<'tcx>,
-    expr: &'tcx hir::Expr<'tcx>,
+    expr: &'tcx Expr<'tcx>,
     ty: Ty<'tcx>,
-) -> Option<&'tcx hir::Expr<'tcx>> {
+) -> Option<&'tcx Expr<'tcx>> {
     fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
         match ty.kind() {
             ty::Slice(_) => true,
@@ -27,7 +26,7 @@ pub(super) fn derefs_to_slice<'tcx>(
         }
     }
 
-    if let hir::ExprKind::MethodCall(path, self_arg, ..) = &expr.kind {
+    if let ExprKind::MethodCall(path, self_arg, ..) = &expr.kind {
         if path.ident.name == sym::iter && may_slice(cx, cx.typeck_results().expr_ty(self_arg)) {
             Some(self_arg)
         } else {
@@ -51,10 +50,10 @@ pub(super) fn derefs_to_slice<'tcx>(
 
 pub(super) fn get_hint_if_single_char_arg(
     cx: &LateContext<'_>,
-    arg: &hir::Expr<'_>,
+    arg: &Expr<'_>,
     applicability: &mut Applicability,
 ) -> Option<String> {
-    if let hir::ExprKind::Lit(lit) = &arg.kind
+    if let ExprKind::Lit(lit) = &arg.kind
         && let ast::LitKind::Str(r, style) = lit.node
         && let string = r.as_str()
         && string.chars().count() == 1
diff --git a/src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs b/src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs
index 2fe5ae9a9ad..181b413a182 100644
--- a/src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/verbose_file_reads.rs
@@ -17,7 +17,7 @@ pub(super) fn check<'tcx>(
     cx: &LateContext<'tcx>,
     expr: &'tcx Expr<'_>,
     recv: &'tcx Expr<'_>,
-    (msg, help): (&str, &str),
+    (msg, help): (&'static str, &'static str),
 ) {
     if is_trait_method(cx, expr, sym::IoRead)
         && matches!(recv.kind, ExprKind::Path(QPath::Resolved(None, _)))
diff --git a/src/tools/clippy/clippy_lints/src/methods/wrong_self_convention.rs b/src/tools/clippy/clippy_lints/src/methods/wrong_self_convention.rs
index 0a810a13f3f..28068c63473 100644
--- a/src/tools/clippy/clippy_lints/src/methods/wrong_self_convention.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/wrong_self_convention.rs
@@ -137,7 +137,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 WRONG_SELF_CONVENTION,
                 first_arg_span,
-                &format!(
+                format!(
                     "{suggestion} usually take {}",
                     &self_kinds
                         .iter()
diff --git a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
index 0016fb33517..c6b7f5b0ce2 100644
--- a/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
+++ b/src/tools/clippy/clippy_lints/src/min_ident_chars.rs
@@ -181,7 +181,7 @@ fn emit_min_ident_chars(conf: &MinIdentChars, cx: &impl LintContext, ident: &str
             conf.min_ident_chars_threshold,
         ))
     };
-    span_lint(cx, MIN_IDENT_CHARS, span, &help);
+    span_lint(cx, MIN_IDENT_CHARS, span, help);
 }
 
 /// Attempt to convert the node to an [`ItemKind::Use`] node.
diff --git a/src/tools/clippy/clippy_lints/src/misc.rs b/src/tools/clippy/clippy_lints/src/misc.rs
index 11fecb7d72e..f5ce8dd29b1 100644
--- a/src/tools/clippy/clippy_lints/src/misc.rs
+++ b/src/tools/clippy/clippy_lints/src/misc.rs
@@ -246,7 +246,7 @@ impl<'tcx> LateLintPass<'tcx> for LintPass {
                 cx,
                 USED_UNDERSCORE_BINDING,
                 expr.span,
-                &format!(
+                format!(
                     "used binding `{name}` which is prefixed with an underscore. A leading \
                      underscore signals that a binding will not be used"
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/builtin_type_shadow.rs b/src/tools/clippy/clippy_lints/src/misc_early/builtin_type_shadow.rs
index 9f6b0bdc7a4..662f7cd8500 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/builtin_type_shadow.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/builtin_type_shadow.rs
@@ -12,7 +12,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, param: &GenericParam) {
                 cx,
                 BUILTIN_TYPE_SHADOW,
                 param.ident.span,
-                &format!("this generic shadows the built-in type `{}`", prim_ty.name()),
+                format!("this generic shadows the built-in type `{}`", prim_ty.name()),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs b/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs
index eda4376f200..e0a5e401a50 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/literal_suffix.rs
@@ -16,7 +16,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str, suffi
                 cx,
                 SEPARATED_LITERAL_SUFFIX,
                 lit_span,
-                &format!("{sugg_type} type suffix should not be separated by an underscore"),
+                format!("{sugg_type} type suffix should not be separated by an underscore"),
                 "remove the underscore",
                 format!("{}{suffix}", &lit_snip[..maybe_last_sep_idx]),
                 Applicability::MachineApplicable,
@@ -26,7 +26,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, lit_span: Span, lit_snip: &str, suffi
                 cx,
                 UNSEPARATED_LITERAL_SUFFIX,
                 lit_span,
-                &format!("{sugg_type} type suffix should be separated by an underscore"),
+                format!("{sugg_type} type suffix should be separated by an underscore"),
                 "add an underscore",
                 format!("{}_{suffix}", &lit_snip[..=maybe_last_sep_idx]),
                 Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
index abe5b00e888..2f5499d7656 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/mod.rs
@@ -394,7 +394,7 @@ impl EarlyLintPass for MiscEarlyLints {
                             cx,
                             DUPLICATE_UNDERSCORE_ARGUMENT,
                             *correspondence,
-                            &format!(
+                            format!(
                                 "`{arg_name}` already exists, having another argument having almost the same \
                                  name makes code comprehension and documentation more difficult"
                             ),
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs
index d7bb0616acb..d5b5b2bf2dd 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/redundant_pattern.rs
@@ -12,7 +12,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
                 cx,
                 REDUNDANT_PATTERN,
                 pat.span,
-                &format!(
+                format!(
                     "the `{} @ _` pattern can be written as just `{}`",
                     ident.name, ident.name,
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
index 676e5d40bb7..cb305cf5582 100644
--- a/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
+++ b/src/tools/clippy/clippy_lints/src/misc_early/unneeded_field_pattern.rs
@@ -27,7 +27,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
                 pat.span,
                 "all the struct fields are matched to a wildcard pattern, consider using `..`",
                 None,
-                &format!("try with `{type_name} {{ .. }}` instead"),
+                format!("try with `{type_name} {{ .. }}` instead"),
             );
             return;
         }
@@ -63,7 +63,7 @@ pub(super) fn check(cx: &EarlyContext<'_>, pat: &Pat) {
                             "you matched a field with a wildcard pattern, consider using `..` \
                              instead",
                             None,
-                            &format!("try with `{type_name} {{ {}, .. }}`", normal[..].join(", ")),
+                            format!("try with `{type_name} {{ {}, .. }}`", normal[..].join(", ")),
                         );
                     }
                 }
diff --git a/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs b/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
index 0739b49fe19..0842a872824 100644
--- a/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
+++ b/src/tools/clippy/clippy_lints/src/mismatching_type_param_order.rs
@@ -101,7 +101,7 @@ impl<'tcx> LateLintPass<'tcx> for TypeParamMismatch {
                         "try `{}`, or a name that does not conflict with `{type_name}`'s generic params",
                         type_param_names[i]
                     );
-                    span_lint_and_help(cx, MISMATCHING_TYPE_PARAM_ORDER, *impl_param_span, &msg, None, &help);
+                    span_lint_and_help(cx, MISMATCHING_TYPE_PARAM_ORDER, *impl_param_span, msg, None, help);
                 }
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
index 39d4ea74b31..c29e46b941c 100644
--- a/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_asserts_for_indexing.rs
@@ -65,7 +65,7 @@ declare_clippy_lint! {
 }
 declare_lint_pass!(MissingAssertsForIndexing => [MISSING_ASSERTS_FOR_INDEXING]);
 
-fn report_lint<F>(cx: &LateContext<'_>, full_span: Span, msg: &str, indexes: &[Span], f: F)
+fn report_lint<F>(cx: &LateContext<'_>, full_span: Span, msg: &'static str, indexes: &[Span], f: F)
 where
     F: FnOnce(&mut Diag<'_, ()>),
 {
diff --git a/src/tools/clippy/clippy_lints/src/missing_doc.rs b/src/tools/clippy/clippy_lints/src/missing_doc.rs
index 2773427e72d..2fb784dae1c 100644
--- a/src/tools/clippy/clippy_lints/src/missing_doc.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_doc.rs
@@ -127,7 +127,7 @@ impl MissingDoc {
                 cx,
                 MISSING_DOCS_IN_PRIVATE_ITEMS,
                 sp,
-                &format!("missing documentation for {article} {desc}"),
+                format!("missing documentation for {article} {desc}"),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
index 3bf9f75e226..a64faa124f0 100644
--- a/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_fields_in_debug.rs
@@ -198,7 +198,7 @@ fn check_struct<'tcx>(
 }
 
 impl<'tcx> LateLintPass<'tcx> for MissingFieldsInDebug {
-    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx rustc_hir::Item<'tcx>) {
+    fn check_item(&mut self, cx: &LateContext<'tcx>, item: &'tcx Item<'tcx>) {
         // is this an `impl Debug for X` block?
         if let ItemKind::Impl(Impl { of_trait: Some(trait_ref), self_ty, items, .. }) = item.kind
             && let Res::Def(DefKind::Trait, trait_def_id) = trait_ref.path.res
diff --git a/src/tools/clippy/clippy_lints/src/missing_inline.rs b/src/tools/clippy/clippy_lints/src/missing_inline.rs
index 7393b39c8f6..c6a76478806 100644
--- a/src/tools/clippy/clippy_lints/src/missing_inline.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_inline.rs
@@ -64,7 +64,7 @@ fn check_missing_inline_attrs(cx: &LateContext<'_>, attrs: &[ast::Attribute], sp
             cx,
             MISSING_INLINE_IN_PUBLIC_ITEMS,
             sp,
-            &format!("missing `#[inline]` for {desc}"),
+            format!("missing `#[inline]` for {desc}"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
index 6bbf18d52d1..6f844bc646a 100644
--- a/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
+++ b/src/tools/clippy/clippy_lints/src/missing_trait_methods.rs
@@ -89,7 +89,7 @@ impl<'tcx> LateLintPass<'tcx> for MissingTraitMethods {
                         cx,
                         MISSING_TRAIT_METHODS,
                         source_map.guess_head_span(item.span),
-                        &format!("missing trait method provided by default: `{}`", assoc.name),
+                        format!("missing trait method provided by default: `{}`", assoc.name),
                         Some(definition_span),
                         "implement the method",
                     );
diff --git a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
index 656fb907fcd..181351910db 100644
--- a/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
+++ b/src/tools/clippy/clippy_lints/src/mixed_read_write_in_expression.rs
@@ -325,7 +325,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ReadVisitor<'a, 'tcx> {
                     self.cx,
                     MIXED_READ_WRITE_IN_EXPRESSION,
                     expr.span,
-                    &format!("unsequenced read of `{}`", self.cx.tcx.hir().name(self.var)),
+                    format!("unsequenced read of `{}`", self.cx.tcx.hir().name(self.var)),
                     Some(self.write_expr.span),
                     "whether read occurs before this write depends on evaluation order",
                 );
diff --git a/src/tools/clippy/clippy_lints/src/module_style.rs b/src/tools/clippy/clippy_lints/src/module_style.rs
index 0226b31dd19..6c031c08175 100644
--- a/src/tools/clippy/clippy_lints/src/module_style.rs
+++ b/src/tools/clippy/clippy_lints/src/module_style.rs
@@ -129,9 +129,9 @@ impl EarlyLintPass for ModStyle {
                         cx,
                         SELF_NAMED_MODULE_FILES,
                         Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
-                        &format!("`mod.rs` files are required, found `{}`", path.display()),
+                        format!("`mod.rs` files are required, found `{}`", path.display()),
                         None,
-                        &format!("move `{}` to `{}`", path.display(), correct.display(),),
+                        format!("move `{}` to `{}`", path.display(), correct.display(),),
                     );
                 }
             }
@@ -169,9 +169,9 @@ fn check_self_named_mod_exists(cx: &EarlyContext<'_>, path: &Path, file: &Source
             cx,
             MOD_MODULE_FILES,
             Span::new(file.start_pos, file.start_pos, SyntaxContext::root(), None),
-            &format!("`mod.rs` files are not allowed, found `{}`", path.display()),
+            format!("`mod.rs` files are not allowed, found `{}`", path.display()),
             None,
-            &format!("move `{}` to `{}`", path.display(), mod_file.display()),
+            format!("move `{}` to `{}`", path.display(), mod_file.display()),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
index 648d780ac09..0e138066780 100644
--- a/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
+++ b/src/tools/clippy/clippy_lints/src/multiple_unsafe_ops_per_block.rs
@@ -77,7 +77,7 @@ impl<'tcx> LateLintPass<'tcx> for MultipleUnsafeOpsPerBlock {
                 cx,
                 MULTIPLE_UNSAFE_OPS_PER_BLOCK,
                 block.span,
-                &format!(
+                format!(
                     "this `unsafe` block contains {} unsafe operations, expected only one",
                     unsafe_ops.len()
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/mut_reference.rs b/src/tools/clippy/clippy_lints/src/mut_reference.rs
index 14a1e6be738..6867f76a723 100644
--- a/src/tools/clippy/clippy_lints/src/mut_reference.rs
+++ b/src/tools/clippy/clippy_lints/src/mut_reference.rs
@@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMutPassed {
                 let method_type = cx.tcx.type_of(def_id).instantiate(cx.tcx, args);
                 check_arguments(
                     cx,
-                    std::iter::once(receiver).chain(arguments.iter()).collect(),
+                    iter::once(receiver).chain(arguments.iter()).collect(),
                     method_type,
                     path.ident.as_str(),
                     "method",
@@ -83,14 +83,13 @@ fn check_arguments<'tcx>(
             let parameters = type_definition.fn_sig(cx.tcx).skip_binder().inputs();
             for (argument, parameter) in iter::zip(arguments, parameters) {
                 match parameter.kind() {
-                    ty::Ref(_, _, Mutability::Not)
-                    | ty::RawPtr(_, Mutability::Not) => {
+                    ty::Ref(_, _, Mutability::Not) | ty::RawPtr(_, Mutability::Not) => {
                         if let ExprKind::AddrOf(BorrowKind::Ref, Mutability::Mut, _) = argument.kind {
                             span_lint(
                                 cx,
                                 UNNECESSARY_MUT_PASSED,
                                 argument.span,
-                                &format!("the {fn_kind} `{name}` doesn't need a mutable reference"),
+                                format!("the {fn_kind} `{name}` doesn't need a mutable reference"),
                             );
                         }
                     },
diff --git a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
index 96cd81ecdf3..e92ba93942e 100644
--- a/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
+++ b/src/tools/clippy/clippy_lints/src/mutable_debug_assertion.rs
@@ -60,7 +60,7 @@ impl<'tcx> LateLintPass<'tcx> for DebugAssertWithMutCall {
                     cx,
                     DEBUG_ASSERT_WITH_MUT_CALL,
                     span,
-                    &format!("do not call a function with mutable arguments inside of `{macro_name}!`"),
+                    format!("do not call a function with mutable arguments inside of `{macro_name}!`"),
                 );
             }
         }
diff --git a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
index 61243c83731..7ecc8617694 100644
--- a/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
+++ b/src/tools/clippy/clippy_lints/src/mutex_atomic.rs
@@ -92,9 +92,9 @@ impl<'tcx> LateLintPass<'tcx> for Mutex {
                          behavior and not the internal type, consider using `Mutex<()>`"
                     );
                     match *mutex_param.kind() {
-                        ty::Uint(t) if t != ty::UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
-                        ty::Int(t) if t != ty::IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, &msg),
-                        _ => span_lint(cx, MUTEX_ATOMIC, expr.span, &msg),
+                        ty::Uint(t) if t != UintTy::Usize => span_lint(cx, MUTEX_INTEGER, expr.span, msg),
+                        ty::Int(t) if t != IntTy::Isize => span_lint(cx, MUTEX_INTEGER, expr.span, msg),
+                        _ => span_lint(cx, MUTEX_ATOMIC, expr.span, msg),
                     };
                 }
             }
diff --git a/src/tools/clippy/clippy_lints/src/needless_bool.rs b/src/tools/clippy/clippy_lints/src/needless_bool.rs
index 166a7f71d69..f9ee4a3dc93 100644
--- a/src/tools/clippy/clippy_lints/src/needless_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_bool.rs
@@ -6,11 +6,12 @@ use clippy_utils::diagnostics::{span_lint, span_lint_and_sugg};
 use clippy_utils::source::snippet_with_applicability;
 use clippy_utils::sugg::Sugg;
 use clippy_utils::{
-    higher, is_else_clause, is_expn_of, peel_blocks, peel_blocks_with_stmt, span_extract_comment, SpanlessEq,
+    higher, is_else_clause, is_expn_of, is_parent_stmt, peel_blocks, peel_blocks_with_stmt, span_extract_comment,
+    SpanlessEq,
 };
 use rustc_ast::ast::LitKind;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, HirId, Node, UnOp};
+use rustc_hir::{BinOpKind, Expr, ExprKind, UnOp};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
 use rustc_span::source_map::Spanned;
@@ -135,13 +136,6 @@ fn condition_needs_parentheses(e: &Expr<'_>) -> bool {
     false
 }
 
-fn is_parent_stmt(cx: &LateContext<'_>, id: HirId) -> bool {
-    matches!(
-        cx.tcx.parent_hir_node(id),
-        Node::Stmt(..) | Node::Block(Block { stmts: &[], .. })
-    )
-}
-
 impl<'tcx> LateLintPass<'tcx> for NeedlessBool {
     fn check_expr(&mut self, cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
         use self::Expression::{Bool, RetBool};
@@ -323,11 +317,11 @@ fn one_side_is_unary_not<'tcx>(left_side: &'tcx Expr<'_>, right_side: &'tcx Expr
 fn check_comparison<'a, 'tcx>(
     cx: &LateContext<'tcx>,
     e: &'tcx Expr<'_>,
-    left_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &str)>,
-    left_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &str)>,
-    right_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &str)>,
-    right_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &str)>,
-    no_literal: Option<(impl FnOnce(Sugg<'a>, Sugg<'a>) -> Sugg<'a>, &str)>,
+    left_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    left_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    right_true: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    right_false: Option<(impl FnOnce(Sugg<'a>) -> Sugg<'a>, &'static str)>,
+    no_literal: Option<(impl FnOnce(Sugg<'a>, Sugg<'a>) -> Sugg<'a>, &'static str)>,
 ) {
     if let ExprKind::Binary(op, left_side, right_side) = e.kind {
         let (l_ty, r_ty) = (
@@ -397,7 +391,7 @@ fn check_comparison<'a, 'tcx>(
                         binop_span,
                         m,
                         "try simplifying it as shown",
-                        h(left_side, right_side).to_string(),
+                        h(left_side, right_side).into_string(),
                         applicability,
                     );
                 }),
@@ -412,7 +406,7 @@ fn suggest_bool_comparison<'a, 'tcx>(
     span: Span,
     expr: &Expr<'_>,
     mut app: Applicability,
-    message: &str,
+    message: &'static str,
     conv_hint: impl FnOnce(Sugg<'a>) -> Sugg<'a>,
 ) {
     let hint = Sugg::hir_with_context(cx, expr, span.ctxt(), "..", &mut app);
@@ -422,7 +416,7 @@ fn suggest_bool_comparison<'a, 'tcx>(
         span,
         message,
         "try simplifying it as shown",
-        conv_hint(hint).to_string(),
+        conv_hint(hint).into_string(),
         app,
     );
 }
diff --git a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
index 4710a69443b..d91329eadcb 100644
--- a/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_borrowed_ref.rs
@@ -119,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for NeedlessBorrowedRef {
 
 fn check_subpatterns<'tcx>(
     cx: &LateContext<'tcx>,
-    message: &str,
+    message: &'static str,
     ref_pat: &Pat<'_>,
     pat: &Pat<'_>,
     subpatterns: impl IntoIterator<Item = &'tcx Pat<'tcx>>,
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
index a32bca3d038..c555fc8675c 100644
--- 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
@@ -381,7 +381,7 @@ fn replace_types<'tcx>(
     fn_sig: FnSig<'tcx>,
     arg_index: usize,
     projection_predicates: &[ProjectionPredicate<'tcx>],
-    args: &mut [ty::GenericArg<'tcx>],
+    args: &mut [GenericArg<'tcx>],
 ) -> bool {
     let mut replaced = BitSet::new_empty(args.len());
 
@@ -399,7 +399,7 @@ fn replace_types<'tcx>(
             return false;
         }
 
-        args[param_ty.index as usize] = ty::GenericArg::from(new_ty);
+        args[param_ty.index as usize] = GenericArg::from(new_ty);
 
         // The `replaced.insert(...)` check provides some protection against infinite loops.
         if replaced.insert(param_ty.index) {
@@ -414,7 +414,7 @@ fn replace_types<'tcx>(
                     ));
 
                     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)
+                        && args[term_param_ty.index as usize] != GenericArg::from(projected_ty)
                     {
                         deque.push_back((*term_param_ty, projected_ty));
                     }
diff --git a/src/tools/clippy/clippy_lints/src/needless_continue.rs b/src/tools/clippy/clippy_lints/src/needless_continue.rs
index ff72b5e69ef..8b4a12bb766 100644
--- a/src/tools/clippy/clippy_lints/src/needless_continue.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_continue.rs
@@ -313,7 +313,7 @@ fn emit_warning(cx: &EarlyContext<'_>, data: &LintData<'_>, header: &str, typ: L
         expr.span,
         message,
         None,
-        &format!("{header}\n{snip}"),
+        format!("{header}\n{snip}"),
     );
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
index d7adf22ff32..37463cfec9a 100644
--- a/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/needless_question_mark.rs
@@ -131,7 +131,7 @@ fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
             NEEDLESS_QUESTION_MARK,
             expr.span,
             "question mark operator is useless here",
-            &format!("try removing question mark and `{sugg_remove}`"),
+            format!("try removing question mark and `{sugg_remove}`"),
             format!("{}", snippet(cx, inner_expr.span, r#""...""#)),
             Applicability::MachineApplicable,
         );
diff --git a/src/tools/clippy/clippy_lints/src/new_without_default.rs b/src/tools/clippy/clippy_lints/src/new_without_default.rs
index 627b4968d9f..78dd1e05162 100644
--- a/src/tools/clippy/clippy_lints/src/new_without_default.rs
+++ b/src/tools/clippy/clippy_lints/src/new_without_default.rs
@@ -134,9 +134,7 @@ impl<'tcx> LateLintPass<'tcx> for NewWithoutDefault {
                                 NEW_WITHOUT_DEFAULT,
                                 id.into(),
                                 impl_item.span,
-                                &format!(
-                                    "you should consider adding a `Default` implementation for `{self_type_snip}`"
-                                ),
+                                format!("you should consider adding a `Default` implementation for `{self_type_snip}`"),
                                 |diag| {
                                     diag.suggest_prepend_item(
                                         cx,
diff --git a/src/tools/clippy/clippy_lints/src/no_effect.rs b/src/tools/clippy/clippy_lints/src/no_effect.rs
index 43810ec0ec7..f915145e794 100644
--- a/src/tools/clippy/clippy_lints/src/no_effect.rs
+++ b/src/tools/clippy/clippy_lints/src/no_effect.rs
@@ -107,7 +107,7 @@ impl<'tcx> LateLintPass<'tcx> for NoEffect {
         }
     }
 
-    fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx rustc_hir::Expr<'tcx>) {
+    fn check_expr(&mut self, _: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
         if let Some(def_id) = path_to_local(expr) {
             // FIXME(rust/#120456) - is `swap_remove` correct?
             self.underscore_bindings.swap_remove(&def_id);
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 6cb84bb78b6..73fc34c2450 100644
--- a/src/tools/clippy/clippy_lints/src/non_copy_const.rs
+++ b/src/tools/clippy/clippy_lints/src/non_copy_const.rs
@@ -285,7 +285,7 @@ impl NonCopyConst {
         let def_id = body_id.hir_id.owner.to_def_id();
         let args = ty::GenericArgs::identity_for_item(cx.tcx, def_id);
         let instance = ty::Instance::new(def_id, args);
-        let cid = rustc_middle::mir::interpret::GlobalId {
+        let cid = GlobalId {
             instance,
             promoted: None,
         };
@@ -534,7 +534,7 @@ impl<'tcx> LateLintPass<'tcx> for NonCopyConst {
     }
 }
 
-fn ignored_macro(cx: &LateContext<'_>, it: &rustc_hir::Item<'_>) -> bool {
+fn ignored_macro(cx: &LateContext<'_>, it: &Item<'_>) -> bool {
     macro_backtrace(it.span).any(|macro_call| {
         matches!(
             cx.tcx.get_diagnostic_name(macro_call.def_id),
diff --git a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
index b8c3c7fa65a..7b26235291a 100644
--- a/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
+++ b/src/tools/clippy/clippy_lints/src/non_expressive_names.rs
@@ -111,7 +111,7 @@ impl<'a, 'tcx> SimilarNamesLocalVisitor<'a, 'tcx> {
                 self.cx,
                 MANY_SINGLE_CHAR_NAMES,
                 span,
-                &format!("{num_single_char_names} bindings with single-character names in scope"),
+                format!("{num_single_char_names} bindings with single-character names in scope"),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
index 408216229a4..74e6c57b52d 100644
--- a/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
+++ b/src/tools/clippy/clippy_lints/src/non_send_fields_in_send_ty.rs
@@ -119,7 +119,7 @@ impl<'tcx> LateLintPass<'tcx> for NonSendFieldInSendTy {
                     cx,
                     NON_SEND_FIELDS_IN_SEND_TY,
                     item.span,
-                    &format!(
+                    format!(
                         "some fields in `{}` are not safe to be sent to another thread",
                         snippet(cx, hir_impl.self_ty.span, "Unknown")
                     ),
diff --git a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
index 1c6069e9c65..88f2eabaccb 100644
--- a/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
+++ b/src/tools/clippy/clippy_lints/src/nonstandard_macro_braces.rs
@@ -121,7 +121,7 @@ fn emit_help(cx: &EarlyContext<'_>, snip: &str, (open, close): (char, char), spa
             cx,
             NONSTANDARD_MACRO_BRACES,
             span,
-            &format!("use of irregular braces for `{macro_name}!` macro"),
+            format!("use of irregular braces for `{macro_name}!` macro"),
             "consider writing",
             format!("{macro_name}!{open}{macro_args}{close}"),
             Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/octal_escapes.rs b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
index 8822dfeeddd..2fc039ae886 100644
--- a/src/tools/clippy/clippy_lints/src/octal_escapes.rs
+++ b/src/tools/clippy/clippy_lints/src/octal_escapes.rs
@@ -94,7 +94,7 @@ fn check_lit(cx: &EarlyContext<'_>, lit: &Lit, span: Span, is_string: bool) {
         cx,
         OCTAL_ESCAPES,
         span,
-        &format!(
+        format!(
             "octal-looking escape in {} literal",
             if is_string { "string" } else { "byte string" }
         ),
diff --git a/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs b/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs
index f4863600ccc..9769da6d3e9 100644
--- a/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/absurd_extreme_comparisons.rs
@@ -42,7 +42,7 @@ pub(super) fn check<'tcx>(
             }
         );
 
-        span_lint_and_help(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, None, &help);
+        span_lint_and_help(cx, ABSURD_EXTREME_COMPARISONS, expr.span, msg, None, help);
     }
 }
 
diff --git a/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs b/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs
index 2e026c369ee..545e680ce0d 100644
--- a/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/bit_mask.rs
@@ -64,7 +64,7 @@ fn check_bit_mask(
                             cx,
                             BAD_BIT_MASK,
                             span,
-                            &format!("incompatible bit mask: `_ & {mask_value}` can never be equal to `{cmp_value}`"),
+                            format!("incompatible bit mask: `_ & {mask_value}` can never be equal to `{cmp_value}`"),
                         );
                     }
                 } else if mask_value == 0 {
@@ -77,7 +77,7 @@ fn check_bit_mask(
                         cx,
                         BAD_BIT_MASK,
                         span,
-                        &format!("incompatible bit mask: `_ | {mask_value}` can never be equal to `{cmp_value}`"),
+                        format!("incompatible bit mask: `_ | {mask_value}` can never be equal to `{cmp_value}`"),
                     );
                 }
             },
@@ -90,7 +90,7 @@ fn check_bit_mask(
                         cx,
                         BAD_BIT_MASK,
                         span,
-                        &format!("incompatible bit mask: `_ & {mask_value}` will always be lower than `{cmp_value}`"),
+                        format!("incompatible bit mask: `_ & {mask_value}` will always be lower than `{cmp_value}`"),
                     );
                 } else if mask_value == 0 {
                     span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero");
@@ -102,7 +102,7 @@ fn check_bit_mask(
                         cx,
                         BAD_BIT_MASK,
                         span,
-                        &format!("incompatible bit mask: `_ | {mask_value}` will never be lower than `{cmp_value}`"),
+                        format!("incompatible bit mask: `_ | {mask_value}` will never be lower than `{cmp_value}`"),
                     );
                 } else {
                     check_ineffective_lt(cx, span, mask_value, cmp_value, "|");
@@ -118,7 +118,7 @@ fn check_bit_mask(
                         cx,
                         BAD_BIT_MASK,
                         span,
-                        &format!("incompatible bit mask: `_ & {mask_value}` will never be higher than `{cmp_value}`"),
+                        format!("incompatible bit mask: `_ & {mask_value}` will never be higher than `{cmp_value}`"),
                     );
                 } else if mask_value == 0 {
                     span_lint(cx, BAD_BIT_MASK, span, "&-masking with zero");
@@ -130,7 +130,7 @@ fn check_bit_mask(
                         cx,
                         BAD_BIT_MASK,
                         span,
-                        &format!("incompatible bit mask: `_ | {mask_value}` will always be higher than `{cmp_value}`"),
+                        format!("incompatible bit mask: `_ | {mask_value}` will always be higher than `{cmp_value}`"),
                     );
                 } else {
                     check_ineffective_gt(cx, span, mask_value, cmp_value, "|");
@@ -149,7 +149,7 @@ fn check_ineffective_lt(cx: &LateContext<'_>, span: Span, m: u128, c: u128, op:
             cx,
             INEFFECTIVE_BIT_MASK,
             span,
-            &format!("ineffective bit mask: `x {op} {m}` compared to `{c}`, is the same as x compared directly"),
+            format!("ineffective bit mask: `x {op} {m}` compared to `{c}`, is the same as x compared directly"),
         );
     }
 }
@@ -160,7 +160,7 @@ fn check_ineffective_gt(cx: &LateContext<'_>, span: Span, m: u128, c: u128, op:
             cx,
             INEFFECTIVE_BIT_MASK,
             span,
-            &format!("ineffective bit mask: `x {op} {m}` compared to `{c}`, is the same as x compared directly"),
+            format!("ineffective bit mask: `x {op} {m}` compared to `{c}`, is the same as x compared directly"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs b/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
index e278cf9835a..7bf9b8ef866 100644
--- a/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/const_comparisons.rs
@@ -89,7 +89,7 @@ pub(super) fn check<'tcx>(
                     span,
                     "left-hand side of `&&` operator has no effect",
                     Some(left_cond.span.until(right_cond.span)),
-                    &format!("`if `{rhs_str}` evaluates to true, {lhs_str}` will always evaluate to true as well"),
+                    format!("`if `{rhs_str}` evaluates to true, {lhs_str}` will always evaluate to true as well"),
                 );
             } else {
                 span_lint_and_note(
@@ -98,7 +98,7 @@ pub(super) fn check<'tcx>(
                     span,
                     "right-hand side of `&&` operator has no effect",
                     Some(and_op.span.to(right_cond.span)),
-                    &format!("`if `{lhs_str}` evaluates to true, {rhs_str}` will always evaluate to true as well"),
+                    format!("`if `{lhs_str}` evaluates to true, {rhs_str}` will always evaluate to true as well"),
                 );
             }
             // We could autofix this error but choose not to,
@@ -124,7 +124,7 @@ pub(super) fn check<'tcx>(
                 span,
                 "boolean expression will never evaluate to 'true'",
                 None,
-                &note,
+                note,
             );
         };
     }
diff --git a/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs b/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs
index f120be13836..ca3112ce5c4 100644
--- a/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/duration_subsec.rs
@@ -31,7 +31,7 @@ pub(crate) fn check<'tcx>(
             cx,
             DURATION_SUBSEC,
             expr.span,
-            &format!("calling `{suggested_fn}()` is more concise than this calculation"),
+            format!("calling `{suggested_fn}()` is more concise than this calculation"),
             "try",
             format!(
                 "{}.{suggested_fn}()",
diff --git a/src/tools/clippy/clippy_lints/src/operators/eq_op.rs b/src/tools/clippy/clippy_lints/src/operators/eq_op.rs
index 01dd418c38b..1421893274f 100644
--- a/src/tools/clippy/clippy_lints/src/operators/eq_op.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/eq_op.rs
@@ -24,7 +24,7 @@ pub(crate) fn check_assert<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) {
             cx,
             EQ_OP,
             lhs.span.to(rhs.span),
-            &format!("identical args used in this `{macro_name}!` macro call"),
+            format!("identical args used in this `{macro_name}!` macro call"),
         );
     }
 }
@@ -41,7 +41,7 @@ pub(crate) fn check<'tcx>(
             cx,
             EQ_OP,
             e.span,
-            &format!("equal expressions as operands to `{}`", op.as_str()),
+            format!("equal expressions as operands to `{}`", op.as_str()),
             |diag| {
                 if let BinOpKind::Ne = op
                     && cx.typeck_results().expr_ty(left).is_floating_point()
diff --git a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
index 2a933a11e12..c56518ac72a 100644
--- a/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/modulo_arithmetic.rs
@@ -113,7 +113,7 @@ fn check_const_operands<'tcx>(
             cx,
             MODULO_ARITHMETIC,
             expr.span,
-            &format!(
+            format!(
                 "you are using modulo operator on constants with different signs: `{} % {}`",
                 lhs_operand.string_representation.as_ref().unwrap(),
                 rhs_operand.string_representation.as_ref().unwrap()
diff --git a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
index a69989e400b..607930561e0 100644
--- a/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/ptr_eq.rs
@@ -30,7 +30,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 PTR_EQ,
                 expr.span,
-                &format!("use `{top_crate}::ptr::eq` when comparing raw pointers"),
+                format!("use `{top_crate}::ptr::eq` when comparing raw pointers"),
                 "try",
                 format!("{top_crate}::ptr::eq({left_snip}, {right_snip})"),
                 Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/operators/self_assignment.rs b/src/tools/clippy/clippy_lints/src/operators/self_assignment.rs
index 7c9d5320a3a..a932378fbb5 100644
--- a/src/tools/clippy/clippy_lints/src/operators/self_assignment.rs
+++ b/src/tools/clippy/clippy_lints/src/operators/self_assignment.rs
@@ -14,7 +14,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, lhs: &'tcx
             cx,
             SELF_ASSIGNMENT,
             e.span,
-            &format!("self-assignment of `{rhs}` to `{lhs}`"),
+            format!("self-assignment of `{rhs}` to `{lhs}`"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
index 556c493d36c..3cbd03a58c5 100644
--- a/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
+++ b/src/tools/clippy/clippy_lints/src/option_if_let_else.rs
@@ -304,7 +304,7 @@ impl<'tcx> LateLintPass<'tcx> for OptionIfLetElse {
                 cx,
                 OPTION_IF_LET_ELSE,
                 expr.span,
-                format!("use Option::{} instead of an if let/else", det.method_sugg).as_str(),
+                format!("use Option::{} instead of an if let/else", det.method_sugg),
                 "try",
                 format!(
                     "{}.{}({}, {})",
diff --git a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
index ec03ab0e41a..bb4a1de9f77 100644
--- a/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
+++ b/src/tools/clippy/clippy_lints/src/pass_by_ref_or_value.rs
@@ -206,7 +206,7 @@ impl<'tcx> PassByRefOrValue {
                             cx,
                             TRIVIALLY_COPY_PASS_BY_REF,
                             input.span,
-                            &format!(
+                            format!(
                                 "this argument ({size} byte) is passed by reference, but would be more efficient if passed by value (limit: {} byte)",
                                 self.ref_min_size
                             ),
@@ -236,7 +236,7 @@ impl<'tcx> PassByRefOrValue {
                             cx,
                             LARGE_TYPES_PASSED_BY_VALUE,
                             input.span,
-                            &format!(
+                            format!(
                                 "this argument ({size} byte) is passed by value, but might be more efficient if passed by reference (limit: {} byte)",
                                 self.value_max_size
                             ),
diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
index 127801de7de..44db061b8be 100644
--- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
+++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs
@@ -1,5 +1,7 @@
 use clippy_utils::diagnostics::span_lint_and_help;
-use rustc_hir::{intravisit, Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind};
+use rustc_hir::{
+    intravisit, Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind,
+};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
@@ -138,7 +140,7 @@ fn apply_lint(cx: &LateContext<'_>, pat: &Pat<'_>, deref_possible: DerefPossible
             span,
             "type of pattern does not match the expression type",
             None,
-            &format!(
+            format!(
                 "{}explicitly match against a `{}` pattern and adjust the enclosed variable bindings",
                 match (deref_possible, level) {
                     (DerefPossible::Possible, Level::Top) => "use `*` to dereference the match expression or ",
diff --git a/src/tools/clippy/clippy_lints/src/ptr.rs b/src/tools/clippy/clippy_lints/src/ptr.rs
index 896c99a7104..83b32000a9f 100644
--- a/src/tools/clippy/clippy_lints/src/ptr.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr.rs
@@ -177,7 +177,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
             )
             .filter(|arg| arg.mutability() == Mutability::Not)
             {
-                span_lint_hir_and_then(cx, PTR_ARG, arg.emission_id, arg.span, &arg.build_msg(), |diag| {
+                span_lint_hir_and_then(cx, PTR_ARG, arg.emission_id, arg.span, arg.build_msg(), |diag| {
                     diag.span_suggestion(
                         arg.span,
                         "change this to",
@@ -237,7 +237,7 @@ impl<'tcx> LateLintPass<'tcx> for Ptr {
         let results = check_ptr_arg_usage(cx, body, &lint_args);
 
         for (result, args) in results.iter().zip(lint_args.iter()).filter(|(r, _)| !r.skip) {
-            span_lint_hir_and_then(cx, PTR_ARG, args.emission_id, args.span, &args.build_msg(), |diag| {
+            span_lint_hir_and_then(cx, PTR_ARG, args.emission_id, args.span, args.build_msg(), |diag| {
                 diag.multipart_suggestion(
                     "change this to",
                     iter::once((args.span, format!("{}{}", args.ref_prefix, args.deref_ty.display(cx))))
@@ -628,7 +628,7 @@ fn check_ptr_arg_usage<'tcx>(cx: &LateContext<'tcx>, body: &'tcx Body<'_>, args:
                         }
                     },
                     ExprKind::MethodCall(name, self_arg, expr_args, _) => {
-                        let i = std::iter::once(self_arg)
+                        let i = iter::once(self_arg)
                             .chain(expr_args.iter())
                             .position(|arg| arg.hir_id == child_id)
                             .unwrap_or(0);
diff --git a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
index ff8ec2ad57c..7c82895d609 100644
--- a/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
+++ b/src/tools/clippy/clippy_lints/src/ptr_offset_with_cast.rs
@@ -64,13 +64,13 @@ impl<'tcx> LateLintPass<'tcx> for PtrOffsetWithCast {
                 cx,
                 PTR_OFFSET_WITH_CAST,
                 expr.span,
-                &msg,
+                msg,
                 "try",
                 sugg,
                 Applicability::MachineApplicable,
             );
         } else {
-            span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, &msg);
+            span_lint(cx, PTR_OFFSET_WITH_CAST, expr.span, msg);
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/question_mark.rs b/src/tools/clippy/clippy_lints/src/question_mark.rs
index b57220e6cf0..927c6f1d519 100644
--- a/src/tools/clippy/clippy_lints/src/question_mark.rs
+++ b/src/tools/clippy/clippy_lints/src/question_mark.rs
@@ -4,7 +4,7 @@ use clippy_config::msrvs::Msrv;
 use clippy_config::types::MatchLintBehaviour;
 use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet_with_applicability;
-use clippy_utils::ty::is_type_diagnostic_item;
+use clippy_utils::ty::{implements_trait, is_type_diagnostic_item};
 use clippy_utils::{
     eq_expr_value, higher, in_constant, is_else_clause, is_lint_allowed, is_path_lang_item, is_res_lang_ctor,
     pat_and_expr_can_be_question_mark, path_to_local, path_to_local_id, peel_blocks, peel_blocks_with_stmt,
@@ -14,7 +14,8 @@ use rustc_errors::Applicability;
 use rustc_hir::def::Res;
 use rustc_hir::LangItem::{self, OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::{
-    BindingAnnotation, Block, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath, Stmt, StmtKind,
+    BindingAnnotation, Block, Body, ByRef, Expr, ExprKind, LetStmt, Mutability, Node, PatKind, PathSegment, QPath,
+    Stmt, StmtKind,
 };
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::ty::Ty;
@@ -109,12 +110,31 @@ fn find_let_else_ret_expression<'hir>(block: &'hir Block<'hir>) -> Option<&'hir
 }
 
 fn check_let_some_else_return_none(cx: &LateContext<'_>, stmt: &Stmt<'_>) {
+    /// Make sure the init expr implements try trait so a valid suggestion could be given.
+    ///
+    /// Because the init expr could have the type of `&Option<T>` which does not implements `Try`.
+    ///
+    /// NB: This conveniently prevents the cause of
+    /// issue [#12412](https://github.com/rust-lang/rust-clippy/issues/12412),
+    /// since accessing an `Option` field from a borrowed struct requires borrow, such as
+    /// `&some_struct.opt`, which is type of `&Option`. And we can't suggest `&some_struct.opt?`
+    /// or `(&some_struct.opt)?` since the first one has different semantics and the later does
+    /// not implements `Try`.
+    fn init_expr_can_use_question_mark(cx: &LateContext<'_>, init_expr: &Expr<'_>) -> bool {
+        let init_ty = cx.typeck_results().expr_ty_adjusted(init_expr);
+        cx.tcx
+            .lang_items()
+            .try_trait()
+            .map_or(false, |did| implements_trait(cx, init_ty, did, &[]))
+    }
+
     if let StmtKind::Let(LetStmt {
         pat,
         init: Some(init_expr),
         els: Some(els),
         ..
     }) = stmt.kind
+        && init_expr_can_use_question_mark(cx, init_expr)
         && let Some(ret) = find_let_else_ret_expression(els)
         && let Some(inner_pat) = pat_and_expr_can_be_question_mark(cx, pat, ret)
         && !span_contains_comment(cx.tcx.sess.source_map(), els.span)
@@ -310,9 +330,9 @@ impl QuestionMark {
     }
 }
 
-fn is_try_block(cx: &LateContext<'_>, bl: &rustc_hir::Block<'_>) -> bool {
+fn is_try_block(cx: &LateContext<'_>, bl: &Block<'_>) -> bool {
     if let Some(expr) = bl.expr
-        && let rustc_hir::ExprKind::Call(callee, _) = expr.kind
+        && let ExprKind::Call(callee, _) = expr.kind
     {
         is_path_lang_item(cx, callee, LangItem::TryTraitFromOutput)
     } else {
@@ -341,7 +361,7 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
         }
     }
 
-    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx rustc_hir::Block<'tcx>) {
+    fn check_block(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         if is_try_block(cx, block) {
             *self
                 .try_block_depth_stack
@@ -350,15 +370,15 @@ impl<'tcx> LateLintPass<'tcx> for QuestionMark {
         }
     }
 
-    fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) {
+    fn check_body(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) {
         self.try_block_depth_stack.push(0);
     }
 
-    fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx rustc_hir::Body<'tcx>) {
+    fn check_body_post(&mut self, _: &LateContext<'tcx>, _: &'tcx Body<'tcx>) {
         self.try_block_depth_stack.pop();
     }
 
-    fn check_block_post(&mut self, cx: &LateContext<'tcx>, block: &'tcx rustc_hir::Block<'tcx>) {
+    fn check_block_post(&mut self, cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
         if is_try_block(cx, block) {
             *self
                 .try_block_depth_stack
diff --git a/src/tools/clippy/clippy_lints/src/ranges.rs b/src/tools/clippy/clippy_lints/src/ranges.rs
index 6b54258dd61..186e548d373 100644
--- a/src/tools/clippy/clippy_lints/src/ranges.rs
+++ b/src/tools/clippy/clippy_lints/src/ranges.rs
@@ -242,7 +242,7 @@ fn check_possible_range_contains(
                 cx,
                 MANUAL_RANGE_CONTAINS,
                 span,
-                &format!("manual `{range_type}::contains` implementation"),
+                format!("manual `{range_type}::contains` implementation"),
                 "use",
                 format!("({lo}{space}{range_op}{hi}).contains(&{name})"),
                 applicability,
@@ -272,7 +272,7 @@ fn check_possible_range_contains(
                 cx,
                 MANUAL_RANGE_CONTAINS,
                 span,
-                &format!("manual `!{range_type}::contains` implementation"),
+                format!("manual `!{range_type}::contains` implementation"),
                 "use",
                 format!("!({lo}{space}{range_op}{hi}).contains(&{name})"),
                 applicability,
diff --git a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
index 435899ddaa7..2863eb190d3 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_closure_call.rs
@@ -56,7 +56,7 @@ impl ReturnVisitor {
 
 impl<'tcx> Visitor<'tcx> for ReturnVisitor {
     fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
-        if let hir::ExprKind::Ret(_) | hir::ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {
+        if let ExprKind::Ret(_) | ExprKind::Match(.., hir::MatchSource::TryDesugar(_)) = ex.kind {
             self.found_return = true;
         } else {
             hir_visit::walk_expr(self, ex);
@@ -68,7 +68,7 @@ impl<'tcx> Visitor<'tcx> for ReturnVisitor {
 /// Returns true for `async || whatever_expression`, but false for `|| async { whatever_expression
 /// }`.
 fn is_async_closure(body: &hir::Body<'_>) -> bool {
-    if let hir::ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind
+    if let ExprKind::Closure(innermost_closure_generated_by_desugar) = body.value.kind
         // checks whether it is `async || whatever_expression`
         && let ClosureKind::Coroutine(CoroutineKind::Desugared(CoroutineDesugaring::Async, CoroutineSource::Closure))
             = innermost_closure_generated_by_desugar.kind
@@ -99,7 +99,7 @@ fn find_innermost_closure<'tcx>(
 )> {
     let mut data = None;
 
-    while let hir::ExprKind::Closure(closure) = expr.kind
+    while let ExprKind::Closure(closure) = expr.kind
         && let body = cx.tcx.hir().body(closure.body)
         && {
             let mut visitor = ReturnVisitor::new();
@@ -137,7 +137,7 @@ fn get_parent_call_exprs<'tcx>(
 ) -> (&'tcx hir::Expr<'tcx>, usize) {
     let mut depth = 1;
     while let Some(parent) = get_parent_expr(cx, expr)
-        && let hir::ExprKind::Call(recv, _) = parent.kind
+        && let ExprKind::Call(recv, _) = parent.kind
         && expr.span == recv.span
     {
         expr = parent;
@@ -152,13 +152,13 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
             return;
         }
 
-        if let hir::ExprKind::Call(recv, _) = expr.kind
+        if let ExprKind::Call(recv, _) = expr.kind
             // don't lint if the receiver is a call, too.
             // we do this in order to prevent linting multiple times; consider:
             // `(|| || 1)()()`
             //           ^^  we only want to lint for this call (but we walk up the calls to consider both calls).
             // without this check, we'd end up linting twice.
-            && !matches!(recv.kind, hir::ExprKind::Call(..))
+            && !matches!(recv.kind, ExprKind::Call(..))
             // Check if `recv` comes from a macro expansion. If it does, make sure that it's an expansion that is
             // the same as the one the call is in.
             // For instance, let's assume `x!()` returns a closure:
@@ -185,7 +185,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                             Sugg::hir_with_context(cx, body, full_expr.span.ctxt(), "..", &mut applicability);
 
                         if coroutine_kind.is_async()
-                            && let hir::ExprKind::Closure(closure) = body.kind
+                            && let ExprKind::Closure(closure) = body.kind
                         {
                             // Like `async fn`, async closures are wrapped in an additional block
                             // to move all of the closure's arguments into the future.
@@ -202,7 +202,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                             };
 
                             // `async x` is a syntax error, so it becomes `async { x }`
-                            if !matches!(body_expr.kind, hir::ExprKind::Block(_, _)) {
+                            if !matches!(body_expr.kind, ExprKind::Block(_, _)) {
                                 hint = hint.blockify();
                             }
 
@@ -210,7 +210,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                         }
 
                         let is_in_fn_call_arg = if let Node::Expr(expr) = cx.tcx.parent_hir_node(expr.hir_id) {
-                            matches!(expr.kind, hir::ExprKind::Call(_, _))
+                            matches!(expr.kind, ExprKind::Call(_, _))
                         } else {
                             false
                         };
@@ -238,12 +238,12 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
                 path: &'tcx hir::Path<'tcx>,
                 count: usize,
             }
-            impl<'a, 'tcx> hir_visit::Visitor<'tcx> for ClosureUsageCount<'a, 'tcx> {
+            impl<'a, 'tcx> Visitor<'tcx> for ClosureUsageCount<'a, 'tcx> {
                 type NestedFilter = nested_filter::OnlyBodies;
 
                 fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
-                    if let hir::ExprKind::Call(closure, _) = expr.kind
-                        && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind
+                    if let ExprKind::Call(closure, _) = expr.kind
+                        && let ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind
                         && self.path.segments[0].ident == path.segments[0].ident
                         && self.path.res == path.res
                     {
@@ -263,13 +263,13 @@ impl<'tcx> LateLintPass<'tcx> for RedundantClosureCall {
 
         for w in block.stmts.windows(2) {
             if let hir::StmtKind::Let(local) = w[0].kind
-                && let Option::Some(t) = local.init
-                && let hir::ExprKind::Closure { .. } = t.kind
+                && let Some(t) = local.init
+                && let ExprKind::Closure { .. } = t.kind
                 && let hir::PatKind::Binding(_, _, ident, _) = local.pat.kind
                 && let hir::StmtKind::Semi(second) = w[1].kind
-                && let hir::ExprKind::Assign(_, call, _) = second.kind
-                && let hir::ExprKind::Call(closure, _) = call.kind
-                && let hir::ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind
+                && let ExprKind::Assign(_, call, _) = second.kind
+                && let ExprKind::Call(closure, _) = call.kind
+                && let ExprKind::Path(hir::QPath::Resolved(_, path)) = closure.kind
                 && ident == path.segments[0].ident
                 && count_closure_usage(cx, block, path) == 1
             {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_locals.rs b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
index 0f579f779df..7202266deeb 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_locals.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_locals.rs
@@ -77,9 +77,9 @@ impl<'tcx> LateLintPass<'tcx> for RedundantLocals {
                 cx,
                 REDUNDANT_LOCALS,
                 local.span,
-                &format!("redundant redefinition of a binding `{ident}`"),
+                format!("redundant redefinition of a binding `{ident}`"),
                 Some(binding_pat.span),
-                &format!("`{ident}` is initially defined here"),
+                format!("`{ident}` is initially defined here"),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
index 0e43e4a7ee5..1b557730eca 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_pub_crate.rs
@@ -56,7 +56,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantPubCrate {
                 cx,
                 REDUNDANT_PUB_CRATE,
                 span,
-                &format!("pub(crate) {descr} inside private module"),
+                format!("pub(crate) {descr} inside private module"),
                 |diag| {
                     diag.span_suggestion(
                         item.vis_span,
diff --git a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
index 07b604f2326..136e7db83bd 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_static_lifetimes.rs
@@ -48,7 +48,7 @@ impl_lint_pass!(RedundantStaticLifetimes => [REDUNDANT_STATIC_LIFETIMES]);
 
 impl RedundantStaticLifetimes {
     // Recursively visit types
-    fn visit_type(ty: &Ty, cx: &EarlyContext<'_>, reason: &str) {
+    fn visit_type(ty: &Ty, cx: &EarlyContext<'_>, reason: &'static str) {
         match ty.kind {
             // Be careful of nested structures (arrays and tuples)
             TyKind::Array(ref ty, _) | TyKind::Slice(ref ty) => {
diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
index 96f6f0ec36f..11b95ee3a54 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
@@ -59,7 +59,7 @@ fn is_same_type<'tcx>(cx: &LateContext<'tcx>, ty_resolved_path: hir::def::Res, f
 
 fn func_hir_id_to_func_ty<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::hir_id::HirId) -> Option<Ty<'tcx>> {
     if let Some((defkind, func_defid)) = cx.typeck_results().type_dependent_def(hir_id)
-        && defkind == hir::def::DefKind::AssocFn
+        && defkind == DefKind::AssocFn
         && let Some(init_ty) = cx.tcx.type_of(func_defid).no_bound_vars()
     {
         Some(init_ty)
diff --git a/src/tools/clippy/clippy_lints/src/regex.rs b/src/tools/clippy/clippy_lints/src/regex.rs
index 687bad35a36..e925ec0271c 100644
--- a/src/tools/clippy/clippy_lints/src/regex.rs
+++ b/src/tools/clippy/clippy_lints/src/regex.rs
@@ -134,13 +134,13 @@ fn lint_syntax_error(cx: &LateContext<'_>, error: &regex_syntax::Error, unescape
             vec![convert_span(primary)]
         };
 
-        span_lint(cx, INVALID_REGEX, spans, &format!("regex syntax error: {kind}"));
+        span_lint(cx, INVALID_REGEX, spans, format!("regex syntax error: {kind}"));
     } else {
         span_lint_and_help(
             cx,
             INVALID_REGEX,
             base,
-            &error.to_string(),
+            error.to_string(),
             None,
             "consider using a raw string literal: `r\"..\"`",
         );
@@ -223,7 +223,7 @@ fn check_regex<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>, utf8: bool) {
                     span_lint_and_help(cx, TRIVIAL_REGEX, expr.span, "trivial regex", None, repl);
                 }
             },
-            Err(e) => span_lint(cx, INVALID_REGEX, expr.span, &e.to_string()),
+            Err(e) => span_lint(cx, INVALID_REGEX, expr.span, e.to_string()),
         }
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
index fcb79f6d694..a358881bf80 100644
--- a/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
+++ b/src/tools/clippy/clippy_lints/src/repeat_vec_with_capacity.rs
@@ -55,7 +55,7 @@ fn emit_lint(cx: &LateContext<'_>, span: Span, kind: &str, note: &'static str, s
         cx,
         REPEAT_VEC_WITH_CAPACITY,
         span,
-        &format!("repeating `Vec::with_capacity` using `{kind}`, which does not retain capacity"),
+        format!("repeating `Vec::with_capacity` using `{kind}`, which does not retain capacity"),
         |diag| {
             diag.note(note);
             diag.span_suggestion_verbose(span, sugg_msg, sugg, Applicability::MaybeIncorrect);
diff --git a/src/tools/clippy/clippy_lints/src/returns.rs b/src/tools/clippy/clippy_lints/src/returns.rs
index 8bc24eda465..e8f9d438104 100644
--- a/src/tools/clippy/clippy_lints/src/returns.rs
+++ b/src/tools/clippy/clippy_lints/src/returns.rs
@@ -3,7 +3,7 @@ use clippy_utils::source::{snippet_opt, snippet_with_context};
 use clippy_utils::sugg::has_enclosing_paren;
 use clippy_utils::visitors::{for_each_expr_with_closures, Descend};
 use clippy_utils::{
-    fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id,
+    fn_def_id, is_from_proc_macro, is_inside_let_else, is_res_lang_ctor, path_res, path_to_local_id, span_contains_cfg,
     span_find_starting_semi,
 };
 use core::ops::ControlFlow;
@@ -232,6 +232,7 @@ impl<'tcx> LateLintPass<'tcx> for Return {
             && !in_external_macro(cx.sess(), initexpr.span)
             && !in_external_macro(cx.sess(), retexpr.span)
             && !local.span.from_expansion()
+            && !span_contains_cfg(cx, stmt.span.between(retexpr.span))
         {
             span_lint_hir_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
index 85a2b1a6735..23b47606f8a 100644
--- a/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
+++ b/src/tools/clippy/clippy_lints/src/self_named_constructors.rs
@@ -81,7 +81,7 @@ impl<'tcx> LateLintPass<'tcx> for SelfNamedConstructors {
                 cx,
                 SELF_NAMED_CONSTRUCTORS,
                 impl_item.span,
-                &format!("constructor `{}` has the same name as the type", impl_item.ident.name),
+                format!("constructor `{}` has the same name as the type", impl_item.ident.name),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_lints/src/serde_api.rs b/src/tools/clippy/clippy_lints/src/serde_api.rs
index b4278d879e5..f1ec91d7aff 100644
--- a/src/tools/clippy/clippy_lints/src/serde_api.rs
+++ b/src/tools/clippy/clippy_lints/src/serde_api.rs
@@ -9,7 +9,7 @@ declare_clippy_lint! {
     /// Checks for misuses of the serde API.
     ///
     /// ### Why is this bad?
-    /// Serde is very finnicky about how its API should be
+    /// Serde is very finicky about how its API should be
     /// used, but the type system can't be used to enforce it (yet?).
     ///
     /// ### Example
diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs
index d98b37bda35..9db08acb03b 100644
--- a/src/tools/clippy/clippy_lints/src/shadow.rs
+++ b/src/tools/clippy/clippy_lints/src/shadow.rs
@@ -194,7 +194,7 @@ fn lint_shadow(cx: &LateContext<'_>, pat: &Pat<'_>, shadowed: HirId, span: Span)
         cx,
         lint,
         span,
-        &msg,
+        msg,
         Some(cx.tcx.hir().span(shadowed)),
         "previous binding is here",
     );
diff --git a/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs b/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
index 95b4a11a783..0a9a3c6307a 100644
--- a/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
+++ b/src/tools/clippy/clippy_lints/src/single_range_in_vec_init.rs
@@ -122,7 +122,7 @@ impl LateLintPass<'_> for SingleRangeInVecInit {
                     cx,
                     SINGLE_RANGE_IN_VEC_INIT,
                     span,
-                    &format!("{suggested_type} of `Range` that is only one element"),
+                    format!("{suggested_type} of `Range` that is only one element"),
                     |diag| {
                         if should_emit_every_value {
                             diag.span_suggestion(
diff --git a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
index ff8e8fe7021..8a9f02b6dcb 100644
--- a/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
+++ b/src/tools/clippy/clippy_lints/src/slow_vector_initialization.rs
@@ -196,7 +196,7 @@ impl SlowVectorInit {
         };
     }
 
-    fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &str) {
+    fn emit_lint(cx: &LateContext<'_>, slow_fill: &Expr<'_>, vec_alloc: &VecAllocation<'_>, msg: &'static str) {
         let len_expr = Sugg::hir(
             cx,
             match vec_alloc.size_expr {
diff --git a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
index cf839941123..926c56332cc 100644
--- a/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
+++ b/src/tools/clippy/clippy_lints/src/std_instead_of_core.rs
@@ -128,8 +128,8 @@ impl<'tcx> LateLintPass<'tcx> for StdReexports {
                     cx,
                     lint,
                     first_segment.ident.span,
-                    &format!("used import from `{used_mod}` instead of `{replace_with}`"),
-                    &format!("consider importing the item from `{replace_with}`"),
+                    format!("used import from `{used_mod}` instead of `{replace_with}`"),
+                    format!("consider importing the item from `{replace_with}`"),
                     replace_with.to_string(),
                     Applicability::MachineApplicable,
                 );
diff --git a/src/tools/clippy/clippy_lints/src/strings.rs b/src/tools/clippy/clippy_lints/src/strings.rs
index 13ae1ff52dd..b3c729dacdd 100644
--- a/src/tools/clippy/clippy_lints/src/strings.rs
+++ b/src/tools/clippy/clippy_lints/src/strings.rs
@@ -495,8 +495,8 @@ impl<'tcx> LateLintPass<'tcx> for TrimSplitWhitespace {
                 cx,
                 TRIM_SPLIT_WHITESPACE,
                 trim_span.with_hi(split_ws_span.lo()),
-                &format!("found call to `str::{trim_fn_name}` before `str::split_whitespace`"),
-                &format!("remove `{trim_fn_name}()`"),
+                format!("found call to `str::{trim_fn_name}` before `str::split_whitespace`"),
+                format!("remove `{trim_fn_name}()`"),
                 String::new(),
                 Applicability::MachineApplicable,
             );
diff --git a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
index 8eab3f5874e..3f030b80331 100644
--- a/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
+++ b/src/tools/clippy/clippy_lints/src/suspicious_trait_impl.rs
@@ -83,7 +83,7 @@ impl<'tcx> LateLintPass<'tcx> for SuspiciousImpl {
                 cx,
                 lint,
                 binop.span,
-                &format!(
+                format!(
                     "suspicious use of `{}` in `{}` impl",
                     binop.node.as_str(),
                     cx.tcx.item_name(trait_id)
diff --git a/src/tools/clippy/clippy_lints/src/swap.rs b/src/tools/clippy/clippy_lints/src/swap.rs
index be590aede15..93bad865809 100644
--- a/src/tools/clippy/clippy_lints/src/swap.rs
+++ b/src/tools/clippy/clippy_lints/src/swap.rs
@@ -1,10 +1,16 @@
 use clippy_utils::diagnostics::{span_lint_and_sugg, span_lint_and_then};
-use clippy_utils::source::snippet_with_context;
+use clippy_utils::source::{snippet_indent, snippet_with_context};
 use clippy_utils::sugg::Sugg;
 use clippy_utils::ty::is_type_diagnostic_item;
+
 use clippy_utils::{can_mut_borrow_both, eq_expr_value, in_constant, std_or_core};
+use itertools::Itertools;
+
+use rustc_hir::intravisit::{walk_expr, Visitor};
+
+use crate::FxHashSet;
 use rustc_errors::Applicability;
-use rustc_hir::{BinOpKind, Block, Expr, ExprKind, PatKind, QPath, Stmt, StmtKind};
+use rustc_hir::{BinOpKind, Block, Expr, ExprKind, LetStmt, PatKind, QPath, Stmt, StmtKind};
 use rustc_lint::{LateContext, LateLintPass, LintContext};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::ty;
@@ -80,7 +86,17 @@ impl<'tcx> LateLintPass<'tcx> for Swap {
     }
 }
 
-fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, span: Span, is_xor_based: bool) {
+#[allow(clippy::too_many_arguments)]
+fn generate_swap_warning<'tcx>(
+    block: &'tcx Block<'tcx>,
+    cx: &LateContext<'tcx>,
+    e1: &'tcx Expr<'tcx>,
+    e2: &'tcx Expr<'tcx>,
+    rhs1: &'tcx Expr<'tcx>,
+    rhs2: &'tcx Expr<'tcx>,
+    span: Span,
+    is_xor_based: bool,
+) {
     let ctxt = span.ctxt();
     let mut applicability = Applicability::MachineApplicable;
 
@@ -99,14 +115,25 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
                 || is_type_diagnostic_item(cx, ty, sym::VecDeque)
             {
                 let slice = Sugg::hir_with_applicability(cx, lhs1, "<slice>", &mut applicability);
+
                 span_lint_and_sugg(
                     cx,
                     MANUAL_SWAP,
                     span,
-                    &format!("this looks like you are swapping elements of `{slice}` manually"),
+                    format!("this looks like you are swapping elements of `{slice}` manually"),
                     "try",
                     format!(
-                        "{}.swap({}, {});",
+                        "{}{}.swap({}, {});",
+                        IndexBinding {
+                            block,
+                            swap1_idx: idx1,
+                            swap2_idx: idx2,
+                            suggest_span: span,
+                            cx,
+                            ctxt,
+                            applicability: &mut applicability,
+                        }
+                        .snippet_index_bindings(&[idx1, idx2, rhs1, rhs2]),
                         slice.maybe_par(),
                         snippet_with_context(cx, idx1.span, ctxt, "..", &mut applicability).0,
                         snippet_with_context(cx, idx2.span, ctxt, "..", &mut applicability).0,
@@ -126,7 +153,7 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
         cx,
         MANUAL_SWAP,
         span,
-        &format!("this looks like you are swapping `{first}` and `{second}` manually"),
+        format!("this looks like you are swapping `{first}` and `{second}` manually"),
         |diag| {
             diag.span_suggestion(
                 span,
@@ -142,7 +169,7 @@ fn generate_swap_warning(cx: &LateContext<'_>, e1: &Expr<'_>, e2: &Expr<'_>, spa
 }
 
 /// Implementation of the `MANUAL_SWAP` lint.
-fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) {
+fn check_manual_swap<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
     if in_constant(cx, block.hir_id) {
         return;
     }
@@ -160,10 +187,10 @@ fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) {
             // bar() = t;
             && let StmtKind::Semi(second) = s3.kind
             && let ExprKind::Assign(lhs2, rhs2, _) = second.kind
-            && let ExprKind::Path(QPath::Resolved(None, rhs2)) = rhs2.kind
-            && rhs2.segments.len() == 1
+            && let ExprKind::Path(QPath::Resolved(None, rhs2_path)) = rhs2.kind
+            && rhs2_path.segments.len() == 1
 
-            && ident.name == rhs2.segments[0].ident.name
+            && ident.name == rhs2_path.segments[0].ident.name
             && eq_expr_value(cx, tmp_init, lhs1)
             && eq_expr_value(cx, rhs1, lhs2)
 
@@ -174,7 +201,7 @@ fn check_manual_swap(cx: &LateContext<'_>, block: &Block<'_>) {
             && second.span.ctxt() == ctxt
         {
             let span = s1.span.to(s3.span);
-            generate_swap_warning(cx, lhs1, lhs2, span, false);
+            generate_swap_warning(block, cx, lhs1, lhs2, rhs1, rhs2, span, false);
         }
     }
 }
@@ -201,7 +228,7 @@ fn check_suspicious_swap(cx: &LateContext<'_>, block: &Block<'_>) {
                 cx,
                 ALMOST_SWAPPED,
                 span,
-                &format!("this looks like you are trying to swap `{lhs_sugg}` and `{rhs_sugg}`"),
+                format!("this looks like you are trying to swap `{lhs_sugg}` and `{rhs_sugg}`"),
                 |diag| {
                     diag.span_suggestion(
                         span,
@@ -254,7 +281,7 @@ fn parse<'a, 'hir>(stmt: &'a Stmt<'hir>) -> Option<(ExprOrIdent<'hir>, &'a Expr<
 }
 
 /// Implementation of the xor case for `MANUAL_SWAP` lint.
-fn check_xor_swap(cx: &LateContext<'_>, block: &Block<'_>) {
+fn check_xor_swap<'tcx>(cx: &LateContext<'tcx>, block: &'tcx Block<'tcx>) {
     for [s1, s2, s3] in block.stmts.array_windows::<3>() {
         let ctxt = s1.span.ctxt();
         if let Some((lhs0, rhs0)) = extract_sides_of_xor_assign(s1, ctxt)
@@ -268,7 +295,7 @@ fn check_xor_swap(cx: &LateContext<'_>, block: &Block<'_>) {
             && s3.span.ctxt() == ctxt
         {
             let span = s1.span.to(s3.span);
-            generate_swap_warning(cx, lhs0, rhs0, span, true);
+            generate_swap_warning(block, cx, lhs0, rhs0, rhs1, rhs2, span, true);
         };
     }
 }
@@ -294,3 +321,130 @@ fn extract_sides_of_xor_assign<'a, 'hir>(
         None
     }
 }
+
+struct IndexBinding<'a, 'tcx> {
+    block: &'a Block<'a>,
+    swap1_idx: &'a Expr<'a>,
+    swap2_idx: &'a Expr<'a>,
+    suggest_span: Span,
+    cx: &'a LateContext<'tcx>,
+    ctxt: SyntaxContext,
+    applicability: &'a mut Applicability,
+}
+
+impl<'a, 'tcx> IndexBinding<'a, 'tcx> {
+    fn snippet_index_bindings(&mut self, exprs: &[&'tcx Expr<'tcx>]) -> String {
+        let mut bindings = FxHashSet::default();
+        for expr in exprs {
+            bindings.insert(self.snippet_index_binding(expr));
+        }
+        bindings.into_iter().join("")
+    }
+
+    fn snippet_index_binding(&mut self, expr: &'tcx Expr<'tcx>) -> String {
+        match expr.kind {
+            ExprKind::Binary(_, lhs, rhs) => {
+                if matches!(lhs.kind, ExprKind::Lit(_)) && matches!(rhs.kind, ExprKind::Lit(_)) {
+                    return String::new();
+                }
+                let lhs_snippet = self.snippet_index_binding(lhs);
+                let rhs_snippet = self.snippet_index_binding(rhs);
+                format!("{lhs_snippet}{rhs_snippet}")
+            },
+            ExprKind::Path(QPath::Resolved(_, path)) => {
+                let init = self.cx.expr_or_init(expr);
+
+                let Some(first_segment) = path.segments.first() else {
+                    return String::new();
+                };
+                if !self.suggest_span.contains(init.span) || !self.is_used_other_than_swapping(first_segment.ident) {
+                    return String::new();
+                }
+
+                let init_str = snippet_with_context(self.cx, init.span, self.ctxt, "", self.applicability)
+                    .0
+                    .to_string();
+                let indent_str = snippet_indent(self.cx, init.span);
+                let indent_str = indent_str.as_deref().unwrap_or("");
+
+                format!("let {} = {init_str};\n{indent_str}", first_segment.ident)
+            },
+            _ => String::new(),
+        }
+    }
+
+    fn is_used_other_than_swapping(&mut self, idx_ident: Ident) -> bool {
+        if Self::is_used_slice_indexed(self.swap1_idx, idx_ident)
+            || Self::is_used_slice_indexed(self.swap2_idx, idx_ident)
+        {
+            return true;
+        }
+        self.is_used_after_swap(idx_ident)
+    }
+
+    fn is_used_after_swap(&mut self, idx_ident: Ident) -> bool {
+        let mut v = IndexBindingVisitor {
+            found_used: false,
+            suggest_span: self.suggest_span,
+            idx: idx_ident,
+        };
+
+        for stmt in self.block.stmts {
+            match stmt.kind {
+                StmtKind::Expr(expr) | StmtKind::Semi(expr) => v.visit_expr(expr),
+                StmtKind::Let(LetStmt { ref init, .. }) => {
+                    if let Some(init) = init.as_ref() {
+                        v.visit_expr(init);
+                    }
+                },
+                StmtKind::Item(_) => {},
+            }
+        }
+
+        v.found_used
+    }
+
+    fn is_used_slice_indexed(swap_index: &Expr<'_>, idx_ident: Ident) -> bool {
+        match swap_index.kind {
+            ExprKind::Binary(_, lhs, rhs) => {
+                if matches!(lhs.kind, ExprKind::Lit(_)) && matches!(rhs.kind, ExprKind::Lit(_)) {
+                    return false;
+                }
+                Self::is_used_slice_indexed(lhs, idx_ident) || Self::is_used_slice_indexed(rhs, idx_ident)
+            },
+            ExprKind::Path(QPath::Resolved(_, path)) => {
+                path.segments.first().map_or(false, |idx| idx.ident == idx_ident)
+            },
+            _ => false,
+        }
+    }
+}
+
+struct IndexBindingVisitor {
+    idx: Ident,
+    suggest_span: Span,
+    found_used: bool,
+}
+
+impl<'tcx> Visitor<'tcx> for IndexBindingVisitor {
+    fn visit_path_segment(&mut self, path_segment: &'tcx rustc_hir::PathSegment<'tcx>) -> Self::Result {
+        if path_segment.ident == self.idx {
+            self.found_used = true;
+        }
+    }
+
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) -> Self::Result {
+        if expr.span.hi() <= self.suggest_span.hi() {
+            return;
+        }
+
+        match expr.kind {
+            ExprKind::Path(QPath::Resolved(_, path)) => {
+                for segment in path.segments {
+                    self.visit_path_segment(segment);
+                }
+            },
+            _ => walk_expr(self, expr),
+        }
+    }
+}
diff --git a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
index f8bdb866ca3..c1e24674e3e 100644
--- a/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
+++ b/src/tools/clippy/clippy_lints/src/thread_local_initializer_can_be_made_const.rs
@@ -59,7 +59,7 @@ impl_lint_pass!(ThreadLocalInitializerCanBeMadeConst => [THREAD_LOCAL_INITIALIZE
 #[inline]
 fn is_thread_local_initializer(
     cx: &LateContext<'_>,
-    fn_kind: rustc_hir::intravisit::FnKind<'_>,
+    fn_kind: intravisit::FnKind<'_>,
     span: rustc_span::Span,
 ) -> Option<bool> {
     let macro_def_id = span.source_callee()?.macro_def_id?;
@@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for ThreadLocalInitializerCanBeMadeConst {
     fn check_fn(
         &mut self,
         cx: &LateContext<'tcx>,
-        fn_kind: rustc_hir::intravisit::FnKind<'tcx>,
+        fn_kind: intravisit::FnKind<'tcx>,
         _: &'tcx rustc_hir::FnDecl<'tcx>,
         body: &'tcx rustc_hir::Body<'tcx>,
         span: rustc_span::Span,
diff --git a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
index cbdf31c9336..462084e96a8 100644
--- a/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
+++ b/src/tools/clippy/clippy_lints/src/trailing_empty_array.rs
@@ -44,7 +44,7 @@ impl<'tcx> LateLintPass<'tcx> for TrailingEmptyArray {
                 item.span,
                 "trailing zero-sized array in a struct which is not marked with a `repr` attribute",
                 None,
-                &format!(
+                format!(
                     "consider annotating `{}` with `#[repr(C)]` or another `repr` attribute",
                     cx.tcx.def_path_str(item.owner_id)
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/trait_bounds.rs b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
index 768623b5d03..9468d367a92 100644
--- a/src/tools/clippy/clippy_lints/src/trait_bounds.rs
+++ b/src/tools/clippy/clippy_lints/src/trait_bounds.rs
@@ -293,7 +293,7 @@ impl TraitBounds {
                     p.span,
                     "this type has already been used as a bound predicate",
                     None,
-                    &hint_string,
+                    hint_string,
                 );
             }
         }
@@ -420,7 +420,11 @@ fn into_comparable_trait_ref(trait_ref: &TraitRef<'_>) -> ComparableTraitRef {
     )
 }
 
-fn rollup_traits(cx: &LateContext<'_>, bounds: &[GenericBound<'_>], msg: &str) -> Vec<(ComparableTraitRef, Span)> {
+fn rollup_traits(
+    cx: &LateContext<'_>,
+    bounds: &[GenericBound<'_>],
+    msg: &'static str,
+) -> Vec<(ComparableTraitRef, Span)> {
     let mut map = FxHashMap::default();
     let mut repeated_res = false;
 
diff --git a/src/tools/clippy/clippy_lints/src/transmute/crosspointer_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/crosspointer_transmute.rs
index 102aee1cb95..c8f959a9854 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/crosspointer_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/crosspointer_transmute.rs
@@ -13,7 +13,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
                 cx,
                 CROSSPOINTER_TRANSMUTE,
                 e.span,
-                &format!("transmute from a type (`{from_ty}`) to the type that it points to (`{to_ty}`)"),
+                format!("transmute from a type (`{from_ty}`) to the type that it points to (`{to_ty}`)"),
             );
             true
         },
@@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
                 cx,
                 CROSSPOINTER_TRANSMUTE,
                 e.span,
-                &format!("transmute from a type (`{from_ty}`) to a pointer to that type (`{to_ty}`)"),
+                format!("transmute from a type (`{from_ty}`) to a pointer to that type (`{to_ty}`)"),
             );
             true
         },
diff --git a/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
new file mode 100644
index 00000000000..cc6ff1cf3b4
--- /dev/null
+++ b/src/tools/clippy/clippy_lints/src/transmute/missing_transmute_annotations.rs
@@ -0,0 +1,87 @@
+use clippy_utils::diagnostics::span_lint_and_sugg;
+use rustc_errors::Applicability;
+use rustc_hir::{GenericArg, HirId, LetStmt, Node, Path, TyKind};
+use rustc_lint::LateContext;
+use rustc_middle::lint::in_external_macro;
+use rustc_middle::ty::Ty;
+
+use crate::transmute::MISSING_TRANSMUTE_ANNOTATIONS;
+
+fn get_parent_local_binding_ty<'tcx>(cx: &LateContext<'tcx>, expr_hir_id: HirId) -> Option<LetStmt<'tcx>> {
+    let mut parent_iter = cx.tcx.hir().parent_iter(expr_hir_id);
+    if let Some((_, node)) = parent_iter.next() {
+        match node {
+            Node::LetStmt(local) => Some(*local),
+            Node::Block(_) => {
+                if let Some((parent_hir_id, Node::Expr(expr))) = parent_iter.next()
+                    && matches!(expr.kind, rustc_hir::ExprKind::Block(_, _))
+                {
+                    get_parent_local_binding_ty(cx, parent_hir_id)
+                } else {
+                    None
+                }
+            },
+            _ => None,
+        }
+    } else {
+        None
+    }
+}
+
+fn is_function_block(cx: &LateContext<'_>, expr_hir_id: HirId) -> bool {
+    let def_id = cx.tcx.hir().enclosing_body_owner(expr_hir_id);
+    if let Some(body_id) = cx.tcx.hir().maybe_body_owned_by(def_id) {
+        let body = cx.tcx.hir().body(body_id);
+        return body.value.peel_blocks().hir_id == expr_hir_id;
+    }
+    false
+}
+
+pub(super) fn check<'tcx>(
+    cx: &LateContext<'tcx>,
+    path: &Path<'tcx>,
+    from_ty: Ty<'tcx>,
+    to_ty: Ty<'tcx>,
+    expr_hir_id: HirId,
+) -> bool {
+    let last = path.segments.last().unwrap();
+    if in_external_macro(cx.tcx.sess, last.ident.span) {
+        // If it comes from a non-local macro, we ignore it.
+        return false;
+    }
+    let args = last.args;
+    let missing_generic = match args {
+        Some(args) if !args.args.is_empty() => args.args.iter().any(|arg| match arg {
+            GenericArg::Infer(_) => true,
+            GenericArg::Type(ty) => matches!(ty.kind, TyKind::Infer),
+            _ => false,
+        }),
+        _ => true,
+    };
+    if !missing_generic {
+        return false;
+    }
+    // If it's being set as a local variable value...
+    if let Some(local) = get_parent_local_binding_ty(cx, expr_hir_id) {
+        // ... which does have type annotations.
+        if let Some(ty) = local.ty
+            // If this is a `let x: _ =`, we should lint.
+            && !matches!(ty.kind, TyKind::Infer)
+        {
+            return false;
+        }
+    // We check if this transmute is not the only element in the function
+    } else if is_function_block(cx, expr_hir_id) {
+        return false;
+    }
+    span_lint_and_sugg(
+        cx,
+        MISSING_TRANSMUTE_ANNOTATIONS,
+        last.ident.span.with_hi(path.span.hi()),
+        "transmute used without annotations",
+        "consider adding missing annotations",
+        format!("{}::<{from_ty}, {to_ty}>", last.ident.as_str()),
+        Applicability::MaybeIncorrect,
+    );
+    true
+}
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 3c11b481310..7fa536a1a29 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -1,5 +1,6 @@
 mod crosspointer_transmute;
 mod eager_transmute;
+mod missing_transmute_annotations;
 mod transmute_float_to_int;
 mod transmute_int_to_bool;
 mod transmute_int_to_char;
@@ -520,6 +521,37 @@ declare_clippy_lint! {
     "eager evaluation of `transmute`"
 }
 
+declare_clippy_lint! {
+    /// ### What it does
+    /// Checks if transmute calls have all generics specified.
+    ///
+    /// ### Why is this bad?
+    /// If not set, some unexpected output type could be retrieved instead of the expected one,
+    /// potentially leading to invalid code.
+    ///
+    /// This is particularly dangerous in case a seemingly innocent/unrelated change can cause type
+    /// inference to start inferring a different type. E.g. the transmute is the tail expression of
+    /// an `if` branch, and a different branches type changes, causing the transmute to silently
+    /// have a different type, instead of a proper error.
+    ///
+    /// ### Example
+    /// ```no_run
+    /// # unsafe {
+    /// let x: i32 = std::mem::transmute([1u16, 2u16]);
+    /// # }
+    /// ```
+    /// Use instead:
+    /// ```no_run
+    /// # unsafe {
+    /// let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+    /// # }
+    /// ```
+    #[clippy::version = "1.77.0"]
+    pub MISSING_TRANSMUTE_ANNOTATIONS,
+    suspicious,
+    "warns if a transmute call doesn't have all generics specified"
+}
+
 pub struct Transmute {
     msrv: Msrv,
 }
@@ -542,6 +574,7 @@ impl_lint_pass!(Transmute => [
     TRANSMUTING_NULL,
     TRANSMUTE_NULL_TO_FN,
     EAGER_TRANSMUTE,
+    MISSING_TRANSMUTE_ANNOTATIONS,
 ]);
 impl Transmute {
     #[must_use]
@@ -579,6 +612,7 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 | transmuting_null::check(cx, e, arg, to_ty)
                 | transmute_null_to_fn::check(cx, e, arg, to_ty)
                 | transmute_ptr_to_ref::check(cx, e, from_ty, to_ty, arg, path, &self.msrv)
+                | missing_transmute_annotations::check(cx, path, from_ty, to_ty, e.hir_id)
                 | transmute_int_to_char::check(cx, e, from_ty, to_ty, arg, const_context)
                 | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
                 | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
index aef520923e4..ab3bb5e1062 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 TRANSMUTE_FLOAT_TO_INT,
                 e.span,
-                &format!("transmute from a `{from_ty}` to a `{to_ty}`"),
+                format!("transmute from a `{from_ty}` to a `{to_ty}`"),
                 |diag| {
                     let mut sugg = sugg::Sugg::hir(cx, arg, "..");
 
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_bool.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_bool.rs
index 58227c53de2..a7192809077 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_bool.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_bool.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 TRANSMUTE_INT_TO_BOOL,
                 e.span,
-                &format!("transmute from a `{from_ty}` to a `bool`"),
+                format!("transmute from a `{from_ty}` to a `bool`"),
                 |diag| {
                     let arg = sugg::Sugg::hir(cx, arg, "..");
                     let zero = sugg::Sugg::NonParen(Cow::from("0"));
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
index 2a6c2481254..81d10a7d5bd 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_char.rs
@@ -23,7 +23,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 TRANSMUTE_INT_TO_CHAR,
                 e.span,
-                &format!("transmute from a `{from_ty}` to a `char`"),
+                format!("transmute from a `{from_ty}` to a `char`"),
                 |diag| {
                     let Some(top_crate) = std_or_core(cx) else { return };
                     let arg = sugg::Sugg::hir(cx, arg, "..");
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
index cc3422edbbf..d51888e3097 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
@@ -22,7 +22,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 TRANSMUTE_INT_TO_FLOAT,
                 e.span,
-                &format!("transmute from a `{from_ty}` to a `{to_ty}`"),
+                format!("transmute from a `{from_ty}` to a `{to_ty}`"),
                 |diag| {
                     let arg = sugg::Sugg::hir(cx, arg, "..");
                     let arg = if let ty::Int(int_ty) = from_ty.kind() {
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
index 97068efd43c..234021f0f47 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_non_zero.rs
@@ -58,7 +58,7 @@ pub(super) fn check<'tcx>(
         cx,
         TRANSMUTE_INT_TO_NON_ZERO,
         e.span,
-        &format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
+        format!("transmute from a `{from_ty}` to a `{nonzero_alias}`"),
         |diag| {
             let arg = sugg::Sugg::hir(cx, arg, "..");
             diag.span_suggestion(
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
index 009d5a7c8ae..88b0ac5a368 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
@@ -31,7 +31,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 TRANSMUTE_NUM_TO_BYTES,
                 e.span,
-                &format!("transmute from a `{from_ty}` to a `{to_ty}`"),
+                format!("transmute from a `{from_ty}` to a `{to_ty}`"),
                 |diag| {
                     let arg = sugg::Sugg::hir(cx, arg, "..");
                     diag.span_suggestion(
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
index cf78709583c..eaf927c0005 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ptr_to_ref.rs
@@ -25,7 +25,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 TRANSMUTE_PTR_TO_REF,
                 e.span,
-                &format!("transmute from a pointer type (`{from_ty}`) to a reference type (`{to_ty}`)"),
+                format!("transmute from a pointer type (`{from_ty}`) to a reference type (`{to_ty}`)"),
                 |diag| {
                     let arg = sugg::Sugg::hir(cx, arg, "..");
                     let (deref, cast) = if *mutbl == Mutability::Mut {
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
index 73321c56f3f..3842c4eb60e 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_ref_to_ref.rs
@@ -35,7 +35,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 TRANSMUTE_BYTES_TO_STR,
                 e.span,
-                &format!("transmute from a `{from_ty}` to a `{to_ty}`"),
+                format!("transmute from a `{from_ty}` to a `{to_ty}`"),
                 "consider using",
                 if const_context {
                     format!("{top_crate}::str::from_utf8_unchecked{postfix}({snippet})")
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
index 33c4031fa87..9c8dd37d53d 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_undefined_repr.rs
@@ -71,7 +71,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     TRANSMUTE_UNDEFINED_REPR,
                     e.span,
-                    &format!("transmute from `{from_ty_orig}` which has an undefined layout"),
+                    format!("transmute from `{from_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if from_ty_orig.peel_refs() != from_ty.peel_refs() {
                             diag.note(format!("the contained type `{from_ty}` has an undefined layout"));
@@ -85,7 +85,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     TRANSMUTE_UNDEFINED_REPR,
                     e.span,
-                    &format!("transmute to `{to_ty_orig}` which has an undefined layout"),
+                    format!("transmute to `{to_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if to_ty_orig.peel_refs() != to_ty.peel_refs() {
                             diag.note(format!("the contained type `{to_ty}` has an undefined layout"));
@@ -111,7 +111,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     TRANSMUTE_UNDEFINED_REPR,
                     e.span,
-                    &format!(
+                    format!(
                         "transmute from `{from_ty_orig}` to `{to_ty_orig}`, both of which have an undefined layout"
                     ),
                     |diag| {
@@ -140,7 +140,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     TRANSMUTE_UNDEFINED_REPR,
                     e.span,
-                    &format!("transmute from `{from_ty_orig}` which has an undefined layout"),
+                    format!("transmute from `{from_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if from_ty_orig.peel_refs() != from_ty {
                             diag.note(format!("the contained type `{from_ty}` has an undefined layout"));
@@ -157,7 +157,7 @@ pub(super) fn check<'tcx>(
                     cx,
                     TRANSMUTE_UNDEFINED_REPR,
                     e.span,
-                    &format!("transmute into `{to_ty_orig}` which has an undefined layout"),
+                    format!("transmute into `{to_ty_orig}` which has an undefined layout"),
                     |diag| {
                         if to_ty_orig.peel_refs() != to_ty {
                             diag.note(format!("the contained type `{to_ty}` has an undefined layout"));
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
index 043c9c88601..6f5ac625e35 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmutes_expressible_as_ptr_casts.rs
@@ -53,7 +53,7 @@ pub(super) fn check<'tcx>(
         cx,
         TRANSMUTES_EXPRESSIBLE_AS_PTR_CASTS,
         e.span,
-        &format!("transmute from `{from_ty}` to `{to_ty}` which could be expressed as a pointer cast instead"),
+        format!("transmute from `{from_ty}` to `{to_ty}` which could be expressed as a pointer cast instead"),
         "try",
         sugg,
         app,
diff --git a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
index 891fefc17a6..35e93830766 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/unsound_collection_transmute.rs
@@ -37,7 +37,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
                     cx,
                     UNSOUND_COLLECTION_TRANSMUTE,
                     e.span,
-                    &format!("transmute from `{from_ty}` to `{to_ty}` with mismatched layout is unsound"),
+                    format!("transmute from `{from_ty}` to `{to_ty}` with mismatched layout is unsound"),
                 );
                 true
             } else {
diff --git a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs
index 70628f3d4f4..ec5fb2793f9 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/useless_transmute.rs
@@ -21,7 +21,7 @@ pub(super) fn check<'tcx>(
                 cx,
                 USELESS_TRANSMUTE,
                 e.span,
-                &format!("transmute from a type (`{from_ty}`) to itself"),
+                format!("transmute from a type (`{from_ty}`) to itself"),
             );
             true
         },
diff --git a/src/tools/clippy/clippy_lints/src/transmute/wrong_transmute.rs b/src/tools/clippy/clippy_lints/src/transmute/wrong_transmute.rs
index ed815884a76..14a5a308a64 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/wrong_transmute.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/wrong_transmute.rs
@@ -13,7 +13,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>, from_ty: Ty
                 cx,
                 WRONG_TRANSMUTE,
                 e.span,
-                &format!("transmute from a `{from_ty}` to a pointer"),
+                format!("transmute from a `{from_ty}` to a pointer"),
             );
             true
         },
diff --git a/src/tools/clippy/clippy_lints/src/types/box_collection.rs b/src/tools/clippy/clippy_lints/src/types/box_collection.rs
index fc3420af020..9ac73394548 100644
--- a/src/tools/clippy/clippy_lints/src/types/box_collection.rs
+++ b/src/tools/clippy/clippy_lints/src/types/box_collection.rs
@@ -21,9 +21,9 @@ pub(super) fn check(cx: &LateContext<'_>, hir_ty: &hir::Ty<'_>, qpath: &QPath<'_
             cx,
             BOX_COLLECTION,
             hir_ty.span,
-            &format!("you seem to be trying to use `Box<{box_content}>`. Consider using just `{box_content}`"),
+            format!("you seem to be trying to use `Box<{box_content}>`. Consider using just `{box_content}`"),
             None,
-            &format!("`{box_content}` is already on the heap, `Box<{box_content}>` makes an extra allocation"),
+            format!("`{box_content}` is already on the heap, `Box<{box_content}>` makes an extra allocation"),
         );
         true
     } else {
diff --git a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
index 37437cbfbec..0801eace4fc 100644
--- a/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
+++ b/src/tools/clippy/clippy_lints/src/types/redundant_allocation.rs
@@ -29,7 +29,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
             cx,
             REDUNDANT_ALLOCATION,
             hir_ty.span,
-            &format!("usage of `{outer_sym}<{generic_snippet}>`"),
+            format!("usage of `{outer_sym}<{generic_snippet}>`"),
             |diag| {
                 diag.span_suggestion(hir_ty.span, "try", format!("{generic_snippet}"), applicability);
                 diag.note(format!(
@@ -73,7 +73,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
             cx,
             REDUNDANT_ALLOCATION,
             hir_ty.span,
-            &format!("usage of `{outer_sym}<{inner_sym}<{generic_snippet}>>`"),
+            format!("usage of `{outer_sym}<{inner_sym}<{generic_snippet}>>`"),
             |diag| {
                 diag.span_suggestion(
                     hir_ty.span,
@@ -92,7 +92,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>, qpath:
             cx,
             REDUNDANT_ALLOCATION,
             hir_ty.span,
-            &format!("usage of `{outer_sym}<{inner_sym}<{generic_snippet}>>`"),
+            format!("usage of `{outer_sym}<{inner_sym}<{generic_snippet}>>`"),
             |diag| {
                 diag.note(format!(
                     "`{inner_sym}<{generic_snippet}>` is already on the heap, `{outer_sym}<{inner_sym}<{generic_snippet}>>` makes an extra allocation"
diff --git a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
index 8764e3006c6..0c4e2c91aec 100644
--- a/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
+++ b/src/tools/clippy/clippy_lints/src/unconditional_recursion.rs
@@ -23,7 +23,7 @@ declare_clippy_lint! {
     /// implementations.
     ///
     /// ### Why is this bad?
-    /// This is a hard to find infinite recursion that will crash any code.
+    /// This is a hard to find infinite recursion that will crash any code
     /// using it.
     ///
     /// ### Example
diff --git a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
index 5fe4b74b3a7..cbd16180077 100644
--- a/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
+++ b/src/tools/clippy/clippy_lints/src/undocumented_unsafe_blocks.rs
@@ -200,7 +200,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
         let item_has_safety_comment = item_has_safety_comment(cx, item);
         match (&item.kind, item_has_safety_comment) {
             // lint unsafe impl without safety comment
-            (hir::ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.unsafety == hir::Unsafety::Unsafe => {
+            (ItemKind::Impl(impl_), HasSafetyComment::No) if impl_.unsafety == hir::Unsafety::Unsafe => {
                 if !is_lint_allowed(cx, UNDOCUMENTED_UNSAFE_BLOCKS, item.hir_id())
                     && !is_unsafe_from_proc_macro(cx, item.span)
                 {
@@ -222,7 +222,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
                 }
             },
             // lint safe impl with unnecessary safety comment
-            (hir::ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.unsafety == hir::Unsafety::Normal => {
+            (ItemKind::Impl(impl_), HasSafetyComment::Yes(pos)) if impl_.unsafety == hir::Unsafety::Normal => {
                 if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, item.hir_id()) {
                     let (span, help_span) = mk_spans(pos);
 
@@ -236,9 +236,9 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
                     );
                 }
             },
-            (hir::ItemKind::Impl(_), _) => {},
+            (ItemKind::Impl(_), _) => {},
             // const and static items only need a safety comment if their body is an unsafe block, lint otherwise
-            (&hir::ItemKind::Const(.., body) | &hir::ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => {
+            (&ItemKind::Const(.., body) | &ItemKind::Static(.., body), HasSafetyComment::Yes(pos)) => {
                 if !is_lint_allowed(cx, UNNECESSARY_SAFETY_COMMENT, body.hir_id) {
                     let body = cx.tcx.hir().body(body);
                     if !matches!(
@@ -251,7 +251,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
                             cx,
                             UNNECESSARY_SAFETY_COMMENT,
                             span,
-                            &format!("{} has unnecessary safety comment", item.kind.descr()),
+                            format!("{} has unnecessary safety comment", item.kind.descr()),
                             Some(help_span),
                             "consider removing the safety comment",
                         );
@@ -268,7 +268,7 @@ impl<'tcx> LateLintPass<'tcx> for UndocumentedUnsafeBlocks {
                         cx,
                         UNNECESSARY_SAFETY_COMMENT,
                         span,
-                        &format!("{} has unnecessary safety comment", item.kind.descr()),
+                        format!("{} has unnecessary safety comment", item.kind.descr()),
                         Some(help_span),
                         "consider removing the safety comment",
                     );
@@ -338,13 +338,13 @@ fn block_parents_have_safety_comment(
     accept_comment_above_statement: bool,
     accept_comment_above_attributes: bool,
     cx: &LateContext<'_>,
-    id: hir::HirId,
+    id: HirId,
 ) -> bool {
     let (span, hir_id) = match cx.tcx.parent_hir_node(id) {
         Node::Expr(expr) => match cx.tcx.parent_hir_node(expr.hir_id) {
             Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
             Node::Item(hir::Item {
-                kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
+                kind: ItemKind::Const(..) | ItemKind::Static(..),
                 span,
                 owner_id,
                 ..
@@ -365,7 +365,7 @@ fn block_parents_have_safety_comment(
         })
         | Node::LetStmt(hir::LetStmt { span, hir_id, .. }) => (*span, *hir_id),
         Node::Item(hir::Item {
-            kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
+            kind: ItemKind::Const(..) | ItemKind::Static(..),
             span,
             owner_id,
             ..
@@ -605,11 +605,11 @@ fn get_body_search_span(cx: &LateContext<'_>) -> Option<Span> {
             Node::Expr(e) => span = e.span,
             Node::Block(_) | Node::Arm(_) | Node::Stmt(_) | Node::LetStmt(_) => (),
             Node::Item(hir::Item {
-                kind: hir::ItemKind::Const(..) | ItemKind::Static(..),
+                kind: ItemKind::Const(..) | ItemKind::Static(..),
                 ..
             }) => maybe_global_var = true,
             Node::Item(hir::Item {
-                kind: hir::ItemKind::Mod(_),
+                kind: ItemKind::Mod(_),
                 span: item_span,
                 ..
             }) => {
diff --git a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
index 729972de6e6..214b69dc925 100644
--- a/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_return_expecting_ord.rs
@@ -153,7 +153,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitReturnExpectingOrd {
                                 cx,
                                 UNIT_RETURN_EXPECTING_ORD,
                                 span,
-                                &format!(
+                                format!(
                                     "this closure returns \
                                    the unit type which also implements {trait_name}"
                                 ),
@@ -164,7 +164,7 @@ impl<'tcx> LateLintPass<'tcx> for UnitReturnExpectingOrd {
                                 cx,
                                 UNIT_RETURN_EXPECTING_ORD,
                                 span,
-                                &format!(
+                                format!(
                                     "this closure returns \
                                    the unit type which also implements {trait_name}"
                                 ),
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 ffb909d7907..80b661a757c 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
@@ -1,9 +1,10 @@
 use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::source::snippet_with_context;
-use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source};
+use clippy_utils::visitors::{for_each_local_assignment, for_each_value_source, is_local_used};
 use core::ops::ControlFlow;
 use rustc_errors::Applicability;
 use rustc_hir::def::{DefKind, Res};
+use rustc_hir::intravisit::{walk_body, Visitor};
 use rustc_hir::{Expr, ExprKind, HirId, HirIdSet, LetStmt, MatchSource, Node, PatKind, QPath, TyKind};
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::lint::{in_external_macro, is_from_async_await};
@@ -75,12 +76,53 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, local: &'tcx LetStmt<'_>) {
                         let snip = snippet_with_context(cx, expr.span, local.span.ctxt(), "()", &mut app).0;
                         diag.span_suggestion(local.span, "omit the `let` binding", format!("{snip};"), app);
                     }
+
+                    if let PatKind::Binding(_, binding_hir_id, ident, ..) = local.pat.kind
+                        && let Some(body_id) = cx.enclosing_body.as_ref()
+                        && let body = cx.tcx.hir().body(*body_id)
+                        && is_local_used(cx, body, binding_hir_id)
+                    {
+                        let identifier = ident.as_str();
+                        let mut visitor = UnitVariableCollector::new(binding_hir_id);
+                        walk_body(&mut visitor, body);
+                        visitor.spans.into_iter().for_each(|span| {
+                            let msg =
+                                format!("variable `{identifier}` of type `()` can be replaced with explicit `()`");
+                            diag.span_suggestion(span, msg, "()", Applicability::MachineApplicable);
+                        });
+                    }
                 },
             );
         }
     }
 }
 
+struct UnitVariableCollector {
+    id: HirId,
+    spans: Vec<rustc_span::Span>,
+}
+
+impl UnitVariableCollector {
+    fn new(id: HirId) -> Self {
+        Self { id, spans: vec![] }
+    }
+}
+
+/**
+ * Collect all instances where a variable is used based on its `HirId`.
+ */
+impl<'tcx> Visitor<'tcx> for UnitVariableCollector {
+    fn visit_expr(&mut self, ex: &'tcx Expr<'tcx>) -> Self::Result {
+        if let ExprKind::Path(QPath::Resolved(None, path)) = ex.kind
+            && let Res::Local(id) = path.res
+            && id == self.id
+        {
+            self.spans.push(path.span);
+        }
+        rustc_hir::intravisit::walk_expr(self, ex);
+    }
+}
+
 /// Checks sub-expressions which create the value returned by the given expression for whether
 /// return value inference is needed. This checks through locals to see if they also need inference
 /// at this point.
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
index eba7fa7b993..afc53e6f32d 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_arg.rs
@@ -2,7 +2,7 @@ use clippy_utils::diagnostics::span_lint_and_then;
 use clippy_utils::is_from_proc_macro;
 use clippy_utils::source::{indent_of, reindent_multiline, snippet_opt};
 use rustc_errors::Applicability;
-use rustc_hir::{self as hir, Block, Expr, ExprKind, MatchSource, Node, StmtKind};
+use rustc_hir::{Block, Expr, ExprKind, MatchSource, Node, StmtKind};
 use rustc_lint::LateContext;
 
 use super::{utils, UNIT_ARG};
@@ -19,7 +19,7 @@ pub(super) fn check<'tcx>(cx: &LateContext<'tcx>, expr: &'tcx Expr<'tcx>) {
     if is_questionmark_desugar_marked_call(expr) {
         return;
     }
-    if let hir::Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id)
+    if let Node::Expr(parent_expr) = cx.tcx.parent_hir_node(expr.hir_id)
         && is_questionmark_desugar_marked_call(parent_expr)
     {
         return;
@@ -69,7 +69,7 @@ fn lint_unit_args(cx: &LateContext<'_>, expr: &Expr<'_>, args_to_recover: &[&Exp
         cx,
         UNIT_ARG,
         expr.span,
-        &format!("passing {singular}unit value{plural} to a function"),
+        format!("passing {singular}unit value{plural} to a function"),
         |db| {
             let mut or = "";
             args_to_recover
diff --git a/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs b/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs
index d4342ec5169..6dcc1195a70 100644
--- a/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs
+++ b/src/tools/clippy/clippy_lints/src/unit_types/unit_cmp.rs
@@ -24,7 +24,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
                 cx,
                 UNIT_CMP,
                 macro_call.span,
-                &format!("`{macro_name}` of unit values detected. This will always {result}"),
+                format!("`{macro_name}` of unit values detected. This will always {result}"),
             );
         }
         return;
@@ -41,7 +41,7 @@ pub(super) fn check(cx: &LateContext<'_>, expr: &Expr<'_>) {
                 cx,
                 UNIT_CMP,
                 expr.span,
-                &format!(
+                format!(
                     "{}-comparison of unit values detected. This will always be {result}",
                     op.as_str()
                 ),
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
index c332cf076ae..bfcefb26153 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
@@ -88,7 +88,7 @@ impl UnnecessaryBoxReturns {
                 cx,
                 UNNECESSARY_BOX_RETURNS,
                 return_ty_hir.span,
-                format!("boxed return of the sized type `{boxed_ty}`").as_str(),
+                format!("boxed return of the sized type `{boxed_ty}`"),
                 |diagnostic| {
                     diagnostic.span_suggestion(
                         return_ty_hir.span,
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
index 2b0d2d61d20..8f1eb5019f0 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_map_on_constructor.rs
@@ -65,7 +65,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
                 hir::QPath::LangItem(..) => return,
             };
             match constructor_symbol {
-                sym::Some | sym::Ok if path.ident.name == rustc_span::sym::map => (),
+                sym::Some | sym::Ok if path.ident.name == sym::map => (),
                 sym::Err if path.ident.name == sym::map_err => (),
                 _ => return,
             }
@@ -86,7 +86,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryMapOnConstructor {
                     cx,
                     UNNECESSARY_MAP_ON_CONSTRUCTOR,
                     expr.span,
-                    &format!(
+                    format!(
                         "unnecessary {} on constructor {constructor_snippet}(_)",
                         path.ident.name
                     ),
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
index 9c8b0ae1727..5c7fbbab988 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_wraps.rs
@@ -156,7 +156,7 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryWraps {
                 )
             };
 
-            span_lint_and_then(cx, UNNECESSARY_WRAPS, span, lint_msg.as_str(), |diag| {
+            span_lint_and_then(cx, UNNECESSARY_WRAPS, span, lint_msg, |diag| {
                 diag.span_suggestion(
                     fn_decl.output.span(),
                     return_type_sugg_msg,
diff --git a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
index d4dd31e1178..0049de931f4 100644
--- a/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnested_or_patterns.rs
@@ -215,7 +215,7 @@ macro_rules! always_pat {
 /// in `alternatives[focus_idx + 1..]`.
 fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: usize) -> bool {
     // Extract the kind; we'll need to make some changes in it.
-    let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, PatKind::Wild);
+    let mut focus_kind = mem::replace(&mut alternatives[focus_idx].kind, Wild);
     // We'll focus on `alternatives[focus_idx]`,
     // so we're draining from `alternatives[focus_idx + 1..]`.
     let start = focus_idx + 1;
@@ -232,7 +232,7 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
         // In the case of only two patterns, replacement adds net characters.
         | Ref(_, Mutability::Not)
         // Dealt with elsewhere.
-        | Or(_) | Paren(_) => false,
+        | Or(_) | Paren(_) | Deref(_) => false,
         // Transform `box x | ... | box y` into `box (x | y)`.
         //
         // The cases below until `Slice(...)` deal with *singleton* products.
@@ -242,8 +242,6 @@ fn transform_with_focus_on_idx(alternatives: &mut ThinVec<P<Pat>>, focus_idx: us
             |k| matches!(k, Box(_)),
             |k| always_pat!(k, Box(p) => p),
         ),
-        // FIXME(deref_patterns): Should we merge patterns here?
-        Deref(_) => false,
         // Transform `&mut x | ... | &mut y` into `&mut (x | y)`.
         Ref(target, Mutability::Mut) => extend_with_matching(
             target, start, alternatives,
diff --git a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
index 3f2f765f751..51b3ea93b6d 100644
--- a/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
+++ b/src/tools/clippy/clippy_lints/src/unsafe_removed_from_name.rs
@@ -65,7 +65,7 @@ fn unsafe_to_safe_check(old_name: Ident, new_name: Ident, cx: &EarlyContext<'_>,
             cx,
             UNSAFE_REMOVED_FROM_NAME,
             span,
-            &format!("removed `unsafe` from the name of `{old_str}` in use as `{new_str}`"),
+            format!("removed `unsafe` from the name of `{old_str}` in use as `{new_str}`"),
         );
     }
 }
diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
index d8c5f1b7382..448946bd66d 100644
--- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs
@@ -85,7 +85,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedIoAmount {
         if let Some(exp) = block.expr
             && matches!(
                 exp.kind,
-                hir::ExprKind::If(_, _, _) | hir::ExprKind::Match(_, _, hir::MatchSource::Normal)
+                ExprKind::If(_, _, _) | ExprKind::Match(_, _, hir::MatchSource::Normal)
             )
         {
             check_expr(cx, exp);
@@ -130,7 +130,7 @@ fn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool {
 
 fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
     match expr.kind {
-        hir::ExprKind::If(cond, _, _)
+        ExprKind::If(cond, _, _)
             if let ExprKind::Let(hir::LetExpr { pat, init, .. }) = cond.kind
                 && is_ok_wild_or_dotdot_pattern(cx, pat)
                 && let Some(op) = should_lint(cx, init) =>
@@ -140,7 +140,7 @@ fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
         // we will capture only the case where the match is Ok( ) or Err( )
         // prefer to match the minimum possible, and expand later if needed
         // to avoid false positives on something as used as this
-        hir::ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
+        ExprKind::Match(expr, [arm1, arm2], hir::MatchSource::Normal) if let Some(op) = should_lint(cx, expr) => {
             if non_consuming_ok_arm(cx, arm1) && non_consuming_err_arm(cx, arm2) {
                 emit_lint(cx, expr.span, expr.hir_id, op, &[arm1.pat.span]);
             }
@@ -148,7 +148,7 @@ fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) {
                 emit_lint(cx, expr.span, expr.hir_id, op, &[arm2.pat.span]);
             }
         },
-        hir::ExprKind::Match(_, _, hir::MatchSource::Normal) => {},
+        ExprKind::Match(_, _, hir::MatchSource::Normal) => {},
         _ if let Some(op) = should_lint(cx, expr) => {
             emit_lint(cx, expr.span, expr.hir_id, op, &[]);
         },
@@ -201,7 +201,7 @@ fn is_unreachable_or_panic(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> bool {
 }
 
 fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
-    while let hir::ExprKind::MethodCall(path, receiver, ..) = expr.kind {
+    while let ExprKind::MethodCall(path, receiver, ..) = expr.kind {
         if matches!(
             path.ident.as_str(),
             "unwrap" | "expect" | "unwrap_or" | "unwrap_or_else" | "ok" | "is_ok" | "is_err" | "or_else" | "or"
@@ -215,10 +215,10 @@ fn unpack_call_chain<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
 }
 
 fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
-    while let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind
+    while let ExprKind::Call(func, [ref arg_0, ..]) = expr.kind
         && matches!(
             func.kind,
-            hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
+            ExprKind::Path(hir::QPath::LangItem(hir::LangItem::TryTraitBranch, ..))
         )
     {
         expr = arg_0;
@@ -227,7 +227,7 @@ fn unpack_try<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
 }
 
 fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
-    while let hir::ExprKind::Match(res, _, _) = expr.kind {
+    while let ExprKind::Match(res, _, _) = expr.kind {
         expr = res;
     }
     expr
@@ -236,11 +236,11 @@ fn unpack_match<'a>(mut expr: &'a hir::Expr<'a>) -> &'a hir::Expr<'a> {
 /// If `expr` is an (e).await, return the inner expression "e" that's being
 /// waited on.  Otherwise return None.
 fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> {
-    if let hir::ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind {
-        if let hir::ExprKind::Call(func, [ref arg_0, ..]) = expr.kind {
+    if let ExprKind::Match(expr, _, hir::MatchSource::AwaitDesugar) = expr.kind {
+        if let ExprKind::Call(func, [ref arg_0, ..]) = expr.kind {
             if matches!(
                 func.kind,
-                hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..))
+                ExprKind::Path(hir::QPath::LangItem(hir::LangItem::IntoFutureIntoFuture, ..))
             ) {
                 return arg_0;
             }
@@ -251,7 +251,7 @@ fn unpack_await<'a>(expr: &'a hir::Expr<'a>) -> &hir::Expr<'a> {
 
 /// Check whether the current expr is a function call for an IO operation
 fn check_io_mode(cx: &LateContext<'_>, call: &hir::Expr<'_>) -> Option<IoOp> {
-    let hir::ExprKind::MethodCall(path, ..) = call.kind else {
+    let ExprKind::MethodCall(path, ..) = call.kind else {
         return None;
     };
 
diff --git a/src/tools/clippy/clippy_lints/src/unused_rounding.rs b/src/tools/clippy/clippy_lints/src/unused_rounding.rs
index d5ca844b9e2..3e5afec541c 100644
--- a/src/tools/clippy/clippy_lints/src/unused_rounding.rs
+++ b/src/tools/clippy/clippy_lints/src/unused_rounding.rs
@@ -55,8 +55,8 @@ impl EarlyLintPass for UnusedRounding {
                 cx,
                 UNUSED_ROUNDING,
                 expr.span,
-                &format!("used the `{method_name}` method with a whole number float"),
-                &format!("remove the `{method_name}` method call"),
+                format!("used the `{method_name}` method with a whole number float"),
+                format!("remove the `{method_name}` method call"),
                 float,
                 Applicability::MachineApplicable,
             );
diff --git a/src/tools/clippy/clippy_lints/src/unwrap.rs b/src/tools/clippy/clippy_lints/src/unwrap.rs
index f2eb774b5cb..2622abd59cb 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap.rs
@@ -338,7 +338,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
                         UNNECESSARY_UNWRAP,
                         expr.hir_id,
                         expr.span,
-                        &format!(
+                        format!(
                             "called `{}` on `{unwrappable_variable_name}` after checking its variant with `{}`",
                             method_name.ident.name,
                             unwrappable.check_name.ident.as_str(),
@@ -373,7 +373,7 @@ impl<'a, 'tcx> Visitor<'tcx> for UnwrappableVariablesVisitor<'a, 'tcx> {
                         PANICKING_UNWRAP,
                         expr.hir_id,
                         expr.span,
-                        &format!("this call to `{}()` will always panic", method_name.ident.name),
+                        format!("this call to `{}()` will always panic", method_name.ident.name),
                         |diag| {
                             diag.span_label(unwrappable.check.span, "because of this check");
                         },
diff --git a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
index a615ef11691..aca500590ce 100644
--- a/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
+++ b/src/tools/clippy/clippy_lints/src/unwrap_in_result.rs
@@ -59,7 +59,7 @@ declare_lint_pass!(UnwrapInResult=> [UNWRAP_IN_RESULT]);
 
 impl<'tcx> LateLintPass<'tcx> for UnwrapInResult {
     fn check_impl_item(&mut self, cx: &LateContext<'tcx>, impl_item: &'tcx hir::ImplItem<'_>) {
-        if let hir::ImplItemKind::Fn(ref _signature, _) = impl_item.kind
+        if let ImplItemKind::Fn(ref _signature, _) = impl_item.kind
             // first check if it's a method or function
             // checking if its return type is `result` or `option`
             && (is_type_diagnostic_item(cx, return_ty(cx, impl_item.owner_id), sym::Result)
diff --git a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
index d2a1d42f279..f376d349646 100644
--- a/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
+++ b/src/tools/clippy/clippy_lints/src/upper_case_acronyms.rs
@@ -94,7 +94,7 @@ fn check_ident(cx: &LateContext<'_>, ident: &Ident, hir_id: HirId, be_aggressive
             UPPER_CASE_ACRONYMS,
             hir_id,
             span,
-            &format!("name `{ident}` contains a capitalized acronym"),
+            format!("name `{ident}` contains a capitalized acronym"),
             |diag| {
                 diag.span_suggestion(
                     span,
diff --git a/src/tools/clippy/clippy_lints/src/use_self.rs b/src/tools/clippy/clippy_lints/src/use_self.rs
index a6b411d6c0f..0bab917607d 100644
--- a/src/tools/clippy/clippy_lints/src/use_self.rs
+++ b/src/tools/clippy/clippy_lints/src/use_self.rs
@@ -207,7 +207,7 @@ impl<'tcx> LateLintPass<'tcx> for UseSelf {
         }
     }
 
-    fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &hir::Ty<'tcx>) {
+    fn check_ty(&mut self, cx: &LateContext<'tcx>, hir_ty: &Ty<'tcx>) {
         if !hir_ty.span.from_expansion()
             && self.msrv.meets(msrvs::TYPE_ALIAS_ENUM_VARIANTS)
             && let Some(&StackItem::Check {
@@ -286,7 +286,7 @@ impl<'tcx> Visitor<'tcx> for SkipTyCollector {
 
         walk_inf(self, inf);
     }
-    fn visit_ty(&mut self, hir_ty: &hir::Ty<'_>) {
+    fn visit_ty(&mut self, hir_ty: &Ty<'_>) {
         self.types_to_skip.push(hir_ty.hir_id);
 
         walk_ty(self, hir_ty);
diff --git a/src/tools/clippy/clippy_lints/src/useless_conversion.rs b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
index f7a455977fa..75541766156 100644
--- a/src/tools/clippy/clippy_lints/src/useless_conversion.rs
+++ b/src/tools/clippy/clippy_lints/src/useless_conversion.rs
@@ -184,7 +184,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                             cx,
                             USELESS_CONVERSION,
                             e.span,
-                            &format!("useless conversion to the same type: `{b}`"),
+                            format!("useless conversion to the same type: `{b}`"),
                             "consider removing `.into()`",
                             sugg.into_owned(),
                             app,
@@ -301,7 +301,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                             cx,
                             USELESS_CONVERSION,
                             e.span,
-                            &format!("useless conversion to the same type: `{b}`"),
+                            format!("useless conversion to the same type: `{b}`"),
                             "consider removing `.into_iter()`",
                             sugg,
                             Applicability::MachineApplicable, // snippet
@@ -321,7 +321,7 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                         cx,
                         USELESS_CONVERSION,
                         e.span,
-                        &format!("useless conversion to the same type: `{b}`"),
+                        format!("useless conversion to the same type: `{b}`"),
                         None,
                         "consider removing `.try_into()`",
                     );
@@ -346,9 +346,9 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                             cx,
                             USELESS_CONVERSION,
                             e.span,
-                            &format!("useless conversion to the same type: `{b}`"),
+                            format!("useless conversion to the same type: `{b}`"),
                             None,
-                            &hint,
+                            hint,
                         );
                     }
 
@@ -360,8 +360,8 @@ impl<'tcx> LateLintPass<'tcx> for UselessConversion {
                             cx,
                             USELESS_CONVERSION,
                             e.span,
-                            &format!("useless conversion to the same type: `{b}`"),
-                            &sugg_msg,
+                            format!("useless conversion to the same type: `{b}`"),
+                            sugg_msg,
                             sugg.to_string(),
                             app,
                         );
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index e45beb4910b..7b43abeef67 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -754,7 +754,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
     }
 }
 
-fn has_attr(cx: &LateContext<'_>, hir_id: hir::HirId) -> bool {
+fn has_attr(cx: &LateContext<'_>, hir_id: HirId) -> bool {
     let attrs = cx.tcx.hir().attrs(hir_id);
     get_attr(cx.sess(), attrs, "author").count() > 0
 }
@@ -771,7 +771,7 @@ fn path_to_string(path: &QPath<'_>) -> Result<String, ()> {
                 }
             },
             QPath::TypeRelative(ty, segment) => match &ty.kind {
-                hir::TyKind::Path(inner_path) => {
+                TyKind::Path(inner_path) => {
                     inner(s, inner_path)?;
                     *s += ", ";
                     write!(s, "{:?}", segment.ident.as_str()).unwrap();
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
index 4822970e47e..5483e80f932 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/almost_standard_lint_formulation.rs
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for AlmostStandardFormulation {
                                         ident.span,
                                         "non-standard lint formulation",
                                         None,
-                                        &format!("consider using `{}`", formulation.correction),
+                                        format!("consider using `{}`", formulation.correction),
                                     );
                                 }
                                 return;
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs
index 7c70d3f45db..f7529682675 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/collapsible_calls.rs
@@ -2,7 +2,6 @@ use clippy_utils::diagnostics::span_lint_and_sugg;
 use clippy_utils::source::snippet;
 use clippy_utils::{is_expr_path_def_path, is_lint_allowed, peel_blocks_with_stmt, SpanlessEq};
 use rustc_errors::Applicability;
-use rustc_hir as hir;
 use rustc_hir::{Closure, Expr, ExprKind};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_session::declare_lint_pass;
@@ -72,7 +71,7 @@ declare_clippy_lint! {
 declare_lint_pass!(CollapsibleCalls => [COLLAPSIBLE_SPAN_LINT_CALLS]);
 
 impl<'tcx> LateLintPass<'tcx> for CollapsibleCalls {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if is_lint_allowed(cx, COLLAPSIBLE_SPAN_LINT_CALLS, expr.hir_id) {
             return;
         }
diff --git a/src/tools/clippy/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs b/src/tools/clippy/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs
index df37619227c..9b6b6871818 100644
--- a/src/tools/clippy/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/internal_lints/compiler_lint_functions.rs
@@ -66,7 +66,7 @@ impl<'tcx> LateLintPass<'tcx> for CompilerLintFunctions {
                 path.ident.span,
                 "usage of a compiler lint function",
                 None,
-                &format!("please use the Clippy variant of this function: `{sugg}`"),
+                format!("please use the Clippy variant of this function: `{sugg}`"),
             );
         }
     }
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 370ed430bcf..9be225759df 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
@@ -181,7 +181,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
                                 cx,
                                 DEFAULT_LINT,
                                 item.span,
-                                &format!("the lint `{}` has the default lint description", item.ident.name),
+                                format!("the lint `{}` has the default lint description", item.ident.name),
                             );
                         }
 
@@ -191,7 +191,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
                             cx,
                             DEFAULT_DEPRECATION_REASON,
                             item.span,
-                            &format!("the lint `{}` has the default deprecation reason", item.ident.name),
+                            format!("the lint `{}` has the default deprecation reason", item.ident.name),
                         );
                     }
                 }
@@ -247,7 +247,7 @@ impl<'tcx> LateLintPass<'tcx> for LintWithoutLintPass {
                     cx,
                     LINT_WITHOUT_LINT_PASS,
                     lint_span,
-                    &format!("the lint `{lint_name}` is not added to any `LintPass`"),
+                    format!("the lint `{lint_name}` is not added to any `LintPass`"),
                 );
             }
         }
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 c56c8ddc7a9..5c1ebb922f1 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
@@ -153,7 +153,7 @@ impl MetadataCollector {
             lints: BinaryHeap::<LintMetadata>::default(),
             applicability_info: FxHashMap::<String, ApplicabilityInfo>::default(),
             config: get_configuration_metadata(),
-            clippy_project_root: std::env::current_dir()
+            clippy_project_root: env::current_dir()
                 .expect("failed to get current dir")
                 .ancestors()
                 .nth(1)
@@ -243,7 +243,7 @@ Please use that command to update the file and do not edit it by hand.
         .unwrap();
 
         // Write configuration links to CHANGELOG.md
-        let changelog = std::fs::read_to_string(CHANGELOG_PATH).unwrap();
+        let changelog = 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 -->")
@@ -822,7 +822,7 @@ fn lint_collection_error_item(cx: &LateContext<'_>, item: &Item<'_>, message: &s
         cx,
         METADATA_COLLECTOR,
         item.ident.span,
-        &format!("metadata collection error for `{}`: {message}", item.ident.name),
+        format!("metadata collection error for `{}`: {message}", item.ident.name),
     );
 }
 
@@ -912,7 +912,7 @@ impl<'a, 'hir> LintResolver<'a, 'hir> {
     }
 }
 
-impl<'a, 'hir> intravisit::Visitor<'hir> for LintResolver<'a, 'hir> {
+impl<'a, 'hir> Visitor<'hir> for LintResolver<'a, 'hir> {
     type NestedFilter = nested_filter::All;
 
     fn nested_visit_map(&mut self) -> Self::Map {
@@ -963,7 +963,7 @@ impl<'a, 'hir> ApplicabilityResolver<'a, 'hir> {
     }
 }
 
-impl<'a, 'hir> intravisit::Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
+impl<'a, 'hir> Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
     type NestedFilter = nested_filter::All;
 
     fn nested_visit_map(&mut self) -> Self::Map {
@@ -994,7 +994,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for ApplicabilityResolver<'a, 'hir> {
 }
 
 /// This returns the parent local node if the expression is a reference one
-fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -> Option<&'hir hir::Local<'hir>> {
+fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -> Option<&'hir hir::LetStmt<'hir>> {
     if let ExprKind::Path(QPath::Resolved(_, path)) = expr.kind {
         if let hir::def::Res::Local(local_hir) = path.res {
             return get_parent_local_hir_id(cx, local_hir);
@@ -1004,7 +1004,7 @@ fn get_parent_local<'hir>(cx: &LateContext<'hir>, expr: &'hir hir::Expr<'hir>) -
     None
 }
 
-fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::Local<'hir>> {
+fn get_parent_local_hir_id<'hir>(cx: &LateContext<'hir>, hir_id: hir::HirId) -> Option<&'hir hir::LetStmt<'hir>> {
     match cx.tcx.parent_hir_node(hir_id) {
         hir::Node::LetStmt(local) => Some(local),
         hir::Node::Pat(pattern) => get_parent_local_hir_id(cx, pattern.hir_id),
@@ -1042,7 +1042,7 @@ impl<'a, 'hir> IsMultiSpanScanner<'a, 'hir> {
     }
 }
 
-impl<'a, 'hir> intravisit::Visitor<'hir> for IsMultiSpanScanner<'a, 'hir> {
+impl<'a, 'hir> Visitor<'hir> for IsMultiSpanScanner<'a, 'hir> {
     type NestedFilter = nested_filter::All;
 
     fn nested_visit_map(&mut self) -> Self::Map {
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 8d208fbb7e9..63fcbd61528 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
@@ -51,8 +51,8 @@ impl LateLintPass<'_> for MsrvAttrImpl {
                 cx,
                 MISSING_MSRV_ATTR_IMPL,
                 span,
-                &format!("`extract_msrv_attr!` macro missing from `{lint_pass}` implementation"),
-                &format!("add `extract_msrv_attr!({context})` to the `{lint_pass}` implementation"),
+                format!("`extract_msrv_attr!` macro missing from `{lint_pass}` implementation"),
+                format!("add `extract_msrv_attr!({context})` to the `{lint_pass}` implementation"),
                 format!("{}\n    extract_msrv_attr!({context});", snippet(cx, span, "..")),
                 Applicability::MachineApplicable,
             );
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 304a1379374..8cf42832761 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
@@ -4,10 +4,9 @@ use clippy_utils::{def_path_def_ids, is_lint_allowed, match_any_def_paths, peel_
 use rustc_ast::ast::LitKind;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_errors::Applicability;
-use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
 use rustc_hir::def_id::DefId;
-use rustc_hir::{Expr, ExprKind, Local, Mutability, Node};
+use rustc_hir::{Expr, ExprKind, LetStmt, Mutability, Node};
 use rustc_lint::{LateContext, LateLintPass};
 use rustc_middle::mir::interpret::{Allocation, GlobalAlloc};
 use rustc_middle::mir::ConstValue;
@@ -49,7 +48,7 @@ pub struct UnnecessaryDefPath {
 }
 
 impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {
-    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx hir::Expr<'_>) {
+    fn check_expr(&mut self, cx: &LateContext<'tcx>, expr: &'tcx Expr<'_>) {
         if is_lint_allowed(cx, UNNECESSARY_DEF_PATH, expr.hir_id) {
             return;
         }
@@ -79,9 +78,9 @@ impl<'tcx> LateLintPass<'tcx> for UnnecessaryDefPath {
                 cx,
                 UNNECESSARY_DEF_PATH,
                 span,
-                &format!("hardcoded path to a {msg}"),
+                format!("hardcoded path to a {msg}"),
                 None,
-                &format!("convert all references to use `{sugg}`"),
+                format!("convert all references to use `{sugg}`"),
             );
         }
     }
@@ -213,11 +212,11 @@ impl UnnecessaryDefPath {
     }
 }
 
-fn path_to_matched_type(cx: &LateContext<'_>, expr: &hir::Expr<'_>) -> Option<Vec<String>> {
+fn path_to_matched_type(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<Vec<String>> {
     match peel_hir_expr_refs(expr).0.kind {
         ExprKind::Path(ref qpath) => match cx.qpath_res(qpath, expr.hir_id) {
             Res::Local(hir_id) => {
-                if let Node::LetStmt(Local { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) {
+                if let Node::LetStmt(LetStmt { init: Some(init), .. }) = cx.tcx.parent_hir_node(hir_id) {
                     path_to_matched_type(cx, init)
                 } else {
                     None
diff --git a/src/tools/clippy/clippy_lints/src/visibility.rs b/src/tools/clippy/clippy_lints/src/visibility.rs
index 83369c66367..9818b98dd5b 100644
--- a/src/tools/clippy/clippy_lints/src/visibility.rs
+++ b/src/tools/clippy/clippy_lints/src/visibility.rs
@@ -89,7 +89,7 @@ impl EarlyLintPass for Visibility {
                     cx,
                     NEEDLESS_PUB_SELF,
                     item.vis.span,
-                    &format!("unnecessary `pub({}self)`", if *shorthand { "" } else { "in " }),
+                    format!("unnecessary `pub({}self)`", if *shorthand { "" } else { "in " }),
                     "remove it",
                     String::new(),
                     Applicability::MachineApplicable,
diff --git a/src/tools/clippy/clippy_lints/src/write.rs b/src/tools/clippy/clippy_lints/src/write.rs
index be16d2e5cc3..26c6859233d 100644
--- a/src/tools/clippy/clippy_lints/src/write.rs
+++ b/src/tools/clippy/clippy_lints/src/write.rs
@@ -297,11 +297,11 @@ impl<'tcx> LateLintPass<'tcx> for Write {
         match diag_name {
             sym::print_macro | sym::println_macro if !allowed_in_tests => {
                 if !is_build_script {
-                    span_lint(cx, PRINT_STDOUT, macro_call.span, &format!("use of `{name}!`"));
+                    span_lint(cx, PRINT_STDOUT, macro_call.span, format!("use of `{name}!`"));
                 }
             },
             sym::eprint_macro | sym::eprintln_macro if !allowed_in_tests => {
-                span_lint(cx, PRINT_STDERR, macro_call.span, &format!("use of `{name}!`"));
+                span_lint(cx, PRINT_STDERR, macro_call.span, format!("use of `{name}!`"));
             },
             sym::write_macro | sym::writeln_macro => {},
             _ => return,
@@ -390,7 +390,7 @@ fn check_newline(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call: &Ma
             cx,
             lint,
             macro_call.span,
-            &format!("using `{name}!()` with a format string that ends in a single newline"),
+            format!("using `{name}!()` with a format string that ends in a single newline"),
             |diag| {
                 let name_span = cx.sess().source_map().span_until_char(macro_call.span, '!');
                 let Some(format_snippet) = snippet_opt(cx, format_string_span) else {
@@ -440,7 +440,7 @@ fn check_empty_string(cx: &LateContext<'_>, format_args: &FormatArgs, macro_call
             cx,
             lint,
             macro_call.span,
-            &format!("empty string literal in `{name}!`"),
+            format!("empty string literal in `{name}!`"),
             |diag| {
                 diag.span_suggestion(
                     span,
diff --git a/src/tools/clippy/clippy_lints/src/zero_div_zero.rs b/src/tools/clippy/clippy_lints/src/zero_div_zero.rs
index d3623d6fda4..662242f6196 100644
--- a/src/tools/clippy/clippy_lints/src/zero_div_zero.rs
+++ b/src/tools/clippy/clippy_lints/src/zero_div_zero.rs
@@ -53,7 +53,7 @@ impl<'tcx> LateLintPass<'tcx> for ZeroDiv {
                 expr.span,
                 "constant division of `0.0` with `0.0` will always result in NaN",
                 None,
-                &format!("consider using `{float_type}::NAN` if you would like a constant representing NaN",),
+                format!("consider using `{float_type}::NAN` if you would like a constant representing NaN",),
             );
         }
     }
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index f7532121aeb..f594a40ff59 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -97,8 +97,8 @@ pub fn eq_path_seg(l: &PathSegment, r: &PathSegment) -> bool {
 
 pub fn eq_generic_args(l: &GenericArgs, r: &GenericArgs) -> bool {
     match (l, r) {
-        (GenericArgs::AngleBracketed(l), GenericArgs::AngleBracketed(r)) => over(&l.args, &r.args, eq_angle_arg),
-        (GenericArgs::Parenthesized(l), GenericArgs::Parenthesized(r)) => {
+        (AngleBracketed(l), AngleBracketed(r)) => over(&l.args, &r.args, eq_angle_arg),
+        (Parenthesized(l), Parenthesized(r)) => {
             over(&l.inputs, &r.inputs, |l, r| eq_ty(l, r)) && eq_fn_ret_ty(&l.output, &r.output)
         },
         _ => false,
@@ -304,25 +304,25 @@ pub fn eq_item_kind(l: &ItemKind, r: &ItemKind) -> bool {
         (ExternCrate(l), ExternCrate(r)) => l == r,
         (Use(l), Use(r)) => eq_use_tree(l, r),
         (
-            Static(box ast::StaticItem {
+            Static(box StaticItem {
                 ty: lt,
                 mutability: lm,
                 expr: le,
             }),
-            Static(box ast::StaticItem {
+            Static(box StaticItem {
                 ty: rt,
                 mutability: rm,
                 expr: re,
             }),
         ) => lm == rm && eq_ty(lt, rt) && eq_expr_opt(le, re),
         (
-            Const(box ast::ConstItem {
+            Const(box ConstItem {
                 defaultness: ld,
                 generics: lg,
                 ty: lt,
                 expr: le,
             }),
-            Const(box ast::ConstItem {
+            Const(box ConstItem {
                 defaultness: rd,
                 generics: rg,
                 ty: rt,
@@ -493,13 +493,13 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
     use AssocItemKind::*;
     match (l, r) {
         (
-            Const(box ast::ConstItem {
+            Const(box ConstItem {
                 defaultness: ld,
                 generics: lg,
                 ty: lt,
                 expr: le,
             }),
-            Const(box ast::ConstItem {
+            Const(box ConstItem {
                 defaultness: rd,
                 generics: rg,
                 ty: rt,
@@ -523,14 +523,14 @@ pub fn eq_assoc_item_kind(l: &AssocItemKind, r: &AssocItemKind) -> bool {
             eq_defaultness(*ld, *rd) && eq_fn_sig(lf, rf) && eq_generics(lg, rg) && both(lb, rb, |l, r| eq_block(l, r))
         },
         (
-            Type(box ast::TyAlias {
+            Type(box TyAlias {
                 defaultness: ld,
                 generics: lg,
                 bounds: lb,
                 ty: lt,
                 ..
             }),
-            Type(box ast::TyAlias {
+            Type(box TyAlias {
                 defaultness: rd,
                 generics: rg,
                 bounds: rb,
diff --git a/src/tools/clippy/clippy_utils/src/attrs.rs b/src/tools/clippy/clippy_utils/src/attrs.rs
index 2d0c2cf1253..d2200bcf710 100644
--- a/src/tools/clippy/clippy_utils/src/attrs.rs
+++ b/src/tools/clippy/clippy_utils/src/attrs.rs
@@ -1,10 +1,15 @@
 use rustc_ast::{ast, attr};
 use rustc_errors::Applicability;
+use rustc_lexer::TokenKind;
+use rustc_lint::LateContext;
 use rustc_middle::ty::{AdtDef, TyCtxt};
 use rustc_session::Session;
-use rustc_span::sym;
+use rustc_span::{sym, Span};
 use std::str::FromStr;
 
+use crate::source::snippet_opt;
+use crate::tokenize_with_text;
+
 /// Deprecation status of attributes known by Clippy.
 pub enum DeprecationStatus {
     /// Attribute is deprecated
@@ -171,3 +176,28 @@ pub fn has_non_exhaustive_attr(tcx: TyCtxt<'_>, adt: AdtDef<'_>) -> bool {
             .all_fields()
             .any(|field_def| tcx.has_attr(field_def.did, sym::non_exhaustive))
 }
+
+/// Checks if the given span contains a `#[cfg(..)]` attribute
+pub fn span_contains_cfg(cx: &LateContext<'_>, s: Span) -> bool {
+    let Some(snip) = snippet_opt(cx, s) else {
+        // Assume true. This would require either an invalid span, or one which crosses file boundaries.
+        return true;
+    };
+    let mut iter = tokenize_with_text(&snip);
+
+    // Search for the token sequence [`#`, `[`, `cfg`]
+    while iter.any(|(t, _)| matches!(t, TokenKind::Pound)) {
+        let mut iter = iter.by_ref().skip_while(|(t, _)| {
+            matches!(
+                t,
+                TokenKind::Whitespace | TokenKind::LineComment { .. } | TokenKind::BlockComment { .. }
+            )
+        });
+        if matches!(iter.next(), Some((TokenKind::OpenBracket, _)))
+            && matches!(iter.next(), Some((TokenKind::Ident, "cfg")))
+        {
+            return true;
+        }
+    }
+    false
+}
diff --git a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
index d751aeaf902..42267310513 100644
--- a/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
+++ b/src/tools/clippy/clippy_utils/src/check_proc_macro.rs
@@ -24,7 +24,7 @@ use rustc_hir::{
 use rustc_lint::{LateContext, LintContext};
 use rustc_middle::ty::TyCtxt;
 use rustc_session::Session;
-use rustc_span::symbol::Ident;
+use rustc_span::symbol::{kw, Ident};
 use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi::Abi;
 
@@ -99,9 +99,13 @@ fn qpath_search_pat(path: &QPath<'_>) -> (Pat, Pat) {
             let start = if ty.is_some() {
                 Pat::Str("<")
             } else {
-                path.segments
-                    .first()
-                    .map_or(Pat::Str(""), |seg| Pat::Sym(seg.ident.name))
+                path.segments.first().map_or(Pat::Str(""), |seg| {
+                    if seg.ident.name == kw::PathRoot {
+                        Pat::Str("::")
+                    } else {
+                        Pat::Sym(seg.ident.name)
+                    }
+                })
             };
             let end = path.segments.last().map_or(Pat::Str(""), |seg| {
                 if seg.args.is_some() {
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 6b86630339f..253ae3aca68 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -17,14 +17,14 @@ use rustc_span::def_id::DefId;
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::SyntaxContext;
 use rustc_target::abi::Size;
-use std::cmp::Ordering::{self, Equal};
+use std::cmp::Ordering;
 use std::hash::{Hash, Hasher};
 use std::iter;
 
 /// A `LitKind`-like enum to fold constant `Expr`s into.
 #[derive(Debug, Clone)]
 pub enum Constant<'tcx> {
-    Adt(rustc_middle::mir::Const<'tcx>),
+    Adt(mir::Const<'tcx>),
     /// A `String` (e.g., "abc").
     Str(String),
     /// A binary string (e.g., `b"abc"`).
@@ -230,7 +230,7 @@ impl<'tcx> Constant<'tcx> {
                     lv,
                     rv,
                 ) {
-                    Some(Equal) => Some(ls.cmp(rs)),
+                    Some(Ordering::Equal) => Some(ls.cmp(rs)),
                     x => x,
                 }
             },
@@ -579,7 +579,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
     /// Lookup a possibly constant expression from an `ExprKind::Path` and apply a function on it.
     fn fetch_path_and_apply<T, F>(&mut self, qpath: &QPath<'_>, id: HirId, ty: Ty<'tcx>, f: F) -> Option<T>
     where
-        F: FnOnce(&mut Self, rustc_middle::mir::Const<'tcx>) -> Option<T>,
+        F: FnOnce(&mut Self, mir::Const<'tcx>) -> Option<T>,
     {
         let res = self.typeck_results.qpath_res(qpath, id);
         match res {
@@ -612,7 +612,7 @@ impl<'a, 'tcx> ConstEvalLateContext<'a, 'tcx> {
                     .tcx
                     .const_eval_resolve(self.param_env, mir::UnevaluatedConst::new(def_id, args), qpath.span())
                     .ok()
-                    .map(|val| rustc_middle::mir::Const::from_value(val, ty))?;
+                    .map(|val| mir::Const::from_value(val, ty))?;
                 f(self, result)
             },
             _ => None,
diff --git a/src/tools/clippy/clippy_utils/src/diagnostics.rs b/src/tools/clippy/clippy_utils/src/diagnostics.rs
index 0352696f93e..dc0a139e3c7 100644
--- a/src/tools/clippy/clippy_utils/src/diagnostics.rs
+++ b/src/tools/clippy/clippy_utils/src/diagnostics.rs
@@ -8,7 +8,7 @@
 //! Thank you!
 //! ~The `INTERNAL_METADATA_COLLECTOR` lint
 
-use rustc_errors::{Applicability, Diag, MultiSpan};
+use rustc_errors::{Applicability, Diag, DiagMessage, MultiSpan, SubdiagMessage};
 use rustc_hir::HirId;
 use rustc_lint::{LateContext, Lint, LintContext};
 use rustc_span::Span;
@@ -59,9 +59,9 @@ fn docs_link(diag: &mut Diag<'_, ()>, lint: &'static Lint) {
 /// 17 |     std::mem::forget(seven);
 ///    |     ^^^^^^^^^^^^^^^^^^^^^^^
 /// ```
-pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: &str) {
+pub fn span_lint<T: LintContext>(cx: &T, lint: &'static Lint, sp: impl Into<MultiSpan>, msg: impl Into<DiagMessage>) {
     #[expect(clippy::disallowed_methods)]
-    cx.span_lint(lint, sp, msg.to_string(), |diag| {
+    cx.span_lint(lint, sp, msg.into(), |diag| {
         docs_link(diag, lint);
     });
 }
@@ -104,17 +104,16 @@ pub fn span_lint_and_help<T: LintContext>(
     cx: &T,
     lint: &'static Lint,
     span: impl Into<MultiSpan>,
-    msg: &str,
+    msg: impl Into<DiagMessage>,
     help_span: Option<Span>,
-    help: &str,
+    help: impl Into<SubdiagMessage>,
 ) {
     #[expect(clippy::disallowed_methods)]
-    cx.span_lint(lint, span, msg.to_string(), |diag| {
-        let help = help.to_string();
+    cx.span_lint(lint, span, msg.into(), |diag| {
         if let Some(help_span) = help_span {
-            diag.span_help(help_span, help);
+            diag.span_help(help_span, help.into());
         } else {
-            diag.help(help);
+            diag.help(help.into());
         }
         docs_link(diag, lint);
     });
@@ -161,17 +160,16 @@ pub fn span_lint_and_note<T: LintContext>(
     cx: &T,
     lint: &'static Lint,
     span: impl Into<MultiSpan>,
-    msg: &str,
+    msg: impl Into<DiagMessage>,
     note_span: Option<Span>,
-    note: &str,
+    note: impl Into<SubdiagMessage>,
 ) {
     #[expect(clippy::disallowed_methods)]
-    cx.span_lint(lint, span, msg.to_string(), |diag| {
-        let note = note.to_string();
+    cx.span_lint(lint, span, msg.into(), |diag| {
         if let Some(note_span) = note_span {
-            diag.span_note(note_span, note);
+            diag.span_note(note_span, note.into());
         } else {
-            diag.note(note);
+            diag.note(note.into());
         }
         docs_link(diag, lint);
     });
@@ -195,14 +193,15 @@ pub fn span_lint_and_note<T: LintContext>(
 /// If you're unsure which function you should use, you can test if the `#[allow]` attribute works
 /// where you would expect it to.
 /// If it doesn't, you likely need to use [`span_lint_hir_and_then`] instead.
-pub fn span_lint_and_then<C, S, F>(cx: &C, lint: &'static Lint, sp: S, msg: &str, f: F)
+pub fn span_lint_and_then<C, S, M, F>(cx: &C, lint: &'static Lint, sp: S, msg: M, f: F)
 where
     C: LintContext,
     S: Into<MultiSpan>,
+    M: Into<DiagMessage>,
     F: FnOnce(&mut Diag<'_, ()>),
 {
     #[expect(clippy::disallowed_methods)]
-    cx.span_lint(lint, sp, msg.to_string(), |diag| {
+    cx.span_lint(lint, sp, msg, |diag| {
         f(diag);
         docs_link(diag, lint);
     });
@@ -232,9 +231,9 @@ where
 /// Instead, use this function and also pass the `HirId` of `<expr_1>`, which will let
 /// the compiler check lint level attributes at the place of the expression and
 /// the `#[allow]` will work.
-pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: &str) {
+pub fn span_lint_hir(cx: &LateContext<'_>, lint: &'static Lint, hir_id: HirId, sp: Span, msg: impl Into<DiagMessage>) {
     #[expect(clippy::disallowed_methods)]
-    cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| {
+    cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| {
         docs_link(diag, lint);
     });
 }
@@ -268,11 +267,11 @@ pub fn span_lint_hir_and_then(
     lint: &'static Lint,
     hir_id: HirId,
     sp: impl Into<MultiSpan>,
-    msg: &str,
+    msg: impl Into<DiagMessage>,
     f: impl FnOnce(&mut Diag<'_, ()>),
 ) {
     #[expect(clippy::disallowed_methods)]
-    cx.tcx.node_span_lint(lint, hir_id, sp, msg.to_string(), |diag| {
+    cx.tcx.node_span_lint(lint, hir_id, sp, msg.into(), |diag| {
         f(diag);
         docs_link(diag, lint);
     });
@@ -316,13 +315,13 @@ pub fn span_lint_and_sugg<T: LintContext>(
     cx: &T,
     lint: &'static Lint,
     sp: Span,
-    msg: &str,
-    help: &str,
+    msg: impl Into<DiagMessage>,
+    help: impl Into<SubdiagMessage>,
     sugg: String,
     applicability: Applicability,
 ) {
-    span_lint_and_then(cx, lint, sp, msg, |diag| {
-        diag.span_suggestion(sp, help.to_string(), sugg, applicability);
+    span_lint_and_then(cx, lint, sp, msg.into(), |diag| {
+        diag.span_suggestion(sp, help.into(), sugg, applicability);
     });
 }
 
@@ -332,7 +331,7 @@ pub fn span_lint_and_sugg<T: LintContext>(
 /// appear once per
 /// replacement. In human-readable format though, it only appears once before
 /// the whole suggestion.
-pub fn multispan_sugg<I>(diag: &mut Diag<'_, ()>, help_msg: &str, sugg: I)
+pub fn multispan_sugg<I>(diag: &mut Diag<'_, ()>, help_msg: impl Into<SubdiagMessage>, sugg: I)
 where
     I: IntoIterator<Item = (Span, String)>,
 {
@@ -346,11 +345,11 @@ where
 /// Suggestions with multiple spans will be silently ignored.
 pub fn multispan_sugg_with_applicability<I>(
     diag: &mut Diag<'_, ()>,
-    help_msg: &str,
+    help_msg: impl Into<SubdiagMessage>,
     applicability: Applicability,
     sugg: I,
 ) where
     I: IntoIterator<Item = (Span, String)>,
 {
-    diag.multipart_suggestion(help_msg.to_string(), sugg.into_iter().collect(), applicability);
+    diag.multipart_suggestion(help_msg.into(), sugg.into_iter().collect(), applicability);
 }
diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs
index 8ce19998a08..801a9852159 100644
--- a/src/tools/clippy/clippy_utils/src/higher.rs
+++ b/src/tools/clippy/clippy_utils/src/higher.rs
@@ -16,11 +16,11 @@ use rustc_span::{sym, symbol, Span};
 /// `for pat in arg { body }` becomes `(pat, arg, body)`. Returns `(pat, arg, body, span)`.
 pub struct ForLoop<'tcx> {
     /// `for` loop item
-    pub pat: &'tcx hir::Pat<'tcx>,
+    pub pat: &'tcx Pat<'tcx>,
     /// `IntoIterator` argument
-    pub arg: &'tcx hir::Expr<'tcx>,
+    pub arg: &'tcx Expr<'tcx>,
     /// `for` loop body
-    pub body: &'tcx hir::Expr<'tcx>,
+    pub body: &'tcx Expr<'tcx>,
     /// Compare this against `hir::Destination.target`
     pub loop_id: HirId,
     /// entire `for` loop span
@@ -30,13 +30,13 @@ pub struct ForLoop<'tcx> {
 impl<'tcx> ForLoop<'tcx> {
     /// Parses a desugared `for` loop
     pub fn hir(expr: &Expr<'tcx>) -> Option<Self> {
-        if let hir::ExprKind::DropTemps(e) = expr.kind
-            && let hir::ExprKind::Match(iterexpr, [arm], hir::MatchSource::ForLoopDesugar) = e.kind
-            && let hir::ExprKind::Call(_, [arg]) = iterexpr.kind
-            && let hir::ExprKind::Loop(block, ..) = arm.body.kind
+        if let ExprKind::DropTemps(e) = expr.kind
+            && let ExprKind::Match(iterexpr, [arm], MatchSource::ForLoopDesugar) = e.kind
+            && let ExprKind::Call(_, [arg]) = iterexpr.kind
+            && let ExprKind::Loop(block, ..) = arm.body.kind
             && let [stmt] = block.stmts
             && let hir::StmtKind::Expr(e) = stmt.kind
-            && let hir::ExprKind::Match(_, [_, some_arm], _) = e.kind
+            && let ExprKind::Match(_, [_, some_arm], _) = e.kind
             && let hir::PatKind::Struct(_, [field], _) = some_arm.pat.kind
         {
             return Some(Self {
@@ -209,28 +209,28 @@ impl<'hir> IfOrIfLet<'hir> {
 #[derive(Debug, Copy, Clone)]
 pub struct Range<'a> {
     /// The lower bound of the range, or `None` for ranges such as `..X`.
-    pub start: Option<&'a hir::Expr<'a>>,
+    pub start: Option<&'a Expr<'a>>,
     /// The upper bound of the range, or `None` for ranges such as `X..`.
-    pub end: Option<&'a hir::Expr<'a>>,
+    pub end: Option<&'a Expr<'a>>,
     /// Whether the interval is open or closed.
     pub limits: ast::RangeLimits,
 }
 
 impl<'a> Range<'a> {
     /// Higher a `hir` range to something similar to `ast::ExprKind::Range`.
-    pub fn hir(expr: &'a hir::Expr<'_>) -> Option<Range<'a>> {
+    pub fn hir(expr: &'a Expr<'_>) -> Option<Range<'a>> {
         /// Finds the field named `name` in the field. Always return `Some` for
         /// convenience.
-        fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c hir::Expr<'c>> {
+        fn get_field<'c>(name: &str, fields: &'c [hir::ExprField<'_>]) -> Option<&'c Expr<'c>> {
             let expr = &fields.iter().find(|field| field.ident.name.as_str() == name)?.expr;
             Some(expr)
         }
 
         match expr.kind {
-            hir::ExprKind::Call(path, args)
+            ExprKind::Call(path, args)
                 if matches!(
                     path.kind,
-                    hir::ExprKind::Path(hir::QPath::LangItem(hir::LangItem::RangeInclusiveNew, ..))
+                    ExprKind::Path(QPath::LangItem(hir::LangItem::RangeInclusiveNew, ..))
                 ) =>
             {
                 Some(Range {
@@ -239,28 +239,28 @@ impl<'a> Range<'a> {
                     limits: ast::RangeLimits::Closed,
                 })
             },
-            hir::ExprKind::Struct(path, fields, None) => match &path {
-                hir::QPath::LangItem(hir::LangItem::RangeFull, ..) => Some(Range {
+            ExprKind::Struct(path, fields, None) => match &path {
+                QPath::LangItem(hir::LangItem::RangeFull, ..) => Some(Range {
                     start: None,
                     end: None,
                     limits: ast::RangeLimits::HalfOpen,
                 }),
-                hir::QPath::LangItem(hir::LangItem::RangeFrom, ..) => Some(Range {
+                QPath::LangItem(hir::LangItem::RangeFrom, ..) => Some(Range {
                     start: Some(get_field("start", fields)?),
                     end: None,
                     limits: ast::RangeLimits::HalfOpen,
                 }),
-                hir::QPath::LangItem(hir::LangItem::Range, ..) => Some(Range {
+                QPath::LangItem(hir::LangItem::Range, ..) => Some(Range {
                     start: Some(get_field("start", fields)?),
                     end: Some(get_field("end", fields)?),
                     limits: ast::RangeLimits::HalfOpen,
                 }),
-                hir::QPath::LangItem(hir::LangItem::RangeToInclusive, ..) => Some(Range {
+                QPath::LangItem(hir::LangItem::RangeToInclusive, ..) => Some(Range {
                     start: None,
                     end: Some(get_field("end", fields)?),
                     limits: ast::RangeLimits::Closed,
                 }),
-                hir::QPath::LangItem(hir::LangItem::RangeTo, ..) => Some(Range {
+                QPath::LangItem(hir::LangItem::RangeTo, ..) => Some(Range {
                     start: None,
                     end: Some(get_field("end", fields)?),
                     limits: ast::RangeLimits::HalfOpen,
@@ -275,17 +275,17 @@ impl<'a> Range<'a> {
 /// Represents the pre-expansion arguments of a `vec!` invocation.
 pub enum VecArgs<'a> {
     /// `vec![elem; len]`
-    Repeat(&'a hir::Expr<'a>, &'a hir::Expr<'a>),
+    Repeat(&'a Expr<'a>, &'a Expr<'a>),
     /// `vec![a, b, c]`
-    Vec(&'a [hir::Expr<'a>]),
+    Vec(&'a [Expr<'a>]),
 }
 
 impl<'a> VecArgs<'a> {
     /// Returns the arguments of the `vec!` macro if this expression was expanded
     /// from `vec!`.
-    pub fn hir(cx: &LateContext<'_>, expr: &'a hir::Expr<'_>) -> Option<VecArgs<'a>> {
-        if let hir::ExprKind::Call(fun, args) = expr.kind
-            && let hir::ExprKind::Path(ref qpath) = fun.kind
+    pub fn hir(cx: &LateContext<'_>, expr: &'a Expr<'_>) -> Option<VecArgs<'a>> {
+        if let ExprKind::Call(fun, args) = expr.kind
+            && let ExprKind::Path(ref qpath) = fun.kind
             && is_expn_of(fun.span, "vec").is_some()
             && let Some(fun_def_id) = cx.qpath_res(qpath, fun.hir_id).opt_def_id()
         {
@@ -294,8 +294,8 @@ impl<'a> VecArgs<'a> {
                 Some(VecArgs::Repeat(&args[0], &args[1]))
             } else if match_def_path(cx, fun_def_id, &paths::SLICE_INTO_VEC) && args.len() == 1 {
                 // `vec![a, b, c]` case
-                if let hir::ExprKind::Call(_, [arg]) = &args[0].kind
-                    && let hir::ExprKind::Array(args) = arg.kind
+                if let ExprKind::Call(_, [arg]) = &args[0].kind
+                    && let ExprKind::Array(args) = arg.kind
                 {
                     Some(VecArgs::Vec(args))
                 } else {
diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs
index 7a4eba9790e..f8bbe997774 100644
--- a/src/tools/clippy/clippy_utils/src/hir_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs
@@ -954,8 +954,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> {
                     self.hash_pat(pat);
                 }
             },
-            PatKind::Box(pat) => self.hash_pat(pat),
-            PatKind::Deref(pat) => self.hash_pat(pat),
+            PatKind::Box(pat) | PatKind::Deref(pat) => self.hash_pat(pat),
             PatKind::Lit(expr) => self.hash_expr(expr),
             PatKind::Or(pats) => {
                 for pat in pats {
diff --git a/src/tools/clippy/clippy_utils/src/lib.rs b/src/tools/clippy/clippy_utils/src/lib.rs
index 95bab5801d1..37c12dd850c 100644
--- a/src/tools/clippy/clippy_utils/src/lib.rs
+++ b/src/tools/clippy/clippy_utils/src/lib.rs
@@ -16,12 +16,14 @@
     rustc::diagnostic_outside_of_impl,
     rustc::untranslatable_diagnostic
 )]
-// warn on the same lints as `clippy_lints`
-#![warn(trivial_casts, trivial_numeric_casts)]
-// warn on lints, that are included in `rust-lang/rust`s bootstrap
-#![warn(rust_2018_idioms, unused_lifetimes)]
-// warn on rustc internal lints
-#![warn(rustc::internal)]
+#![warn(
+    trivial_casts,
+    trivial_numeric_casts,
+    rust_2018_idioms,
+    unused_lifetimes,
+    unused_qualifications,
+    rustc::internal
+)]
 
 // FIXME: switch to something more ergonomic here, once available.
 // (Currently there is no way to opt into sysroot crates without `extern crate`.)
@@ -99,8 +101,8 @@ use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
 use rustc_hir::{
     self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, ByRef, Closure, Destination, Expr,
     ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item,
-    ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy,
-    QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
+    ItemKind, LangItem, LetStmt, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment,
+    PrimTy, QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
 };
 use rustc_lexer::{tokenize, TokenKind};
 use rustc_lint::{LateContext, Level, Lint, LintContext};
@@ -297,9 +299,10 @@ pub fn is_ty_alias(qpath: &QPath<'_>) -> bool {
 /// Checks if the method call given in `expr` belongs to the given trait.
 /// This is a deprecated function, consider using [`is_trait_method`].
 pub fn match_trait_method(cx: &LateContext<'_>, expr: &Expr<'_>, path: &[&str]) -> bool {
-    let def_id = cx.typeck_results().type_dependent_def_id(expr.hir_id).unwrap();
-    let trt_id = cx.tcx.trait_of_item(def_id);
-    trt_id.map_or(false, |trt_id| match_def_path(cx, trt_id, path))
+    cx.typeck_results()
+        .type_dependent_def_id(expr.hir_id)
+        .and_then(|defid| cx.tcx.trait_of_item(defid))
+        .map_or(false, |trt_id| match_def_path(cx, trt_id, path))
 }
 
 /// Checks if a method is defined in an impl of a diagnostic item
@@ -348,7 +351,7 @@ pub fn is_def_id_trait_method(cx: &LateContext<'_>, def_id: LocalDefId) -> bool
 /// refers to an item of the trait `Default`, which is associated with the
 /// `diag_item` of `sym::Default`.
 pub fn is_trait_item(cx: &LateContext<'_>, expr: &Expr<'_>, diag_item: Symbol) -> bool {
-    if let hir::ExprKind::Path(ref qpath) = expr.kind {
+    if let ExprKind::Path(ref qpath) = expr.kind {
         cx.qpath_res(qpath, expr.hir_id)
             .opt_def_id()
             .map_or(false, |def_id| is_diag_trait_item(cx, def_id, diag_item))
@@ -722,8 +725,8 @@ pub fn trait_ref_of_method<'tcx>(cx: &LateContext<'tcx>, def_id: LocalDefId) ->
     let hir_id = cx.tcx.local_def_id_to_hir_id(def_id);
     let parent_impl = cx.tcx.hir().get_parent_item(hir_id);
     if parent_impl != hir::CRATE_OWNER_ID
-        && let hir::Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id)
-        && let hir::ItemKind::Impl(impl_) = &item.kind
+        && let Node::Item(item) = cx.tcx.hir_node_by_def_id(parent_impl.def_id)
+        && let ItemKind::Impl(impl_) = &item.kind
     {
         return impl_.of_trait.as_ref();
     }
@@ -829,7 +832,7 @@ fn is_default_equivalent_ctor(cx: &LateContext<'_>, def_id: DefId, path: &QPath<
 
 /// Returns true if the expr is equal to `Default::default` when evaluated.
 pub fn is_default_equivalent_call(cx: &LateContext<'_>, repl_func: &Expr<'_>) -> bool {
-    if let hir::ExprKind::Path(ref repl_func_qpath) = repl_func.kind
+    if let ExprKind::Path(ref repl_func_qpath) = repl_func.kind
         && let Some(repl_def_id) = cx.qpath_res(repl_func_qpath, repl_func.hir_id).opt_def_id()
         && (is_diag_trait_item(cx, repl_def_id, sym::Default)
             || is_default_equivalent_ctor(cx, repl_def_id, repl_func_qpath))
@@ -1295,7 +1298,7 @@ pub fn contains_name<'tcx>(name: Symbol, expr: &'tcx Expr<'_>, cx: &LateContext<
 /// Returns `true` if `expr` contains a return expression
 pub fn contains_return<'tcx>(expr: impl Visitable<'tcx>) -> bool {
     for_each_expr(expr, |e| {
-        if matches!(e.kind, hir::ExprKind::Ret(..)) {
+        if matches!(e.kind, ExprKind::Ret(..)) {
             ControlFlow::Break(())
         } else {
             ControlFlow::Continue(())
@@ -1311,7 +1314,7 @@ pub fn get_parent_expr<'tcx>(cx: &LateContext<'tcx>, e: &Expr<'_>) -> Option<&'t
 
 /// This retrieves the parent for the given `HirId` if it's an expression. This is useful for
 /// constraint lints
-pub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: hir::HirId) -> Option<&'tcx Expr<'tcx>> {
+pub fn get_parent_expr_for_hir<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<'tcx>> {
     match cx.tcx.parent_hir_node(hir_id) {
         Node::Expr(parent) => Some(parent),
         _ => None,
@@ -1635,13 +1638,13 @@ pub fn is_direct_expn_of(span: Span, name: &str) -> Option<Span> {
 }
 
 /// Convenience function to get the return type of a function.
-pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId) -> Ty<'tcx> {
+pub fn return_ty<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId) -> Ty<'tcx> {
     let ret_ty = cx.tcx.fn_sig(fn_def_id).instantiate_identity().output();
     cx.tcx.instantiate_bound_regions_with_erased(ret_ty)
 }
 
 /// Convenience function to get the nth argument type of a function.
-pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: hir::OwnerId, nth: usize) -> Ty<'tcx> {
+pub fn nth_arg<'tcx>(cx: &LateContext<'tcx>, fn_def_id: OwnerId, nth: usize) -> Ty<'tcx> {
     let arg = cx.tcx.fn_sig(fn_def_id).instantiate_identity().input(nth);
     cx.tcx.instantiate_bound_regions_with_erased(arg)
 }
@@ -1652,8 +1655,8 @@ pub fn is_ctor_or_promotable_const_function(cx: &LateContext<'_>, expr: &Expr<'_
         if let ExprKind::Path(ref qp) = fun.kind {
             let res = cx.qpath_res(qp, fun.hir_id);
             return match res {
-                def::Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
-                def::Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
+                Res::Def(DefKind::Variant | DefKind::Ctor(..), ..) => true,
+                Res::Def(_, def_id) => cx.tcx.is_promotable_const_fn(def_id),
                 _ => false,
             };
         }
@@ -1667,7 +1670,7 @@ pub fn is_refutable(cx: &LateContext<'_>, pat: &Pat<'_>) -> bool {
     fn is_enum_variant(cx: &LateContext<'_>, qpath: &QPath<'_>, id: HirId) -> bool {
         matches!(
             cx.qpath_res(qpath, id),
-            def::Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _)
+            Res::Def(DefKind::Variant, ..) | Res::Def(DefKind::Ctor(def::CtorOf::Variant, _), _)
         )
     }
 
@@ -1823,26 +1826,26 @@ pub fn strip_pat_refs<'hir>(mut pat: &'hir Pat<'hir>) -> &'hir Pat<'hir> {
     pat
 }
 
-pub fn int_bits(tcx: TyCtxt<'_>, ity: rustc_ty::IntTy) -> u64 {
+pub fn int_bits(tcx: TyCtxt<'_>, ity: IntTy) -> u64 {
     Integer::from_int_ty(&tcx, ity).size().bits()
 }
 
 #[expect(clippy::cast_possible_wrap)]
 /// Turn a constant int byte representation into an i128
-pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: rustc_ty::IntTy) -> i128 {
+pub fn sext(tcx: TyCtxt<'_>, u: u128, ity: IntTy) -> i128 {
     let amt = 128 - int_bits(tcx, ity);
     ((u as i128) << amt) >> amt
 }
 
 #[expect(clippy::cast_sign_loss)]
 /// clip unused bytes
-pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: rustc_ty::IntTy) -> u128 {
+pub fn unsext(tcx: TyCtxt<'_>, u: i128, ity: IntTy) -> u128 {
     let amt = 128 - int_bits(tcx, ity);
     ((u as u128) << amt) >> amt
 }
 
 /// clip unused bytes
-pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: rustc_ty::UintTy) -> u128 {
+pub fn clip(tcx: TyCtxt<'_>, u: u128, ity: UintTy) -> u128 {
     let bits = Integer::from_uint_ty(&tcx, ity).size().bits();
     let amt = 128 - bits;
     (u << amt) >> amt
@@ -2007,7 +2010,7 @@ pub fn is_must_use_func_call(cx: &LateContext<'_>, expr: &Expr<'_>) -> bool {
     let did = match expr.kind {
         ExprKind::Call(path, _) => {
             if let ExprKind::Path(ref qpath) = path.kind
-                && let def::Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id)
+                && let Res::Def(_, did) = cx.qpath_res(qpath, path.hir_id)
             {
                 Some(did)
             } else {
@@ -2218,7 +2221,7 @@ pub fn is_no_core_crate(cx: &LateContext<'_>) -> bool {
 /// ```
 pub fn is_trait_impl_item(cx: &LateContext<'_>, hir_id: HirId) -> bool {
     if let Node::Item(item) = cx.tcx.parent_hir_node(hir_id) {
-        matches!(item.kind, ItemKind::Impl(hir::Impl { of_trait: Some(_), .. }))
+        matches!(item.kind, ItemKind::Impl(Impl { of_trait: Some(_), .. }))
     } else {
         false
     }
@@ -2254,7 +2257,7 @@ pub fn fn_def_id(cx: &LateContext<'_>, expr: &Expr<'_>) -> Option<DefId> {
 pub fn fn_def_id_with_node_args<'tcx>(
     cx: &LateContext<'tcx>,
     expr: &Expr<'_>,
-) -> Option<(DefId, rustc_ty::GenericArgsRef<'tcx>)> {
+) -> Option<(DefId, GenericArgsRef<'tcx>)> {
     let typeck = cx.typeck_results();
     match &expr.kind {
         ExprKind::MethodCall(..) => Some((
@@ -2500,7 +2503,7 @@ fn with_test_item_names(tcx: TyCtxt<'_>, module: LocalModDefId, f: impl Fn(&[Sym
 /// Checks if the function containing the given `HirId` is a `#[test]` function
 ///
 /// Note: Add `//@compile-flags: --test` to UI tests with a `#[test]` function
-pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
+pub fn is_in_test_function(tcx: TyCtxt<'_>, id: HirId) -> bool {
     with_test_item_names(tcx, tcx.parent_module(id), |names| {
         tcx.hir()
             .parent_iter(id)
@@ -2523,7 +2526,7 @@ pub fn is_in_test_function(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
 ///
 /// This only checks directly applied attributes, to see if a node is inside a `#[cfg(test)]` parent
 /// use [`is_in_cfg_test`]
-pub fn is_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
+pub fn is_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
     tcx.hir().attrs(id).iter().any(|attr| {
         if attr.has_name(sym::cfg)
             && let Some(items) = attr.meta_item_list()
@@ -2538,7 +2541,7 @@ pub fn is_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
 }
 
 /// Checks if any parent node of `HirId` has `#[cfg(test)]` attribute applied
-pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: hir::HirId) -> bool {
+pub fn is_in_cfg_test(tcx: TyCtxt<'_>, id: HirId) -> bool {
     tcx.hir()
         .parent_id_iter(id)
         .any(|parent_id| is_cfg_test(tcx, parent_id))
@@ -3333,3 +3336,12 @@ fn maybe_get_relative_path(from: &DefPath, to: &DefPath, max_super: usize) -> St
         repeat(String::from("super")).take(go_up_by).chain(path).join("::")
     }
 }
+
+/// Returns true if the specified `HirId` is the top-level expression of a statement or the only
+/// expression in a block.
+pub fn is_parent_stmt(cx: &LateContext<'_>, id: HirId) -> bool {
+    matches!(
+        cx.tcx.parent_hir_node(id),
+        Node::Stmt(..) | Node::Block(Block { stmts: &[], .. })
+    )
+}
diff --git a/src/tools/clippy/clippy_utils/src/macros.rs b/src/tools/clippy/clippy_utils/src/macros.rs
index c475e7b7c43..f166087dc3c 100644
--- a/src/tools/clippy/clippy_utils/src/macros.rs
+++ b/src/tools/clippy/clippy_utils/src/macros.rs
@@ -429,7 +429,7 @@ pub fn find_format_args(cx: &LateContext<'_>, start: &Expr<'_>, expn_id: ExpnId)
 pub fn find_format_arg_expr<'hir, 'ast>(
     start: &'hir Expr<'hir>,
     target: &'ast FormatArgument,
-) -> Result<&'hir rustc_hir::Expr<'hir>, &'ast rustc_ast::Expr> {
+) -> Result<&'hir Expr<'hir>, &'ast rustc_ast::Expr> {
     let SpanData {
         lo,
         hi,
diff --git a/src/tools/clippy/clippy_utils/src/mir/mod.rs b/src/tools/clippy/clippy_utils/src/mir/mod.rs
index 9dbb4c68d13..e4966690d8c 100644
--- a/src/tools/clippy/clippy_utils/src/mir/mod.rs
+++ b/src/tools/clippy/clippy_utils/src/mir/mod.rs
@@ -111,7 +111,7 @@ pub fn block_in_cycle(body: &Body<'_>, block: BasicBlock) -> bool {
 }
 
 /// Convenience wrapper around `visit_local_usage`.
-pub fn used_exactly_once(mir: &Body<'_>, local: rustc_middle::mir::Local) -> Option<bool> {
+pub fn used_exactly_once(mir: &Body<'_>, local: Local) -> Option<bool> {
     visit_local_usage(
         &[local],
         mir,
diff --git a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
index 12b08005997..325c9bee057 100644
--- a/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
+++ b/src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs
@@ -149,7 +149,7 @@ fn check_rvalue<'tcx>(
                 Err((span, "unsizing casts are not allowed in const fn".into()))
             }
         },
-        Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => {
+        Rvalue::Cast(CastKind::PointerExposeProvenance, _, _) => {
             Err((span, "casting pointers to ints is unstable in const fn".into()))
         },
         Rvalue::Cast(CastKind::DynStar, _, _) => {
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index 5090d0bd98b..8d6057272c4 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -41,7 +41,7 @@ pub const ONE: Sugg<'static> = Sugg::NonParen(Cow::Borrowed("1"));
 pub const EMPTY: Sugg<'static> = Sugg::NonParen(Cow::Borrowed(""));
 
 impl Display for Sugg<'_> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
         match *self {
             Sugg::NonParen(ref s) | Sugg::MaybeParen(ref s) => s.fmt(f),
             Sugg::BinOp(op, ref lhs, ref rhs) => binop_to_string(op, lhs, rhs).fmt(f),
@@ -124,48 +124,48 @@ impl<'a> Sugg<'a> {
         }
 
         match expr.kind {
-            hir::ExprKind::AddrOf(..)
-            | hir::ExprKind::If(..)
-            | hir::ExprKind::Let(..)
-            | hir::ExprKind::Closure { .. }
-            | hir::ExprKind::Unary(..)
-            | hir::ExprKind::Match(..) => Sugg::MaybeParen(get_snippet(expr.span)),
-            hir::ExprKind::Continue(..)
-            | hir::ExprKind::Yield(..)
-            | hir::ExprKind::Array(..)
-            | hir::ExprKind::Block(..)
-            | hir::ExprKind::Break(..)
-            | hir::ExprKind::Call(..)
-            | hir::ExprKind::Field(..)
-            | hir::ExprKind::Index(..)
-            | hir::ExprKind::InlineAsm(..)
-            | hir::ExprKind::OffsetOf(..)
-            | hir::ExprKind::ConstBlock(..)
-            | hir::ExprKind::Lit(..)
-            | hir::ExprKind::Loop(..)
-            | hir::ExprKind::MethodCall(..)
-            | hir::ExprKind::Path(..)
-            | hir::ExprKind::Repeat(..)
-            | hir::ExprKind::Ret(..)
-            | hir::ExprKind::Become(..)
-            | hir::ExprKind::Struct(..)
-            | hir::ExprKind::Tup(..)
-            | hir::ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)),
-            hir::ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet),
-            hir::ExprKind::Assign(lhs, rhs, _) => {
+            ExprKind::AddrOf(..)
+            | ExprKind::If(..)
+            | ExprKind::Let(..)
+            | ExprKind::Closure { .. }
+            | ExprKind::Unary(..)
+            | ExprKind::Match(..) => Sugg::MaybeParen(get_snippet(expr.span)),
+            ExprKind::Continue(..)
+            | ExprKind::Yield(..)
+            | ExprKind::Array(..)
+            | ExprKind::Block(..)
+            | ExprKind::Break(..)
+            | ExprKind::Call(..)
+            | ExprKind::Field(..)
+            | ExprKind::Index(..)
+            | ExprKind::InlineAsm(..)
+            | ExprKind::OffsetOf(..)
+            | ExprKind::ConstBlock(..)
+            | ExprKind::Lit(..)
+            | ExprKind::Loop(..)
+            | ExprKind::MethodCall(..)
+            | ExprKind::Path(..)
+            | ExprKind::Repeat(..)
+            | ExprKind::Ret(..)
+            | ExprKind::Become(..)
+            | ExprKind::Struct(..)
+            | ExprKind::Tup(..)
+            | ExprKind::Err(_) => Sugg::NonParen(get_snippet(expr.span)),
+            ExprKind::DropTemps(inner) => Self::hir_from_snippet(inner, get_snippet),
+            ExprKind::Assign(lhs, rhs, _) => {
                 Sugg::BinOp(AssocOp::Assign, get_snippet(lhs.span), get_snippet(rhs.span))
             },
-            hir::ExprKind::AssignOp(op, lhs, rhs) => {
+            ExprKind::AssignOp(op, lhs, rhs) => {
                 Sugg::BinOp(hirbinop2assignop(op), get_snippet(lhs.span), get_snippet(rhs.span))
             },
-            hir::ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp(
+            ExprKind::Binary(op, lhs, rhs) => Sugg::BinOp(
                 AssocOp::from_ast_binop(op.node),
                 get_snippet(lhs.span),
                 get_snippet(rhs.span),
             ),
-            hir::ExprKind::Cast(lhs, ty) |
+            ExprKind::Cast(lhs, ty) |
             //FIXME(chenyukang), remove this after type ascription is removed from AST
-            hir::ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)),
+            ExprKind::Type(lhs, ty) => Sugg::BinOp(AssocOp::As, get_snippet(lhs.span), get_snippet(ty.span)),
         }
     }
 
@@ -358,6 +358,13 @@ impl<'a> Sugg<'a> {
             },
         }
     }
+
+    pub fn into_string(self) -> String {
+        match self {
+            Sugg::NonParen(p) | Sugg::MaybeParen(p) => p.into_owned(),
+            Sugg::BinOp(b, l, r) => binop_to_string(b, &l, &r),
+        }
+    }
 }
 
 /// Generates a string from the operator and both sides.
@@ -508,7 +515,7 @@ impl<T> ParenHelper<T> {
 }
 
 impl<T: Display> Display for ParenHelper<T> {
-    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<(), fmt::Error> {
         if self.paren {
             write!(f, "({})", self.wrapped)
         } else {
@@ -801,7 +808,7 @@ pub struct DerefClosure {
 ///
 /// note: this only works on single line immutable closures with exactly one input parameter.
 pub fn deref_closure_args(cx: &LateContext<'_>, closure: &hir::Expr<'_>) -> Option<DerefClosure> {
-    if let hir::ExprKind::Closure(&Closure {
+    if let ExprKind::Closure(&Closure {
         fn_decl, def_id, body, ..
     }) = closure.kind
     {
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index 97ce755adbb..ab1be66dc78 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -91,12 +91,16 @@ pub fn contains_ty_adt_constructor_opaque<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'
                     return true;
                 }
 
-                if let ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) = *inner_ty.kind() {
+                if let ty::Alias(ty::Opaque, AliasTy { def_id, .. }) = *inner_ty.kind() {
                     if !seen.insert(def_id) {
                         return false;
                     }
 
-                    for (predicate, _span) in cx.tcx.explicit_item_super_predicates(def_id).instantiate_identity_iter_copied() {
+                    for (predicate, _span) in cx
+                        .tcx
+                        .explicit_item_super_predicates(def_id)
+                        .instantiate_identity_iter_copied()
+                    {
                         match predicate.kind().skip_binder() {
                             // For `impl Trait<U>`, it will register a predicate of `T: Trait<U>`, so we go through
                             // and check substitutions to find `U`.
@@ -159,6 +163,16 @@ pub fn get_type_diagnostic_name(cx: &LateContext<'_>, ty: Ty<'_>) -> Option<Symb
     }
 }
 
+/// Returns true if `ty` is a type on which calling `Clone` through a function instead of
+/// as a method, such as `Arc::clone()` is considered idiomatic. Lints should avoid suggesting to
+/// replace instances of `ty::Clone()` by `.clone()` for objects of those types.
+pub fn should_call_clone_as_function(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
+    matches!(
+        get_type_diagnostic_name(cx, ty),
+        Some(sym::Arc | sym::ArcWeak | sym::Rc | sym::RcWeak)
+    )
+}
+
 /// Returns true if ty has `iter` or `iter_mut` methods
 pub fn has_iter_method(cx: &LateContext<'_>, probably_ref_ty: Ty<'_>) -> Option<Symbol> {
     // FIXME: instead of this hard-coded list, we should check if `<adt>::iter`
@@ -301,7 +315,7 @@ pub fn implements_trait_with_env_from_iter<'tcx>(
         cause: ObligationCause::dummy(),
         param_env,
         recursion_depth: 0,
-        predicate: ty::Binder::dummy(trait_ref).to_predicate(tcx),
+        predicate: Binder::dummy(trait_ref).to_predicate(tcx),
     };
     infcx
         .evaluate_obligation(&obligation)
@@ -327,7 +341,7 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
             is_must_use_ty(cx, *ty)
         },
         ty::Tuple(args) => args.iter().any(|ty| is_must_use_ty(cx, ty)),
-        ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }) => {
+        ty::Alias(ty::Opaque, AliasTy { def_id, .. }) => {
             for (predicate, _) in cx.tcx.explicit_item_super_predicates(def_id).skip_binder() {
                 if let ty::ClauseKind::Trait(trait_predicate) = predicate.kind().skip_binder() {
                     if cx.tcx.has_attr(trait_predicate.trait_ref.def_id, sym::must_use) {
@@ -356,13 +370,13 @@ pub fn is_must_use_ty<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> bool {
 // not succeed
 /// Checks if `Ty` is normalizable. This function is useful
 /// to avoid crashes on `layout_of`.
-pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
+pub fn is_normalizable<'tcx>(cx: &LateContext<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
     is_normalizable_helper(cx, param_env, ty, &mut FxHashMap::default())
 }
 
 fn is_normalizable_helper<'tcx>(
     cx: &LateContext<'tcx>,
-    param_env: ty::ParamEnv<'tcx>,
+    param_env: ParamEnv<'tcx>,
     ty: Ty<'tcx>,
     cache: &mut FxHashMap<Ty<'tcx>, bool>,
 ) -> bool {
@@ -372,7 +386,7 @@ fn is_normalizable_helper<'tcx>(
     // prevent recursive loops, false-negative is better than endless loop leading to stack overflow
     cache.insert(ty, false);
     let infcx = cx.tcx.infer_ctxt().build();
-    let cause = rustc_middle::traits::ObligationCause::dummy();
+    let cause = ObligationCause::dummy();
     let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
         match ty.kind() {
             ty::Adt(def, args) => def.variants().iter().all(|variant| {
@@ -446,7 +460,7 @@ pub fn is_type_diagnostic_item(cx: &LateContext<'_>, ty: Ty<'_>, diag_item: Symb
 /// Checks if the type is equal to a lang item.
 ///
 /// Returns `false` if the `LangItem` is not defined.
-pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: hir::LangItem) -> bool {
+pub fn is_type_lang_item(cx: &LateContext<'_>, ty: Ty<'_>, lang_item: LangItem) -> bool {
     match ty.kind() {
         ty::Adt(adt, _) => cx.tcx.lang_items().get(lang_item) == Some(adt.did()),
         _ => false,
@@ -726,7 +740,7 @@ pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'t
             Some(ExprFnSig::Closure(decl, subs.as_closure().sig()))
         },
         ty::FnDef(id, subs) => Some(ExprFnSig::Sig(cx.tcx.fn_sig(id).instantiate(cx.tcx, subs), Some(id))),
-        ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) => sig_from_bounds(
+        ty::Alias(ty::Opaque, AliasTy { def_id, args, .. }) => sig_from_bounds(
             cx,
             ty,
             cx.tcx.item_super_predicates(def_id).iter_instantiated(cx.tcx, args),
@@ -807,7 +821,7 @@ fn sig_for_projection<'tcx>(cx: &LateContext<'tcx>, ty: AliasTy<'tcx>) -> Option
 
     for (pred, _) in cx
         .tcx
-        .explicit_item_super_predicates(ty.def_id)
+        .explicit_item_bounds(ty.def_id)
         .iter_instantiated_copied(cx.tcx, ty.args)
     {
         match pred.kind().skip_binder() {
@@ -899,7 +913,7 @@ pub fn is_c_void(cx: &LateContext<'_>, ty: Ty<'_>) -> bool {
     if let ty::Adt(adt, _) = ty.kind()
         && let &[krate, .., name] = &*cx.get_def_path(adt.did())
         && let sym::libc | sym::core | sym::std = krate
-        && name == rustc_span::sym::c_void
+        && name == sym::c_void
     {
         true
     } else {
@@ -1134,7 +1148,7 @@ pub fn make_projection<'tcx>(
         #[cfg(debug_assertions)]
         assert_generic_args_match(tcx, assoc_item.def_id, args);
 
-        Some(ty::AliasTy::new(tcx, assoc_item.def_id, args))
+        Some(AliasTy::new(tcx, assoc_item.def_id, args))
     }
     helper(
         tcx,
@@ -1251,7 +1265,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
             );
             return None;
         }
-        let cause = rustc_middle::traits::ObligationCause::dummy();
+        let cause = ObligationCause::dummy();
         match tcx
             .infer_ctxt()
             .build()
@@ -1269,7 +1283,7 @@ pub fn make_normalized_projection_with_regions<'tcx>(
 }
 
 pub fn normalize_with_regions<'tcx>(tcx: TyCtxt<'tcx>, param_env: ParamEnv<'tcx>, ty: Ty<'tcx>) -> Ty<'tcx> {
-    let cause = rustc_middle::traits::ObligationCause::dummy();
+    let cause = ObligationCause::dummy();
     match tcx.infer_ctxt().build().at(&cause, param_env).query_normalize(ty) {
         Ok(ty) => ty.value,
         Err(_) => ty,
diff --git a/src/tools/clippy/clippy_utils/src/usage.rs b/src/tools/clippy/clippy_utils/src/usage.rs
index ec131c7f6a3..a145920aa85 100644
--- a/src/tools/clippy/clippy_utils/src/usage.rs
+++ b/src/tools/clippy/clippy_utils/src/usage.rs
@@ -83,15 +83,15 @@ impl<'tcx> Delegate<'tcx> for MutVarsDelegate {
         self.update(cmt);
     }
 
-    fn fake_read(&mut self, _: &rustc_hir_typeck::expr_use_visitor::PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
+    fn fake_read(&mut self, _: &PlaceWithHirId<'tcx>, _: FakeReadCause, _: HirId) {}
 }
 
 pub struct ParamBindingIdCollector {
-    pub binding_hir_ids: Vec<hir::HirId>,
+    pub binding_hir_ids: Vec<HirId>,
 }
 impl<'tcx> ParamBindingIdCollector {
-    fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec<hir::HirId> {
-        let mut hir_ids: Vec<hir::HirId> = Vec::new();
+    fn collect_binding_hir_ids(body: &'tcx hir::Body<'tcx>) -> Vec<HirId> {
+        let mut hir_ids: Vec<HirId> = Vec::new();
         for param in body.params {
             let mut finder = ParamBindingIdCollector {
                 binding_hir_ids: Vec::new(),
@@ -104,7 +104,7 @@ impl<'tcx> ParamBindingIdCollector {
         hir_ids
     }
 }
-impl<'tcx> intravisit::Visitor<'tcx> for ParamBindingIdCollector {
+impl<'tcx> Visitor<'tcx> for ParamBindingIdCollector {
     fn visit_pat(&mut self, pat: &'tcx hir::Pat<'tcx>) {
         if let hir::PatKind::Binding(_, hir_id, ..) = pat.kind {
             self.binding_hir_ids.push(hir_id);
@@ -115,7 +115,7 @@ impl<'tcx> intravisit::Visitor<'tcx> for ParamBindingIdCollector {
 
 pub struct BindingUsageFinder<'a, 'tcx> {
     cx: &'a LateContext<'tcx>,
-    binding_ids: Vec<hir::HirId>,
+    binding_ids: Vec<HirId>,
     usage_found: bool,
 }
 impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
@@ -129,16 +129,16 @@ impl<'a, 'tcx> BindingUsageFinder<'a, 'tcx> {
         finder.usage_found
     }
 }
-impl<'a, 'tcx> intravisit::Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
+impl<'a, 'tcx> Visitor<'tcx> for BindingUsageFinder<'a, 'tcx> {
     type NestedFilter = nested_filter::OnlyBodies;
 
-    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) {
+    fn visit_expr(&mut self, expr: &'tcx Expr<'tcx>) {
         if !self.usage_found {
             intravisit::walk_expr(self, expr);
         }
     }
 
-    fn visit_path(&mut self, path: &hir::Path<'tcx>, _: hir::HirId) {
+    fn visit_path(&mut self, path: &hir::Path<'tcx>, _: HirId) {
         if let Res::Local(id) = path.res {
             if self.binding_ids.contains(&id) {
                 self.usage_found = true;
diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs
index 0a05ac029ea..a3f3b32ed37 100644
--- a/src/tools/clippy/clippy_utils/src/visitors.rs
+++ b/src/tools/clippy/clippy_utils/src/visitors.rs
@@ -180,9 +180,9 @@ pub fn for_each_expr_with_closures<'tcx, B, C: Continue>(
 }
 
 /// returns `true` if expr contains match expr desugared from try
-fn contains_try(expr: &hir::Expr<'_>) -> bool {
+fn contains_try(expr: &Expr<'_>) -> bool {
     for_each_expr(expr, |e| {
-        if matches!(e.kind, hir::ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) {
+        if matches!(e.kind, ExprKind::Match(_, _, hir::MatchSource::TryDesugar(_))) {
             ControlFlow::Break(())
         } else {
             ControlFlow::Continue(())
@@ -191,9 +191,9 @@ fn contains_try(expr: &hir::Expr<'_>) -> bool {
     .is_some()
 }
 
-pub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir hir::Expr<'hir>, callback: F) -> bool
+pub fn find_all_ret_expressions<'hir, F>(_cx: &LateContext<'_>, expr: &'hir Expr<'hir>, callback: F) -> bool
 where
-    F: FnMut(&'hir hir::Expr<'hir>) -> bool,
+    F: FnMut(&'hir Expr<'hir>) -> bool,
 {
     struct RetFinder<F> {
         in_stmt: bool,
@@ -236,37 +236,37 @@ where
         }
     }
 
-    impl<'hir, F: FnMut(&'hir hir::Expr<'hir>) -> bool> intravisit::Visitor<'hir> for RetFinder<F> {
-        fn visit_stmt(&mut self, stmt: &'hir hir::Stmt<'_>) {
+    impl<'hir, F: FnMut(&'hir Expr<'hir>) -> bool> Visitor<'hir> for RetFinder<F> {
+        fn visit_stmt(&mut self, stmt: &'hir Stmt<'_>) {
             intravisit::walk_stmt(&mut *self.inside_stmt(true), stmt);
         }
 
-        fn visit_expr(&mut self, expr: &'hir hir::Expr<'_>) {
+        fn visit_expr(&mut self, expr: &'hir Expr<'_>) {
             if self.failed {
                 return;
             }
             if self.in_stmt {
                 match expr.kind {
-                    hir::ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr),
-                    _ => intravisit::walk_expr(self, expr),
+                    ExprKind::Ret(Some(expr)) => self.inside_stmt(false).visit_expr(expr),
+                    _ => walk_expr(self, expr),
                 }
             } else {
                 match expr.kind {
-                    hir::ExprKind::If(cond, then, else_opt) => {
+                    ExprKind::If(cond, then, else_opt) => {
                         self.inside_stmt(true).visit_expr(cond);
                         self.visit_expr(then);
                         if let Some(el) = else_opt {
                             self.visit_expr(el);
                         }
                     },
-                    hir::ExprKind::Match(cond, arms, _) => {
+                    ExprKind::Match(cond, arms, _) => {
                         self.inside_stmt(true).visit_expr(cond);
                         for arm in arms {
                             self.visit_expr(arm.body);
                         }
                     },
-                    hir::ExprKind::Block(..) => intravisit::walk_expr(self, expr),
-                    hir::ExprKind::Ret(Some(expr)) => self.visit_expr(expr),
+                    ExprKind::Block(..) => walk_expr(self, expr),
+                    ExprKind::Ret(Some(expr)) => self.visit_expr(expr),
                     _ => self.failed |= !(self.cb)(expr),
                 }
             }
@@ -316,7 +316,7 @@ pub fn is_const_evaluatable<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) ->
         is_const: bool,
     }
     impl<'tcx> Visitor<'tcx> for V<'_, 'tcx> {
-        type NestedFilter = rustc_hir::intravisit::nested_filter::None;
+        type NestedFilter = intravisit::nested_filter::None;
 
         fn visit_expr(&mut self, e: &'tcx Expr<'_>) {
             if !self.is_const {
diff --git a/src/tools/clippy/lintcheck/src/main.rs b/src/tools/clippy/lintcheck/src/main.rs
index 66442998161..4251151c454 100644
--- a/src/tools/clippy/lintcheck/src/main.rs
+++ b/src/tools/clippy/lintcheck/src/main.rs
@@ -5,6 +5,13 @@
 // When a new lint is introduced, we can search the results for new warnings and check for false
 // positives.
 
+#![warn(
+    trivial_casts,
+    trivial_numeric_casts,
+    rust_2018_idioms,
+    unused_lifetimes,
+    unused_qualifications
+)]
 #![allow(clippy::collapsible_else_if)]
 
 mod config;
@@ -189,13 +196,13 @@ impl CrateSource {
                 // don't download/extract if we already have done so
                 if !krate_file_path.is_file() {
                     // create a file path to download and write the crate data into
-                    let mut krate_dest = std::fs::File::create(&krate_file_path).unwrap();
+                    let mut krate_dest = fs::File::create(&krate_file_path).unwrap();
                     let mut krate_req = get(&url).unwrap().into_reader();
                     // copy the crate into the file
-                    std::io::copy(&mut krate_req, &mut krate_dest).unwrap();
+                    io::copy(&mut krate_req, &mut krate_dest).unwrap();
 
                     // unzip the tarball
-                    let ungz_tar = flate2::read::GzDecoder::new(std::fs::File::open(&krate_file_path).unwrap());
+                    let ungz_tar = flate2::read::GzDecoder::new(fs::File::open(&krate_file_path).unwrap());
                     // extract the tar archive
                     let mut archive = tar::Archive::new(ungz_tar);
                     archive.unpack(&extract_dir).expect("Failed to extract!");
@@ -257,7 +264,7 @@ impl CrateSource {
             },
             CrateSource::Path { name, path, options } => {
                 fn is_cache_dir(entry: &DirEntry) -> bool {
-                    std::fs::read(entry.path().join("CACHEDIR.TAG"))
+                    fs::read(entry.path().join("CACHEDIR.TAG"))
                         .map(|x| x.starts_with(b"Signature: 8a477f597d28d172789f06886806bc55"))
                         .unwrap_or(false)
                 }
@@ -268,7 +275,7 @@ impl CrateSource {
                 let dest_crate_root = PathBuf::from(LINTCHECK_SOURCES).join(name);
                 if dest_crate_root.exists() {
                     println!("Deleting existing directory at {dest_crate_root:?}");
-                    std::fs::remove_dir_all(&dest_crate_root).unwrap();
+                    fs::remove_dir_all(&dest_crate_root).unwrap();
                 }
 
                 println!("Copying {path:?} to {dest_crate_root:?}");
@@ -281,9 +288,9 @@ impl CrateSource {
                     let metadata = entry_path.symlink_metadata().unwrap();
 
                     if metadata.is_dir() {
-                        std::fs::create_dir(dest_path).unwrap();
+                        fs::create_dir(dest_path).unwrap();
                     } else if metadata.is_file() {
-                        std::fs::copy(entry_path, dest_path).unwrap();
+                        fs::copy(entry_path, dest_path).unwrap();
                     }
                 }
 
@@ -330,7 +337,7 @@ impl Crate {
             );
         }
 
-        let cargo_clippy_path = std::fs::canonicalize(cargo_clippy_path).unwrap();
+        let cargo_clippy_path = fs::canonicalize(cargo_clippy_path).unwrap();
 
         let shared_target_dir = clippy_project_root().join("target/lintcheck/shared_target_dir");
 
@@ -353,7 +360,7 @@ impl Crate {
             clippy_args.push("--cap-lints=warn");
         } else {
             clippy_args.push("--cap-lints=allow");
-            clippy_args.extend(lint_filter.iter().map(std::string::String::as_str));
+            clippy_args.extend(lint_filter.iter().map(String::as_str));
         }
 
         if let Some(server) = server {
@@ -454,7 +461,7 @@ fn build_clippy() {
 /// Read a `lintcheck_crates.toml` file
 fn read_crates(toml_path: &Path) -> (Vec<CrateSource>, RecursiveOptions) {
     let toml_content: String =
-        std::fs::read_to_string(toml_path).unwrap_or_else(|_| panic!("Failed to read {}", toml_path.display()));
+        fs::read_to_string(toml_path).unwrap_or_else(|_| panic!("Failed to read {}", toml_path.display()));
     let crate_list: SourceList =
         toml::from_str(&toml_content).unwrap_or_else(|e| panic!("Failed to parse {}: \n{e}", toml_path.display()));
     // parse the hashmap of the toml file into a list of crates
@@ -549,7 +556,7 @@ fn main() {
     }
 
     // assert that we launch lintcheck from the repo root (via cargo lintcheck)
-    if std::fs::metadata("lintcheck/Cargo.toml").is_err() {
+    if fs::metadata("lintcheck/Cargo.toml").is_err() {
         eprintln!("lintcheck needs to be run from clippy's repo root!\nUse `cargo lintcheck` alternatively.");
         std::process::exit(3);
     }
@@ -570,7 +577,7 @@ fn main() {
         cargo_clippy_path.display()
     );
 
-    let clippy_ver = std::process::Command::new(&cargo_clippy_path)
+    let clippy_ver = Command::new(&cargo_clippy_path)
         .arg("--version")
         .output()
         .map(|o| String::from_utf8_lossy(&o.stdout).into_owned())
@@ -699,7 +706,7 @@ fn main() {
 
 /// read the previous stats from the lintcheck-log file
 fn read_stats_from_file(file_path: &Path) -> HashMap<String, usize> {
-    let file_content: String = match std::fs::read_to_string(file_path).ok() {
+    let file_content: String = match fs::read_to_string(file_path).ok() {
         Some(content) => content,
         None => {
             return HashMap::new();
@@ -779,17 +786,17 @@ fn print_stats(old_stats: HashMap<String, usize>, new_stats: HashMap<&String, us
 ///
 /// This function panics if creating one of the dirs fails.
 fn create_dirs(krate_download_dir: &Path, extract_dir: &Path) {
-    std::fs::create_dir("target/lintcheck/").unwrap_or_else(|err| {
+    fs::create_dir("target/lintcheck/").unwrap_or_else(|err| {
         assert_eq!(
             err.kind(),
             ErrorKind::AlreadyExists,
             "cannot create lintcheck target dir"
         );
     });
-    std::fs::create_dir(krate_download_dir).unwrap_or_else(|err| {
+    fs::create_dir(krate_download_dir).unwrap_or_else(|err| {
         assert_eq!(err.kind(), ErrorKind::AlreadyExists, "cannot create crate download dir");
     });
-    std::fs::create_dir(extract_dir).unwrap_or_else(|err| {
+    fs::create_dir(extract_dir).unwrap_or_else(|err| {
         assert_eq!(
             err.kind(),
             ErrorKind::AlreadyExists,
@@ -816,7 +823,7 @@ fn lintcheck_test() {
         "--crates-toml",
         "lintcheck/test_sources.toml",
     ];
-    let status = std::process::Command::new(env::var("CARGO").unwrap_or("cargo".into()))
+    let status = Command::new(env::var("CARGO").unwrap_or("cargo".into()))
         .args(args)
         .current_dir("..") // repo root
         .status();
diff --git a/src/tools/clippy/rust-toolchain b/src/tools/clippy/rust-toolchain
index a63e66f3214..b2fe5c8bee7 100644
--- a/src/tools/clippy/rust-toolchain
+++ b/src/tools/clippy/rust-toolchain
@@ -1,3 +1,3 @@
 [toolchain]
-channel = "nightly-2024-03-21"
+channel = "nightly-2024-04-04"
 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 a0c8bf9334c..32a31f5e082 100644
--- a/src/tools/clippy/tests/compile-test.rs
+++ b/src/tools/clippy/tests/compile-test.rs
@@ -146,6 +146,8 @@ fn base_config(test_dir: &str) -> (Config, Args) {
     );
 
     config.program.args.extend(EXTERN_FLAGS.iter().map(OsString::from));
+    // Prevent rustc from creating `rustc-ice-*` files the console output is enough.
+    config.program.envs.push(("RUSTC_ICE".into(), Some("0".into())));
 
     if let Some(host_libs) = option_env!("HOST_LIBS") {
         let dep = format!("-Ldependency={}", Path::new(host_libs).join("deps").display());
diff --git a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
index 0e6a54452ee..a828701bcee 100644
--- a/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
+++ b/src/tools/clippy/tests/ui-toml/absolute_paths/absolute_paths.rs
@@ -3,7 +3,7 @@
 //@revisions: allow_crates disallow_crates
 //@[allow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/allow_crates
 //@[disallow_crates] rustc-env:CLIPPY_CONF_DIR=tests/ui-toml/absolute_paths/disallow_crates
-#![allow(clippy::no_effect, unused)]
+#![allow(clippy::no_effect, clippy::legacy_numeric_constants, unused)]
 #![warn(clippy::absolute_paths)]
 #![feature(decl_macro)]
 
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
index 39798ffea49..a612e56570f 100644
--- 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
@@ -10,7 +10,7 @@ fn f() {
     let _x = create_array::<1000>();
 }
 fn f2() {
-    //~^ ERROR: this function allocates a large amount of stack space
+    //~^ ERROR: this function may allocate 1001 bytes on the stack
     let _x = create_array::<1001>();
 }
 
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
index c23fac14564..19983e2f3e8 100644
--- 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
@@ -1,13 +1,14 @@
-error: this function allocates a large amount of stack space
-  --> tests/ui-toml/large_stack_frames/large_stack_frames.rs:12:1
+error: this function may allocate 1001 bytes on the stack
+  --> tests/ui-toml/large_stack_frames/large_stack_frames.rs:12:4
    |
-LL | / fn f2() {
-LL | |
-LL | |     let _x = create_array::<1001>();
-LL | | }
-   | |_^
+LL | fn f2() {
+   |    ^^
+LL |
+LL |     let _x = create_array::<1001>();
+   |         -- `_x` is the largest part, at 1001 bytes for type `[u8; 1001]`
    |
-   = note: allocating large amounts of stack space can overflow the stack
+   = note: 1001 bytes is larger than Clippy's configured `stack-size-threshold` of 1000
+   = note: allocating large amounts of stack space can overflow the stack and cause the program to abort
    = note: `-D clippy::large-stack-frames` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
 
diff --git a/src/tools/clippy/tests/ui/assigning_clones.fixed b/src/tools/clippy/tests/ui/assigning_clones.fixed
index 160f3b94663..8387c7d6156 100644
--- a/src/tools/clippy/tests/ui/assigning_clones.fixed
+++ b/src/tools/clippy/tests/ui/assigning_clones.fixed
@@ -153,6 +153,19 @@ fn clone_inside_macro() {
     clone_inside!(a, b);
 }
 
+// Make sure that we don't suggest the lint when we call clone inside a Clone impl
+// https://github.com/rust-lang/rust-clippy/issues/12600
+pub struct AvoidRecursiveCloneFrom;
+
+impl Clone for AvoidRecursiveCloneFrom {
+    fn clone(&self) -> Self {
+        Self
+    }
+    fn clone_from(&mut self, source: &Self) {
+        *self = source.clone();
+    }
+}
+
 // ToOwned
 fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {
     ref_str.clone_into(mut_string);
diff --git a/src/tools/clippy/tests/ui/assigning_clones.rs b/src/tools/clippy/tests/ui/assigning_clones.rs
index 14ba1d4db9a..6f4da9f652c 100644
--- a/src/tools/clippy/tests/ui/assigning_clones.rs
+++ b/src/tools/clippy/tests/ui/assigning_clones.rs
@@ -153,6 +153,19 @@ fn clone_inside_macro() {
     clone_inside!(a, b);
 }
 
+// Make sure that we don't suggest the lint when we call clone inside a Clone impl
+// https://github.com/rust-lang/rust-clippy/issues/12600
+pub struct AvoidRecursiveCloneFrom;
+
+impl Clone for AvoidRecursiveCloneFrom {
+    fn clone(&self) -> Self {
+        Self
+    }
+    fn clone_from(&mut self, source: &Self) {
+        *self = source.clone();
+    }
+}
+
 // ToOwned
 fn owned_method_mut_ref(mut_string: &mut String, ref_str: &str) {
     *mut_string = ref_str.to_owned();
diff --git a/src/tools/clippy/tests/ui/assigning_clones.stderr b/src/tools/clippy/tests/ui/assigning_clones.stderr
index ba59f067431..793927bd1cb 100644
--- a/src/tools/clippy/tests/ui/assigning_clones.stderr
+++ b/src/tools/clippy/tests/ui/assigning_clones.stderr
@@ -86,37 +86,37 @@ LL |     a = c.to_owned();
    |     ^^^^^^^^^^^^^^^^ help: use `clone_into()`: `c.clone_into(&mut a)`
 
 error: assigning the result of `ToOwned::to_owned()` may be inefficient
-  --> tests/ui/assigning_clones.rs:158:5
+  --> tests/ui/assigning_clones.rs:171:5
    |
 LL |     *mut_string = ref_str.to_owned();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(mut_string)`
 
 error: assigning the result of `ToOwned::to_owned()` may be inefficient
-  --> tests/ui/assigning_clones.rs:162:5
+  --> tests/ui/assigning_clones.rs:175:5
    |
 LL |     mut_string = ref_str.to_owned();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut mut_string)`
 
 error: assigning the result of `ToOwned::to_owned()` may be inefficient
-  --> tests/ui/assigning_clones.rs:183:5
+  --> tests/ui/assigning_clones.rs:196:5
    |
 LL |     **mut_box_string = ref_str.to_owned();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
 
 error: assigning the result of `ToOwned::to_owned()` may be inefficient
-  --> tests/ui/assigning_clones.rs:187:5
+  --> tests/ui/assigning_clones.rs:200:5
    |
 LL |     **mut_box_string = ref_str.to_owned();
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ref_str.clone_into(&mut (*mut_box_string))`
 
 error: assigning the result of `ToOwned::to_owned()` may be inefficient
-  --> tests/ui/assigning_clones.rs:191:5
+  --> tests/ui/assigning_clones.rs:204:5
    |
 LL |     *mut_thing = ToOwned::to_owned(ref_str);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, mut_thing)`
 
 error: assigning the result of `ToOwned::to_owned()` may be inefficient
-  --> tests/ui/assigning_clones.rs:195:5
+  --> tests/ui/assigning_clones.rs:208:5
    |
 LL |     mut_thing = ToOwned::to_owned(ref_str);
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use `clone_into()`: `ToOwned::clone_into(ref_str, &mut mut_thing)`
diff --git a/src/tools/clippy/tests/ui/author/issue_3849.rs b/src/tools/clippy/tests/ui/author/issue_3849.rs
index bae4570e539..5f65746d71f 100644
--- a/src/tools/clippy/tests/ui/author/issue_3849.rs
+++ b/src/tools/clippy/tests/ui/author/issue_3849.rs
@@ -1,7 +1,7 @@
 #![allow(dead_code)]
 #![allow(clippy::zero_ptr)]
 #![allow(clippy::transmute_ptr_to_ref)]
-#![allow(clippy::transmuting_null)]
+#![allow(clippy::transmuting_null, clippy::missing_transmute_annotations)]
 
 pub const ZPTR: *const usize = 0 as *const _;
 
diff --git a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs
index 6b164967a28..9efbb390849 100644
--- a/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs
+++ b/src/tools/clippy/tests/ui/auxiliary/macro_rules.rs
@@ -50,3 +50,10 @@ macro_rules! macro_with_panic {
         panic!()
     };
 }
+
+#[macro_export]
+macro_rules! bad_transmute {
+    ($e:expr) => {
+        std::mem::transmute($e)
+    };
+}
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
index caf29e23d54..a2da5f9c5fb 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.fixed
@@ -1,7 +1,12 @@
 //@aux-build:proc_macro_attr.rs
 
 #![warn(clippy::blocks_in_conditions)]
-#![allow(unused, clippy::let_and_return, clippy::needless_if)]
+#![allow(
+    unused,
+    clippy::let_and_return,
+    clippy::needless_if,
+    clippy::missing_transmute_annotations
+)]
 #![warn(clippy::nonminimal_bool)]
 
 macro_rules! blocky {
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.rs b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
index e72daaa910d..608ca4cf267 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.rs
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.rs
@@ -1,7 +1,12 @@
 //@aux-build:proc_macro_attr.rs
 
 #![warn(clippy::blocks_in_conditions)]
-#![allow(unused, clippy::let_and_return, clippy::needless_if)]
+#![allow(
+    unused,
+    clippy::let_and_return,
+    clippy::needless_if,
+    clippy::missing_transmute_annotations
+)]
 #![warn(clippy::nonminimal_bool)]
 
 macro_rules! blocky {
diff --git a/src/tools/clippy/tests/ui/blocks_in_conditions.stderr b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr
index 3641e71aae8..a55e1efb575 100644
--- a/src/tools/clippy/tests/ui/blocks_in_conditions.stderr
+++ b/src/tools/clippy/tests/ui/blocks_in_conditions.stderr
@@ -1,5 +1,5 @@
 error: in an `if` condition, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
-  --> tests/ui/blocks_in_conditions.rs:25:5
+  --> tests/ui/blocks_in_conditions.rs:30:5
    |
 LL | /     if {
 LL | |
@@ -20,13 +20,13 @@ LL ~     }; if res {
    |
 
 error: omit braces around single expression condition
-  --> tests/ui/blocks_in_conditions.rs:37:8
+  --> tests/ui/blocks_in_conditions.rs:42:8
    |
 LL |     if { true } { 6 } else { 10 }
    |        ^^^^^^^^ help: try: `true`
 
 error: this boolean expression can be simplified
-  --> tests/ui/blocks_in_conditions.rs:43:8
+  --> tests/ui/blocks_in_conditions.rs:48:8
    |
 LL |     if true && x == 3 { 6 } else { 10 }
    |        ^^^^^^^^^^^^^^ help: try: `x == 3`
@@ -35,7 +35,7 @@ LL |     if true && x == 3 { 6 } else { 10 }
    = help: to override `-D warnings` add `#[allow(clippy::nonminimal_bool)]`
 
 error: in a `match` scrutinee, avoid complex blocks or closures with blocks; instead, move the block or closure higher and bind it with a `let`
-  --> tests/ui/blocks_in_conditions.rs:70:5
+  --> tests/ui/blocks_in_conditions.rs:75:5
    |
 LL | /     match {
 LL | |
diff --git a/src/tools/clippy/tests/ui/box_default.fixed b/src/tools/clippy/tests/ui/box_default.fixed
index fea7405c685..6c2896b3aa0 100644
--- a/src/tools/clippy/tests/ui/box_default.fixed
+++ b/src/tools/clippy/tests/ui/box_default.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::box_default)]
-#![allow(clippy::default_constructed_unit_structs)]
+#![allow(clippy::boxed_local, clippy::default_constructed_unit_structs)]
 
 #[derive(Default)]
 struct ImplementsDefault;
@@ -12,26 +12,50 @@ impl OwnDefault {
     }
 }
 
-macro_rules! outer {
-    ($e: expr) => {
-        $e
+macro_rules! default {
+    () => {
+        Default::default()
+    };
+}
+
+macro_rules! string_new {
+    () => {
+        String::new()
+    };
+}
+
+macro_rules! box_new {
+    ($e:expr) => {
+        Box::new($e)
     };
 }
 
 fn main() {
-    let _string: Box<String> = Box::default();
-    let _byte = Box::<u8>::default();
-    let _vec = Box::<Vec::<u8>>::default();
-    let _impl = Box::<ImplementsDefault>::default();
-    let _impl2 = Box::<ImplementsDefault>::default();
-    let _impl3: Box<ImplementsDefault> = Box::default();
-    let _own = Box::new(OwnDefault::default()); // should not lint
-    let _in_macro = outer!(Box::<String>::default());
-    let _string_default = outer!(Box::<String>::default());
-    let _vec2: Box<Vec<ImplementsDefault>> = Box::default();
-    let _vec3: Box<Vec<bool>> = Box::default();
-    let _vec4: Box<_> = Box::<Vec<bool>>::default();
-    let _more = ret_ty_fn();
+    let string1: Box<String> = Box::default();
+    let string2: Box<String> = Box::default();
+    let impl1: Box<ImplementsDefault> = Box::default();
+    let vec: Box<Vec<u8>> = Box::default();
+    let byte: Box<u8> = Box::default();
+    let vec2: Box<Vec<ImplementsDefault>> = Box::default();
+    let vec3: Box<Vec<bool>> = Box::default();
+
+    let plain_default = Box::default();
+    let _: Box<String> = plain_default;
+
+    let _: Box<String> = Box::new(default!());
+    let _: Box<String> = Box::new(string_new!());
+    let _: Box<String> = box_new!(Default::default());
+    let _: Box<String> = box_new!(String::new());
+    let _: Box<String> = box_new!(default!());
+    let _: Box<String> = box_new!(string_new!());
+
+    let own: Box<OwnDefault> = Box::new(OwnDefault::default()); // should not lint
+
+    // Do not suggest where a turbofish would be required
+    let impl2 = Box::new(ImplementsDefault::default());
+    let impl3 = Box::new(<ImplementsDefault as Default>::default());
+    let vec4: Box<_> = Box::new(Vec::from([false; 0]));
+    let more = ret_ty_fn();
     call_ty_fn(Box::default());
     issue_10381();
 
@@ -44,10 +68,9 @@ fn main() {
 }
 
 fn ret_ty_fn() -> Box<bool> {
-    Box::<bool>::default()
+    Box::new(bool::default()) // Could lint, currently doesn't
 }
 
-#[allow(clippy::boxed_local)]
 fn call_ty_fn(_b: Box<u8>) {
     issue_9621_dyn_trait();
 }
@@ -61,7 +84,7 @@ impl Read for ImplementsDefault {
 }
 
 fn issue_9621_dyn_trait() {
-    let _: Box<dyn Read> = Box::<ImplementsDefault>::default();
+    let _: Box<dyn Read> = Box::new(ImplementsDefault::default());
     issue_10089();
 }
 
@@ -70,7 +93,7 @@ fn issue_10089() {
         #[derive(Default)]
         struct WeirdPathed;
 
-        let _ = Box::<WeirdPathed>::default();
+        let _ = Box::new(WeirdPathed::default());
     };
 }
 
@@ -82,7 +105,7 @@ fn issue_10381() {
 
     fn maybe_get_bar(i: u32) -> Option<Box<dyn Bar>> {
         if i % 2 == 0 {
-            Some(Box::<Foo>::default())
+            Some(Box::new(Foo::default()))
         } else {
             None
         }
@@ -91,20 +114,6 @@ fn issue_10381() {
     assert!(maybe_get_bar(2).is_some());
 }
 
-#[allow(unused)]
-fn issue_11868() {
-    fn foo(_: &mut Vec<usize>) {}
-
-    macro_rules! bar {
-        ($baz:expr) => {
-            Box::leak(Box::new($baz))
-        };
-    }
-
-    foo(bar!(vec![]));
-    foo(bar!(vec![1]));
-}
-
 // Issue #11927: The quickfix for the `Box::new` suggests replacing with `Box::<Inner>::default()`,
 // removing the `outer::` segment.
 fn issue_11927() {
@@ -116,7 +125,7 @@ fn issue_11927() {
     }
 
     fn foo() {
-        let _b = Box::<outer::Inner>::default();
-        let _b = Box::<std::collections::HashSet::<i32>>::default();
+        let _b = Box::new(outer::Inner::default());
+        let _b = Box::new(std::collections::HashSet::<i32>::new());
     }
 }
diff --git a/src/tools/clippy/tests/ui/box_default.rs b/src/tools/clippy/tests/ui/box_default.rs
index eecba7464ec..e19a62a9022 100644
--- a/src/tools/clippy/tests/ui/box_default.rs
+++ b/src/tools/clippy/tests/ui/box_default.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::box_default)]
-#![allow(clippy::default_constructed_unit_structs)]
+#![allow(clippy::boxed_local, clippy::default_constructed_unit_structs)]
 
 #[derive(Default)]
 struct ImplementsDefault;
@@ -12,26 +12,50 @@ impl OwnDefault {
     }
 }
 
-macro_rules! outer {
-    ($e: expr) => {
-        $e
+macro_rules! default {
+    () => {
+        Default::default()
+    };
+}
+
+macro_rules! string_new {
+    () => {
+        String::new()
+    };
+}
+
+macro_rules! box_new {
+    ($e:expr) => {
+        Box::new($e)
     };
 }
 
 fn main() {
-    let _string: Box<String> = Box::new(Default::default());
-    let _byte = Box::new(u8::default());
-    let _vec = Box::new(Vec::<u8>::new());
-    let _impl = Box::new(ImplementsDefault::default());
-    let _impl2 = Box::new(<ImplementsDefault as Default>::default());
-    let _impl3: Box<ImplementsDefault> = Box::new(Default::default());
-    let _own = Box::new(OwnDefault::default()); // should not lint
-    let _in_macro = outer!(Box::new(String::new()));
-    let _string_default = outer!(Box::new(String::from("")));
-    let _vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);
-    let _vec3: Box<Vec<bool>> = Box::new(Vec::from([]));
-    let _vec4: Box<_> = Box::new(Vec::from([false; 0]));
-    let _more = ret_ty_fn();
+    let string1: Box<String> = Box::new(Default::default());
+    let string2: Box<String> = Box::new(String::new());
+    let impl1: Box<ImplementsDefault> = Box::new(Default::default());
+    let vec: Box<Vec<u8>> = Box::new(Vec::new());
+    let byte: Box<u8> = Box::new(u8::default());
+    let vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);
+    let vec3: Box<Vec<bool>> = Box::new(Vec::from([]));
+
+    let plain_default = Box::new(Default::default());
+    let _: Box<String> = plain_default;
+
+    let _: Box<String> = Box::new(default!());
+    let _: Box<String> = Box::new(string_new!());
+    let _: Box<String> = box_new!(Default::default());
+    let _: Box<String> = box_new!(String::new());
+    let _: Box<String> = box_new!(default!());
+    let _: Box<String> = box_new!(string_new!());
+
+    let own: Box<OwnDefault> = Box::new(OwnDefault::default()); // should not lint
+
+    // Do not suggest where a turbofish would be required
+    let impl2 = Box::new(ImplementsDefault::default());
+    let impl3 = Box::new(<ImplementsDefault as Default>::default());
+    let vec4: Box<_> = Box::new(Vec::from([false; 0]));
+    let more = ret_ty_fn();
     call_ty_fn(Box::new(u8::default()));
     issue_10381();
 
@@ -44,10 +68,9 @@ fn main() {
 }
 
 fn ret_ty_fn() -> Box<bool> {
-    Box::new(bool::default())
+    Box::new(bool::default()) // Could lint, currently doesn't
 }
 
-#[allow(clippy::boxed_local)]
 fn call_ty_fn(_b: Box<u8>) {
     issue_9621_dyn_trait();
 }
@@ -91,20 +114,6 @@ fn issue_10381() {
     assert!(maybe_get_bar(2).is_some());
 }
 
-#[allow(unused)]
-fn issue_11868() {
-    fn foo(_: &mut Vec<usize>) {}
-
-    macro_rules! bar {
-        ($baz:expr) => {
-            Box::leak(Box::new($baz))
-        };
-    }
-
-    foo(bar!(vec![]));
-    foo(bar!(vec![1]));
-}
-
 // Issue #11927: The quickfix for the `Box::new` suggests replacing with `Box::<Inner>::default()`,
 // removing the `outer::` segment.
 fn issue_11927() {
diff --git a/src/tools/clippy/tests/ui/box_default.stderr b/src/tools/clippy/tests/ui/box_default.stderr
index 8bb5917a627..f172a875dce 100644
--- a/src/tools/clippy/tests/ui/box_default.stderr
+++ b/src/tools/clippy/tests/ui/box_default.stderr
@@ -1,113 +1,59 @@
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:22:32
+  --> tests/ui/box_default.rs:34:32
    |
-LL |     let _string: Box<String> = Box::new(Default::default());
+LL |     let string1: Box<String> = Box::new(Default::default());
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
    |
    = note: `-D clippy::box-default` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::box_default)]`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:23:17
+  --> tests/ui/box_default.rs:35:32
    |
-LL |     let _byte = Box::new(u8::default());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<u8>::default()`
+LL |     let string2: Box<String> = Box::new(String::new());
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:24:16
+  --> tests/ui/box_default.rs:36:41
    |
-LL |     let _vec = Box::new(Vec::<u8>::new());
-   |                ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Vec::<u8>>::default()`
+LL |     let impl1: Box<ImplementsDefault> = Box::new(Default::default());
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:25:17
+  --> tests/ui/box_default.rs:37:29
    |
-LL |     let _impl = Box::new(ImplementsDefault::default());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
+LL |     let vec: Box<Vec<u8>> = Box::new(Vec::new());
+   |                             ^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:26:18
+  --> tests/ui/box_default.rs:38:25
    |
-LL |     let _impl2 = Box::new(<ImplementsDefault as Default>::default());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
+LL |     let byte: Box<u8> = Box::new(u8::default());
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:27:42
+  --> tests/ui/box_default.rs:39:45
    |
-LL |     let _impl3: Box<ImplementsDefault> = Box::new(Default::default());
-   |                                          ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
+LL |     let vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);
+   |                                             ^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:29:28
+  --> tests/ui/box_default.rs:40:32
    |
-LL |     let _in_macro = outer!(Box::new(String::new()));
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<String>::default()`
+LL |     let vec3: Box<Vec<bool>> = Box::new(Vec::from([]));
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:30:34
+  --> tests/ui/box_default.rs:42:25
    |
-LL |     let _string_default = outer!(Box::new(String::from("")));
-   |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<String>::default()`
+LL |     let plain_default = Box::new(Default::default());
+   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
 error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:31:46
-   |
-LL |     let _vec2: Box<Vec<ImplementsDefault>> = Box::new(vec![]);
-   |                                              ^^^^^^^^^^^^^^^^ help: try: `Box::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:32:33
-   |
-LL |     let _vec3: Box<Vec<bool>> = Box::new(Vec::from([]));
-   |                                 ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:33:25
-   |
-LL |     let _vec4: Box<_> = Box::new(Vec::from([false; 0]));
-   |                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Vec<bool>>::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:35:16
+  --> tests/ui/box_default.rs:59:16
    |
 LL |     call_ty_fn(Box::new(u8::default()));
    |                ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::default()`
 
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:47:5
-   |
-LL |     Box::new(bool::default())
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<bool>::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:64:28
-   |
-LL |     let _: Box<dyn Read> = Box::new(ImplementsDefault::default());
-   |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<ImplementsDefault>::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:73:17
-   |
-LL |         let _ = Box::new(WeirdPathed::default());
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<WeirdPathed>::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:85:18
-   |
-LL |             Some(Box::new(Foo::default()))
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<Foo>::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:119:18
-   |
-LL |         let _b = Box::new(outer::Inner::default());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<outer::Inner>::default()`
-
-error: `Box::new(_)` of default value
-  --> tests/ui/box_default.rs:120:18
-   |
-LL |         let _b = Box::new(std::collections::HashSet::<i32>::new());
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Box::<std::collections::HashSet::<i32>>::default()`
-
-error: aborting due to 18 previous errors
+error: aborting due to 9 previous errors
 
diff --git a/src/tools/clippy/tests/ui/cast.rs b/src/tools/clippy/tests/ui/cast.rs
index a7331ddc7d0..ce76ad3d3ad 100644
--- a/src/tools/clippy/tests/ui/cast.rs
+++ b/src/tools/clippy/tests/ui/cast.rs
@@ -9,7 +9,12 @@
     clippy::cast_sign_loss,
     clippy::cast_possible_wrap
 )]
-#![allow(clippy::cast_abs_to_unsigned, clippy::no_effect, clippy::unnecessary_operation)]
+#![allow(
+    clippy::cast_abs_to_unsigned,
+    clippy::no_effect,
+    clippy::unnecessary_operation,
+    clippy::unnecessary_literal_unwrap
+)]
 
 fn main() {
     // Test clippy::cast_precision_loss
@@ -457,3 +462,8 @@ fn issue11642() {
         //~^ ERROR: casting `i32` to `u32` may lose the sign of the value
     }
 }
+
+fn issue12506() -> usize {
+    let bar: Result<Option<i64>, u32> = Ok(Some(10));
+    bar.unwrap().unwrap() as usize
+}
diff --git a/src/tools/clippy/tests/ui/cast.stderr b/src/tools/clippy/tests/ui/cast.stderr
index dd5d339b81b..3736e8aee0a 100644
--- a/src/tools/clippy/tests/ui/cast.stderr
+++ b/src/tools/clippy/tests/ui/cast.stderr
@@ -1,5 +1,5 @@
 error: casting `i32` to `f32` causes a loss of precision (`i32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:17:5
+  --> tests/ui/cast.rs:22:5
    |
 LL |     x0 as f32;
    |     ^^^^^^^^^
@@ -8,37 +8,37 @@ LL |     x0 as f32;
    = help: to override `-D warnings` add `#[allow(clippy::cast_precision_loss)]`
 
 error: casting `i64` to `f32` causes a loss of precision (`i64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:21:5
+  --> tests/ui/cast.rs:26:5
    |
 LL |     x1 as f32;
    |     ^^^^^^^^^
 
 error: casting `i64` to `f64` causes a loss of precision (`i64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
-  --> tests/ui/cast.rs:23:5
+  --> tests/ui/cast.rs:28:5
    |
 LL |     x1 as f64;
    |     ^^^^^^^^^
 
 error: casting `u32` to `f32` causes a loss of precision (`u32` is 32 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:26:5
+  --> tests/ui/cast.rs:31:5
    |
 LL |     x2 as f32;
    |     ^^^^^^^^^
 
 error: casting `u64` to `f32` causes a loss of precision (`u64` is 64 bits wide, but `f32`'s mantissa is only 23 bits wide)
-  --> tests/ui/cast.rs:29:5
+  --> tests/ui/cast.rs:34:5
    |
 LL |     x3 as f32;
    |     ^^^^^^^^^
 
 error: casting `u64` to `f64` causes a loss of precision (`u64` is 64 bits wide, but `f64`'s mantissa is only 52 bits wide)
-  --> tests/ui/cast.rs:31:5
+  --> tests/ui/cast.rs:36:5
    |
 LL |     x3 as f64;
    |     ^^^^^^^^^
 
 error: casting `f32` to `i32` may truncate the value
-  --> tests/ui/cast.rs:34:5
+  --> tests/ui/cast.rs:39:5
    |
 LL |     1f32 as i32;
    |     ^^^^^^^^^^^
@@ -48,7 +48,7 @@ LL |     1f32 as i32;
    = help: to override `-D warnings` add `#[allow(clippy::cast_possible_truncation)]`
 
 error: casting `f32` to `u32` may truncate the value
-  --> tests/ui/cast.rs:36:5
+  --> tests/ui/cast.rs:41:5
    |
 LL |     1f32 as u32;
    |     ^^^^^^^^^^^
@@ -56,7 +56,7 @@ LL |     1f32 as u32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:36:5
+  --> tests/ui/cast.rs:41:5
    |
 LL |     1f32 as u32;
    |     ^^^^^^^^^^^
@@ -65,7 +65,7 @@ LL |     1f32 as u32;
    = help: to override `-D warnings` add `#[allow(clippy::cast_sign_loss)]`
 
 error: casting `f64` to `f32` may truncate the value
-  --> tests/ui/cast.rs:40:5
+  --> tests/ui/cast.rs:45:5
    |
 LL |     1f64 as f32;
    |     ^^^^^^^^^^^
@@ -73,7 +73,7 @@ LL |     1f64 as f32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `i32` to `i8` may truncate the value
-  --> tests/ui/cast.rs:42:5
+  --> tests/ui/cast.rs:47:5
    |
 LL |     1i32 as i8;
    |     ^^^^^^^^^^
@@ -85,7 +85,7 @@ LL |     i8::try_from(1i32);
    |     ~~~~~~~~~~~~~~~~~~
 
 error: casting `i32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:44:5
+  --> tests/ui/cast.rs:49:5
    |
 LL |     1i32 as u8;
    |     ^^^^^^^^^^
@@ -97,7 +97,7 @@ LL |     u8::try_from(1i32);
    |     ~~~~~~~~~~~~~~~~~~
 
 error: casting `f64` to `isize` may truncate the value
-  --> tests/ui/cast.rs:46:5
+  --> tests/ui/cast.rs:51:5
    |
 LL |     1f64 as isize;
    |     ^^^^^^^^^^^^^
@@ -105,7 +105,7 @@ LL |     1f64 as isize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f64` to `usize` may truncate the value
-  --> tests/ui/cast.rs:48:5
+  --> tests/ui/cast.rs:53:5
    |
 LL |     1f64 as usize;
    |     ^^^^^^^^^^^^^
@@ -113,13 +113,13 @@ LL |     1f64 as usize;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f64` to `usize` may lose the sign of the value
-  --> tests/ui/cast.rs:48:5
+  --> tests/ui/cast.rs:53:5
    |
 LL |     1f64 as usize;
    |     ^^^^^^^^^^^^^
 
 error: casting `u32` to `u16` may truncate the value
-  --> tests/ui/cast.rs:51:5
+  --> tests/ui/cast.rs:56:5
    |
 LL |     1f32 as u32 as u16;
    |     ^^^^^^^^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL |     u16::try_from(1f32 as u32);
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `f32` to `u32` may truncate the value
-  --> tests/ui/cast.rs:51:5
+  --> tests/ui/cast.rs:56:5
    |
 LL |     1f32 as u32 as u16;
    |     ^^^^^^^^^^^
@@ -139,13 +139,13 @@ LL |     1f32 as u32 as u16;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:51:5
+  --> tests/ui/cast.rs:56:5
    |
 LL |     1f32 as u32 as u16;
    |     ^^^^^^^^^^^
 
 error: casting `i32` to `i8` may truncate the value
-  --> tests/ui/cast.rs:56:22
+  --> tests/ui/cast.rs:61:22
    |
 LL |         let _x: i8 = 1i32 as _;
    |                      ^^^^^^^^^
@@ -157,7 +157,7 @@ LL |         let _x: i8 = 1i32.try_into();
    |                      ~~~~~~~~~~~~~~~
 
 error: casting `f32` to `i32` may truncate the value
-  --> tests/ui/cast.rs:58:9
+  --> tests/ui/cast.rs:63:9
    |
 LL |         1f32 as i32;
    |         ^^^^^^^^^^^
@@ -165,7 +165,7 @@ LL |         1f32 as i32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f64` to `i32` may truncate the value
-  --> tests/ui/cast.rs:60:9
+  --> tests/ui/cast.rs:65:9
    |
 LL |         1f64 as i32;
    |         ^^^^^^^^^^^
@@ -173,7 +173,7 @@ LL |         1f64 as i32;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:62:9
+  --> tests/ui/cast.rs:67:9
    |
 LL |         1f32 as u8;
    |         ^^^^^^^^^^
@@ -181,13 +181,13 @@ LL |         1f32 as u8;
    = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
 
 error: casting `f32` to `u8` may lose the sign of the value
-  --> tests/ui/cast.rs:62:9
+  --> tests/ui/cast.rs:67:9
    |
 LL |         1f32 as u8;
    |         ^^^^^^^^^^
 
 error: casting `u8` to `i8` may wrap around the value
-  --> tests/ui/cast.rs:67:5
+  --> tests/ui/cast.rs:72:5
    |
 LL |     1u8 as i8;
    |     ^^^^^^^^^
@@ -196,31 +196,31 @@ LL |     1u8 as i8;
    = help: to override `-D warnings` add `#[allow(clippy::cast_possible_wrap)]`
 
 error: casting `u16` to `i16` may wrap around the value
-  --> tests/ui/cast.rs:70:5
+  --> tests/ui/cast.rs:75:5
    |
 LL |     1u16 as i16;
    |     ^^^^^^^^^^^
 
 error: casting `u32` to `i32` may wrap around the value
-  --> tests/ui/cast.rs:72:5
+  --> tests/ui/cast.rs:77:5
    |
 LL |     1u32 as i32;
    |     ^^^^^^^^^^^
 
 error: casting `u64` to `i64` may wrap around the value
-  --> tests/ui/cast.rs:74:5
+  --> tests/ui/cast.rs:79:5
    |
 LL |     1u64 as i64;
    |     ^^^^^^^^^^^
 
 error: casting `usize` to `isize` may wrap around the value
-  --> tests/ui/cast.rs:76:5
+  --> tests/ui/cast.rs:81:5
    |
 LL |     1usize as isize;
    |     ^^^^^^^^^^^^^^^
 
 error: casting `usize` to `i8` may truncate the value
-  --> tests/ui/cast.rs:79:5
+  --> tests/ui/cast.rs:84:5
    |
 LL |     1usize as i8;
    |     ^^^^^^^^^^^^
@@ -232,7 +232,7 @@ LL |     i8::try_from(1usize);
    |     ~~~~~~~~~~~~~~~~~~~~
 
 error: casting `usize` to `i16` may truncate the value
-  --> tests/ui/cast.rs:82:5
+  --> tests/ui/cast.rs:87:5
    |
 LL |     1usize as i16;
    |     ^^^^^^^^^^^^^
@@ -244,7 +244,7 @@ LL |     i16::try_from(1usize);
    |     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `usize` to `i16` may wrap around the value on targets with 16-bit wide pointers
-  --> tests/ui/cast.rs:82:5
+  --> tests/ui/cast.rs:87:5
    |
 LL |     1usize as i16;
    |     ^^^^^^^^^^^^^
@@ -253,7 +253,7 @@ LL |     1usize as i16;
    = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
 
 error: casting `usize` to `i32` may truncate the value on targets with 64-bit wide pointers
-  --> tests/ui/cast.rs:87:5
+  --> tests/ui/cast.rs:92:5
    |
 LL |     1usize as i32;
    |     ^^^^^^^^^^^^^
@@ -265,19 +265,19 @@ LL |     i32::try_from(1usize);
    |     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `usize` to `i32` may wrap around the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:87:5
+  --> tests/ui/cast.rs:92:5
    |
 LL |     1usize as i32;
    |     ^^^^^^^^^^^^^
 
 error: casting `usize` to `i64` may wrap around the value on targets with 64-bit wide pointers
-  --> tests/ui/cast.rs:91:5
+  --> tests/ui/cast.rs:96:5
    |
 LL |     1usize as i64;
    |     ^^^^^^^^^^^^^
 
 error: casting `u16` to `isize` may wrap around the value on targets with 16-bit wide pointers
-  --> tests/ui/cast.rs:96:5
+  --> tests/ui/cast.rs:101:5
    |
 LL |     1u16 as isize;
    |     ^^^^^^^^^^^^^
@@ -286,13 +286,13 @@ LL |     1u16 as isize;
    = note: for more information see https://doc.rust-lang.org/reference/types/numeric.html#machine-dependent-integer-types
 
 error: casting `u32` to `isize` may wrap around the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:100:5
+  --> tests/ui/cast.rs:105:5
    |
 LL |     1u32 as isize;
    |     ^^^^^^^^^^^^^
 
 error: casting `u64` to `isize` may truncate the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:103:5
+  --> tests/ui/cast.rs:108:5
    |
 LL |     1u64 as isize;
    |     ^^^^^^^^^^^^^
@@ -304,55 +304,55 @@ LL |     isize::try_from(1u64);
    |     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `u64` to `isize` may wrap around the value on targets with 64-bit wide pointers
-  --> tests/ui/cast.rs:103:5
+  --> tests/ui/cast.rs:108:5
    |
 LL |     1u64 as isize;
    |     ^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:108:5
+  --> tests/ui/cast.rs:113:5
    |
 LL |     -1i32 as u32;
    |     ^^^^^^^^^^^^
 
 error: casting `isize` to `usize` may lose the sign of the value
-  --> tests/ui/cast.rs:111:5
+  --> tests/ui/cast.rs:116:5
    |
 LL |     -1isize as usize;
    |     ^^^^^^^^^^^^^^^^
 
 error: casting `i8` to `u8` may lose the sign of the value
-  --> tests/ui/cast.rs:122:5
+  --> tests/ui/cast.rs:127:5
    |
 LL |     (i8::MIN).abs() as u8;
    |     ^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `u64` may lose the sign of the value
-  --> tests/ui/cast.rs:126:5
+  --> tests/ui/cast.rs:131:5
    |
 LL |     (-1i64).abs() as u64;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: casting `isize` to `usize` may lose the sign of the value
-  --> tests/ui/cast.rs:127:5
+  --> tests/ui/cast.rs:132:5
    |
 LL |     (-1isize).abs() as usize;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `u64` may lose the sign of the value
-  --> tests/ui/cast.rs:134:5
+  --> tests/ui/cast.rs:139:5
    |
 LL |     (unsafe { (-1i64).checked_abs().unwrap_unchecked() }) as u64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `u64` may lose the sign of the value
-  --> tests/ui/cast.rs:149:5
+  --> tests/ui/cast.rs:154:5
    |
 LL |     (unsafe { (-1i64).checked_isqrt().unwrap_unchecked() }) as u64;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i64` to `i8` may truncate the value
-  --> tests/ui/cast.rs:200:5
+  --> tests/ui/cast.rs:205:5
    |
 LL |     (-99999999999i64).min(1) as i8;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -364,7 +364,7 @@ LL |     i8::try_from((-99999999999i64).min(1));
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `u64` to `u8` may truncate the value
-  --> tests/ui/cast.rs:214:5
+  --> tests/ui/cast.rs:219:5
    |
 LL |     999999u64.clamp(0, 256) as u8;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -376,7 +376,7 @@ LL |     u8::try_from(999999u64.clamp(0, 256));
    |     ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E2` to `u8` may truncate the value
-  --> tests/ui/cast.rs:237:21
+  --> tests/ui/cast.rs:242:21
    |
 LL |             let _ = self as u8;
    |                     ^^^^^^^^^^
@@ -388,7 +388,7 @@ LL |             let _ = u8::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E2::B` to `u8` will truncate the value
-  --> tests/ui/cast.rs:239:21
+  --> tests/ui/cast.rs:244:21
    |
 LL |             let _ = Self::B as u8;
    |                     ^^^^^^^^^^^^^
@@ -397,7 +397,7 @@ LL |             let _ = Self::B as u8;
    = help: to override `-D warnings` add `#[allow(clippy::cast_enum_truncation)]`
 
 error: casting `main::E5` to `i8` may truncate the value
-  --> tests/ui/cast.rs:281:21
+  --> tests/ui/cast.rs:286:21
    |
 LL |             let _ = self as i8;
    |                     ^^^^^^^^^^
@@ -409,13 +409,13 @@ LL |             let _ = i8::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E5::A` to `i8` will truncate the value
-  --> tests/ui/cast.rs:283:21
+  --> tests/ui/cast.rs:288:21
    |
 LL |             let _ = Self::A as i8;
    |                     ^^^^^^^^^^^^^
 
 error: casting `main::E6` to `i16` may truncate the value
-  --> tests/ui/cast.rs:300:21
+  --> tests/ui/cast.rs:305:21
    |
 LL |             let _ = self as i16;
    |                     ^^^^^^^^^^^
@@ -427,7 +427,7 @@ LL |             let _ = i16::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E7` to `usize` may truncate the value on targets with 32-bit wide pointers
-  --> tests/ui/cast.rs:319:21
+  --> tests/ui/cast.rs:324:21
    |
 LL |             let _ = self as usize;
    |                     ^^^^^^^^^^^^^
@@ -439,7 +439,7 @@ LL |             let _ = usize::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `main::E10` to `u16` may truncate the value
-  --> tests/ui/cast.rs:366:21
+  --> tests/ui/cast.rs:371:21
    |
 LL |             let _ = self as u16;
    |                     ^^^^^^^^^^^
@@ -451,7 +451,7 @@ LL |             let _ = u16::try_from(self);
    |                     ~~~~~~~~~~~~~~~~~~~
 
 error: casting `u32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:377:13
+  --> tests/ui/cast.rs:382:13
    |
 LL |     let c = (q >> 16) as u8;
    |             ^^^^^^^^^^^^^^^
@@ -463,7 +463,7 @@ LL |     let c = u8::try_from(q >> 16);
    |             ~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `u32` to `u8` may truncate the value
-  --> tests/ui/cast.rs:381:13
+  --> tests/ui/cast.rs:386:13
    |
 LL |     let c = (q / 1000) as u8;
    |             ^^^^^^^^^^^^^^^^
@@ -475,85 +475,85 @@ LL |     let c = u8::try_from(q / 1000);
    |             ~~~~~~~~~~~~~~~~~~~~~~
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:393:9
+  --> tests/ui/cast.rs:398:9
    |
 LL |         (x * x) as u32;
    |         ^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:398:32
+  --> tests/ui/cast.rs:403:32
    |
 LL |     let _a = |x: i32| -> u32 { (x * x * x * x) as u32 };
    |                                ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:400:5
+  --> tests/ui/cast.rs:405:5
    |
 LL |     (2_i32).checked_pow(3).unwrap() as u32;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:401:5
+  --> tests/ui/cast.rs:406:5
    |
 LL |     (-2_i32).pow(3) as u32;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:406:5
+  --> tests/ui/cast.rs:411:5
    |
 LL |     (-5_i32 % 2) as u32;
    |     ^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:408:5
+  --> tests/ui/cast.rs:413:5
    |
 LL |     (-5_i32 % -2) as u32;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:411:5
+  --> tests/ui/cast.rs:416:5
    |
 LL |     (-2_i32 >> 1) as u32;
    |     ^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:415:5
+  --> tests/ui/cast.rs:420:5
    |
 LL |     (x * x) as u32;
    |     ^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:416:5
+  --> tests/ui/cast.rs:421:5
    |
 LL |     (x * x * x) as u32;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:420:5
+  --> tests/ui/cast.rs:425:5
    |
 LL |     (y * y * y * y * -2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:422:5
+  --> tests/ui/cast.rs:427:5
    |
 LL |     (y * y * y / y * 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:423:5
+  --> tests/ui/cast.rs:428:5
    |
 LL |     (y * y / y * 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:425:5
+  --> tests/ui/cast.rs:430:5
    |
 LL |     (y / y * y * -2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: equal expressions as operands to `/`
-  --> tests/ui/cast.rs:425:6
+  --> tests/ui/cast.rs:430:6
    |
 LL |     (y / y * y * -2) as u16;
    |      ^^^^^
@@ -561,94 +561,112 @@ LL |     (y / y * y * -2) as u16;
    = note: `#[deny(clippy::eq_op)]` on by default
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:428:5
+  --> tests/ui/cast.rs:433:5
    |
 LL |     (y + y + y + -2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:430:5
+  --> tests/ui/cast.rs:435:5
    |
 LL |     (y + y + y + 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:434:5
+  --> tests/ui/cast.rs:439:5
    |
 LL |     (z + -2) as u16;
    |     ^^^^^^^^^^^^^^^
 
 error: casting `i16` to `u16` may lose the sign of the value
-  --> tests/ui/cast.rs:436:5
+  --> tests/ui/cast.rs:441:5
    |
 LL |     (z + z + 2) as u16;
    |     ^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:439:9
+  --> tests/ui/cast.rs:444:9
    |
 LL |         (a * a * b * b * c * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:440:9
+  --> tests/ui/cast.rs:445:9
    |
 LL |         (a * b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:442:9
+  --> tests/ui/cast.rs:447:9
    |
 LL |         (a * -b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:444:9
+  --> tests/ui/cast.rs:449:9
    |
 LL |         (a * b * c * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:445:9
+  --> tests/ui/cast.rs:450:9
    |
 LL |         (a * -2) as u32;
    |         ^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:447:9
+  --> tests/ui/cast.rs:452:9
    |
 LL |         (a * b * c * -2) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:449:9
+  --> tests/ui/cast.rs:454:9
    |
 LL |         (a / b) as u32;
    |         ^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:450:9
+  --> tests/ui/cast.rs:455:9
    |
 LL |         (a / b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:452:9
+  --> tests/ui/cast.rs:457:9
    |
 LL |         (a / b + b * c) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:454:9
+  --> tests/ui/cast.rs:459:9
    |
 LL |         a.saturating_pow(3) as u32;
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: casting `i32` to `u32` may lose the sign of the value
-  --> tests/ui/cast.rs:456:9
+  --> tests/ui/cast.rs:461:9
    |
 LL |         (a.abs() * b.pow(2) / c.abs()) as u32
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 85 previous errors
+error: casting `i64` to `usize` may truncate the value on targets with 32-bit wide pointers
+  --> tests/ui/cast.rs:468:5
+   |
+LL |     bar.unwrap().unwrap() as usize
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: if this is intentional allow the lint with `#[allow(clippy::cast_possible_truncation)]` ...
+help: ... or use `try_from` and handle the error accordingly
+   |
+LL |     usize::try_from(bar.unwrap().unwrap())
+   |
+
+error: casting `i64` to `usize` may lose the sign of the value
+  --> tests/ui/cast.rs:468:5
+   |
+LL |     bar.unwrap().unwrap() as usize
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 87 previous errors
 
diff --git a/src/tools/clippy/tests/ui/checked_conversions.fixed b/src/tools/clippy/tests/ui/checked_conversions.fixed
index 0e05a27429b..1e8da331614 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.fixed
+++ b/src/tools/clippy/tests/ui/checked_conversions.fixed
@@ -1,5 +1,6 @@
 #![allow(
     clippy::cast_lossless,
+    clippy::legacy_numeric_constants,
     unused,
     // Int::max_value will be deprecated in the future
     deprecated,
diff --git a/src/tools/clippy/tests/ui/checked_conversions.rs b/src/tools/clippy/tests/ui/checked_conversions.rs
index ac782699265..67a9adc049e 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.rs
+++ b/src/tools/clippy/tests/ui/checked_conversions.rs
@@ -1,5 +1,6 @@
 #![allow(
     clippy::cast_lossless,
+    clippy::legacy_numeric_constants,
     unused,
     // Int::max_value will be deprecated in the future
     deprecated,
diff --git a/src/tools/clippy/tests/ui/checked_conversions.stderr b/src/tools/clippy/tests/ui/checked_conversions.stderr
index 223e379cce9..453cd7fcf01 100644
--- a/src/tools/clippy/tests/ui/checked_conversions.stderr
+++ b/src/tools/clippy/tests/ui/checked_conversions.stderr
@@ -1,5 +1,5 @@
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:14:13
+  --> tests/ui/checked_conversions.rs:15:13
    |
 LL |     let _ = value <= (u32::max_value() as i64) && value >= 0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
@@ -8,97 +8,97 @@ LL |     let _ = value <= (u32::max_value() as i64) && value >= 0;
    = help: to override `-D warnings` add `#[allow(clippy::checked_conversions)]`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:15:13
+  --> tests/ui/checked_conversions.rs:16:13
    |
 LL |     let _ = value <= (u32::MAX as i64) && value >= 0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:19:13
+  --> tests/ui/checked_conversions.rs:20:13
    |
 LL |     let _ = value <= i64::from(u16::max_value()) && value >= 0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:20:13
+  --> tests/ui/checked_conversions.rs:21:13
    |
 LL |     let _ = value <= i64::from(u16::MAX) && value >= 0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:24:13
+  --> tests/ui/checked_conversions.rs:25:13
    |
 LL |     let _ = value <= (u8::max_value() as isize) && value >= 0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:25:13
+  --> tests/ui/checked_conversions.rs:26:13
    |
 LL |     let _ = value <= (u8::MAX as isize) && value >= 0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u8::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:31:13
+  --> tests/ui/checked_conversions.rs:32:13
    |
 LL |     let _ = value <= (i32::max_value() as i64) && value >= (i32::min_value() as i64);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:32:13
+  --> tests/ui/checked_conversions.rs:33:13
    |
 LL |     let _ = value <= (i32::MAX as i64) && value >= (i32::MIN as i64);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:36:13
+  --> tests/ui/checked_conversions.rs:37:13
    |
 LL |     let _ = value <= i64::from(i16::max_value()) && value >= i64::from(i16::min_value());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:37:13
+  --> tests/ui/checked_conversions.rs:38:13
    |
 LL |     let _ = value <= i64::from(i16::MAX) && value >= i64::from(i16::MIN);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i16::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:43:13
+  --> tests/ui/checked_conversions.rs:44:13
    |
 LL |     let _ = value <= i32::max_value() as u32;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:44:13
+  --> tests/ui/checked_conversions.rs:45:13
    |
 LL |     let _ = value <= i32::MAX as u32;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `i32::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:48:13
+  --> tests/ui/checked_conversions.rs:49:13
    |
 LL |     let _ = value <= isize::max_value() as usize && value as i32 == 5;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:49:13
+  --> tests/ui/checked_conversions.rs:50:13
    |
 LL |     let _ = value <= isize::MAX as usize && value as i32 == 5;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `isize::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:53:13
+  --> tests/ui/checked_conversions.rs:54:13
    |
 LL |     let _ = value <= u16::max_value() as u32 && value as i32 == 5;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:54:13
+  --> tests/ui/checked_conversions.rs:55:13
    |
 LL |     let _ = value <= u16::MAX as u32 && value as i32 == 5;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u16::try_from(value).is_ok()`
 
 error: checked cast can be simplified
-  --> tests/ui/checked_conversions.rs:87:13
+  --> tests/ui/checked_conversions.rs:88:13
    |
 LL |     let _ = value <= (u32::MAX as i64) && value >= 0;
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `u32::try_from(value).is_ok()`
diff --git a/src/tools/clippy/tests/ui/crashes/ice-12616.fixed b/src/tools/clippy/tests/ui/crashes/ice-12616.fixed
new file mode 100644
index 00000000000..a5a5b3d1e78
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-12616.fixed
@@ -0,0 +1,7 @@
+#![warn(clippy::ptr_as_ptr)]
+#![allow(clippy::unnecessary_operation, clippy::unnecessary_cast)]
+
+fn main() {
+    let s = std::ptr::null::<()>;
+    s().cast::<()>();
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-12616.rs b/src/tools/clippy/tests/ui/crashes/ice-12616.rs
new file mode 100644
index 00000000000..6ee9a5ec08f
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-12616.rs
@@ -0,0 +1,7 @@
+#![warn(clippy::ptr_as_ptr)]
+#![allow(clippy::unnecessary_operation, clippy::unnecessary_cast)]
+
+fn main() {
+    let s = std::ptr::null::<()>;
+    s() as *const ();
+}
diff --git a/src/tools/clippy/tests/ui/crashes/ice-12616.stderr b/src/tools/clippy/tests/ui/crashes/ice-12616.stderr
new file mode 100644
index 00000000000..ef573f55cf3
--- /dev/null
+++ b/src/tools/clippy/tests/ui/crashes/ice-12616.stderr
@@ -0,0 +1,19 @@
+error: `as` casting between raw pointers without changing its mutability
+  --> tests/ui/crashes/ice-12616.rs:6:5
+   |
+LL |     s() as *const ();
+   |     ^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `s().cast::<()>()`
+   |
+   = note: `-D clippy::ptr-as-ptr` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::ptr_as_ptr)]`
+
+error: `as` casting between raw pointers without changing its mutability
+  --> tests/ui/crashes/ice-12616.rs:6:5
+   |
+LL |     s() as *const ();
+   |     ^^^^^^^^^^^^^^^^ help: try `pointer::cast`, a safer alternative: `s().cast::<()>()`
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/crashes/ice-1782.rs b/src/tools/clippy/tests/ui/crashes/ice-1782.rs
index 19ab03418ee..73de5721cbc 100644
--- a/src/tools/clippy/tests/ui/crashes/ice-1782.rs
+++ b/src/tools/clippy/tests/ui/crashes/ice-1782.rs
@@ -1,5 +1,5 @@
 #![allow(dead_code, unused_variables)]
-#![allow(clippy::unnecessary_cast)]
+#![allow(clippy::unnecessary_cast, clippy::missing_transmute_annotations)]
 
 /// Should not trigger an ICE in `SpanlessEq` / `consts::constant`
 ///
diff --git a/src/tools/clippy/tests/ui/duplicated_attributes.rs b/src/tools/clippy/tests/ui/duplicated_attributes.rs
index 0f036c684c1..d051c881f15 100644
--- a/src/tools/clippy/tests/ui/duplicated_attributes.rs
+++ b/src/tools/clippy/tests/ui/duplicated_attributes.rs
@@ -2,16 +2,17 @@
 #![cfg(any(unix, windows))]
 #![allow(dead_code)]
 #![allow(dead_code)] //~ ERROR: duplicated attribute
-#![cfg(any(unix, windows))]
-//~^ ERROR: duplicated attribute
-//~| ERROR: duplicated attribute
+#![cfg(any(unix, windows))] // Should not warn!
 
 #[cfg(any(unix, windows, target_os = "linux"))]
 #[allow(dead_code)]
 #[allow(dead_code)] //~ ERROR: duplicated attribute
-#[cfg(any(unix, windows, target_os = "linux"))]
-//~^ ERROR: duplicated attribute
-//~| ERROR: duplicated attribute
+#[cfg(any(unix, windows, target_os = "linux"))] // Should not warn!
 fn foo() {}
 
+#[cfg(unix)]
+#[cfg(windows)]
+#[cfg(unix)] //~ ERROR: duplicated attribute
+fn bar() {}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/duplicated_attributes.stderr b/src/tools/clippy/tests/ui/duplicated_attributes.stderr
index 1c6578dbb43..9e26ba990ac 100644
--- a/src/tools/clippy/tests/ui/duplicated_attributes.stderr
+++ b/src/tools/clippy/tests/ui/duplicated_attributes.stderr
@@ -18,106 +18,38 @@ LL | #![allow(dead_code)]
    = help: to override `-D warnings` add `#[allow(clippy::duplicated_attributes)]`
 
 error: duplicated attribute
-  --> tests/ui/duplicated_attributes.rs:5:12
-   |
-LL | #![cfg(any(unix, windows))]
-   |            ^^^^
-   |
-note: first defined here
-  --> tests/ui/duplicated_attributes.rs:2:12
-   |
-LL | #![cfg(any(unix, windows))]
-   |            ^^^^
-help: remove this attribute
-  --> tests/ui/duplicated_attributes.rs:5:12
-   |
-LL | #![cfg(any(unix, windows))]
-   |            ^^^^
-
-error: duplicated attribute
-  --> tests/ui/duplicated_attributes.rs:5:18
-   |
-LL | #![cfg(any(unix, windows))]
-   |                  ^^^^^^^
-   |
-note: first defined here
-  --> tests/ui/duplicated_attributes.rs:2:18
-   |
-LL | #![cfg(any(unix, windows))]
-   |                  ^^^^^^^
-help: remove this attribute
-  --> tests/ui/duplicated_attributes.rs:5:18
-   |
-LL | #![cfg(any(unix, windows))]
-   |                  ^^^^^^^
-
-error: duplicated attribute
-  --> tests/ui/duplicated_attributes.rs:11:9
+  --> tests/ui/duplicated_attributes.rs:9:9
    |
 LL | #[allow(dead_code)]
    |         ^^^^^^^^^
    |
 note: first defined here
-  --> tests/ui/duplicated_attributes.rs:10:9
+  --> tests/ui/duplicated_attributes.rs:8:9
    |
 LL | #[allow(dead_code)]
    |         ^^^^^^^^^
 help: remove this attribute
-  --> tests/ui/duplicated_attributes.rs:11:9
+  --> tests/ui/duplicated_attributes.rs:9:9
    |
 LL | #[allow(dead_code)]
    |         ^^^^^^^^^
 
 error: duplicated attribute
-  --> tests/ui/duplicated_attributes.rs:12:11
-   |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |           ^^^^
-   |
-note: first defined here
-  --> tests/ui/duplicated_attributes.rs:9:11
-   |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |           ^^^^
-help: remove this attribute
-  --> tests/ui/duplicated_attributes.rs:12:11
-   |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |           ^^^^
-
-error: duplicated attribute
-  --> tests/ui/duplicated_attributes.rs:12:17
-   |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |                 ^^^^^^^
-   |
-note: first defined here
-  --> tests/ui/duplicated_attributes.rs:9:17
-   |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |                 ^^^^^^^
-help: remove this attribute
-  --> tests/ui/duplicated_attributes.rs:12:17
-   |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |                 ^^^^^^^
-
-error: duplicated attribute
-  --> tests/ui/duplicated_attributes.rs:12:26
+  --> tests/ui/duplicated_attributes.rs:15:7
    |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |                          ^^^^^^^^^^^^^^^^^^^
+LL | #[cfg(unix)]
+   |       ^^^^
    |
 note: first defined here
-  --> tests/ui/duplicated_attributes.rs:9:26
+  --> tests/ui/duplicated_attributes.rs:13:7
    |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |                          ^^^^^^^^^^^^^^^^^^^
+LL | #[cfg(unix)]
+   |       ^^^^
 help: remove this attribute
-  --> tests/ui/duplicated_attributes.rs:12:26
+  --> tests/ui/duplicated_attributes.rs:15:7
    |
-LL | #[cfg(any(unix, windows, target_os = "linux"))]
-   |                          ^^^^^^^^^^^^^^^^^^^
+LL | #[cfg(unix)]
+   |       ^^^^
 
-error: aborting due to 7 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/src/tools/clippy/tests/ui/eager_transmute.fixed b/src/tools/clippy/tests/ui/eager_transmute.fixed
index bece09bba1a..c29e7dd9ab3 100644
--- a/src/tools/clippy/tests/ui/eager_transmute.fixed
+++ b/src/tools/clippy/tests/ui/eager_transmute.fixed
@@ -1,6 +1,6 @@
 #![feature(rustc_attrs)]
 #![warn(clippy::eager_transmute)]
-#![allow(clippy::transmute_int_to_non_zero)]
+#![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)]
 
 use std::num::NonZeroU8;
 
diff --git a/src/tools/clippy/tests/ui/eager_transmute.rs b/src/tools/clippy/tests/ui/eager_transmute.rs
index a82bd578f76..491a9485c93 100644
--- a/src/tools/clippy/tests/ui/eager_transmute.rs
+++ b/src/tools/clippy/tests/ui/eager_transmute.rs
@@ -1,6 +1,6 @@
 #![feature(rustc_attrs)]
 #![warn(clippy::eager_transmute)]
-#![allow(clippy::transmute_int_to_non_zero)]
+#![allow(clippy::transmute_int_to_non_zero, clippy::missing_transmute_annotations)]
 
 use std::num::NonZeroU8;
 
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.fixed b/src/tools/clippy/tests/ui/filter_map_identity.fixed
index ad438afaca7..f3f6848e5f9 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.fixed
+++ b/src/tools/clippy/tests/ui/filter_map_identity.fixed
@@ -1,17 +1,83 @@
-#![allow(unused_imports, clippy::needless_return)]
+#![allow(unused_imports, clippy::needless_return, clippy::useless_vec)]
 #![warn(clippy::filter_map_identity)]
+#![feature(stmt_expr_attributes)]
+
+use std::option::Option;
+struct NonCopy;
+use std::convert::identity;
+
+fn non_copy_vec() -> Vec<Option<NonCopy>> {
+    todo!()
+}
+
+fn copy_vec<T: Copy>() -> Vec<Option<T>> {
+    todo!()
+}
+
+fn copy_vec_non_inferred() -> Vec<Option<i32>> {
+    todo!()
+}
+
+fn opaque<T: Default>() -> impl IntoIterator<Item = Option<T>> {
+    vec![Some(T::default())]
+}
 
 fn main() {
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.flatten();
+    {
+        // into_iter
+        copy_vec_non_inferred().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().flatten();
+        //~^ ERROR: use of
+
+        non_copy_vec().into_iter().flatten();
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().flatten();
+        //~^ ERROR: use of
+
+        non_copy_vec().into_iter().flatten();
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().flatten();
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().flatten();
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().flatten();
+        //~^ ERROR: use of
 
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.flatten();
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
 
-    use std::convert::identity;
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.flatten();
+        // we are forced to pass the type in the call.
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        #[rustfmt::skip]
+            copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+        #[rustfmt::skip]
+            copy_vec::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
 
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.flatten();
+        // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference,
+        // it behaves the same as copy_vec.
+        opaque::<i32>().into_iter().flatten();
+        //~^ ERROR: use of
+    }
 }
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.rs b/src/tools/clippy/tests/ui/filter_map_identity.rs
index d7423276872..b9aa9c05be8 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.rs
+++ b/src/tools/clippy/tests/ui/filter_map_identity.rs
@@ -1,17 +1,83 @@
-#![allow(unused_imports, clippy::needless_return)]
+#![allow(unused_imports, clippy::needless_return, clippy::useless_vec)]
 #![warn(clippy::filter_map_identity)]
+#![feature(stmt_expr_attributes)]
+
+use std::option::Option;
+struct NonCopy;
+use std::convert::identity;
+
+fn non_copy_vec() -> Vec<Option<NonCopy>> {
+    todo!()
+}
+
+fn copy_vec<T: Copy>() -> Vec<Option<T>> {
+    todo!()
+}
+
+fn copy_vec_non_inferred() -> Vec<Option<i32>> {
+    todo!()
+}
+
+fn opaque<T: Default>() -> impl IntoIterator<Item = Option<T>> {
+    vec![Some(T::default())]
+}
 
 fn main() {
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.filter_map(|x| x);
+    {
+        // into_iter
+        copy_vec_non_inferred().into_iter().filter_map(|x| x);
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().filter_map(std::convert::identity);
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().filter_map(identity);
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().filter_map(|x| return x);
+        //~^ ERROR: use of
+        copy_vec_non_inferred().into_iter().filter_map(|x| return x);
+        //~^ ERROR: use of
+
+        non_copy_vec().into_iter().filter_map(|x| x);
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().filter_map(|x| x);
+        //~^ ERROR: use of
+
+        non_copy_vec().into_iter().filter_map(std::convert::identity);
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().filter_map(identity);
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().filter_map(|x| return x);
+        //~^ ERROR: use of
+        non_copy_vec().into_iter().filter_map(|x| return x);
+        //~^ ERROR: use of
 
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.filter_map(std::convert::identity);
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);
+        //~^ ERROR: use of
 
-    use std::convert::identity;
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.filter_map(identity);
+        // we are forced to pass the type in the call.
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);
+        //~^ ERROR: use of
+        copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);
+        //~^ ERROR: use of
+        #[rustfmt::skip]
+            copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ x }});
+        //~^ ERROR: use of
+        #[rustfmt::skip]
+            copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ return x }});
+        //~^ ERROR: use of
 
-    let iterator = vec![Some(1), None, Some(2)].into_iter();
-    let _ = iterator.filter_map(|x| return x);
+        // note, the compiler requires that we pass the type to `opaque`. This is mostly for reference,
+        // it behaves the same as copy_vec.
+        opaque::<i32>().into_iter().filter_map(|x| x);
+        //~^ ERROR: use of
+    }
 }
diff --git a/src/tools/clippy/tests/ui/filter_map_identity.stderr b/src/tools/clippy/tests/ui/filter_map_identity.stderr
index 5aa46ad6d23..55068db4e9d 100644
--- a/src/tools/clippy/tests/ui/filter_map_identity.stderr
+++ b/src/tools/clippy/tests/ui/filter_map_identity.stderr
@@ -1,29 +1,137 @@
 error: use of `filter_map` with an identity function
-  --> tests/ui/filter_map_identity.rs:6:22
+  --> tests/ui/filter_map_identity.rs:28:45
    |
-LL |     let _ = iterator.filter_map(|x| x);
-   |                      ^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+LL |         copy_vec_non_inferred().into_iter().filter_map(|x| x);
+   |                                             ^^^^^^^^^^^^^^^^^ help: try: `flatten()`
    |
    = note: `-D clippy::filter-map-identity` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::filter_map_identity)]`
 
 error: use of `filter_map` with an identity function
-  --> tests/ui/filter_map_identity.rs:9:22
+  --> tests/ui/filter_map_identity.rs:30:45
    |
-LL |     let _ = iterator.filter_map(std::convert::identity);
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+LL |         copy_vec_non_inferred().into_iter().filter_map(std::convert::identity);
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
 
 error: use of `filter_map` with an identity function
-  --> tests/ui/filter_map_identity.rs:13:22
+  --> tests/ui/filter_map_identity.rs:32:45
    |
-LL |     let _ = iterator.filter_map(identity);
-   |                      ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+LL |         copy_vec_non_inferred().into_iter().filter_map(identity);
+   |                                             ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
 
 error: use of `filter_map` with an identity function
-  --> tests/ui/filter_map_identity.rs:16:22
+  --> tests/ui/filter_map_identity.rs:34:45
    |
-LL |     let _ = iterator.filter_map(|x| return x);
-   |                      ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+LL |         copy_vec_non_inferred().into_iter().filter_map(|x| return x);
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
 
-error: aborting due to 4 previous errors
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:36:45
+   |
+LL |         copy_vec_non_inferred().into_iter().filter_map(|x| return x);
+   |                                             ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:39:36
+   |
+LL |         non_copy_vec().into_iter().filter_map(|x| x);
+   |                                    ^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:41:36
+   |
+LL |         non_copy_vec().into_iter().filter_map(|x| x);
+   |                                    ^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:44:36
+   |
+LL |         non_copy_vec().into_iter().filter_map(std::convert::identity);
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:46:36
+   |
+LL |         non_copy_vec().into_iter().filter_map(identity);
+   |                                    ^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:48:36
+   |
+LL |         non_copy_vec().into_iter().filter_map(|x| return x);
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:50:36
+   |
+LL |         non_copy_vec().into_iter().filter_map(|x| return x);
+   |                                    ^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:53:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:55:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:57:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:59:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<_>| return x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:63:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:65:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:67:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:69:39
+   |
+LL |         copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| return x);
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:72:43
+   |
+LL |             copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ x }});
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:75:43
+   |
+LL |             copy_vec::<i32>().into_iter().filter_map(|x: Option<i32>| -> Option<i32> {{ return x }});
+   |                                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: use of `filter_map` with an identity function
+  --> tests/ui/filter_map_identity.rs:80:37
+   |
+LL |         opaque::<i32>().into_iter().filter_map(|x| x);
+   |                                     ^^^^^^^^^^^^^^^^^ help: try: `flatten()`
+
+error: aborting due to 22 previous errors
 
diff --git a/src/tools/clippy/tests/ui/large_stack_frames.rs b/src/tools/clippy/tests/ui/large_stack_frames.rs
index f32368f9397..e6c030b8a9e 100644
--- a/src/tools/clippy/tests/ui/large_stack_frames.rs
+++ b/src/tools/clippy/tests/ui/large_stack_frames.rs
@@ -1,3 +1,5 @@
+//@ normalize-stderr-test: "\b10000(08|16|32)\b" -> "100$$PTR"
+//@ normalize-stderr-test: "\b2500(060|120)\b" -> "250$$PTR"
 #![allow(unused, incomplete_features)]
 #![warn(clippy::large_stack_frames)]
 #![feature(unsized_locals)]
@@ -23,8 +25,7 @@ impl<const N: usize> Default for ArrayDefault<N> {
 }
 
 fn many_small_arrays() {
-    //~^ ERROR: this function allocates a large amount of stack space
-    //~| NOTE: allocating large amounts of stack space can overflow the stack
+    //~^ ERROR: this function may allocate
     let x = [0u8; 500_000];
     let x2 = [0u8; 500_000];
     let x3 = [0u8; 500_000];
@@ -34,17 +35,21 @@ fn many_small_arrays() {
 }
 
 fn large_return_value() -> ArrayDefault<1_000_000> {
-    //~^ ERROR: this function allocates a large amount of stack space
-    //~| NOTE: allocating large amounts of stack space can overflow the stack
+    //~^ ERROR: this function may allocate 1000000 bytes on the stack
     Default::default()
 }
 
 fn large_fn_arg(x: ArrayDefault<1_000_000>) {
-    //~^ ERROR: this function allocates a large amount of stack space
-    //~| NOTE: allocating large amounts of stack space can overflow the stack
+    //~^ ERROR: this function may allocate
     black_box(&x);
 }
 
+fn has_large_closure() {
+    let f = || black_box(&[0u8; 1_000_000]);
+    //~^ ERROR: this function may allocate
+    f();
+}
+
 fn main() {
     generic::<ArrayDefault<1_000_000>>();
 }
diff --git a/src/tools/clippy/tests/ui/large_stack_frames.stderr b/src/tools/clippy/tests/ui/large_stack_frames.stderr
index b99500fd9c3..f2e0a127f5f 100644
--- a/src/tools/clippy/tests/ui/large_stack_frames.stderr
+++ b/src/tools/clippy/tests/ui/large_stack_frames.stderr
@@ -1,42 +1,42 @@
-error: this function allocates a large amount of stack space
-  --> tests/ui/large_stack_frames.rs:25:1
-   |
-LL | / fn many_small_arrays() {
-LL | |
-LL | |
-LL | |     let x = [0u8; 500_000];
-...  |
-LL | |     black_box((&x, &x2, &x3, &x4, &x5));
-LL | | }
-   | |_^
-   |
-   = note: allocating large amounts of stack space can overflow the stack
+error: this function may allocate 250$PTR bytes on the stack
+  --> tests/ui/large_stack_frames.rs:27:4
+   |
+LL | fn many_small_arrays() {
+   |    ^^^^^^^^^^^^^^^^^
+...
+LL |     let x5 = [0u8; 500_000];
+   |         -- `x5` is the largest part, at 500000 bytes for type `[u8; 500000]`
+   |
+   = note: 250$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000
+   = note: allocating large amounts of stack space can overflow the stack and cause the program to abort
    = note: `-D clippy::large-stack-frames` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::large_stack_frames)]`
 
-error: this function allocates a large amount of stack space
-  --> tests/ui/large_stack_frames.rs:36:1
+error: this function may allocate 1000000 bytes on the stack
+  --> tests/ui/large_stack_frames.rs:37:4
+   |
+LL | fn large_return_value() -> ArrayDefault<1_000_000> {
+   |    ^^^^^^^^^^^^^^^^^^      ----------------------- this is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
+   |
+   = note: 1000000 bytes is larger than Clippy's configured `stack-size-threshold` of 512000
+
+error: this function may allocate 100$PTR bytes on the stack
+  --> tests/ui/large_stack_frames.rs:42:4
    |
-LL | / fn large_return_value() -> ArrayDefault<1_000_000> {
-LL | |
-LL | |
-LL | |     Default::default()
-LL | | }
-   | |_^
+LL | fn large_fn_arg(x: ArrayDefault<1_000_000>) {
+   |    ^^^^^^^^^^^^ - `x` is the largest part, at 1000000 bytes for type `ArrayDefault<1000000>`
    |
-   = note: allocating large amounts of stack space can overflow the stack
+   = note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000
 
-error: this function allocates a large amount of stack space
-  --> tests/ui/large_stack_frames.rs:42:1
+error: this function may allocate 100$PTR bytes on the stack
+  --> tests/ui/large_stack_frames.rs:48:13
    |
-LL | / fn large_fn_arg(x: ArrayDefault<1_000_000>) {
-LL | |
-LL | |
-LL | |     black_box(&x);
-LL | | }
-   | |_^
+LL |     let f = || black_box(&[0u8; 1_000_000]);
+   |             ^^^^^^^^^^^^^^----------------^
+   |                           |
+   |                           this is the largest part, at 1000000 bytes for type `[u8; 1000000]`
    |
-   = note: allocating large amounts of stack space can overflow the stack
+   = note: 100$PTR bytes is larger than Clippy's configured `stack-size-threshold` of 512000
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed b/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
new file mode 100644
index 00000000000..a6ef8f8c119
--- /dev/null
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.fixed
@@ -0,0 +1,117 @@
+//@aux-build:proc_macros.rs
+#![allow(clippy::no_effect, deprecated, unused)]
+#![allow(clippy::legacy_numeric_constants)] // For imports.
+
+#[macro_use]
+extern crate proc_macros;
+
+pub mod a {
+    pub use std::u128;
+}
+
+macro_rules! b {
+    () => {
+        mod b {
+            #[warn(clippy::legacy_numeric_constants)]
+            fn b() {
+                let x = u64::MAX;
+                //~^ ERROR: usage of a legacy numeric constant
+                //~| HELP: use the associated constant instead
+            }
+        }
+    };
+}
+
+use std::u32::MAX;
+use std::u8::MIN;
+use std::{f64, u32};
+
+#[warn(clippy::legacy_numeric_constants)]
+fn main() {
+    f32::EPSILON;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    u8::MIN;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    usize::MIN;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    u32::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    u32::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    u32::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    i32::MAX;
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    u8::MAX;
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    u8::MIN;
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    u8::MIN;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    ::std::primitive::u8::MIN;
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    std::primitive::i32::MAX;
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    u128::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    u32::MAX;
+    u128::MAX;
+    f32::EPSILON;
+    ::std::primitive::u8::MIN;
+    std::f32::consts::E;
+    f64::consts::E;
+    u8::MIN;
+    std::f32::consts::E;
+    f64::consts::E;
+    b!();
+
+    [(0, "", i128::MAX)];
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+}
+
+#[warn(clippy::legacy_numeric_constants)]
+fn ext() {
+    external! {
+        ::std::primitive::u8::MIN;
+        ::std::u8::MIN;
+        ::std::primitive::u8::min_value();
+        use std::u64;
+        use std::u8::MIN;
+    }
+}
+
+#[allow(clippy::legacy_numeric_constants)]
+fn allow() {
+    ::std::primitive::u8::MIN;
+    ::std::u8::MIN;
+    ::std::primitive::u8::min_value();
+    use std::u64;
+    use std::u8::MIN;
+}
+
+#[warn(clippy::legacy_numeric_constants)]
+#[clippy::msrv = "1.42.0"]
+fn msrv_too_low() {
+    std::u32::MAX;
+}
+
+#[warn(clippy::legacy_numeric_constants)]
+#[clippy::msrv = "1.43.0"]
+fn msrv_juust_right() {
+    u32::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+}
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.rs b/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
new file mode 100644
index 00000000000..cd633545372
--- /dev/null
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.rs
@@ -0,0 +1,117 @@
+//@aux-build:proc_macros.rs
+#![allow(clippy::no_effect, deprecated, unused)]
+#![allow(clippy::legacy_numeric_constants)] // For imports.
+
+#[macro_use]
+extern crate proc_macros;
+
+pub mod a {
+    pub use std::u128;
+}
+
+macro_rules! b {
+    () => {
+        mod b {
+            #[warn(clippy::legacy_numeric_constants)]
+            fn b() {
+                let x = std::u64::MAX;
+                //~^ ERROR: usage of a legacy numeric constant
+                //~| HELP: use the associated constant instead
+            }
+        }
+    };
+}
+
+use std::u32::MAX;
+use std::u8::MIN;
+use std::{f64, u32};
+
+#[warn(clippy::legacy_numeric_constants)]
+fn main() {
+    std::f32::EPSILON;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    std::u8::MIN;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    std::usize::MIN;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    std::u32::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    core::u32::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    i32::max_value();
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    u8::max_value();
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    u8::min_value();
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    ::std::u8::MIN;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    ::std::primitive::u8::min_value();
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    std::primitive::i32::max_value();
+    //~^ ERROR: usage of a legacy numeric method
+    //~| HELP: use the associated constant instead
+    self::a::u128::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+    u32::MAX;
+    u128::MAX;
+    f32::EPSILON;
+    ::std::primitive::u8::MIN;
+    std::f32::consts::E;
+    f64::consts::E;
+    u8::MIN;
+    std::f32::consts::E;
+    f64::consts::E;
+    b!();
+
+    [(0, "", std::i128::MAX)];
+    //~^ ERROR: usage of a legacy numeric constant
+    //~| HELP: use the associated constant instead
+}
+
+#[warn(clippy::legacy_numeric_constants)]
+fn ext() {
+    external! {
+        ::std::primitive::u8::MIN;
+        ::std::u8::MIN;
+        ::std::primitive::u8::min_value();
+        use std::u64;
+        use std::u8::MIN;
+    }
+}
+
+#[allow(clippy::legacy_numeric_constants)]
+fn allow() {
+    ::std::primitive::u8::MIN;
+    ::std::u8::MIN;
+    ::std::primitive::u8::min_value();
+    use std::u64;
+    use std::u8::MIN;
+}
+
+#[warn(clippy::legacy_numeric_constants)]
+#[clippy::msrv = "1.42.0"]
+fn msrv_too_low() {
+    std::u32::MAX;
+}
+
+#[warn(clippy::legacy_numeric_constants)]
+#[clippy::msrv = "1.43.0"]
+fn msrv_juust_right() {
+    std::u32::MAX;
+    //~^ ERROR: usage of a legacy numeric constant
+}
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
new file mode 100644
index 00000000000..267b9ac8e4d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants.stderr
@@ -0,0 +1,184 @@
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:31:5
+   |
+LL |     std::f32::EPSILON;
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]`
+help: use the associated constant instead
+   |
+LL |     f32::EPSILON;
+   |     ~~~~~~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:34:5
+   |
+LL |     std::u8::MIN;
+   |     ^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u8::MIN;
+   |     ~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:37:5
+   |
+LL |     std::usize::MIN;
+   |     ^^^^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     usize::MIN;
+   |     ~~~~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:40:5
+   |
+LL |     std::u32::MAX;
+   |     ^^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u32::MAX;
+   |     ~~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:43:5
+   |
+LL |     core::u32::MAX;
+   |     ^^^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u32::MAX;
+   |     ~~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:46:5
+   |
+LL |     MAX;
+   |     ^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u32::MAX;
+   |     ~~~~~~~~
+
+error: usage of a legacy numeric method
+  --> tests/ui/legacy_numeric_constants.rs:49:10
+   |
+LL |     i32::max_value();
+   |          ^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     i32::MAX;
+   |          ~~~
+
+error: usage of a legacy numeric method
+  --> tests/ui/legacy_numeric_constants.rs:52:9
+   |
+LL |     u8::max_value();
+   |         ^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u8::MAX;
+   |         ~~~
+
+error: usage of a legacy numeric method
+  --> tests/ui/legacy_numeric_constants.rs:55:9
+   |
+LL |     u8::min_value();
+   |         ^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u8::MIN;
+   |         ~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:58:5
+   |
+LL |     ::std::u8::MIN;
+   |     ^^^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u8::MIN;
+   |     ~~~~~~~
+
+error: usage of a legacy numeric method
+  --> tests/ui/legacy_numeric_constants.rs:61:27
+   |
+LL |     ::std::primitive::u8::min_value();
+   |                           ^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     ::std::primitive::u8::MIN;
+   |                           ~~~
+
+error: usage of a legacy numeric method
+  --> tests/ui/legacy_numeric_constants.rs:64:26
+   |
+LL |     std::primitive::i32::max_value();
+   |                          ^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     std::primitive::i32::MAX;
+   |                          ~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:67:5
+   |
+LL |     self::a::u128::MAX;
+   |     ^^^^^^^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u128::MAX;
+   |     ~~~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:17:25
+   |
+LL |                 let x = std::u64::MAX;
+   |                         ^^^^^^^^^^^^^
+...
+LL |     b!();
+   |     ---- in this macro invocation
+   |
+   = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use the associated constant instead
+   |
+LL |                 let x = u64::MAX;
+   |                         ~~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:81:14
+   |
+LL |     [(0, "", std::i128::MAX)];
+   |              ^^^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     [(0, "", i128::MAX)];
+   |              ~~~~~~~~~
+
+error: usage of a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants.rs:115:5
+   |
+LL |     std::u32::MAX;
+   |     ^^^^^^^^^^^^^
+   |
+help: use the associated constant instead
+   |
+LL |     u32::MAX;
+   |     ~~~~~~~~
+
+error: aborting due to 16 previous errors
+
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.rs b/src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.rs
new file mode 100644
index 00000000000..86738ede210
--- /dev/null
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.rs
@@ -0,0 +1,78 @@
+//@no-rustfix
+//@aux-build:proc_macros.rs
+#![allow(clippy::no_effect, deprecated, unused)]
+#![warn(clippy::legacy_numeric_constants)]
+
+#[macro_use]
+extern crate proc_macros;
+
+use std::u128 as _;
+//~^ ERROR: importing legacy numeric constants
+//~| HELP: remove this import
+pub mod a {
+    pub use std::{mem, u128};
+    //~^ ERROR: importing legacy numeric constants
+    //~| HELP: remove this import
+}
+
+macro_rules! b {
+    () => {
+        mod b {
+            use std::u32;
+            //~^ ERROR: importing legacy numeric constants
+            //~| HELP: remove this import
+        }
+    };
+}
+
+fn main() {
+    use std::u32::MAX;
+    //~^ ERROR: importing a legacy numeric constant
+    //~| HELP: remove this import and use the associated constant `u32::MAX`
+    use std::u8::MIN;
+    //~^ ERROR: importing a legacy numeric constant
+    //~| HELP: remove this import and use the associated constant `u8::MIN`
+    f64::MAX;
+    use std::u32;
+    //~^ ERROR: importing legacy numeric constants
+    //~| HELP: remove this import
+    u32::MAX;
+    use std::f32::MIN_POSITIVE;
+    //~^ ERROR: importing a legacy numeric constant
+    //~| HELP: remove this import and use the associated constant `f32::MIN_POSITIVE`
+    use std::f64;
+    use std::i16::*;
+    //~^ ERROR: importing legacy numeric constants
+    //~| HELP: remove this import and use associated constants `i16::<CONST>`
+    u128::MAX;
+    f32::EPSILON;
+    f64::EPSILON;
+    ::std::primitive::u8::MIN;
+    std::f32::consts::E;
+    f64::consts::E;
+    u8::MIN;
+    std::f32::consts::E;
+    f64::consts::E;
+    b!();
+}
+
+fn ext() {
+    external! {
+        ::std::primitive::u8::MIN;
+        ::std::u8::MIN;
+        ::std::primitive::u8::min_value();
+        use std::u64;
+        use std::u8::MIN;
+    }
+}
+
+#[clippy::msrv = "1.42.0"]
+fn msrv_too_low() {
+    use std::u32::MAX;
+}
+
+#[clippy::msrv = "1.43.0"]
+fn msrv_juust_right() {
+    use std::u32::MAX;
+    //~^ ERROR: importing a legacy numeric constant
+}
diff --git a/src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.stderr b/src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.stderr
new file mode 100644
index 00000000000..2edcf718836
--- /dev/null
+++ b/src/tools/clippy/tests/ui/legacy_numeric_constants_unfixable.stderr
@@ -0,0 +1,83 @@
+error: importing legacy numeric constants
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:9:5
+   |
+LL | use std::u128 as _;
+   |     ^^^^^^^^^
+   |
+   = help: remove this import
+   = note: `-D clippy::legacy-numeric-constants` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::legacy_numeric_constants)]`
+
+error: importing legacy numeric constants
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:13:24
+   |
+LL |     pub use std::{mem, u128};
+   |                        ^^^^
+   |
+   = help: remove this import
+   = note: then `u128::<CONST>` will resolve to the respective associated constant
+
+error: importing a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:29:9
+   |
+LL |     use std::u32::MAX;
+   |         ^^^^^^^^^^^^^
+   |
+   = help: remove this import and use the associated constant `u32::MAX` from the primitive type instead
+
+error: importing a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:32:9
+   |
+LL |     use std::u8::MIN;
+   |         ^^^^^^^^^^^^
+   |
+   = help: remove this import and use the associated constant `u8::MIN` from the primitive type instead
+
+error: importing legacy numeric constants
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:36:9
+   |
+LL |     use std::u32;
+   |         ^^^^^^^^
+   |
+   = help: remove this import
+   = note: then `u32::<CONST>` will resolve to the respective associated constant
+
+error: importing a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:40:9
+   |
+LL |     use std::f32::MIN_POSITIVE;
+   |         ^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: remove this import and use the associated constant `f32::MIN_POSITIVE` from the primitive type instead
+
+error: importing legacy numeric constants
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:44:9
+   |
+LL |     use std::i16::*;
+   |         ^^^^^^^^
+   |
+   = help: remove this import and use associated constants `i16::<CONST>` from the primitive type instead
+
+error: importing legacy numeric constants
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:21:17
+   |
+LL |             use std::u32;
+   |                 ^^^^^^^^
+...
+LL |     b!();
+   |     ---- in this macro invocation
+   |
+   = help: remove this import
+   = note: then `u32::<CONST>` will resolve to the respective associated constant
+   = note: this error originates in the macro `b` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: importing a legacy numeric constant
+  --> tests/ui/legacy_numeric_constants_unfixable.rs:76:9
+   |
+LL |     use std::u32::MAX;
+   |         ^^^^^^^^^^^^^
+   |
+   = help: remove this import and use the associated constant `u32::MAX` from the primitive type instead
+
+error: aborting due to 9 previous errors
+
diff --git a/src/tools/clippy/tests/ui/len_zero.fixed b/src/tools/clippy/tests/ui/len_zero.fixed
index c16d7a26616..27319d9c20e 100644
--- a/src/tools/clippy/tests/ui/len_zero.fixed
+++ b/src/tools/clippy/tests/ui/len_zero.fixed
@@ -189,3 +189,40 @@ fn main() {
 fn test_slice(b: &[u8]) {
     if !b.is_empty() {}
 }
+
+// issue #11992
+fn binop_with_macros() {
+    macro_rules! len {
+        ($seq:ident) => {
+            $seq.len()
+        };
+    }
+
+    macro_rules! compare_to {
+        ($val:literal) => {
+            $val
+        };
+        ($val:expr) => {{ $val }};
+    }
+
+    macro_rules! zero {
+        () => {
+            0
+        };
+    }
+
+    let has_is_empty = HasIsEmpty;
+    // Don't lint, suggesting changes might break macro compatibility.
+    (len!(has_is_empty) > 0).then(|| println!("This can happen."));
+    // Don't lint, suggesting changes might break macro compatibility.
+    if len!(has_is_empty) == 0 {}
+    // Don't lint
+    if has_is_empty.len() == compare_to!(if true { 0 } else { 1 }) {}
+    // This is fine
+    if has_is_empty.len() == compare_to!(1) {}
+
+    if has_is_empty.is_empty() {}
+    if has_is_empty.is_empty() {}
+
+    (!has_is_empty.is_empty()).then(|| println!("This can happen."));
+}
diff --git a/src/tools/clippy/tests/ui/len_zero.rs b/src/tools/clippy/tests/ui/len_zero.rs
index 5c49a5abf81..03c05bc6ed7 100644
--- a/src/tools/clippy/tests/ui/len_zero.rs
+++ b/src/tools/clippy/tests/ui/len_zero.rs
@@ -189,3 +189,40 @@ fn main() {
 fn test_slice(b: &[u8]) {
     if b.len() != 0 {}
 }
+
+// issue #11992
+fn binop_with_macros() {
+    macro_rules! len {
+        ($seq:ident) => {
+            $seq.len()
+        };
+    }
+
+    macro_rules! compare_to {
+        ($val:literal) => {
+            $val
+        };
+        ($val:expr) => {{ $val }};
+    }
+
+    macro_rules! zero {
+        () => {
+            0
+        };
+    }
+
+    let has_is_empty = HasIsEmpty;
+    // Don't lint, suggesting changes might break macro compatibility.
+    (len!(has_is_empty) > 0).then(|| println!("This can happen."));
+    // Don't lint, suggesting changes might break macro compatibility.
+    if len!(has_is_empty) == 0 {}
+    // Don't lint
+    if has_is_empty.len() == compare_to!(if true { 0 } else { 1 }) {}
+    // This is fine
+    if has_is_empty.len() == compare_to!(1) {}
+
+    if has_is_empty.len() == compare_to!(0) {}
+    if has_is_empty.len() == zero!() {}
+
+    (compare_to!(0) < has_is_empty.len()).then(|| println!("This can happen."));
+}
diff --git a/src/tools/clippy/tests/ui/len_zero.stderr b/src/tools/clippy/tests/ui/len_zero.stderr
index dd07a85d62c..5c849a2aca6 100644
--- a/src/tools/clippy/tests/ui/len_zero.stderr
+++ b/src/tools/clippy/tests/ui/len_zero.stderr
@@ -142,5 +142,23 @@ error: length comparison to zero
 LL |     if b.len() != 0 {}
    |        ^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!b.is_empty()`
 
-error: aborting due to 23 previous errors
+error: length comparison to zero
+  --> tests/ui/len_zero.rs:224:8
+   |
+LL |     if has_is_empty.len() == compare_to!(0) {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`
+
+error: length comparison to zero
+  --> tests/ui/len_zero.rs:225:8
+   |
+LL |     if has_is_empty.len() == zero!() {}
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `is_empty` is clearer and more explicit: `has_is_empty.is_empty()`
+
+error: length comparison to zero
+  --> tests/ui/len_zero.rs:227:6
+   |
+LL |     (compare_to!(0) < has_is_empty.len()).then(|| println!("This can happen."));
+   |      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: using `!is_empty` is clearer and more explicit: `!has_is_empty.is_empty()`
+
+error: aborting due to 26 previous errors
 
diff --git a/src/tools/clippy/tests/ui/let_and_return.fixed b/src/tools/clippy/tests/ui/let_and_return.fixed
index b5584fcde8c..4187019e589 100644
--- a/src/tools/clippy/tests/ui/let_and_return.fixed
+++ b/src/tools/clippy/tests/ui/let_and_return.fixed
@@ -203,4 +203,11 @@ fn_in_macro!({
     return 1;
 });
 
+fn issue9150() -> usize {
+    let x = 1;
+    #[cfg(any())]
+    panic!("can't see me");
+    x
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/let_and_return.rs b/src/tools/clippy/tests/ui/let_and_return.rs
index f13c7c4e203..54444957b7d 100644
--- a/src/tools/clippy/tests/ui/let_and_return.rs
+++ b/src/tools/clippy/tests/ui/let_and_return.rs
@@ -203,4 +203,11 @@ fn_in_macro!({
     return 1;
 });
 
+fn issue9150() -> usize {
+    let x = 1;
+    #[cfg(any())]
+    panic!("can't see me");
+    x
+}
+
 fn main() {}
diff --git a/src/tools/clippy/tests/ui/let_unit.fixed b/src/tools/clippy/tests/ui/let_unit.fixed
index 4d41b5e5e50..20940daffa7 100644
--- a/src/tools/clippy/tests/ui/let_unit.fixed
+++ b/src/tools/clippy/tests/ui/let_unit.fixed
@@ -177,3 +177,21 @@ async fn issue10433() {
 }
 
 pub async fn issue11502(a: ()) {}
+
+pub fn issue12594() {
+    fn returns_unit() {}
+
+    fn returns_result<T>(res: T) -> Result<T, ()> {
+        Ok(res)
+    }
+
+    fn actual_test() {
+        // create first a unit value'd value
+        returns_unit();
+        returns_result(()).unwrap();
+        returns_result(()).unwrap();
+        // make sure we replace only the first variable
+        let res = 1;
+        returns_result(res).unwrap();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/let_unit.rs b/src/tools/clippy/tests/ui/let_unit.rs
index daa660be25e..dca66f2e3ed 100644
--- a/src/tools/clippy/tests/ui/let_unit.rs
+++ b/src/tools/clippy/tests/ui/let_unit.rs
@@ -177,3 +177,21 @@ async fn issue10433() {
 }
 
 pub async fn issue11502(a: ()) {}
+
+pub fn issue12594() {
+    fn returns_unit() {}
+
+    fn returns_result<T>(res: T) -> Result<T, ()> {
+        Ok(res)
+    }
+
+    fn actual_test() {
+        // create first a unit value'd value
+        let res = returns_unit();
+        returns_result(res).unwrap();
+        returns_result(res).unwrap();
+        // make sure we replace only the first variable
+        let res = 1;
+        returns_result(res).unwrap();
+    }
+}
diff --git a/src/tools/clippy/tests/ui/let_unit.stderr b/src/tools/clippy/tests/ui/let_unit.stderr
index 0f1f3d78223..aafb77bcd0d 100644
--- a/src/tools/clippy/tests/ui/let_unit.stderr
+++ b/src/tools/clippy/tests/ui/let_unit.stderr
@@ -51,5 +51,24 @@ LL +         Some(_) => (),
 LL +     };
    |
 
-error: aborting due to 3 previous errors
+error: this let-binding has unit value
+  --> tests/ui/let_unit.rs:190:9
+   |
+LL |         let res = returns_unit();
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: omit the `let` binding
+   |
+LL |         returns_unit();
+   |
+help: variable `res` of type `()` can be replaced with explicit `()`
+   |
+LL |         returns_result(()).unwrap();
+   |                        ~~
+help: variable `res` of type `()` can be replaced with explicit `()`
+   |
+LL |         returns_result(()).unwrap();
+   |                        ~~
+
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
index 75beedfa450..75835780801 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.fixed
@@ -66,3 +66,11 @@ fn issue7730(a: u8) {
 // comment after `panic!`
 assert!(!(a > 2), "panic with comment");
 }
+
+fn issue12505() {
+    struct Foo<T, const N: usize>(T);
+
+    impl<T, const N: usize> Foo<T, N> {
+        const BAR: () = assert!(!(N == 0), );
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
index 57015933d40..1eebe1bfe17 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2018.stderr
@@ -82,5 +82,14 @@ help: try instead
 LL |     assert!(!(a > 2), "panic with comment");
    |
 
-error: aborting due to 9 previous errors
+error: only a `panic!` in `if`-then statement
+  --> tests/ui/manual_assert.rs:91:25
+   |
+LL |           const BAR: () = if N == 0 {
+   |  _________________________^
+LL | |             panic!()
+LL | |         };
+   | |_________^ help: try instead: `assert!(!(N == 0), )`
+
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
index 75beedfa450..75835780801 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.fixed
@@ -66,3 +66,11 @@ fn issue7730(a: u8) {
 // comment after `panic!`
 assert!(!(a > 2), "panic with comment");
 }
+
+fn issue12505() {
+    struct Foo<T, const N: usize>(T);
+
+    impl<T, const N: usize> Foo<T, N> {
+        const BAR: () = assert!(!(N == 0), );
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
index 57015933d40..1eebe1bfe17 100644
--- a/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
+++ b/src/tools/clippy/tests/ui/manual_assert.edition2021.stderr
@@ -82,5 +82,14 @@ help: try instead
 LL |     assert!(!(a > 2), "panic with comment");
    |
 
-error: aborting due to 9 previous errors
+error: only a `panic!` in `if`-then statement
+  --> tests/ui/manual_assert.rs:91:25
+   |
+LL |           const BAR: () = if N == 0 {
+   |  _________________________^
+LL | |             panic!()
+LL | |         };
+   | |_________^ help: try instead: `assert!(!(N == 0), )`
+
+error: aborting due to 10 previous errors
 
diff --git a/src/tools/clippy/tests/ui/manual_assert.rs b/src/tools/clippy/tests/ui/manual_assert.rs
index 5979496ca83..363bafdf05d 100644
--- a/src/tools/clippy/tests/ui/manual_assert.rs
+++ b/src/tools/clippy/tests/ui/manual_assert.rs
@@ -83,3 +83,13 @@ fn issue7730(a: u8) {
         panic!("panic with comment") // comment after `panic!`
     }
 }
+
+fn issue12505() {
+    struct Foo<T, const N: usize>(T);
+
+    impl<T, const N: usize> Foo<T, N> {
+        const BAR: () = if N == 0 {
+            panic!()
+        };
+    }
+}
diff --git a/src/tools/clippy/tests/ui/manual_clamp.fixed b/src/tools/clippy/tests/ui/manual_clamp.fixed
index c5355cce8e2..8d57cbbf51b 100644
--- a/src/tools/clippy/tests/ui/manual_clamp.fixed
+++ b/src/tools/clippy/tests/ui/manual_clamp.fixed
@@ -17,48 +17,171 @@ const CONST_F64_MIN: f64 = 4.0;
 
 fn main() {
     let (input, min, max) = (0, -2, 3);
-    // Lint
-    let x0 = input.clamp(min, max);
+    // Min and max are not const, so this shouldn't trigger the lint.
+    let x0 = if max < input {
+        max
+    } else if min > input {
+        min
+    } else {
+        input
+    };
+
+    let x1 = if input > max {
+        max
+    } else if input < min {
+        min
+    } else {
+        input
+    };
+
+    let x2 = if input < min {
+        min
+    } else if input > max {
+        max
+    } else {
+        input
+    };
 
-    let x1 = input.clamp(min, max);
+    let x3 = if min > input {
+        min
+    } else if max < input {
+        max
+    } else {
+        input
+    };
 
-    let x2 = input.clamp(min, max);
+    let x4 = input.max(min).min(max);
 
-    let x3 = input.clamp(min, max);
+    let x5 = input.min(max).max(min);
+
+    let x6 = match input {
+        x if x > max => max,
+        x if x < min => min,
+        x => x,
+    };
 
-    let x4 = input.clamp(min, max);
+    let x7 = match input {
+        x if x < min => min,
+        x if x > max => max,
+        x => x,
+    };
+
+    let x8 = match input {
+        x if max < x => max,
+        x if min > x => min,
+        x => x,
+    };
+
+    let mut x9 = input;
+    if x9 < min {
+        x9 = min;
+    }
+    if x9 > max {
+        x9 = max;
+    }
+
+    let x10 = match input {
+        x if min > x => min,
+        x if max < x => max,
+        x => x,
+    };
+
+    let mut x11 = input;
+    let _ = 1;
+    if x11 > max {
+        x11 = max;
+    }
+    if x11 < min {
+        x11 = min;
+    }
+
+    let mut x12 = input;
+    if min > x12 {
+        x12 = min;
+    }
+    if max < x12 {
+        x12 = max;
+    }
+
+    let mut x13 = input;
+    if max < x13 {
+        x13 = max;
+    }
+    if min > x13 {
+        x13 = min;
+    }
+
+    {
+        let (input, min, max) = (0.0f64, -2.0, 3.0);
+        let x14 = if input > max {
+            max
+        } else if input < min {
+            min
+        } else {
+            input
+        };
+    }
+    let mut x15 = input;
+    if x15 < min {
+        x15 = min;
+    } else if x15 > max {
+        x15 = max;
+    }
+
+    // It's important this be the last set of statements
+    let mut x16 = input;
+    if max < x16 {
+        x16 = max;
+    }
+    if min > x16 {
+        x16 = min;
+    }
+}
+
+fn const_main() {
+    let input = 0;
+    // Min and max are const, so this should trigger the lint.
+    let x0 = input.clamp(CONST_MIN, CONST_MAX);
+
+    let x1 = input.clamp(CONST_MIN, CONST_MAX);
+
+    let x2 = input.clamp(CONST_MIN, CONST_MAX);
+
+    let x3 = input.clamp(CONST_MIN, CONST_MAX);
+
+    let x4 = input.clamp(CONST_MIN, CONST_MAX);
     //~^ ERROR: clamp-like pattern without using clamp function
     //~| NOTE: clamp will panic if max < min
 
-    let x5 = input.clamp(min, max);
+    let x5 = input.clamp(CONST_MIN, CONST_MAX);
     //~^ ERROR: clamp-like pattern without using clamp function
     //~| NOTE: clamp will panic if max < min
 
-    let x6 = input.clamp(min, max);
+    let x6 = input.clamp(CONST_MIN, CONST_MAX);
 
-    let x7 = input.clamp(min, max);
+    let x7 = input.clamp(CONST_MIN, CONST_MAX);
 
-    let x8 = input.clamp(min, max);
+    let x8 = input.clamp(CONST_MIN, CONST_MAX);
 
     let mut x9 = input;
-    x9 = x9.clamp(min, max);
+    x9 = x9.clamp(CONST_MIN, CONST_MAX);
 
-    let x10 = input.clamp(min, max);
+    let x10 = input.clamp(CONST_MIN, CONST_MAX);
 
     let mut x11 = input;
     let _ = 1;
-    x11 = x11.clamp(min, max);
+    x11 = x11.clamp(CONST_MIN, CONST_MAX);
 
     let mut x12 = input;
-    x12 = x12.clamp(min, max);
+    x12 = x12.clamp(CONST_MIN, CONST_MAX);
 
     let mut x13 = input;
-    x13 = x13.clamp(min, max);
+    x13 = x13.clamp(CONST_MIN, CONST_MAX);
 
     let x14 = input.clamp(CONST_MIN, CONST_MAX);
     {
-        let (input, min, max) = (0.0f64, -2.0, 3.0);
-        let x15 = input.clamp(min, max);
+        let input = 0.0f64;
+        let x15 = input.clamp(CONST_F64_MIN, CONST_F64_MAX);
     }
     {
         let input: i32 = cmp_min_max(1);
@@ -114,108 +237,128 @@ fn main() {
         //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
     }
     let mut x32 = input;
-    x32 = x32.clamp(min, max);
+    x32 = x32.clamp(CONST_MIN, CONST_MAX);
 
-    // It's important this be the last set of statements
+    // Flip the script, swap the places of min and max. Make sure this doesn't
+    // trigger when clamp would be guaranteed to panic.
     let mut x33 = input;
-    x33 = x33.clamp(min, max);
+    if x33 < CONST_MAX {
+        x33 = CONST_MAX;
+    } else if x33 > CONST_MIN {
+        x33 = CONST_MIN;
+    }
+
+    // Do it again for NaN
+    #[allow(invalid_nan_comparisons)]
+    {
+        let mut x34 = input as f64;
+        if x34 < f64::NAN {
+            x34 = f64::NAN;
+        } else if x34 > CONST_F64_MAX {
+            x34 = CONST_F64_MAX;
+        }
+    }
+
+    // It's important this be the last set of statements
+    let mut x35 = input;
+    x35 = x35.clamp(CONST_MIN, CONST_MAX);
 }
 
 // This code intentionally nonsense.
 fn no_lint() {
-    let (input, min, max) = (0, -2, 3);
-    let x0 = if max < input {
-        max
-    } else if min > input {
-        max
+    let input = 0;
+    let x0 = if CONST_MAX < input {
+        CONST_MAX
+    } else if CONST_MIN > input {
+        CONST_MAX
     } else {
-        min
+        CONST_MIN
     };
 
-    let x1 = if input > max {
-        max
-    } else if input > min {
-        min
+    let x1 = if input > CONST_MAX {
+        CONST_MAX
+    } else if input > CONST_MIN {
+        CONST_MIN
     } else {
-        max
+        CONST_MAX
     };
 
-    let x2 = if max < min {
-        min
-    } else if input > max {
+    let x2 = if CONST_MAX < CONST_MIN {
+        CONST_MIN
+    } else if input > CONST_MAX {
         input
     } else {
         input
     };
 
-    let x3 = if min > input {
+    let x3 = if CONST_MIN > input {
         input
-    } else if max < input {
-        max
+    } else if CONST_MAX < input {
+        CONST_MAX
     } else {
-        max
+        CONST_MAX
     };
 
     let x6 = match input {
-        x if x < max => x,
-        x if x < min => x,
+        x if x < CONST_MAX => x,
+        x if x < CONST_MIN => x,
         x => x,
     };
 
     let x7 = match input {
-        x if x < min => max,
-        x if x > max => min,
+        x if x < CONST_MIN => CONST_MAX,
+        x if x > CONST_MAX => CONST_MIN,
         x => x,
     };
 
     let x8 = match input {
-        x if max > x => max,
-        x if min > x => min,
+        x if CONST_MAX > x => CONST_MAX,
+        x if CONST_MIN > x => CONST_MIN,
         x => x,
     };
 
     let mut x9 = input;
-    if x9 > min {
-        x9 = min;
+    if x9 > CONST_MIN {
+        x9 = CONST_MIN;
     }
-    if x9 > max {
-        x9 = max;
+    if x9 > CONST_MAX {
+        x9 = CONST_MAX;
     }
 
     let x10 = match input {
-        x if min > x => min,
-        x if max < x => max,
-        x => min,
+        x if CONST_MIN > x => CONST_MIN,
+        x if CONST_MAX < x => CONST_MAX,
+        x => CONST_MIN,
     };
 
     let mut x11 = input;
-    if x11 > max {
-        x11 = min;
+    if x11 > CONST_MAX {
+        x11 = CONST_MIN;
     }
-    if x11 < min {
-        x11 = max;
+    if x11 < CONST_MIN {
+        x11 = CONST_MAX;
     }
 
     let mut x12 = input;
-    if min > x12 {
-        x12 = max * 3;
+    if CONST_MIN > x12 {
+        x12 = CONST_MAX * 3;
     }
-    if max < x12 {
-        x12 = min;
+    if CONST_MAX < x12 {
+        x12 = CONST_MIN;
     }
 
     let mut x13 = input;
-    if max < x13 {
-        let x13 = max;
+    if CONST_MAX < x13 {
+        let x13 = CONST_MAX;
     }
-    if min > x13 {
-        x13 = min;
+    if CONST_MIN > x13 {
+        x13 = CONST_MIN;
     }
     let mut x14 = input;
-    if x14 < min {
+    if x14 < CONST_MIN {
         x14 = 3;
-    } else if x14 > max {
-        x14 = max;
+    } else if x14 > CONST_MAX {
+        x14 = CONST_MAX;
     }
     {
         let input: i32 = cmp_min_max(1);
@@ -272,8 +415,8 @@ fn msrv_1_49() {
 
 #[clippy::msrv = "1.50"]
 fn msrv_1_50() {
-    let (input, min, max) = (0, -1, 2);
-    let _ = input.clamp(min, max);
+    let input = 0;
+    let _ = input.clamp(CONST_MIN, CONST_MAX);
 }
 
 const fn _const() {
diff --git a/src/tools/clippy/tests/ui/manual_clamp.rs b/src/tools/clippy/tests/ui/manual_clamp.rs
index cacb40ae027..4d2a0c47bbd 100644
--- a/src/tools/clippy/tests/ui/manual_clamp.rs
+++ b/src/tools/clippy/tests/ui/manual_clamp.rs
@@ -17,10 +17,8 @@ const CONST_F64_MIN: f64 = 4.0;
 
 fn main() {
     let (input, min, max) = (0, -2, 3);
-    // Lint
+    // Min and max are not const, so this shouldn't trigger the lint.
     let x0 = if max < input {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         max
     } else if min > input {
         min
@@ -29,8 +27,6 @@ fn main() {
     };
 
     let x1 = if input > max {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         max
     } else if input < min {
         min
@@ -39,8 +35,6 @@ fn main() {
     };
 
     let x2 = if input < min {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         min
     } else if input > max {
         max
@@ -49,8 +43,6 @@ fn main() {
     };
 
     let x3 = if min > input {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         min
     } else if max < input {
         max
@@ -59,32 +51,22 @@ fn main() {
     };
 
     let x4 = input.max(min).min(max);
-    //~^ ERROR: clamp-like pattern without using clamp function
-    //~| NOTE: clamp will panic if max < min
 
     let x5 = input.min(max).max(min);
-    //~^ ERROR: clamp-like pattern without using clamp function
-    //~| NOTE: clamp will panic if max < min
 
     let x6 = match input {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x if x > max => max,
         x if x < min => min,
         x => x,
     };
 
     let x7 = match input {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x if x < min => min,
         x if x > max => max,
         x => x,
     };
 
     let x8 = match input {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x if max < x => max,
         x if min > x => min,
         x => x,
@@ -92,8 +74,6 @@ fn main() {
 
     let mut x9 = input;
     if x9 < min {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x9 = min;
     }
     if x9 > max {
@@ -101,8 +81,6 @@ fn main() {
     }
 
     let x10 = match input {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x if min > x => min,
         x if max < x => max,
         x => x,
@@ -111,8 +89,6 @@ fn main() {
     let mut x11 = input;
     let _ = 1;
     if x11 > max {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x11 = max;
     }
     if x11 < min {
@@ -121,8 +97,6 @@ fn main() {
 
     let mut x12 = input;
     if min > x12 {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x12 = min;
     }
     if max < x12 {
@@ -131,14 +105,163 @@ fn main() {
 
     let mut x13 = input;
     if max < x13 {
-        //~^ ERROR: clamp-like pattern without using clamp function
-        //~| NOTE: clamp will panic if max < min
         x13 = max;
     }
     if min > x13 {
         x13 = min;
     }
 
+    {
+        let (input, min, max) = (0.0f64, -2.0, 3.0);
+        let x14 = if input > max {
+            max
+        } else if input < min {
+            min
+        } else {
+            input
+        };
+    }
+    let mut x15 = input;
+    if x15 < min {
+        x15 = min;
+    } else if x15 > max {
+        x15 = max;
+    }
+
+    // It's important this be the last set of statements
+    let mut x16 = input;
+    if max < x16 {
+        x16 = max;
+    }
+    if min > x16 {
+        x16 = min;
+    }
+}
+
+fn const_main() {
+    let input = 0;
+    // Min and max are const, so this should trigger the lint.
+    let x0 = if CONST_MAX < input {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        CONST_MAX
+    } else if CONST_MIN > input {
+        CONST_MIN
+    } else {
+        input
+    };
+
+    let x1 = if input > CONST_MAX {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        CONST_MAX
+    } else if input < CONST_MIN {
+        CONST_MIN
+    } else {
+        input
+    };
+
+    let x2 = if input < CONST_MIN {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        CONST_MIN
+    } else if input > CONST_MAX {
+        CONST_MAX
+    } else {
+        input
+    };
+
+    let x3 = if CONST_MIN > input {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        CONST_MIN
+    } else if CONST_MAX < input {
+        CONST_MAX
+    } else {
+        input
+    };
+
+    let x4 = input.max(CONST_MIN).min(CONST_MAX);
+    //~^ ERROR: clamp-like pattern without using clamp function
+    //~| NOTE: clamp will panic if max < min
+
+    let x5 = input.min(CONST_MAX).max(CONST_MIN);
+    //~^ ERROR: clamp-like pattern without using clamp function
+    //~| NOTE: clamp will panic if max < min
+
+    let x6 = match input {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x if x > CONST_MAX => CONST_MAX,
+        x if x < CONST_MIN => CONST_MIN,
+        x => x,
+    };
+
+    let x7 = match input {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x if x < CONST_MIN => CONST_MIN,
+        x if x > CONST_MAX => CONST_MAX,
+        x => x,
+    };
+
+    let x8 = match input {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x if CONST_MAX < x => CONST_MAX,
+        x if CONST_MIN > x => CONST_MIN,
+        x => x,
+    };
+
+    let mut x9 = input;
+    if x9 < CONST_MIN {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x9 = CONST_MIN;
+    }
+    if x9 > CONST_MAX {
+        x9 = CONST_MAX;
+    }
+
+    let x10 = match input {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x if CONST_MIN > x => CONST_MIN,
+        x if CONST_MAX < x => CONST_MAX,
+        x => x,
+    };
+
+    let mut x11 = input;
+    let _ = 1;
+    if x11 > CONST_MAX {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x11 = CONST_MAX;
+    }
+    if x11 < CONST_MIN {
+        x11 = CONST_MIN;
+    }
+
+    let mut x12 = input;
+    if CONST_MIN > x12 {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x12 = CONST_MIN;
+    }
+    if CONST_MAX < x12 {
+        x12 = CONST_MAX;
+    }
+
+    let mut x13 = input;
+    if CONST_MAX < x13 {
+        //~^ ERROR: clamp-like pattern without using clamp function
+        //~| NOTE: clamp will panic if max < min
+        x13 = CONST_MAX;
+    }
+    if CONST_MIN > x13 {
+        x13 = CONST_MIN;
+    }
+
     let x14 = if input > CONST_MAX {
         //~^ ERROR: clamp-like pattern without using clamp function
         //~| NOTE: clamp will panic if max < min
@@ -149,13 +272,13 @@ fn main() {
         input
     };
     {
-        let (input, min, max) = (0.0f64, -2.0, 3.0);
-        let x15 = if input > max {
+        let input = 0.0f64;
+        let x15 = if input > CONST_F64_MAX {
             //~^ ERROR: clamp-like pattern without using clamp function
-            //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
-            max
-        } else if input < min {
-            min
+            //~| NOTE: clamp will panic if max < min
+            CONST_F64_MAX
+        } else if input < CONST_F64_MIN {
+            CONST_F64_MIN
         } else {
             input
         };
@@ -214,121 +337,141 @@ fn main() {
         //~| NOTE: clamp will panic if max < min, min.is_nan(), or max.is_nan()
     }
     let mut x32 = input;
-    if x32 < min {
+    if x32 < CONST_MIN {
         //~^ ERROR: clamp-like pattern without using clamp function
         //~| NOTE: clamp will panic if max < min
-        x32 = min;
-    } else if x32 > max {
-        x32 = max;
+        x32 = CONST_MIN;
+    } else if x32 > CONST_MAX {
+        x32 = CONST_MAX;
     }
 
-    // It's important this be the last set of statements
+    // Flip the script, swap the places of min and max. Make sure this doesn't
+    // trigger when clamp would be guaranteed to panic.
     let mut x33 = input;
-    if max < x33 {
+    if x33 < CONST_MAX {
+        x33 = CONST_MAX;
+    } else if x33 > CONST_MIN {
+        x33 = CONST_MIN;
+    }
+
+    // Do it again for NaN
+    #[allow(invalid_nan_comparisons)]
+    {
+        let mut x34 = input as f64;
+        if x34 < f64::NAN {
+            x34 = f64::NAN;
+        } else if x34 > CONST_F64_MAX {
+            x34 = CONST_F64_MAX;
+        }
+    }
+
+    // It's important this be the last set of statements
+    let mut x35 = input;
+    if CONST_MAX < x35 {
         //~^ ERROR: clamp-like pattern without using clamp function
         //~| NOTE: clamp will panic if max < min
-        x33 = max;
+        x35 = CONST_MAX;
     }
-    if min > x33 {
-        x33 = min;
+    if CONST_MIN > x35 {
+        x35 = CONST_MIN;
     }
 }
 
 // This code intentionally nonsense.
 fn no_lint() {
-    let (input, min, max) = (0, -2, 3);
-    let x0 = if max < input {
-        max
-    } else if min > input {
-        max
+    let input = 0;
+    let x0 = if CONST_MAX < input {
+        CONST_MAX
+    } else if CONST_MIN > input {
+        CONST_MAX
     } else {
-        min
+        CONST_MIN
     };
 
-    let x1 = if input > max {
-        max
-    } else if input > min {
-        min
+    let x1 = if input > CONST_MAX {
+        CONST_MAX
+    } else if input > CONST_MIN {
+        CONST_MIN
     } else {
-        max
+        CONST_MAX
     };
 
-    let x2 = if max < min {
-        min
-    } else if input > max {
+    let x2 = if CONST_MAX < CONST_MIN {
+        CONST_MIN
+    } else if input > CONST_MAX {
         input
     } else {
         input
     };
 
-    let x3 = if min > input {
+    let x3 = if CONST_MIN > input {
         input
-    } else if max < input {
-        max
+    } else if CONST_MAX < input {
+        CONST_MAX
     } else {
-        max
+        CONST_MAX
     };
 
     let x6 = match input {
-        x if x < max => x,
-        x if x < min => x,
+        x if x < CONST_MAX => x,
+        x if x < CONST_MIN => x,
         x => x,
     };
 
     let x7 = match input {
-        x if x < min => max,
-        x if x > max => min,
+        x if x < CONST_MIN => CONST_MAX,
+        x if x > CONST_MAX => CONST_MIN,
         x => x,
     };
 
     let x8 = match input {
-        x if max > x => max,
-        x if min > x => min,
+        x if CONST_MAX > x => CONST_MAX,
+        x if CONST_MIN > x => CONST_MIN,
         x => x,
     };
 
     let mut x9 = input;
-    if x9 > min {
-        x9 = min;
+    if x9 > CONST_MIN {
+        x9 = CONST_MIN;
     }
-    if x9 > max {
-        x9 = max;
+    if x9 > CONST_MAX {
+        x9 = CONST_MAX;
     }
 
     let x10 = match input {
-        x if min > x => min,
-        x if max < x => max,
-        x => min,
+        x if CONST_MIN > x => CONST_MIN,
+        x if CONST_MAX < x => CONST_MAX,
+        x => CONST_MIN,
     };
 
     let mut x11 = input;
-    if x11 > max {
-        x11 = min;
+    if x11 > CONST_MAX {
+        x11 = CONST_MIN;
     }
-    if x11 < min {
-        x11 = max;
+    if x11 < CONST_MIN {
+        x11 = CONST_MAX;
     }
 
     let mut x12 = input;
-    if min > x12 {
-        x12 = max * 3;
+    if CONST_MIN > x12 {
+        x12 = CONST_MAX * 3;
     }
-    if max < x12 {
-        x12 = min;
+    if CONST_MAX < x12 {
+        x12 = CONST_MIN;
     }
 
     let mut x13 = input;
-    if max < x13 {
-        let x13 = max;
+    if CONST_MAX < x13 {
+        let x13 = CONST_MAX;
     }
-    if min > x13 {
-        x13 = min;
+    if CONST_MIN > x13 {
+        x13 = CONST_MIN;
     }
     let mut x14 = input;
-    if x14 < min {
+    if x14 < CONST_MIN {
         x14 = 3;
-    } else if x14 > max {
-        x14 = max;
+    } else if x14 > CONST_MAX {
+        x14 = CONST_MAX;
     }
     {
         let input: i32 = cmp_min_max(1);
@@ -385,13 +528,13 @@ fn msrv_1_49() {
 
 #[clippy::msrv = "1.50"]
 fn msrv_1_50() {
-    let (input, min, max) = (0, -1, 2);
-    let _ = if input < min {
+    let input = 0;
+    let _ = if input > CONST_MAX {
         //~^ ERROR: clamp-like pattern without using clamp function
         //~| NOTE: clamp will panic if max < min
-        min
-    } else if input > max {
-        max
+        CONST_MAX
+    } else if input < CONST_MIN {
+        CONST_MIN
     } else {
         input
     };
diff --git a/src/tools/clippy/tests/ui/manual_clamp.stderr b/src/tools/clippy/tests/ui/manual_clamp.stderr
index 52c816f2b34..459d46796d8 100644
--- a/src/tools/clippy/tests/ui/manual_clamp.stderr
+++ b/src/tools/clippy/tests/ui/manual_clamp.stderr
@@ -1,213 +1,213 @@
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:94:5
+  --> tests/ui/manual_clamp.rs:217:5
    |
-LL | /     if x9 < min {
+LL | /     if x9 < CONST_MIN {
 LL | |
 LL | |
-LL | |         x9 = min;
+LL | |         x9 = CONST_MIN;
 ...  |
-LL | |         x9 = max;
+LL | |         x9 = CONST_MAX;
 LL | |     }
-   | |_____^ help: replace with clamp: `x9 = x9.clamp(min, max);`
+   | |_____^ help: replace with clamp: `x9 = x9.clamp(CONST_MIN, CONST_MAX);`
    |
    = note: clamp will panic if max < min
    = note: `-D clippy::manual-clamp` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::manual_clamp)]`
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:113:5
+  --> tests/ui/manual_clamp.rs:236:5
    |
-LL | /     if x11 > max {
+LL | /     if x11 > CONST_MAX {
 LL | |
 LL | |
-LL | |         x11 = max;
+LL | |         x11 = CONST_MAX;
 ...  |
-LL | |         x11 = min;
+LL | |         x11 = CONST_MIN;
 LL | |     }
-   | |_____^ help: replace with clamp: `x11 = x11.clamp(min, max);`
+   | |_____^ help: replace with clamp: `x11 = x11.clamp(CONST_MIN, CONST_MAX);`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:123:5
+  --> tests/ui/manual_clamp.rs:246:5
    |
-LL | /     if min > x12 {
+LL | /     if CONST_MIN > x12 {
 LL | |
 LL | |
-LL | |         x12 = min;
+LL | |         x12 = CONST_MIN;
 ...  |
-LL | |         x12 = max;
+LL | |         x12 = CONST_MAX;
 LL | |     }
-   | |_____^ help: replace with clamp: `x12 = x12.clamp(min, max);`
+   | |_____^ help: replace with clamp: `x12 = x12.clamp(CONST_MIN, CONST_MAX);`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:133:5
+  --> tests/ui/manual_clamp.rs:256:5
    |
-LL | /     if max < x13 {
+LL | /     if CONST_MAX < x13 {
 LL | |
 LL | |
-LL | |         x13 = max;
+LL | |         x13 = CONST_MAX;
 ...  |
-LL | |         x13 = min;
+LL | |         x13 = CONST_MIN;
 LL | |     }
-   | |_____^ help: replace with clamp: `x13 = x13.clamp(min, max);`
+   | |_____^ help: replace with clamp: `x13 = x13.clamp(CONST_MIN, CONST_MAX);`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:227:5
+  --> tests/ui/manual_clamp.rs:370:5
    |
-LL | /     if max < x33 {
+LL | /     if CONST_MAX < x35 {
 LL | |
 LL | |
-LL | |         x33 = max;
+LL | |         x35 = CONST_MAX;
 ...  |
-LL | |         x33 = min;
+LL | |         x35 = CONST_MIN;
 LL | |     }
-   | |_____^ help: replace with clamp: `x33 = x33.clamp(min, max);`
+   | |_____^ help: replace with clamp: `x35 = x35.clamp(CONST_MIN, CONST_MAX);`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:21:14
+  --> tests/ui/manual_clamp.rs:144:14
    |
-LL |       let x0 = if max < input {
+LL |       let x0 = if CONST_MAX < input {
    |  ______________^
 LL | |
 LL | |
-LL | |         max
+LL | |         CONST_MAX
 ...  |
 LL | |         input
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:31:14
+  --> tests/ui/manual_clamp.rs:154:14
    |
-LL |       let x1 = if input > max {
+LL |       let x1 = if input > CONST_MAX {
    |  ______________^
 LL | |
 LL | |
-LL | |         max
+LL | |         CONST_MAX
 ...  |
 LL | |         input
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:41:14
+  --> tests/ui/manual_clamp.rs:164:14
    |
-LL |       let x2 = if input < min {
+LL |       let x2 = if input < CONST_MIN {
    |  ______________^
 LL | |
 LL | |
-LL | |         min
+LL | |         CONST_MIN
 ...  |
 LL | |         input
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:51:14
+  --> tests/ui/manual_clamp.rs:174:14
    |
-LL |       let x3 = if min > input {
+LL |       let x3 = if CONST_MIN > input {
    |  ______________^
 LL | |
 LL | |
-LL | |         min
+LL | |         CONST_MIN
 ...  |
 LL | |         input
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:61:14
+  --> tests/ui/manual_clamp.rs:184:14
    |
-LL |     let x4 = input.max(min).min(max);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
+LL |     let x4 = input.max(CONST_MIN).min(CONST_MAX);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:65:14
+  --> tests/ui/manual_clamp.rs:188:14
    |
-LL |     let x5 = input.min(max).max(min);
-   |              ^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(min, max)`
+LL |     let x5 = input.min(CONST_MAX).max(CONST_MIN);
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:69:14
+  --> tests/ui/manual_clamp.rs:192:14
    |
 LL |       let x6 = match input {
    |  ______________^
 LL | |
 LL | |
-LL | |         x if x > max => max,
-LL | |         x if x < min => min,
+LL | |         x if x > CONST_MAX => CONST_MAX,
+LL | |         x if x < CONST_MIN => CONST_MIN,
 LL | |         x => x,
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:77:14
+  --> tests/ui/manual_clamp.rs:200:14
    |
 LL |       let x7 = match input {
    |  ______________^
 LL | |
 LL | |
-LL | |         x if x < min => min,
-LL | |         x if x > max => max,
+LL | |         x if x < CONST_MIN => CONST_MIN,
+LL | |         x if x > CONST_MAX => CONST_MAX,
 LL | |         x => x,
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:85:14
+  --> tests/ui/manual_clamp.rs:208:14
    |
 LL |       let x8 = match input {
    |  ______________^
 LL | |
 LL | |
-LL | |         x if max < x => max,
-LL | |         x if min > x => min,
+LL | |         x if CONST_MAX < x => CONST_MAX,
+LL | |         x if CONST_MIN > x => CONST_MIN,
 LL | |         x => x,
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:103:15
+  --> tests/ui/manual_clamp.rs:226:15
    |
 LL |       let x10 = match input {
    |  _______________^
 LL | |
 LL | |
-LL | |         x if min > x => min,
-LL | |         x if max < x => max,
+LL | |         x if CONST_MIN > x => CONST_MIN,
+LL | |         x if CONST_MAX < x => CONST_MAX,
 LL | |         x => x,
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:142:15
+  --> tests/ui/manual_clamp.rs:265:15
    |
 LL |       let x14 = if input > CONST_MAX {
    |  _______________^
@@ -222,23 +222,23 @@ LL | |     };
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:153:19
+  --> tests/ui/manual_clamp.rs:276:19
    |
-LL |           let x15 = if input > max {
+LL |           let x15 = if input > CONST_F64_MAX {
    |  ___________________^
 LL | |
 LL | |
-LL | |             max
+LL | |             CONST_F64_MAX
 ...  |
 LL | |             input
 LL | |         };
-   | |_________^ help: replace with clamp: `input.clamp(min, max)`
+   | |_________^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
    |
    = note: clamp will panic if max < min, min.is_nan(), or max.is_nan()
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:166:19
+  --> tests/ui/manual_clamp.rs:289:19
    |
 LL |         let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -246,7 +246,7 @@ LL |         let x16 = cmp_max(cmp_min(input, CONST_MAX), CONST_MIN);
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:169:19
+  --> tests/ui/manual_clamp.rs:292:19
    |
 LL |         let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -254,7 +254,7 @@ LL |         let x17 = cmp_min(cmp_max(input, CONST_MIN), CONST_MAX);
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:172:19
+  --> tests/ui/manual_clamp.rs:295:19
    |
 LL |         let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -262,7 +262,7 @@ LL |         let x18 = cmp_max(CONST_MIN, cmp_min(input, CONST_MAX));
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:175:19
+  --> tests/ui/manual_clamp.rs:298:19
    |
 LL |         let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -270,7 +270,7 @@ LL |         let x19 = cmp_min(CONST_MAX, cmp_max(input, CONST_MIN));
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:178:19
+  --> tests/ui/manual_clamp.rs:301:19
    |
 LL |         let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -278,7 +278,7 @@ LL |         let x20 = cmp_max(cmp_min(CONST_MAX, input), CONST_MIN);
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:181:19
+  --> tests/ui/manual_clamp.rs:304:19
    |
 LL |         let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -286,7 +286,7 @@ LL |         let x21 = cmp_min(cmp_max(CONST_MIN, input), CONST_MAX);
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:184:19
+  --> tests/ui/manual_clamp.rs:307:19
    |
 LL |         let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -294,7 +294,7 @@ LL |         let x22 = cmp_max(CONST_MIN, cmp_min(CONST_MAX, input));
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:187:19
+  --> tests/ui/manual_clamp.rs:310:19
    |
 LL |         let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
@@ -302,7 +302,7 @@ LL |         let x23 = cmp_min(CONST_MAX, cmp_max(CONST_MIN, input));
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:191:19
+  --> tests/ui/manual_clamp.rs:314:19
    |
 LL |         let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -311,7 +311,7 @@ LL |         let x24 = f64::max(f64::min(input, CONST_F64_MAX), CONST_F64_MIN);
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:194:19
+  --> tests/ui/manual_clamp.rs:317:19
    |
 LL |         let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -320,7 +320,7 @@ LL |         let x25 = f64::min(f64::max(input, CONST_F64_MIN), CONST_F64_MAX);
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:197:19
+  --> tests/ui/manual_clamp.rs:320:19
    |
 LL |         let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -329,7 +329,7 @@ LL |         let x26 = f64::max(CONST_F64_MIN, f64::min(input, CONST_F64_MAX));
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:200:19
+  --> tests/ui/manual_clamp.rs:323:19
    |
 LL |         let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -338,7 +338,7 @@ LL |         let x27 = f64::min(CONST_F64_MAX, f64::max(input, CONST_F64_MIN));
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:203:19
+  --> tests/ui/manual_clamp.rs:326:19
    |
 LL |         let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -347,7 +347,7 @@ LL |         let x28 = f64::max(f64::min(CONST_F64_MAX, input), CONST_F64_MIN);
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:206:19
+  --> tests/ui/manual_clamp.rs:329:19
    |
 LL |         let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -356,7 +356,7 @@ LL |         let x29 = f64::min(f64::max(CONST_F64_MIN, input), CONST_F64_MAX);
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:209:19
+  --> tests/ui/manual_clamp.rs:332:19
    |
 LL |         let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -365,7 +365,7 @@ LL |         let x30 = f64::max(CONST_F64_MIN, f64::min(CONST_F64_MAX, input));
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:212:19
+  --> tests/ui/manual_clamp.rs:335:19
    |
 LL |         let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: replace with clamp: `input.clamp(CONST_F64_MIN, CONST_F64_MAX)`
@@ -374,31 +374,31 @@ LL |         let x31 = f64::min(CONST_F64_MAX, f64::max(CONST_F64_MIN, input));
    = note: clamp returns NaN if the input is NaN
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:217:5
+  --> tests/ui/manual_clamp.rs:340:5
    |
-LL | /     if x32 < min {
+LL | /     if x32 < CONST_MIN {
 LL | |
 LL | |
-LL | |         x32 = min;
-LL | |     } else if x32 > max {
-LL | |         x32 = max;
+LL | |         x32 = CONST_MIN;
+LL | |     } else if x32 > CONST_MAX {
+LL | |         x32 = CONST_MAX;
 LL | |     }
-   | |_____^ help: replace with clamp: `x32 = x32.clamp(min, max);`
+   | |_____^ help: replace with clamp: `x32 = x32.clamp(CONST_MIN, CONST_MAX);`
    |
    = note: clamp will panic if max < min
 
 error: clamp-like pattern without using clamp function
-  --> tests/ui/manual_clamp.rs:389:13
+  --> tests/ui/manual_clamp.rs:532:13
    |
-LL |       let _ = if input < min {
+LL |       let _ = if input > CONST_MAX {
    |  _____________^
 LL | |
 LL | |
-LL | |         min
+LL | |         CONST_MAX
 ...  |
 LL | |         input
 LL | |     };
-   | |_____^ help: replace with clamp: `input.clamp(min, max)`
+   | |_____^ help: replace with clamp: `input.clamp(CONST_MIN, CONST_MAX)`
    |
    = note: clamp will panic if max < min
 
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
index 8218f10881a..41a32df32ee 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.fixed
@@ -1,4 +1,4 @@
-#![allow(unused_imports)]
+#![allow(clippy::legacy_numeric_constants, unused_imports)]
 
 use std::{i128, i32, u128, u32};
 
diff --git a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
index 60022b54b02..3a6b32d8069 100644
--- a/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
+++ b/src/tools/clippy/tests/ui/manual_saturating_arithmetic.rs
@@ -1,4 +1,4 @@
-#![allow(unused_imports)]
+#![allow(clippy::legacy_numeric_constants, unused_imports)]
 
 use std::{i128, i32, u128, u32};
 
diff --git a/src/tools/clippy/tests/ui/manual_swap_auto_fix.fixed b/src/tools/clippy/tests/ui/manual_swap_auto_fix.fixed
new file mode 100644
index 00000000000..28466ff3f9b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_swap_auto_fix.fixed
@@ -0,0 +1,57 @@
+#![warn(clippy::manual_swap)]
+#![no_main]
+
+fn swap1() {
+    let mut v = [3, 2, 1, 0];
+    let index = v[0];
+    v.swap(0, index);
+}
+
+fn swap2() {
+    let mut v = [3, 2, 1, 0];
+    let tmp = v[0];
+    v.swap(0, 1);
+    // check not found in this scope.
+    let _ = tmp;
+}
+
+fn swap3() {
+    let mut v = [3, 2];
+    let i1 = 0;
+    let i2 = 1;
+    v.swap(i1, i2);
+}
+
+fn swap4() {
+    let mut v = [3, 2, 1];
+    let i1 = 0;
+    let i2 = 1;
+    v.swap(i1, i2 + 1);
+}
+
+fn swap5() {
+    let mut v = [0, 1, 2, 3];
+    let i1 = 0;
+    let i2 = 1;
+    v.swap(i1, i2 + 1);
+}
+
+fn swap6() {
+    let mut v = [0, 1, 2, 3];
+    let index = v[0];
+    v.swap(0, index + 1);
+}
+
+fn swap7() {
+    let mut v = [0, 1, 2, 3];
+    let i1 = 0;
+    let i2 = 6;
+    v.swap(i1 * 3, i2 / 2);
+}
+
+fn swap8() {
+    let mut v = [1, 2, 3, 4];
+    let i1 = 1;
+    let i2 = 1;
+    v.swap(i1 + i2, i2);
+}
diff --git a/src/tools/clippy/tests/ui/manual_swap_auto_fix.rs b/src/tools/clippy/tests/ui/manual_swap_auto_fix.rs
new file mode 100644
index 00000000000..702a9e67d3d
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_swap_auto_fix.rs
@@ -0,0 +1,72 @@
+#![warn(clippy::manual_swap)]
+#![no_main]
+
+fn swap1() {
+    let mut v = [3, 2, 1, 0];
+    let index = v[0];
+    //~^ ERROR: this looks like you are swapping elements of `v` manually
+    v[0] = v[index];
+    v[index] = index;
+}
+
+fn swap2() {
+    let mut v = [3, 2, 1, 0];
+    let tmp = v[0];
+    v[0] = v[1];
+    v[1] = tmp;
+    // check not found in this scope.
+    let _ = tmp;
+}
+
+fn swap3() {
+    let mut v = [3, 2];
+    let i1 = 0;
+    let i2 = 1;
+    let temp = v[i1];
+    v[i1] = v[i2];
+    v[i2] = temp;
+}
+
+fn swap4() {
+    let mut v = [3, 2, 1];
+    let i1 = 0;
+    let i2 = 1;
+    let temp = v[i1];
+    v[i1] = v[i2 + 1];
+    v[i2 + 1] = temp;
+}
+
+fn swap5() {
+    let mut v = [0, 1, 2, 3];
+    let i1 = 0;
+    let i2 = 1;
+    let temp = v[i1];
+    v[i1] = v[i2 + 1];
+    v[i2 + 1] = temp;
+}
+
+fn swap6() {
+    let mut v = [0, 1, 2, 3];
+    let index = v[0];
+    //~^ ERROR: this looks like you are swapping elements of `v` manually
+    v[0] = v[index + 1];
+    v[index + 1] = index;
+}
+
+fn swap7() {
+    let mut v = [0, 1, 2, 3];
+    let i1 = 0;
+    let i2 = 6;
+    let tmp = v[i1 * 3];
+    v[i1 * 3] = v[i2 / 2];
+    v[i2 / 2] = tmp;
+}
+
+fn swap8() {
+    let mut v = [1, 2, 3, 4];
+    let i1 = 1;
+    let i2 = 1;
+    let tmp = v[i1 + i2];
+    v[i1 + i2] = v[i2];
+    v[i2] = tmp;
+}
diff --git a/src/tools/clippy/tests/ui/manual_swap_auto_fix.stderr b/src/tools/clippy/tests/ui/manual_swap_auto_fix.stderr
new file mode 100644
index 00000000000..eecfcd3977b
--- /dev/null
+++ b/src/tools/clippy/tests/ui/manual_swap_auto_fix.stderr
@@ -0,0 +1,88 @@
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:6:5
+   |
+LL | /     let index = v[0];
+LL | |
+LL | |     v[0] = v[index];
+LL | |     v[index] = index;
+   | |_____________________^
+   |
+   = note: `-D clippy::manual-swap` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::manual_swap)]`
+help: try
+   |
+LL ~     let index = v[0];
+LL +     v.swap(0, index);
+   |
+
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:14:5
+   |
+LL | /     let tmp = v[0];
+LL | |     v[0] = v[1];
+LL | |     v[1] = tmp;
+   | |_______________^
+   |
+help: try
+   |
+LL ~     let tmp = v[0];
+LL +     v.swap(0, 1);
+   |
+
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:25:5
+   |
+LL | /     let temp = v[i1];
+LL | |     v[i1] = v[i2];
+LL | |     v[i2] = temp;
+   | |_________________^ help: try: `v.swap(i1, i2);`
+
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:34:5
+   |
+LL | /     let temp = v[i1];
+LL | |     v[i1] = v[i2 + 1];
+LL | |     v[i2 + 1] = temp;
+   | |_____________________^ help: try: `v.swap(i1, i2 + 1);`
+
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:43:5
+   |
+LL | /     let temp = v[i1];
+LL | |     v[i1] = v[i2 + 1];
+LL | |     v[i2 + 1] = temp;
+   | |_____________________^ help: try: `v.swap(i1, i2 + 1);`
+
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:50:5
+   |
+LL | /     let index = v[0];
+LL | |
+LL | |     v[0] = v[index + 1];
+LL | |     v[index + 1] = index;
+   | |_________________________^
+   |
+help: try
+   |
+LL ~     let index = v[0];
+LL +     v.swap(0, index + 1);
+   |
+
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:60:5
+   |
+LL | /     let tmp = v[i1 * 3];
+LL | |     v[i1 * 3] = v[i2 / 2];
+LL | |     v[i2 / 2] = tmp;
+   | |____________________^ help: try: `v.swap(i1 * 3, i2 / 2);`
+
+error: this looks like you are swapping elements of `v` manually
+  --> tests/ui/manual_swap_auto_fix.rs:69:5
+   |
+LL | /     let tmp = v[i1 + i2];
+LL | |     v[i1 + i2] = v[i2];
+LL | |     v[i2] = tmp;
+   | |________________^ help: try: `v.swap(i1 + i2, i2);`
+
+error: aborting due to 8 previous errors
+
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed b/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed
index c8456805ee6..a0b707628a8 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or_default.fixed
@@ -17,3 +17,48 @@ fn main() {
     let x: Option<Vec<String>> = None;
     x.unwrap_or_default();
 }
+
+// Issue #12531
+unsafe fn no_deref_ptr(a: Option<i32>, b: *const Option<i32>) -> i32 {
+    match a {
+        // `*b` being correct depends on `a == Some(_)`
+        Some(_) => (*b).unwrap_or_default(),
+        _ => 0,
+    }
+}
+
+const fn issue_12568(opt: Option<bool>) -> bool {
+    match opt {
+        Some(s) => s,
+        None => false,
+    }
+}
+
+fn issue_12569() {
+    let match_none_se = match 1u32.checked_div(0) {
+        Some(v) => v,
+        None => {
+            println!("important");
+            0
+        },
+    };
+    let match_some_se = match 1u32.checked_div(0) {
+        Some(v) => {
+            println!("important");
+            v
+        },
+        None => 0,
+    };
+    let iflet_else_se = if let Some(v) = 1u32.checked_div(0) {
+        v
+    } else {
+        println!("important");
+        0
+    };
+    let iflet_then_se = if let Some(v) = 1u32.checked_div(0) {
+        println!("important");
+        v
+    } else {
+        0
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs b/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs
index 820717be53a..1d4cca12f6c 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or_default.rs
@@ -38,3 +38,51 @@ fn main() {
         Vec::default()
     };
 }
+
+// Issue #12531
+unsafe fn no_deref_ptr(a: Option<i32>, b: *const Option<i32>) -> i32 {
+    match a {
+        // `*b` being correct depends on `a == Some(_)`
+        Some(_) => match *b {
+            Some(v) => v,
+            _ => 0,
+        },
+        _ => 0,
+    }
+}
+
+const fn issue_12568(opt: Option<bool>) -> bool {
+    match opt {
+        Some(s) => s,
+        None => false,
+    }
+}
+
+fn issue_12569() {
+    let match_none_se = match 1u32.checked_div(0) {
+        Some(v) => v,
+        None => {
+            println!("important");
+            0
+        },
+    };
+    let match_some_se = match 1u32.checked_div(0) {
+        Some(v) => {
+            println!("important");
+            v
+        },
+        None => 0,
+    };
+    let iflet_else_se = if let Some(v) = 1u32.checked_div(0) {
+        v
+    } else {
+        println!("important");
+        0
+    };
+    let iflet_then_se = if let Some(v) = 1u32.checked_div(0) {
+        println!("important");
+        v
+    } else {
+        0
+    };
+}
diff --git a/src/tools/clippy/tests/ui/manual_unwrap_or_default.stderr b/src/tools/clippy/tests/ui/manual_unwrap_or_default.stderr
index f4eb6583588..d89212e6045 100644
--- a/src/tools/clippy/tests/ui/manual_unwrap_or_default.stderr
+++ b/src/tools/clippy/tests/ui/manual_unwrap_or_default.stderr
@@ -52,5 +52,15 @@ LL | |         Vec::default()
 LL | |     };
    | |_____^ help: replace it with: `x.unwrap_or_default()`
 
-error: aborting due to 5 previous errors
+error: match can be simplified with `.unwrap_or_default()`
+  --> tests/ui/manual_unwrap_or_default.rs:46:20
+   |
+LL |           Some(_) => match *b {
+   |  ____________________^
+LL | |             Some(v) => v,
+LL | |             _ => 0,
+LL | |         },
+   | |_________^ help: replace it with: `(*b).unwrap_or_default()`
+
+error: aborting due to 6 previous errors
 
diff --git a/src/tools/clippy/tests/ui/map_clone.fixed b/src/tools/clippy/tests/ui/map_clone.fixed
index e58b6b2f19e..f9f8dc1a512 100644
--- a/src/tools/clippy/tests/ui/map_clone.fixed
+++ b/src/tools/clippy/tests/ui/map_clone.fixed
@@ -131,4 +131,28 @@ fn main() {
         let x: Vec<&u8> = vec![];
         let y = x.into_iter().map(|x| u8::clone(loop {}));
     }
+
+    // Issue #12528
+    {
+        // Don't lint these
+        use std::rc::{Rc, Weak as RcWeak};
+        use std::sync::{Arc, Weak as ArcWeak};
+        struct Foo;
+
+        let x = Arc::new(Foo);
+        let y = Some(&x);
+        let _z = y.map(Arc::clone);
+
+        let x = Rc::new(Foo);
+        let y = Some(&x);
+        let _z = y.map(Rc::clone);
+
+        let x = Arc::downgrade(&Arc::new(Foo));
+        let y = Some(&x);
+        let _z = y.map(ArcWeak::clone);
+
+        let x = Rc::downgrade(&Rc::new(Foo));
+        let y = Some(&x);
+        let _z = y.map(RcWeak::clone);
+    }
 }
diff --git a/src/tools/clippy/tests/ui/map_clone.rs b/src/tools/clippy/tests/ui/map_clone.rs
index e642e4046f8..a5c19ce0631 100644
--- a/src/tools/clippy/tests/ui/map_clone.rs
+++ b/src/tools/clippy/tests/ui/map_clone.rs
@@ -131,4 +131,28 @@ fn main() {
         let x: Vec<&u8> = vec![];
         let y = x.into_iter().map(|x| u8::clone(loop {}));
     }
+
+    // Issue #12528
+    {
+        // Don't lint these
+        use std::rc::{Rc, Weak as RcWeak};
+        use std::sync::{Arc, Weak as ArcWeak};
+        struct Foo;
+
+        let x = Arc::new(Foo);
+        let y = Some(&x);
+        let _z = y.map(Arc::clone);
+
+        let x = Rc::new(Foo);
+        let y = Some(&x);
+        let _z = y.map(Rc::clone);
+
+        let x = Arc::downgrade(&Arc::new(Foo));
+        let y = Some(&x);
+        let _z = y.map(ArcWeak::clone);
+
+        let x = Rc::downgrade(&Rc::new(Foo));
+        let y = Some(&x);
+        let _z = y.map(RcWeak::clone);
+    }
 }
diff --git a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
index 6985c2d0c19..12a8320c8f3 100644
--- a/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
+++ b/src/tools/clippy/tests/ui/missing_const_for_fn/could_be_const.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::missing_const_for_fn)]
-#![allow(incomplete_features, clippy::let_and_return)]
+#![allow(incomplete_features, clippy::let_and_return, clippy::missing_transmute_annotations)]
 #![feature(const_mut_refs)]
 #![feature(const_trait_impl)]
 
diff --git a/src/tools/clippy/tests/ui/missing_transmute_annotations.fixed b/src/tools/clippy/tests/ui/missing_transmute_annotations.fixed
new file mode 100644
index 00000000000..a3c94ab139e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_transmute_annotations.fixed
@@ -0,0 +1,78 @@
+//@aux-build:macro_rules.rs
+
+#![warn(clippy::missing_transmute_annotations)]
+#![allow(clippy::let_with_type_underscore)]
+
+#[macro_use]
+extern crate macro_rules;
+
+macro_rules! local_bad_transmute {
+    ($e:expr) => {
+        std::mem::transmute::<[u16; 2], i32>($e)
+        //~^ ERROR: transmute used without annotations
+    };
+}
+
+fn bar(x: i32) -> i32 {
+    x
+}
+
+unsafe fn foo1() -> i32 {
+    // Should not warn!
+    std::mem::transmute([1u16, 2u16])
+}
+
+// Should not warn!
+const _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
+
+#[repr(i32)]
+enum Foo {
+    A = 0,
+}
+
+unsafe fn foo2() -> i32 {
+    let mut i: i32 = 0;
+    i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+    i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+    i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+    i = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+
+    let x: i32 = bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));
+    //~^ ERROR: transmute used without annotations
+    bar(std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]));
+    //~^ ERROR: transmute used without annotations
+
+    i = local_bad_transmute!([1u16, 2u16]);
+
+    // Should not warn.
+    i = bad_transmute!([1u16, 2u16]);
+
+    i = std::mem::transmute::<[i16; 2], i32>([0i16, 0i16]);
+    //~^ ERROR: transmute used without annotations
+
+    i = std::mem::transmute::<Foo, i32>(Foo::A);
+    //~^ ERROR: transmute used without annotations
+
+    i
+}
+
+fn main() {
+    let x: _ = unsafe { std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]) };
+    //~^ ERROR: transmute used without annotations
+    unsafe {
+        let x: _ = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+        //~^ ERROR: transmute used without annotations
+
+        // Should not warn.
+        std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+        let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+        let x: i32 = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
+        let x: i32 = std::mem::transmute::<_, i32>([1u16, 2u16]);
+        let x: i32 = std::mem::transmute([1u16, 2u16]);
+    }
+    let x: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
+}
diff --git a/src/tools/clippy/tests/ui/missing_transmute_annotations.rs b/src/tools/clippy/tests/ui/missing_transmute_annotations.rs
new file mode 100644
index 00000000000..c12e1b0f8d2
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_transmute_annotations.rs
@@ -0,0 +1,78 @@
+//@aux-build:macro_rules.rs
+
+#![warn(clippy::missing_transmute_annotations)]
+#![allow(clippy::let_with_type_underscore)]
+
+#[macro_use]
+extern crate macro_rules;
+
+macro_rules! local_bad_transmute {
+    ($e:expr) => {
+        std::mem::transmute($e)
+        //~^ ERROR: transmute used without annotations
+    };
+}
+
+fn bar(x: i32) -> i32 {
+    x
+}
+
+unsafe fn foo1() -> i32 {
+    // Should not warn!
+    std::mem::transmute([1u16, 2u16])
+}
+
+// Should not warn!
+const _: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
+
+#[repr(i32)]
+enum Foo {
+    A = 0,
+}
+
+unsafe fn foo2() -> i32 {
+    let mut i: i32 = 0;
+    i = std::mem::transmute([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+    i = std::mem::transmute::<_, _>([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+    i = std::mem::transmute::<_, i32>([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+    i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
+    //~^ ERROR: transmute used without annotations
+
+    let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
+    //~^ ERROR: transmute used without annotations
+    bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
+    //~^ ERROR: transmute used without annotations
+
+    i = local_bad_transmute!([1u16, 2u16]);
+
+    // Should not warn.
+    i = bad_transmute!([1u16, 2u16]);
+
+    i = std::mem::transmute([0i16, 0i16]);
+    //~^ ERROR: transmute used without annotations
+
+    i = std::mem::transmute(Foo::A);
+    //~^ ERROR: transmute used without annotations
+
+    i
+}
+
+fn main() {
+    let x: _ = unsafe { std::mem::transmute::<_, i32>([1u16, 2u16]) };
+    //~^ ERROR: transmute used without annotations
+    unsafe {
+        let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]);
+        //~^ ERROR: transmute used without annotations
+
+        // Should not warn.
+        std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+        let x = std::mem::transmute::<[u16; 2], i32>([1u16, 2u16]);
+        let x: i32 = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
+        let x: i32 = std::mem::transmute::<_, i32>([1u16, 2u16]);
+        let x: i32 = std::mem::transmute([1u16, 2u16]);
+    }
+    let x: i32 = unsafe { std::mem::transmute([1u16, 2u16]) };
+}
diff --git a/src/tools/clippy/tests/ui/missing_transmute_annotations.stderr b/src/tools/clippy/tests/ui/missing_transmute_annotations.stderr
new file mode 100644
index 00000000000..5903ed488ef
--- /dev/null
+++ b/src/tools/clippy/tests/ui/missing_transmute_annotations.stderr
@@ -0,0 +1,76 @@
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:35:19
+   |
+LL |     i = std::mem::transmute([1u16, 2u16]);
+   |                   ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+   |
+   = note: `-D clippy::missing-transmute-annotations` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::missing_transmute_annotations)]`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:37:19
+   |
+LL |     i = std::mem::transmute::<_, _>([1u16, 2u16]);
+   |                   ^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:39:19
+   |
+LL |     i = std::mem::transmute::<_, i32>([1u16, 2u16]);
+   |                   ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:41:19
+   |
+LL |     i = std::mem::transmute::<[u16; 2], _>([1u16, 2u16]);
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:44:32
+   |
+LL |     let x: i32 = bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
+   |                                ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:46:19
+   |
+LL |     bar(std::mem::transmute::<[u16; 2], _>([1u16, 2u16]));
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:11:19
+   |
+LL |         std::mem::transmute($e)
+   |                   ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+...
+LL |     i = local_bad_transmute!([1u16, 2u16]);
+   |         ---------------------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `local_bad_transmute` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:54:19
+   |
+LL |     i = std::mem::transmute([0i16, 0i16]);
+   |                   ^^^^^^^^^ help: consider adding missing annotations: `transmute::<[i16; 2], i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:57:19
+   |
+LL |     i = std::mem::transmute(Foo::A);
+   |                   ^^^^^^^^^ help: consider adding missing annotations: `transmute::<Foo, i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:64:35
+   |
+LL |     let x: _ = unsafe { std::mem::transmute::<_, i32>([1u16, 2u16]) };
+   |                                   ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: transmute used without annotations
+  --> tests/ui/missing_transmute_annotations.rs:67:30
+   |
+LL |         let x: _ = std::mem::transmute::<_, i32>([1u16, 2u16]);
+   |                              ^^^^^^^^^^^^^^^^^^^ help: consider adding missing annotations: `transmute::<[u16; 2], i32>`
+
+error: aborting due to 11 previous errors
+
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.rs b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
index 4f89aa8a5e5..1a646c26522 100644
--- a/src/tools/clippy/tests/ui/mixed_attributes_style.rs
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.rs
@@ -1,6 +1,12 @@
+//@aux-build:proc_macro_attr.rs
+//@compile-flags: --test --cfg dummy_cfg
+#![feature(custom_inner_attributes)]
 #![warn(clippy::mixed_attributes_style)]
 #![allow(clippy::duplicated_attributes)]
 
+#[macro_use]
+extern crate proc_macro_attr;
+
 #[allow(unused)] //~ ERROR: item has both inner and outer attributes
 fn foo1() {
     #![allow(unused)]
@@ -38,3 +44,57 @@ mod bar {
 fn main() {
     // test code goes here
 }
+
+// issue #12435
+#[cfg(test)]
+mod tests {
+    //! Module doc, don't lint
+}
+#[allow(unused)]
+mod baz {
+    //! Module doc, don't lint
+    const FOO: u8 = 0;
+}
+/// Module doc, don't lint
+mod quz {
+    #![allow(unused)]
+}
+
+mod issue_12530 {
+    // don't lint different attributes entirely
+    #[cfg(test)]
+    mod tests {
+        #![allow(clippy::unreadable_literal)]
+
+        #[allow(dead_code)] //~ ERROR: item has both inner and outer attributes
+        mod inner_mod {
+            #![allow(dead_code)]
+        }
+    }
+    #[cfg(dummy_cfg)]
+    mod another_mod {
+        #![allow(clippy::question_mark)]
+    }
+    /// Nested mod
+    mod nested_mod {
+        #[allow(dead_code)] //~ ERROR: item has both inner and outer attributes
+        mod inner_mod {
+            #![allow(dead_code)]
+        }
+    }
+    /// Nested mod //~ ERROR: item has both inner and outer attributes
+    #[allow(unused)]
+    mod nest_mod_2 {
+        #![allow(unused)]
+
+        #[allow(dead_code)] //~ ERROR: item has both inner and outer attributes
+        mod inner_mod {
+            #![allow(dead_code)]
+        }
+    }
+    // Different path symbols - Known FN
+    #[dummy]
+    fn use_dummy() {
+        #![proc_macro_attr::dummy]
+    }
+}
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style.stderr b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
index ed798073cb7..a1d3fc430f6 100644
--- a/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style.stderr
@@ -1,5 +1,5 @@
 error: item has both inner and outer attributes
-  --> tests/ui/mixed_attributes_style.rs:4:1
+  --> tests/ui/mixed_attributes_style.rs:10:1
    |
 LL | / #[allow(unused)]
 LL | | fn foo1() {
@@ -10,7 +10,7 @@ LL | |     #![allow(unused)]
    = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]`
 
 error: item has both inner and outer attributes
-  --> tests/ui/mixed_attributes_style.rs:18:1
+  --> tests/ui/mixed_attributes_style.rs:24:1
    |
 LL | / /// linux
 LL | |
@@ -19,12 +19,45 @@ LL | |     //! windows
    | |_______________^
 
 error: item has both inner and outer attributes
-  --> tests/ui/mixed_attributes_style.rs:33:1
+  --> tests/ui/mixed_attributes_style.rs:39:1
    |
 LL | / #[allow(unused)]
 LL | | mod bar {
 LL | |     #![allow(unused)]
    | |_____________________^
 
-error: aborting due to 3 previous errors
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:69:9
+   |
+LL | /         #[allow(dead_code)]
+LL | |         mod inner_mod {
+LL | |             #![allow(dead_code)]
+   | |________________________________^
+
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:80:9
+   |
+LL | /         #[allow(dead_code)]
+LL | |         mod inner_mod {
+LL | |             #![allow(dead_code)]
+   | |________________________________^
+
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:85:5
+   |
+LL | /     /// Nested mod
+LL | |     #[allow(unused)]
+LL | |     mod nest_mod_2 {
+LL | |         #![allow(unused)]
+   | |_________________________^
+
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style.rs:90:9
+   |
+LL | /         #[allow(dead_code)]
+LL | |         mod inner_mod {
+LL | |             #![allow(dead_code)]
+   | |________________________________^
+
+error: aborting due to 7 previous errors
 
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style/auxiliary/submodule.rs b/src/tools/clippy/tests/ui/mixed_attributes_style/auxiliary/submodule.rs
new file mode 100644
index 00000000000..df44b07a694
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style/auxiliary/submodule.rs
@@ -0,0 +1,9 @@
+//! Module level doc
+
+#![allow(dead_code)]
+
+#[allow(unused)]
+//~^ ERROR: item has both inner and outer attributes
+mod foo {
+    #![allow(dead_code)]
+}
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style/global_allow.rs b/src/tools/clippy/tests/ui/mixed_attributes_style/global_allow.rs
new file mode 100644
index 00000000000..153262e6557
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style/global_allow.rs
@@ -0,0 +1,7 @@
+// issue 12436
+#![allow(clippy::mixed_attributes_style)]
+
+#[path = "auxiliary/submodule.rs"]
+mod submodule;
+
+fn main() {}
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.rs b/src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.rs
new file mode 100644
index 00000000000..b0f1f0bda9e
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.rs
@@ -0,0 +1,3 @@
+#[path = "auxiliary/submodule.rs"] // don't lint.
+/// This doc comment should not lint, it could be used to add context to the original module doc
+mod submodule;
diff --git a/src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.stderr b/src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.stderr
new file mode 100644
index 00000000000..968c537c7e4
--- /dev/null
+++ b/src/tools/clippy/tests/ui/mixed_attributes_style/mod_declaration.stderr
@@ -0,0 +1,14 @@
+error: item has both inner and outer attributes
+  --> tests/ui/mixed_attributes_style/auxiliary/submodule.rs:5:1
+   |
+LL | / #[allow(unused)]
+LL | |
+LL | | mod foo {
+LL | |     #![allow(dead_code)]
+   | |________________________^
+   |
+   = note: `-D clippy::mixed-attributes-style` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::mixed_attributes_style)]`
+
+error: aborting due to 1 previous error
+
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
index c410a660dc4..33c0725faad 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.fixed
@@ -1,7 +1,12 @@
 //@aux-build:proc_macros.rs
 
 #![warn(clippy::ptr_cast_constness)]
-#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)]
+#![allow(
+    clippy::transmute_ptr_to_ref,
+    clippy::unnecessary_cast,
+    unused,
+    clippy::missing_transmute_annotations
+)]
 
 extern crate proc_macros;
 use proc_macros::{external, inline_macros};
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.rs b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
index 6025b857b8f..24d959856db 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.rs
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.rs
@@ -1,7 +1,12 @@
 //@aux-build:proc_macros.rs
 
 #![warn(clippy::ptr_cast_constness)]
-#![allow(clippy::transmute_ptr_to_ref, clippy::unnecessary_cast, unused)]
+#![allow(
+    clippy::transmute_ptr_to_ref,
+    clippy::unnecessary_cast,
+    unused,
+    clippy::missing_transmute_annotations
+)]
 
 extern crate proc_macros;
 use proc_macros::{external, inline_macros};
diff --git a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
index 8e2bec527ff..322c3585e62 100644
--- a/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
+++ b/src/tools/clippy/tests/ui/ptr_cast_constness.stderr
@@ -1,5 +1,5 @@
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:10:41
+  --> tests/ui/ptr_cast_constness.rs:15:41
    |
 LL |     let _: &mut T = std::mem::transmute(p as *mut T);
    |                                         ^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()`
@@ -8,37 +8,37 @@ LL |     let _: &mut T = std::mem::transmute(p as *mut T);
    = help: to override `-D warnings` add `#[allow(clippy::ptr_cast_constness)]`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:11:19
+  --> tests/ui/ptr_cast_constness.rs:16:19
    |
 LL |     let _ = &mut *(p as *mut T);
    |                   ^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `p.cast_mut()`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:26:17
+  --> tests/ui/ptr_cast_constness.rs:31:17
    |
 LL |         let _ = *ptr_ptr as *mut u32;
    |                 ^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `(*ptr_ptr).cast_mut()`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:29:13
+  --> tests/ui/ptr_cast_constness.rs:34:13
    |
 LL |     let _ = ptr as *mut u32;
    |             ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:30:13
+  --> tests/ui/ptr_cast_constness.rs:35:13
    |
 LL |     let _ = mut_ptr as *const u32;
    |             ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:59:13
+  --> tests/ui/ptr_cast_constness.rs:64:13
    |
 LL |     let _ = ptr as *mut u32;
    |             ^^^^^^^^^^^^^^^ help: try `pointer::cast_mut`, a safer alternative: `ptr.cast_mut()`
 
 error: `as` casting between raw pointers while changing only its constness
-  --> tests/ui/ptr_cast_constness.rs:60:13
+  --> tests/ui/ptr_cast_constness.rs:65:13
    |
 LL |     let _ = mut_ptr as *const u32;
    |             ^^^^^^^^^^^^^^^^^^^^^ help: try `pointer::cast_const`, a safer alternative: `mut_ptr.cast_const()`
diff --git a/src/tools/clippy/tests/ui/question_mark.fixed b/src/tools/clippy/tests/ui/question_mark.fixed
index 567472a8af2..679388372e6 100644
--- a/src/tools/clippy/tests/ui/question_mark.fixed
+++ b/src/tools/clippy/tests/ui/question_mark.fixed
@@ -283,3 +283,37 @@ fn issue12337() -> Option<i32> {
     };
     Some(42)
 }
+
+fn issue11983(option: &Option<String>) -> Option<()> {
+    // Don't lint, `&Option` dose not impl `Try`.
+    let Some(v) = option else { return None };
+
+    let opt = Some(String::new());
+    // Don't lint, `branch` method in `Try` takes ownership of `opt`,
+    // and `(&opt)?` also doesn't work since it's `&Option`.
+    let Some(v) = &opt else { return None };
+    let mov = opt;
+
+    Some(())
+}
+
+struct Foo {
+    owned: Option<String>,
+}
+struct Bar {
+    foo: Foo,
+}
+#[allow(clippy::disallowed_names)]
+fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {
+    // Don't lint, `owned` is behind a shared reference.
+    let Some(v) = &foo.owned else {
+        return None;
+    };
+    // Don't lint, `owned` is behind a shared reference.
+    let Some(v) = &bar.foo.owned else {
+        return None;
+    };
+    // lint
+    let v = bar.foo.owned.clone()?;
+    Some(())
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.rs b/src/tools/clippy/tests/ui/question_mark.rs
index abf8c270de8..601ab78bf5a 100644
--- a/src/tools/clippy/tests/ui/question_mark.rs
+++ b/src/tools/clippy/tests/ui/question_mark.rs
@@ -323,3 +323,39 @@ fn issue12337() -> Option<i32> {
     };
     Some(42)
 }
+
+fn issue11983(option: &Option<String>) -> Option<()> {
+    // Don't lint, `&Option` dose not impl `Try`.
+    let Some(v) = option else { return None };
+
+    let opt = Some(String::new());
+    // Don't lint, `branch` method in `Try` takes ownership of `opt`,
+    // and `(&opt)?` also doesn't work since it's `&Option`.
+    let Some(v) = &opt else { return None };
+    let mov = opt;
+
+    Some(())
+}
+
+struct Foo {
+    owned: Option<String>,
+}
+struct Bar {
+    foo: Foo,
+}
+#[allow(clippy::disallowed_names)]
+fn issue12412(foo: &Foo, bar: &Bar) -> Option<()> {
+    // Don't lint, `owned` is behind a shared reference.
+    let Some(v) = &foo.owned else {
+        return None;
+    };
+    // Don't lint, `owned` is behind a shared reference.
+    let Some(v) = &bar.foo.owned else {
+        return None;
+    };
+    // lint
+    let Some(v) = bar.foo.owned.clone() else {
+        return None;
+    };
+    Some(())
+}
diff --git a/src/tools/clippy/tests/ui/question_mark.stderr b/src/tools/clippy/tests/ui/question_mark.stderr
index 4fcccdf5512..5f26a7ea2c3 100644
--- a/src/tools/clippy/tests/ui/question_mark.stderr
+++ b/src/tools/clippy/tests/ui/question_mark.stderr
@@ -141,5 +141,13 @@ LL | |                 // https://github.com/rust-lang/rust-clippy/pull/11001#is
 LL | |             }
    | |_____________^ help: replace it with: `a?;`
 
-error: aborting due to 16 previous errors
+error: this `let...else` may be rewritten with the `?` operator
+  --> tests/ui/question_mark.rs:357:5
+   |
+LL | /     let Some(v) = bar.foo.owned.clone() else {
+LL | |         return None;
+LL | |     };
+   | |______^ help: replace it with: `let v = bar.foo.owned.clone()?;`
+
+error: aborting due to 17 previous errors
 
diff --git a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs
index 1bd4cd5fb50..07280351e76 100644
--- a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs
+++ b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.rs
@@ -1,3 +1,4 @@
+#![allow(clippy::legacy_numeric_constants)]
 #![warn(clippy::suspicious_arithmetic_impl)]
 use std::ops::{
     Add, AddAssign, BitAnd, BitOr, BitOrAssign, BitXor, Div, DivAssign, Mul, MulAssign, Rem, Shl, Shr, Sub,
diff --git a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
index 193cd64149b..1bfca49a635 100644
--- a/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
+++ b/src/tools/clippy/tests/ui/suspicious_arithmetic_impl.stderr
@@ -1,5 +1,5 @@
 error: suspicious use of `-` in `Add` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:13:20
+  --> tests/ui/suspicious_arithmetic_impl.rs:14:20
    |
 LL |         Foo(self.0 - other.0)
    |                    ^
@@ -8,7 +8,7 @@ LL |         Foo(self.0 - other.0)
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_arithmetic_impl)]`
 
 error: suspicious use of `-` in `AddAssign` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:21:23
+  --> tests/ui/suspicious_arithmetic_impl.rs:22:23
    |
 LL |         *self = *self - other;
    |                       ^
@@ -17,43 +17,43 @@ LL |         *self = *self - other;
    = help: to override `-D warnings` add `#[allow(clippy::suspicious_op_assign_impl)]`
 
 error: suspicious use of `/` in `MulAssign` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:36:16
+  --> tests/ui/suspicious_arithmetic_impl.rs:37:16
    |
 LL |         self.0 /= other.0;
    |                ^^
 
 error: suspicious use of `/` in `Rem` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:75:20
+  --> tests/ui/suspicious_arithmetic_impl.rs:76:20
    |
 LL |         Foo(self.0 / other.0)
    |                    ^
 
 error: suspicious use of `|` in `BitAnd` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:84:20
+  --> tests/ui/suspicious_arithmetic_impl.rs:85:20
    |
 LL |         Foo(self.0 | other.0)
    |                    ^
 
 error: suspicious use of `^` in `BitOr` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:93:20
+  --> tests/ui/suspicious_arithmetic_impl.rs:94:20
    |
 LL |         Foo(self.0 ^ other.0)
    |                    ^
 
 error: suspicious use of `&` in `BitXor` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:102:20
+  --> tests/ui/suspicious_arithmetic_impl.rs:103:20
    |
 LL |         Foo(self.0 & other.0)
    |                    ^
 
 error: suspicious use of `>>` in `Shl` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:111:20
+  --> tests/ui/suspicious_arithmetic_impl.rs:112:20
    |
 LL |         Foo(self.0 >> other.0)
    |                    ^^
 
 error: suspicious use of `<<` in `Shr` impl
-  --> tests/ui/suspicious_arithmetic_impl.rs:120:20
+  --> tests/ui/suspicious_arithmetic_impl.rs:121:20
    |
 LL |         Foo(self.0 << other.0)
    |                    ^^
diff --git a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
index c0856427eae..3d5c892eb60 100644
--- a/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
+++ b/src/tools/clippy/tests/ui/suspicious_else_formatting.rs
@@ -120,6 +120,34 @@ fn main() {
     /* whelp */
     {
     }
+
+    // #12497 Don't trigger lint as rustfmt wants it
+    if true {
+        println!("true");
+    }
+    /*else if false {
+}*/
+    else {
+        println!("false");
+    }
+
+    if true {
+        println!("true");
+    } // else if false {}
+    else {
+        println!("false");
+    }
+
+    if true {
+        println!("true");
+    } /* if true {
+        println!("true");
+}
+    */
+    else {
+        println!("false");
+    }
+
 }
 
 // #7650 - Don't lint. Proc-macro using bad spans for `if` expressions.
diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs
index 1796ccaf28e..be6e071767d 100644
--- a/src/tools/clippy/tests/ui/transmute.rs
+++ b/src/tools/clippy/tests/ui/transmute.rs
@@ -1,4 +1,9 @@
-#![allow(dead_code, clippy::borrow_as_ptr, clippy::needless_lifetimes)]
+#![allow(
+    dead_code,
+    clippy::borrow_as_ptr,
+    clippy::needless_lifetimes,
+    clippy::missing_transmute_annotations
+)]
 //@no-rustfix
 extern crate core;
 
diff --git a/src/tools/clippy/tests/ui/transmute.stderr b/src/tools/clippy/tests/ui/transmute.stderr
index 3ed6cb2b3f9..375e8f19dd6 100644
--- a/src/tools/clippy/tests/ui/transmute.stderr
+++ b/src/tools/clippy/tests/ui/transmute.stderr
@@ -1,5 +1,5 @@
 error: transmute from a reference to a pointer
-  --> tests/ui/transmute.rs:24:23
+  --> tests/ui/transmute.rs:29:23
    |
 LL |     let _: *const T = core::intrinsics::transmute(t);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T`
@@ -8,61 +8,61 @@ LL |     let _: *const T = core::intrinsics::transmute(t);
    = help: to override `-D warnings` add `#[allow(clippy::useless_transmute)]`
 
 error: transmute from a reference to a pointer
-  --> tests/ui/transmute.rs:28:21
+  --> tests/ui/transmute.rs:33:21
    |
 LL |     let _: *mut T = core::intrinsics::transmute(t);
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *mut T`
 
 error: transmute from a reference to a pointer
-  --> tests/ui/transmute.rs:31:23
+  --> tests/ui/transmute.rs:36:23
    |
 LL |     let _: *const U = core::intrinsics::transmute(t);
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `t as *const T as *const U`
 
 error: transmute from a type (`std::vec::Vec<i32>`) to itself
-  --> tests/ui/transmute.rs:38:27
+  --> tests/ui/transmute.rs:43:27
    |
 LL |         let _: Vec<i32> = core::intrinsics::transmute(my_vec());
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from a type (`std::vec::Vec<i32>`) to itself
-  --> tests/ui/transmute.rs:41:27
+  --> tests/ui/transmute.rs:46:27
    |
 LL |         let _: Vec<i32> = core::mem::transmute(my_vec());
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from a type (`std::vec::Vec<i32>`) to itself
-  --> tests/ui/transmute.rs:44:27
+  --> tests/ui/transmute.rs:49:27
    |
 LL |         let _: Vec<i32> = std::intrinsics::transmute(my_vec());
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from a type (`std::vec::Vec<i32>`) to itself
-  --> tests/ui/transmute.rs:47:27
+  --> tests/ui/transmute.rs:52:27
    |
 LL |         let _: Vec<i32> = std::mem::transmute(my_vec());
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from a type (`std::vec::Vec<i32>`) to itself
-  --> tests/ui/transmute.rs:50:27
+  --> tests/ui/transmute.rs:55:27
    |
 LL |         let _: Vec<i32> = my_transmute(my_vec());
    |                           ^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from an integer to a pointer
-  --> tests/ui/transmute.rs:53:31
+  --> tests/ui/transmute.rs:58:31
    |
 LL |         let _: *const usize = std::mem::transmute(5_isize);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `5_isize as *const usize`
 
 error: transmute from an integer to a pointer
-  --> tests/ui/transmute.rs:58:31
+  --> tests/ui/transmute.rs:63:31
    |
 LL |         let _: *const usize = std::mem::transmute(1 + 1usize);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `(1 + 1usize) as *const usize`
 
 error: transmute from a type (`*const Usize`) to the type that it points to (`Usize`)
-  --> tests/ui/transmute.rs:90:24
+  --> tests/ui/transmute.rs:95:24
    |
 LL |         let _: Usize = core::intrinsics::transmute(int_const_ptr);
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -71,25 +71,25 @@ LL |         let _: Usize = core::intrinsics::transmute(int_const_ptr);
    = help: to override `-D warnings` add `#[allow(clippy::crosspointer_transmute)]`
 
 error: transmute from a type (`*mut Usize`) to the type that it points to (`Usize`)
-  --> tests/ui/transmute.rs:94:24
+  --> tests/ui/transmute.rs:99:24
    |
 LL |         let _: Usize = core::intrinsics::transmute(int_mut_ptr);
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from a type (`Usize`) to a pointer to that type (`*const Usize`)
-  --> tests/ui/transmute.rs:97:31
+  --> tests/ui/transmute.rs:102:31
    |
 LL |         let _: *const Usize = core::intrinsics::transmute(my_int());
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from a type (`Usize`) to a pointer to that type (`*mut Usize`)
-  --> tests/ui/transmute.rs:100:29
+  --> tests/ui/transmute.rs:105:29
    |
 LL |         let _: *mut Usize = core::intrinsics::transmute(my_int());
    |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from a `u8` to a `bool`
-  --> tests/ui/transmute.rs:107:28
+  --> tests/ui/transmute.rs:112:28
    |
 LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `0_u8 != 0`
@@ -98,7 +98,7 @@ LL |     let _: bool = unsafe { std::mem::transmute(0_u8) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_bool)]`
 
 error: transmute from a `u32` to a `f32`
-  --> tests/ui/transmute.rs:115:31
+  --> tests/ui/transmute.rs:120:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
@@ -107,25 +107,25 @@ LL |         let _: f32 = unsafe { std::mem::transmute(0_u32) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_float)]`
 
 error: transmute from a `i32` to a `f32`
-  --> tests/ui/transmute.rs:118:31
+  --> tests/ui/transmute.rs:123:31
    |
 LL |         let _: f32 = unsafe { std::mem::transmute(0_i32) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_i32 as u32)`
 
 error: transmute from a `u64` to a `f64`
-  --> tests/ui/transmute.rs:120:31
+  --> tests/ui/transmute.rs:125:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_u64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_u64)`
 
 error: transmute from a `i64` to a `f64`
-  --> tests/ui/transmute.rs:122:31
+  --> tests/ui/transmute.rs:127:31
    |
 LL |         let _: f64 = unsafe { std::mem::transmute(0_i64) };
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:143:30
+  --> tests/ui/transmute.rs:148:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@@ -134,85 +134,85 @@ LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:146:30
+  --> tests/ui/transmute.rs:151:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:148:31
+  --> tests/ui/transmute.rs:153:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:150:30
+  --> tests/ui/transmute.rs:155:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:152:30
+  --> tests/ui/transmute.rs:157:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:154:31
+  --> tests/ui/transmute.rs:159:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `f32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:156:30
+  --> tests/ui/transmute.rs:161:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0.0f32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
 
 error: transmute from a `f64` to a `[u8; 8]`
-  --> tests/ui/transmute.rs:158:30
+  --> tests/ui/transmute.rs:163:30
    |
 LL |             let _: [u8; 8] = std::mem::transmute(0.0f64);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:164:30
+  --> tests/ui/transmute.rs:169:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:166:30
+  --> tests/ui/transmute.rs:171:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:168:31
+  --> tests/ui/transmute.rs:173:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:170:30
+  --> tests/ui/transmute.rs:175:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:172:30
+  --> tests/ui/transmute.rs:177:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:174:31
+  --> tests/ui/transmute.rs:179:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> tests/ui/transmute.rs:185:28
+  --> tests/ui/transmute.rs:190:28
    |
 LL |     let _: &str = unsafe { std::mem::transmute(B) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
@@ -221,13 +221,13 @@ LL |     let _: &str = unsafe { std::mem::transmute(B) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
 
 error: transmute from a `&mut [u8]` to a `&mut str`
-  --> tests/ui/transmute.rs:188:32
+  --> tests/ui/transmute.rs:193:32
    |
 LL |     let _: &mut str = unsafe { std::mem::transmute(mb) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> tests/ui/transmute.rs:190:30
+  --> tests/ui/transmute.rs:195:30
    |
 LL |     const _: &str = unsafe { std::mem::transmute(B) };
    |                              ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
diff --git a/src/tools/clippy/tests/ui/transmute_collection.rs b/src/tools/clippy/tests/ui/transmute_collection.rs
index 8bf45457335..e30b34a5d7d 100644
--- a/src/tools/clippy/tests/ui/transmute_collection.rs
+++ b/src/tools/clippy/tests/ui/transmute_collection.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::unsound_collection_transmute)]
+#![allow(clippy::missing_transmute_annotations)]
 
 use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};
 use std::mem::{transmute, MaybeUninit};
diff --git a/src/tools/clippy/tests/ui/transmute_collection.stderr b/src/tools/clippy/tests/ui/transmute_collection.stderr
index f71fba6315c..06db9321064 100644
--- a/src/tools/clippy/tests/ui/transmute_collection.stderr
+++ b/src/tools/clippy/tests/ui/transmute_collection.stderr
@@ -1,5 +1,5 @@
 error: transmute from `std::vec::Vec<u8>` to `std::vec::Vec<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:9:17
+  --> tests/ui/transmute_collection.rs:10:17
    |
 LL |         let _ = transmute::<_, Vec<u32>>(vec![0u8]);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,103 +8,103 @@ LL |         let _ = transmute::<_, Vec<u32>>(vec![0u8]);
    = help: to override `-D warnings` add `#[allow(clippy::unsound_collection_transmute)]`
 
 error: transmute from `std::vec::Vec<u32>` to `std::vec::Vec<[u8; 4]>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:13:17
+  --> tests/ui/transmute_collection.rs:14:17
    |
 LL |         let _ = transmute::<_, Vec<[u8; 4]>>(vec![1234u32]);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::VecDeque<u8>` to `std::collections::VecDeque<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:17:17
+  --> tests/ui/transmute_collection.rs:18:17
    |
 LL |         let _ = transmute::<_, VecDeque<u32>>(VecDeque::<u8>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::VecDeque<[u8; 4]>` to `std::collections::VecDeque<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:20:17
+  --> tests/ui/transmute_collection.rs:21:17
    |
 LL |         let _ = transmute::<_, VecDeque<u32>>(VecDeque::<[u8; 4]>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BinaryHeap<u8>` to `std::collections::BinaryHeap<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:24:17
+  --> tests/ui/transmute_collection.rs:25:17
    |
 LL |         let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<u8>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BinaryHeap<[u8; 4]>` to `std::collections::BinaryHeap<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:27:17
+  --> tests/ui/transmute_collection.rs:28:17
    |
 LL |         let _ = transmute::<_, BinaryHeap<u32>>(BinaryHeap::<[u8; 4]>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BTreeSet<u8>` to `std::collections::BTreeSet<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:31:17
+  --> tests/ui/transmute_collection.rs:32:17
    |
 LL |         let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<u8>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BTreeSet<[u8; 4]>` to `std::collections::BTreeSet<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:34:17
+  --> tests/ui/transmute_collection.rs:35:17
    |
 LL |         let _ = transmute::<_, BTreeSet<u32>>(BTreeSet::<[u8; 4]>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::HashSet<u8>` to `std::collections::HashSet<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:38:17
+  --> tests/ui/transmute_collection.rs:39:17
    |
 LL |         let _ = transmute::<_, HashSet<u32>>(HashSet::<u8>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::HashSet<[u8; 4]>` to `std::collections::HashSet<u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:41:17
+  --> tests/ui/transmute_collection.rs:42:17
    |
 LL |         let _ = transmute::<_, HashSet<u32>>(HashSet::<[u8; 4]>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BTreeMap<u8, u8>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:45:17
+  --> tests/ui/transmute_collection.rs:46:17
    |
 LL |         let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, u8>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BTreeMap<u32, u32>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:47:17
+  --> tests/ui/transmute_collection.rs:48:17
    |
 LL |         let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u32, u32>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BTreeMap<u8, [u8; 4]>` to `std::collections::BTreeMap<u8, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:50:17
+  --> tests/ui/transmute_collection.rs:51:17
    |
 LL |         let _ = transmute::<_, BTreeMap<u8, u32>>(BTreeMap::<u8, [u8; 4]>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::BTreeMap<[u8; 4], u32>` to `std::collections::BTreeMap<u32, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:52:17
+  --> tests/ui/transmute_collection.rs:53:17
    |
 LL |         let _ = transmute::<_, BTreeMap<u32, u32>>(BTreeMap::<[u8; 4], u32>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::HashMap<u8, u8>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:56:17
+  --> tests/ui/transmute_collection.rs:57:17
    |
 LL |         let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, u8>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::HashMap<u32, u32>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:58:17
+  --> tests/ui/transmute_collection.rs:59:17
    |
 LL |         let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u32, u32>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::HashMap<u8, [u8; 4]>` to `std::collections::HashMap<u8, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:61:17
+  --> tests/ui/transmute_collection.rs:62:17
    |
 LL |         let _ = transmute::<_, HashMap<u8, u32>>(HashMap::<u8, [u8; 4]>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `std::collections::HashMap<[u8; 4], u32>` to `std::collections::HashMap<u32, u32>` with mismatched layout is unsound
-  --> tests/ui/transmute_collection.rs:63:17
+  --> tests/ui/transmute_collection.rs:64:17
    |
 LL |         let _ = transmute::<_, HashMap<u32, u32>>(HashMap::<[u8; 4], u32>::new());
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
index cef0bcfa623..82d5f7fdca1 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
@@ -1,4 +1,5 @@
 #![warn(clippy::transmute_float_to_int)]
+#![allow(clippy::missing_transmute_annotations)]
 
 fn float_to_int() {
     let _: u32 = unsafe { 1f32.to_bits() };
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.rs b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
index 3d95bec2a20..9f056330adf 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.rs
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::transmute_float_to_int)]
+#![allow(clippy::missing_transmute_annotations)]
 
 fn float_to_int() {
     let _: u32 = unsafe { std::mem::transmute(1f32) };
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.stderr b/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
index e89258d9102..ac3aae5f8b7 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
@@ -1,5 +1,5 @@
 error: transmute from a `f32` to a `u32`
-  --> tests/ui/transmute_float_to_int.rs:4:27
+  --> tests/ui/transmute_float_to_int.rs:5:27
    |
 LL |     let _: u32 = unsafe { std::mem::transmute(1f32) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits()`
@@ -8,31 +8,31 @@ LL |     let _: u32 = unsafe { std::mem::transmute(1f32) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_float_to_int)]`
 
 error: transmute from a `f32` to a `i32`
-  --> tests/ui/transmute_float_to_int.rs:7:27
+  --> tests/ui/transmute_float_to_int.rs:8:27
    |
 LL |     let _: i32 = unsafe { std::mem::transmute(1f32) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32`
 
 error: transmute from a `f64` to a `u64`
-  --> tests/ui/transmute_float_to_int.rs:9:27
+  --> tests/ui/transmute_float_to_int.rs:10:27
    |
 LL |     let _: u64 = unsafe { std::mem::transmute(1f64) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()`
 
 error: transmute from a `f64` to a `i64`
-  --> tests/ui/transmute_float_to_int.rs:11:27
+  --> tests/ui/transmute_float_to_int.rs:12:27
    |
 LL |     let _: i64 = unsafe { std::mem::transmute(1f64) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits() as i64`
 
 error: transmute from a `f64` to a `u64`
-  --> tests/ui/transmute_float_to_int.rs:13:27
+  --> tests/ui/transmute_float_to_int.rs:14:27
    |
 LL |     let _: u64 = unsafe { std::mem::transmute(1.0) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1.0f64.to_bits()`
 
 error: transmute from a `f64` to a `u64`
-  --> tests/ui/transmute_float_to_int.rs:15:27
+  --> tests/ui/transmute_float_to_int.rs:16:27
    |
 LL |     let _: u64 = unsafe { std::mem::transmute(-1.0) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()`
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.fixed b/src/tools/clippy/tests/ui/transmute_int_to_char.fixed
index 17080118175..d3277d1b8c7 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_char.fixed
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char.fixed
@@ -1,4 +1,5 @@
 #![warn(clippy::transmute_int_to_char)]
+#![allow(clippy::missing_transmute_annotations)]
 
 fn int_to_char() {
     let _: char = unsafe { std::char::from_u32(0_u32).unwrap() };
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.rs b/src/tools/clippy/tests/ui/transmute_int_to_char.rs
index 5846a97e88a..d21c4fd6fea 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_char.rs
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::transmute_int_to_char)]
+#![allow(clippy::missing_transmute_annotations)]
 
 fn int_to_char() {
     let _: char = unsafe { std::mem::transmute(0_u32) };
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char.stderr b/src/tools/clippy/tests/ui/transmute_int_to_char.stderr
index 8444afbd21e..e3a3620f28b 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_char.stderr
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char.stderr
@@ -1,5 +1,5 @@
 error: transmute from a `u32` to a `char`
-  --> tests/ui/transmute_int_to_char.rs:4:28
+  --> tests/ui/transmute_int_to_char.rs:5:28
    |
 LL |     let _: char = unsafe { std::mem::transmute(0_u32) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_u32).unwrap()`
@@ -8,7 +8,7 @@ LL |     let _: char = unsafe { std::mem::transmute(0_u32) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
 
 error: transmute from a `i32` to a `char`
-  --> tests/ui/transmute_int_to_char.rs:7:28
+  --> tests/ui/transmute_int_to_char.rs:8:28
    |
 LL |     let _: char = unsafe { std::mem::transmute(0_i32) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::char::from_u32(0_i32 as u32).unwrap()`
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed
index 9ae4e11fb56..32a57645b46 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.fixed
@@ -1,6 +1,7 @@
 #![no_std]
 #![feature(lang_items)]
 #![warn(clippy::transmute_int_to_char)]
+#![allow(clippy::missing_transmute_annotations)]
 
 use core::panic::PanicInfo;
 
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs
index 9a2afd5bd2f..942794c32f8 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.rs
@@ -1,6 +1,7 @@
 #![no_std]
 #![feature(lang_items)]
 #![warn(clippy::transmute_int_to_char)]
+#![allow(clippy::missing_transmute_annotations)]
 
 use core::panic::PanicInfo;
 
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr
index d2c3842b684..d94580a84d7 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr
+++ b/src/tools/clippy/tests/ui/transmute_int_to_char_no_std.stderr
@@ -1,5 +1,5 @@
 error: transmute from a `u32` to a `char`
-  --> tests/ui/transmute_int_to_char_no_std.rs:16:28
+  --> tests/ui/transmute_int_to_char_no_std.rs:17:28
    |
 LL |     let _: char = unsafe { core::mem::transmute(0_u32) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_u32).unwrap()`
@@ -8,7 +8,7 @@ LL |     let _: char = unsafe { core::mem::transmute(0_u32) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_char)]`
 
 error: transmute from a `i32` to a `char`
-  --> tests/ui/transmute_int_to_char_no_std.rs:19:28
+  --> tests/ui/transmute_int_to_char_no_std.rs:20:28
    |
 LL |     let _: char = unsafe { core::mem::transmute(0_i32) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `core::char::from_u32(0_i32 as u32).unwrap()`
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed
index 866c0bbf127..fe8db3dcb0c 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed
+++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.fixed
@@ -1,4 +1,5 @@
 #![warn(clippy::transmute_int_to_non_zero)]
+#![allow(clippy::missing_transmute_annotations)]
 
 use core::num::*;
 
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs
index 803c4945c75..a79ed5279b1 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs
+++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::transmute_int_to_non_zero)]
+#![allow(clippy::missing_transmute_annotations)]
 
 use core::num::*;
 
diff --git a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr
index dd37bd21055..bb0b0d0ff4f 100644
--- a/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr
+++ b/src/tools/clippy/tests/ui/transmute_int_to_non_zero.stderr
@@ -1,5 +1,5 @@
 error: transmute from a `u8` to a `NonZeroU8`
-  --> tests/ui/transmute_int_to_non_zero.rs:18:33
+  --> tests/ui/transmute_int_to_non_zero.rs:19:33
    |
 LL |     let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) };
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU8::new_unchecked(int_u8)`
@@ -8,55 +8,55 @@ LL |     let _: NonZeroU8 = unsafe { std::mem::transmute(int_u8) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_int_to_non_zero)]`
 
 error: transmute from a `u16` to a `NonZeroU16`
-  --> tests/ui/transmute_int_to_non_zero.rs:21:34
+  --> tests/ui/transmute_int_to_non_zero.rs:22:34
    |
 LL |     let _: NonZeroU16 = unsafe { std::mem::transmute(int_u16) };
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU16::new_unchecked(int_u16)`
 
 error: transmute from a `u32` to a `NonZeroU32`
-  --> tests/ui/transmute_int_to_non_zero.rs:23:34
+  --> tests/ui/transmute_int_to_non_zero.rs:24:34
    |
 LL |     let _: NonZeroU32 = unsafe { std::mem::transmute(int_u32) };
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU32::new_unchecked(int_u32)`
 
 error: transmute from a `u64` to a `NonZeroU64`
-  --> tests/ui/transmute_int_to_non_zero.rs:25:34
+  --> tests/ui/transmute_int_to_non_zero.rs:26:34
    |
 LL |     let _: NonZeroU64 = unsafe { std::mem::transmute(int_u64) };
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU64::new_unchecked(int_u64)`
 
 error: transmute from a `u128` to a `NonZeroU128`
-  --> tests/ui/transmute_int_to_non_zero.rs:27:35
+  --> tests/ui/transmute_int_to_non_zero.rs:28:35
    |
 LL |     let _: NonZeroU128 = unsafe { std::mem::transmute(int_u128) };
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroU128::new_unchecked(int_u128)`
 
 error: transmute from a `i8` to a `NonZeroI8`
-  --> tests/ui/transmute_int_to_non_zero.rs:30:33
+  --> tests/ui/transmute_int_to_non_zero.rs:31:33
    |
 LL |     let _: NonZeroI8 = unsafe { std::mem::transmute(int_i8) };
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI8::new_unchecked(int_i8)`
 
 error: transmute from a `i16` to a `NonZeroI16`
-  --> tests/ui/transmute_int_to_non_zero.rs:32:34
+  --> tests/ui/transmute_int_to_non_zero.rs:33:34
    |
 LL |     let _: NonZeroI16 = unsafe { std::mem::transmute(int_i16) };
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI16::new_unchecked(int_i16)`
 
 error: transmute from a `i32` to a `NonZeroI32`
-  --> tests/ui/transmute_int_to_non_zero.rs:34:34
+  --> tests/ui/transmute_int_to_non_zero.rs:35:34
    |
 LL |     let _: NonZeroI32 = unsafe { std::mem::transmute(int_i32) };
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI32::new_unchecked(int_i32)`
 
 error: transmute from a `i64` to a `NonZeroI64`
-  --> tests/ui/transmute_int_to_non_zero.rs:36:34
+  --> tests/ui/transmute_int_to_non_zero.rs:37:34
    |
 LL |     let _: NonZeroI64 = unsafe { std::mem::transmute(int_i64) };
    |                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI64::new_unchecked(int_i64)`
 
 error: transmute from a `i128` to a `NonZeroI128`
-  --> tests/ui/transmute_int_to_non_zero.rs:38:35
+  --> tests/ui/transmute_int_to_non_zero.rs:39:35
    |
 LL |     let _: NonZeroI128 = unsafe { std::mem::transmute(int_i128) };
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `NonZeroI128::new_unchecked(int_i128)`
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 b07851e864f..c0196ad52d4 100644
--- a/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
+++ b/src/tools/clippy/tests/ui/transmute_null_to_fn.rs
@@ -1,6 +1,6 @@
 #![allow(dead_code)]
 #![warn(clippy::transmute_null_to_fn)]
-#![allow(clippy::zero_ptr)]
+#![allow(clippy::zero_ptr, clippy::missing_transmute_annotations)]
 
 // Easy to lint because these only span one line.
 fn one_liners() {
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed
index 696def08f14..b696a574ae3 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.fixed
@@ -1,5 +1,5 @@
 #![warn(clippy::transmute_ptr_to_ptr)]
-#![allow(clippy::borrow_as_ptr)]
+#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
 
 // Make sure we can modify lifetimes, which is one of the recommended uses
 // of transmute
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
index 0700d8c1957..85cc1d7802c 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ptr.rs
@@ -1,5 +1,5 @@
 #![warn(clippy::transmute_ptr_to_ptr)]
-#![allow(clippy::borrow_as_ptr)]
+#![allow(clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
 
 // Make sure we can modify lifetimes, which is one of the recommended uses
 // of transmute
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
index acec14ccb6b..56330d71938 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.fixed
@@ -1,5 +1,9 @@
 #![warn(clippy::transmute_ptr_to_ref)]
-#![allow(clippy::match_single_binding, clippy::unnecessary_cast)]
+#![allow(
+    clippy::match_single_binding,
+    clippy::unnecessary_cast,
+    clippy::missing_transmute_annotations
+)]
 
 unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
     let _: &T = &*p;
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
index 3376401e284..ce1ee8bfbfa 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.rs
@@ -1,5 +1,9 @@
 #![warn(clippy::transmute_ptr_to_ref)]
-#![allow(clippy::match_single_binding, clippy::unnecessary_cast)]
+#![allow(
+    clippy::match_single_binding,
+    clippy::unnecessary_cast,
+    clippy::missing_transmute_annotations
+)]
 
 unsafe fn _ptr_to_ref<T, U>(p: *const T, m: *mut T, o: *const U, om: *mut U) {
     let _: &T = std::mem::transmute(p);
diff --git a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
index d7d180398e1..44cda254c3f 100644
--- a/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
+++ b/src/tools/clippy/tests/ui/transmute_ptr_to_ref.stderr
@@ -1,5 +1,5 @@
 error: transmute from a pointer type (`*const T`) to a reference type (`&T`)
-  --> tests/ui/transmute_ptr_to_ref.rs:5:17
+  --> tests/ui/transmute_ptr_to_ref.rs:9:17
    |
 LL |     let _: &T = std::mem::transmute(p);
    |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*p`
@@ -8,127 +8,127 @@ LL |     let _: &T = std::mem::transmute(p);
    = help: to override `-D warnings` add `#[allow(clippy::transmute_ptr_to_ref)]`
 
 error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)
-  --> tests/ui/transmute_ptr_to_ref.rs:8:21
+  --> tests/ui/transmute_ptr_to_ref.rs:12:21
    |
 LL |     let _: &mut T = std::mem::transmute(m);
    |                     ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *m`
 
 error: transmute from a pointer type (`*mut T`) to a reference type (`&T`)
-  --> tests/ui/transmute_ptr_to_ref.rs:11:17
+  --> tests/ui/transmute_ptr_to_ref.rs:15:17
    |
 LL |     let _: &T = std::mem::transmute(m);
    |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*m`
 
 error: transmute from a pointer type (`*mut T`) to a reference type (`&mut T`)
-  --> tests/ui/transmute_ptr_to_ref.rs:14:21
+  --> tests/ui/transmute_ptr_to_ref.rs:18:21
    |
 LL |     let _: &mut T = std::mem::transmute(p as *mut T);
    |                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(p as *mut T)`
 
 error: transmute from a pointer type (`*const U`) to a reference type (`&T`)
-  --> tests/ui/transmute_ptr_to_ref.rs:17:17
+  --> tests/ui/transmute_ptr_to_ref.rs:21:17
    |
 LL |     let _: &T = std::mem::transmute(o);
    |                 ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(o as *const T)`
 
 error: transmute from a pointer type (`*mut U`) to a reference type (`&mut T`)
-  --> tests/ui/transmute_ptr_to_ref.rs:20:21
+  --> tests/ui/transmute_ptr_to_ref.rs:24:21
    |
 LL |     let _: &mut T = std::mem::transmute(om);
    |                     ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&mut *(om as *mut T)`
 
 error: transmute from a pointer type (`*mut U`) to a reference type (`&T`)
-  --> tests/ui/transmute_ptr_to_ref.rs:23:17
+  --> tests/ui/transmute_ptr_to_ref.rs:27:17
    |
 LL |     let _: &T = std::mem::transmute(om);
    |                 ^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(om as *const T)`
 
 error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, u8>`)
-  --> tests/ui/transmute_ptr_to_ref.rs:33:32
+  --> tests/ui/transmute_ptr_to_ref.rs:37:32
    |
 LL |     let _: &Foo<u8> = unsafe { std::mem::transmute::<_, &Foo<_>>(raw) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<_>>()`
 
 error: transmute from a pointer type (`*const i32`) to a reference type (`&_issue1231::Foo<'_, &u8>`)
-  --> tests/ui/transmute_ptr_to_ref.rs:35:33
+  --> tests/ui/transmute_ptr_to_ref.rs:39:33
    |
 LL |     let _: &Foo<&u8> = unsafe { std::mem::transmute::<_, &Foo<&_>>(raw) };
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*raw.cast::<Foo<&_>>()`
 
 error: transmute from a pointer type (`*const i32`) to a reference type (`&u8`)
-  --> tests/ui/transmute_ptr_to_ref.rs:39:14
+  --> tests/ui/transmute_ptr_to_ref.rs:43:14
    |
 LL |     unsafe { std::mem::transmute::<_, Bar>(raw) };
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(raw as *const u8)`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:44:14
+  --> tests/ui/transmute_ptr_to_ref.rs:48:14
    |
 LL |         0 => std::mem::transmute(x),
    |              ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:45:14
+  --> tests/ui/transmute_ptr_to_ref.rs:49:14
    |
 LL |         1 => std::mem::transmute(y),
    |              ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&u32>()`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:46:14
+  --> tests/ui/transmute_ptr_to_ref.rs:50:14
    |
 LL |         2 => std::mem::transmute::<_, &&'b u32>(x),
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:47:14
+  --> tests/ui/transmute_ptr_to_ref.rs:51:14
    |
 LL |         _ => std::mem::transmute::<_, &&'b u32>(y),
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*y.cast::<&'b u32>()`
 
 error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:55:19
+  --> tests/ui/transmute_ptr_to_ref.rs:59:19
    |
 LL |     let _: &u32 = std::mem::transmute(a);
    |                   ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`
 
 error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:56:19
+  --> tests/ui/transmute_ptr_to_ref.rs:60:19
    |
 LL |     let _: &u32 = std::mem::transmute::<_, &u32>(a);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a.cast::<u32>()`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:58:14
+  --> tests/ui/transmute_ptr_to_ref.rs:62:14
    |
 LL |         0 => std::mem::transmute(x),
    |              ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&u32>()`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:59:14
+  --> tests/ui/transmute_ptr_to_ref.rs:63:14
    |
 LL |         _ => std::mem::transmute::<_, &&'b u32>(x),
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*x.cast::<&'b u32>()`
 
 error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:67:19
+  --> tests/ui/transmute_ptr_to_ref.rs:71:19
    |
 LL |     let _: &u32 = std::mem::transmute(a);
    |                   ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*a`
 
 error: transmute from a pointer type (`*const u32`) to a reference type (`&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:68:19
+  --> tests/ui/transmute_ptr_to_ref.rs:72:19
    |
 LL |     let _: &u32 = std::mem::transmute::<_, &u32>(a);
    |                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(a as *const u32)`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:70:14
+  --> tests/ui/transmute_ptr_to_ref.rs:74:14
    |
 LL |         0 => std::mem::transmute(x),
    |              ^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &u32)`
 
 error: transmute from a pointer type (`*const &u32`) to a reference type (`&&u32`)
-  --> tests/ui/transmute_ptr_to_ref.rs:71:14
+  --> tests/ui/transmute_ptr_to_ref.rs:75:14
    |
 LL |         _ => std::mem::transmute::<_, &&'b u32>(x),
    |              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `&*(x as *const () as *const &'b u32)`
diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs b/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs
index bdc7b9f6478..44d7af44a80 100644
--- a/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs
+++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref.rs
@@ -1,7 +1,7 @@
 //@no-rustfix
 
 #![deny(clippy::transmute_ptr_to_ptr)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::missing_transmute_annotations)]
 
 fn main() {
     unsafe {
diff --git a/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs b/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs
index b67386f8588..59177058754 100644
--- a/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs
+++ b/src/tools/clippy/tests/ui/transmute_ref_to_ref_no_std.rs
@@ -1,7 +1,7 @@
 //@no-rustfix
 
 #![deny(clippy::transmute_ptr_to_ptr)]
-#![allow(dead_code)]
+#![allow(dead_code, clippy::missing_transmute_annotations)]
 #![feature(lang_items)]
 #![no_std]
 
diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
index a087d09c120..dd4bac7f1ed 100644
--- a/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
+++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.rs
@@ -1,5 +1,10 @@
 #![warn(clippy::transmute_undefined_repr)]
-#![allow(clippy::unit_arg, clippy::transmute_ptr_to_ref, clippy::useless_transmute)]
+#![allow(
+    clippy::unit_arg,
+    clippy::transmute_ptr_to_ref,
+    clippy::useless_transmute,
+    clippy::missing_transmute_annotations
+)]
 
 use core::any::TypeId;
 use core::ffi::c_void;
diff --git a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
index 5504fbe16e4..b41d37a5cd1 100644
--- a/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
+++ b/src/tools/clippy/tests/ui/transmute_undefined_repr.stderr
@@ -1,5 +1,5 @@
 error: transmute from `Ty2<u32, i32>` which has an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:29:33
+  --> tests/ui/transmute_undefined_repr.rs:34:33
    |
 LL |         let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>());
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,13 +8,13 @@ LL |         let _: Ty2C<u32, i32> = transmute(value::<Ty2<u32, i32>>());
    = help: to override `-D warnings` add `#[allow(clippy::transmute_undefined_repr)]`
 
 error: transmute into `Ty2<u32, i32>` which has an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:33:32
+  --> tests/ui/transmute_undefined_repr.rs:38:32
    |
 LL |         let _: Ty2<u32, i32> = transmute(value::<Ty2C<u32, i32>>());
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: transmute from `Ty<Ty2<u32, i32>>` to `Ty2<u32, f32>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:42:32
+  --> tests/ui/transmute_undefined_repr.rs:47:32
    |
 LL |         let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>());
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -22,7 +22,7 @@ LL |         let _: Ty2<u32, f32> = transmute(value::<Ty<Ty2<u32, i32>>>());
    = note: two instances of the same generic type (`Ty2`) may have different layouts
 
 error: transmute from `Ty2<u32, f32>` to `Ty<Ty2<u32, i32>>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:46:36
+  --> tests/ui/transmute_undefined_repr.rs:51:36
    |
 LL |         let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>());
    |                                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -30,7 +30,7 @@ LL |         let _: Ty<Ty2<u32, i32>> = transmute(value::<Ty2<u32, f32>>());
    = note: two instances of the same generic type (`Ty2`) may have different layouts
 
 error: transmute from `Ty<&Ty2<u32, i32>>` to `&Ty2<u32, f32>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:54:33
+  --> tests/ui/transmute_undefined_repr.rs:59:33
    |
 LL |         let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>());
    |                                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -38,7 +38,7 @@ LL |         let _: &Ty2<u32, f32> = transmute(value::<Ty<&Ty2<u32, i32>>>());
    = note: two instances of the same generic type (`Ty2`) may have different layouts
 
 error: transmute from `&Ty2<u32, f32>` to `Ty<&Ty2<u32, i32>>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:58:37
+  --> tests/ui/transmute_undefined_repr.rs:63:37
    |
 LL |         let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>());
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -46,7 +46,7 @@ LL |         let _: Ty<&Ty2<u32, i32>> = transmute(value::<&Ty2<u32, f32>>());
    = note: two instances of the same generic type (`Ty2`) may have different layouts
 
 error: transmute from `std::boxed::Box<Ty2<u32, u32>>` to `&mut Ty2<u32, f32>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:88:45
+  --> tests/ui/transmute_undefined_repr.rs:93:45
    |
 LL |         let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32, u32>>>());
    |                                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -54,7 +54,7 @@ LL |         let _: &'static mut Ty2<u32, f32> = transmute(value::<Box<Ty2<u32,
    = note: two instances of the same generic type (`Ty2`) may have different layouts
 
 error: transmute from `&mut Ty2<u32, f32>` to `std::boxed::Box<Ty2<u32, u32>>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:92:37
+  --> tests/ui/transmute_undefined_repr.rs:97:37
    |
 LL |         let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32, f32>>());
    |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -62,7 +62,7 @@ LL |         let _: Box<Ty2<u32, u32>> = transmute(value::<&'static mut Ty2<u32,
    = note: two instances of the same generic type (`Ty2`) may have different layouts
 
 error: transmute into `*const Ty2<u32, u32>` which has an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:189:39
+  --> tests/ui/transmute_undefined_repr.rs:194:39
    |
 LL |         let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty2<u32, u32>>>());
    |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -70,7 +70,7 @@ LL |         let _: *const Ty2<u32, u32> = transmute(value::<*const Ty2C<u32, Ty
    = note: the contained type `Ty2<u32, u32>` has an undefined layout
 
 error: transmute from `*const Ty2<u32, u32>` which has an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:193:50
+  --> tests/ui/transmute_undefined_repr.rs:198:50
    |
 LL |         let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const Ty2<u32, u32>>());
    |                                                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -78,7 +78,7 @@ LL |         let _: *const Ty2C<u32, Ty2<u32, u32>> = transmute(value::<*const T
    = note: the contained type `Ty2<u32, u32>` has an undefined layout
 
 error: transmute from `std::vec::Vec<Ty2<U, i32>>` to `std::vec::Vec<Ty2<T, u32>>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:240:35
+  --> tests/ui/transmute_undefined_repr.rs:245:35
    |
 LL |         let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>());
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -86,7 +86,7 @@ LL |         let _: Vec<Ty2<T, u32>> = transmute(value::<Vec<Ty2<U, i32>>>());
    = note: two instances of the same generic type (`Vec`) may have different layouts
 
 error: transmute from `std::vec::Vec<Ty2<T, u32>>` to `std::vec::Vec<Ty2<U, i32>>`, both of which have an undefined layout
-  --> tests/ui/transmute_undefined_repr.rs:244:35
+  --> tests/ui/transmute_undefined_repr.rs:249:35
    |
 LL |         let _: Vec<Ty2<U, i32>> = transmute(value::<Vec<Ty2<T, u32>>>());
    |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
index 2365695d691..51682da4a98 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.fixed
@@ -3,7 +3,7 @@
 // would otherwise be responsible for
 #![warn(clippy::useless_transmute)]
 #![warn(clippy::transmute_ptr_to_ptr)]
-#![allow(unused, clippy::borrow_as_ptr)]
+#![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
 
 use std::mem::{size_of, transmute};
 
diff --git a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
index cd1607b4c19..e5fcdef7a1c 100644
--- a/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
+++ b/src/tools/clippy/tests/ui/transmutes_expressible_as_ptr_casts.rs
@@ -3,7 +3,7 @@
 // would otherwise be responsible for
 #![warn(clippy::useless_transmute)]
 #![warn(clippy::transmute_ptr_to_ptr)]
-#![allow(unused, clippy::borrow_as_ptr)]
+#![allow(unused, clippy::borrow_as_ptr, clippy::missing_transmute_annotations)]
 
 use std::mem::{size_of, transmute};
 
diff --git a/src/tools/clippy/tests/ui/transmuting_null.rs b/src/tools/clippy/tests/ui/transmuting_null.rs
index 88b8c996523..c2deb6b6c46 100644
--- a/src/tools/clippy/tests/ui/transmuting_null.rs
+++ b/src/tools/clippy/tests/ui/transmuting_null.rs
@@ -2,7 +2,7 @@
 #![warn(clippy::transmuting_null)]
 #![allow(clippy::zero_ptr)]
 #![allow(clippy::transmute_ptr_to_ref)]
-#![allow(clippy::eq_op)]
+#![allow(clippy::eq_op, clippy::missing_transmute_annotations)]
 
 // Easy to lint because these only span one line.
 fn one_liners() {
diff --git a/src/tools/clippy/tests/ui/type_id_on_box.fixed b/src/tools/clippy/tests/ui/type_id_on_box.fixed
index 538c38b70e6..3656043700f 100644
--- a/src/tools/clippy/tests/ui/type_id_on_box.fixed
+++ b/src/tools/clippy/tests/ui/type_id_on_box.fixed
@@ -19,19 +19,37 @@ fn existential() -> impl Any {
     Box::new(1) as Box<dyn Any>
 }
 
+trait AnySubTrait: Any {}
+impl<T: Any> AnySubTrait for T {}
+
 fn main() {
+    // Don't lint, calling `.type_id()` on a `&dyn Any` does the expected thing
+    let ref_dyn: &dyn Any = &42;
+    let _ = ref_dyn.type_id();
+
     let any_box: Box<dyn Any> = Box::new(0usize);
     let _ = (*any_box).type_id();
-    let _ = TypeId::of::<Box<dyn Any>>(); // Don't lint. We explicitly say "do this instead" if this is intentional
+    //~^ ERROR: calling `.type_id()` on
+
+    // Don't lint. We explicitly say "do this instead" if this is intentional
+    let _ = TypeId::of::<Box<dyn Any>>();
     let _ = (*any_box).type_id();
+
+    // 2 derefs are needed here to get to the `dyn Any`
     let any_box: &Box<dyn Any> = &(Box::new(0usize) as Box<dyn Any>);
-    let _ = (**any_box).type_id(); // 2 derefs are needed here to get to the `dyn Any`
+    let _ = (**any_box).type_id();
+    //~^ ERROR: calling `.type_id()` on
 
     let b = existential();
-    let _ = b.type_id(); // Don't lint.
+    let _ = b.type_id(); // Don't
+
+    let b: Box<dyn AnySubTrait> = Box::new(1);
+    let _ = (*b).type_id();
+    //~^ ERROR: calling `.type_id()` on
 
     let b: SomeBox = Box::new(0usize);
     let _ = (*b).type_id();
+    //~^ ERROR: calling `.type_id()` on
 
     let b = BadBox(Box::new(0usize));
     let _ = b.type_id(); // Don't lint. This is a call to `<BadBox as Any>::type_id`. Not `std::boxed::Box`!
diff --git a/src/tools/clippy/tests/ui/type_id_on_box.rs b/src/tools/clippy/tests/ui/type_id_on_box.rs
index f224d273bc2..4bd9e73f2da 100644
--- a/src/tools/clippy/tests/ui/type_id_on_box.rs
+++ b/src/tools/clippy/tests/ui/type_id_on_box.rs
@@ -19,19 +19,37 @@ fn existential() -> impl Any {
     Box::new(1) as Box<dyn Any>
 }
 
+trait AnySubTrait: Any {}
+impl<T: Any> AnySubTrait for T {}
+
 fn main() {
+    // Don't lint, calling `.type_id()` on a `&dyn Any` does the expected thing
+    let ref_dyn: &dyn Any = &42;
+    let _ = ref_dyn.type_id();
+
     let any_box: Box<dyn Any> = Box::new(0usize);
     let _ = any_box.type_id();
-    let _ = TypeId::of::<Box<dyn Any>>(); // Don't lint. We explicitly say "do this instead" if this is intentional
+    //~^ ERROR: calling `.type_id()` on
+
+    // Don't lint. We explicitly say "do this instead" if this is intentional
+    let _ = TypeId::of::<Box<dyn Any>>();
     let _ = (*any_box).type_id();
+
+    // 2 derefs are needed here to get to the `dyn Any`
     let any_box: &Box<dyn Any> = &(Box::new(0usize) as Box<dyn Any>);
-    let _ = any_box.type_id(); // 2 derefs are needed here to get to the `dyn Any`
+    let _ = any_box.type_id();
+    //~^ ERROR: calling `.type_id()` on
 
     let b = existential();
-    let _ = b.type_id(); // Don't lint.
+    let _ = b.type_id(); // Don't
+
+    let b: Box<dyn AnySubTrait> = Box::new(1);
+    let _ = b.type_id();
+    //~^ ERROR: calling `.type_id()` on
 
     let b: SomeBox = Box::new(0usize);
     let _ = b.type_id();
+    //~^ ERROR: calling `.type_id()` on
 
     let b = BadBox(Box::new(0usize));
     let _ = b.type_id(); // Don't lint. This is a call to `<BadBox as Any>::type_id`. Not `std::boxed::Box`!
diff --git a/src/tools/clippy/tests/ui/type_id_on_box.stderr b/src/tools/clippy/tests/ui/type_id_on_box.stderr
index 0fce6a37c00..4528195607d 100644
--- a/src/tools/clippy/tests/ui/type_id_on_box.stderr
+++ b/src/tools/clippy/tests/ui/type_id_on_box.stderr
@@ -1,37 +1,48 @@
-error: calling `.type_id()` on a `Box<dyn Any>`
-  --> tests/ui/type_id_on_box.rs:24:13
+error: calling `.type_id()` on `Box<dyn Any>`
+  --> tests/ui/type_id_on_box.rs:31:13
    |
 LL |     let _ = any_box.type_id();
    |             -------^^^^^^^^^^
    |             |
    |             help: consider dereferencing first: `(*any_box)`
    |
-   = note: this returns the type id of the literal type `Box<dyn Any>` instead of the type id of the boxed value, which is most likely not what you want
+   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want
    = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear
    = note: `-D clippy::type-id-on-box` implied by `-D warnings`
    = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]`
 
-error: calling `.type_id()` on a `Box<dyn Any>`
-  --> tests/ui/type_id_on_box.rs:28:13
+error: calling `.type_id()` on `Box<dyn Any>`
+  --> tests/ui/type_id_on_box.rs:40:13
    |
-LL |     let _ = any_box.type_id(); // 2 derefs are needed here to get to the `dyn Any`
+LL |     let _ = any_box.type_id();
    |             -------^^^^^^^^^^
    |             |
    |             help: consider dereferencing first: `(**any_box)`
    |
-   = note: this returns the type id of the literal type `Box<dyn Any>` instead of the type id of the boxed value, which is most likely not what you want
+   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want
    = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear
 
-error: calling `.type_id()` on a `Box<dyn Any>`
-  --> tests/ui/type_id_on_box.rs:34:13
+error: calling `.type_id()` on `Box<dyn AnySubTrait>`
+  --> tests/ui/type_id_on_box.rs:47:13
+   |
+LL |     let _ = b.type_id();
+   |             -^^^^^^^^^^
+   |             |
+   |             help: consider dereferencing first: `(*b)`
+   |
+   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want
+   = note: if this is intentional, use `TypeId::of::<Box<dyn AnySubTrait>>()` instead, which makes it more clear
+
+error: calling `.type_id()` on `Box<dyn Any>`
+  --> tests/ui/type_id_on_box.rs:51:13
    |
 LL |     let _ = b.type_id();
    |             -^^^^^^^^^^
    |             |
    |             help: consider dereferencing first: `(*b)`
    |
-   = note: this returns the type id of the literal type `Box<dyn Any>` instead of the type id of the boxed value, which is most likely not what you want
+   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want
    = note: if this is intentional, use `TypeId::of::<Box<dyn Any>>()` instead, which makes it more clear
 
-error: aborting due to 3 previous errors
+error: aborting due to 4 previous errors
 
diff --git a/src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs b/src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs
new file mode 100644
index 00000000000..f6d09834adb
--- /dev/null
+++ b/src/tools/clippy/tests/ui/type_id_on_box_unfixable.rs
@@ -0,0 +1,31 @@
+#![warn(clippy::type_id_on_box)]
+
+use std::any::{Any, TypeId};
+use std::ops::Deref;
+
+trait AnySubTrait: Any {}
+impl<T: Any> AnySubTrait for T {}
+
+// `Any` is an indirect supertrait
+trait AnySubSubTrait: AnySubTrait {}
+impl<T: AnySubTrait> AnySubSubTrait for T {}
+
+// This trait mentions `Any` in its predicates, but it is not a subtrait of `Any`.
+trait NormalTrait
+where
+    i32: Any,
+{
+}
+impl<T> NormalTrait for T {}
+
+fn main() {
+    // (currently we don't look deeper than one level into the supertrait hierachy, but we probably
+    // could)
+    let b: Box<dyn AnySubSubTrait> = Box::new(1);
+    let _ = b.type_id();
+    //~^ ERROR: calling `.type_id()` on
+
+    let b: Box<dyn NormalTrait> = Box::new(1);
+    let _ = b.type_id();
+    //~^ ERROR: calling `.type_id()` on
+}
diff --git a/src/tools/clippy/tests/ui/type_id_on_box_unfixable.stderr b/src/tools/clippy/tests/ui/type_id_on_box_unfixable.stderr
new file mode 100644
index 00000000000..539ed481ec1
--- /dev/null
+++ b/src/tools/clippy/tests/ui/type_id_on_box_unfixable.stderr
@@ -0,0 +1,22 @@
+error: calling `.type_id()` on `Box<dyn AnySubSubTrait>`
+  --> tests/ui/type_id_on_box_unfixable.rs:25:13
+   |
+LL |     let _ = b.type_id();
+   |             ^^^^^^^^^^^
+   |
+   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want
+   = note: if this is intentional, use `TypeId::of::<Box<dyn AnySubSubTrait>>()` instead, which makes it more clear
+   = note: `-D clippy::type-id-on-box` implied by `-D warnings`
+   = help: to override `-D warnings` add `#[allow(clippy::type_id_on_box)]`
+
+error: calling `.type_id()` on `Box<dyn NormalTrait>`
+  --> tests/ui/type_id_on_box_unfixable.rs:29:13
+   |
+LL |     let _ = b.type_id();
+   |             ^^^^^^^^^^^
+   |
+   = note: this returns the type id of the literal type `Box<_>` instead of the type id of the boxed value, which is most likely not what you want
+   = note: if this is intentional, use `TypeId::of::<Box<dyn NormalTrait>>()` instead, which makes it more clear
+
+error: aborting due to 2 previous errors
+
diff --git a/src/tools/clippy/tests/ui/uninhabited_references.rs b/src/tools/clippy/tests/ui/uninhabited_references.rs
index cd07b590a61..3569366ed05 100644
--- a/src/tools/clippy/tests/ui/uninhabited_references.rs
+++ b/src/tools/clippy/tests/ui/uninhabited_references.rs
@@ -1,4 +1,5 @@
 #![warn(clippy::uninhabited_references)]
+#![allow(clippy::missing_transmute_annotations)]
 #![feature(never_type)]
 
 fn ret_uninh_ref() -> &'static std::convert::Infallible {
diff --git a/src/tools/clippy/tests/ui/uninhabited_references.stderr b/src/tools/clippy/tests/ui/uninhabited_references.stderr
index 446d4e75557..8c9b206f429 100644
--- a/src/tools/clippy/tests/ui/uninhabited_references.stderr
+++ b/src/tools/clippy/tests/ui/uninhabited_references.stderr
@@ -1,5 +1,5 @@
 error: dereferencing a reference to an uninhabited type would be undefined behavior
-  --> tests/ui/uninhabited_references.rs:4:23
+  --> tests/ui/uninhabited_references.rs:5:23
    |
 LL | fn ret_uninh_ref() -> &'static std::convert::Infallible {
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -8,7 +8,7 @@ LL | fn ret_uninh_ref() -> &'static std::convert::Infallible {
    = help: to override `-D warnings` add `#[allow(clippy::uninhabited_references)]`
 
 error: dereferencing a reference to an uninhabited type would be undefined behavior
-  --> tests/ui/uninhabited_references.rs:10:30
+  --> tests/ui/uninhabited_references.rs:11:30
    |
 LL |         fn $name(x: &$ty) -> &$ty {
    |                              ^^^^
@@ -19,7 +19,7 @@ LL | ret_something!(id_never, !);
    = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: dereferencing a reference to an uninhabited type is undefined behavior
-  --> tests/ui/uninhabited_references.rs:11:14
+  --> tests/ui/uninhabited_references.rs:12:14
    |
 LL |             &*x
    |              ^^
@@ -30,7 +30,7 @@ LL | ret_something!(id_never, !);
    = note: this error originates in the macro `ret_something` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: dereferencing a reference to an uninhabited type is undefined behavior
-  --> tests/ui/uninhabited_references.rs:21:13
+  --> tests/ui/uninhabited_references.rs:22:13
    |
 LL |     let _ = *x;
    |             ^^
diff --git a/src/tools/clippy/tests/ui/use_self.fixed b/src/tools/clippy/tests/ui/use_self.fixed
index 6ea7857a238..ffc5b74d7bd 100644
--- a/src/tools/clippy/tests/ui/use_self.fixed
+++ b/src/tools/clippy/tests/ui/use_self.fixed
@@ -7,7 +7,8 @@
     clippy::upper_case_acronyms,
     clippy::from_over_into,
     clippy::self_named_constructors,
-    clippy::needless_lifetimes
+    clippy::needless_lifetimes,
+    clippy::missing_transmute_annotations
 )]
 
 #[macro_use]
diff --git a/src/tools/clippy/tests/ui/use_self.rs b/src/tools/clippy/tests/ui/use_self.rs
index 338cc00e45a..eb9d96168bc 100644
--- a/src/tools/clippy/tests/ui/use_self.rs
+++ b/src/tools/clippy/tests/ui/use_self.rs
@@ -7,7 +7,8 @@
     clippy::upper_case_acronyms,
     clippy::from_over_into,
     clippy::self_named_constructors,
-    clippy::needless_lifetimes
+    clippy::needless_lifetimes,
+    clippy::missing_transmute_annotations
 )]
 
 #[macro_use]
diff --git a/src/tools/clippy/tests/ui/use_self.stderr b/src/tools/clippy/tests/ui/use_self.stderr
index d7aa8410a47..bd5b685b45d 100644
--- a/src/tools/clippy/tests/ui/use_self.stderr
+++ b/src/tools/clippy/tests/ui/use_self.stderr
@@ -1,5 +1,5 @@
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:22:21
+  --> tests/ui/use_self.rs:23:21
    |
 LL |         fn new() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
@@ -8,253 +8,253 @@ LL |         fn new() -> Foo {
    = help: to override `-D warnings` add `#[allow(clippy::use_self)]`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:23:13
+  --> tests/ui/use_self.rs:24:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:25:22
+  --> tests/ui/use_self.rs:26:22
    |
 LL |         fn test() -> Foo {
    |                      ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:26:13
+  --> tests/ui/use_self.rs:27:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:31:25
+  --> tests/ui/use_self.rs:32:25
    |
 LL |         fn default() -> Foo {
    |                         ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:32:13
+  --> tests/ui/use_self.rs:33:13
    |
 LL |             Foo::new()
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:73:28
+  --> tests/ui/use_self.rs:74:28
    |
 LL |         fn clone(&self) -> Foo<'a> {
    |                            ^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:106:24
+  --> tests/ui/use_self.rs:107:24
    |
 LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
    |                        ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:106:55
+  --> tests/ui/use_self.rs:107:55
    |
 LL |         fn bad(foos: &[Foo]) -> impl Iterator<Item = &Foo> {
    |                                                       ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:121:13
+  --> tests/ui/use_self.rs:122:13
    |
 LL |             TS(0)
    |             ^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:156:29
+  --> tests/ui/use_self.rs:157:29
    |
 LL |                 fn bar() -> Bar {
    |                             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:157:21
+  --> tests/ui/use_self.rs:158:21
    |
 LL |                     Bar { foo: Foo {} }
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:168:21
+  --> tests/ui/use_self.rs:169:21
    |
 LL |         fn baz() -> Foo {
    |                     ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:169:13
+  --> tests/ui/use_self.rs:170:13
    |
 LL |             Foo {}
    |             ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:186:21
+  --> tests/ui/use_self.rs:187:21
    |
 LL |             let _ = Enum::B(42);
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:187:21
+  --> tests/ui/use_self.rs:188:21
    |
 LL |             let _ = Enum::C { field: true };
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:188:21
+  --> tests/ui/use_self.rs:189:21
    |
 LL |             let _ = Enum::A;
    |                     ^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:230:13
+  --> tests/ui/use_self.rs:231:13
    |
 LL |             nested::A::fun_1();
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:231:13
+  --> tests/ui/use_self.rs:232:13
    |
 LL |             nested::A::A;
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:233:13
+  --> tests/ui/use_self.rs:234:13
    |
 LL |             nested::A {};
    |             ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:252:13
+  --> tests/ui/use_self.rs:253:13
    |
 LL |             TestStruct::from_something()
    |             ^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:266:25
+  --> tests/ui/use_self.rs:267:25
    |
 LL |         async fn g() -> S {
    |                         ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:267:13
+  --> tests/ui/use_self.rs:268:13
    |
 LL |             S {}
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:271:16
+  --> tests/ui/use_self.rs:272:16
    |
 LL |             &p[S::A..S::B]
    |                ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:271:22
+  --> tests/ui/use_self.rs:272:22
    |
 LL |             &p[S::A..S::B]
    |                      ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:294:29
+  --> tests/ui/use_self.rs:295:29
    |
 LL |         fn foo(value: T) -> Foo<T> {
    |                             ^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:295:13
+  --> tests/ui/use_self.rs:296:13
    |
 LL |             Foo::<T> { value }
    |             ^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:467:13
+  --> tests/ui/use_self.rs:468:13
    |
 LL |             A::new::<submod::B>(submod::B {})
    |             ^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:504:13
+  --> tests/ui/use_self.rs:505:13
    |
 LL |             S2::new()
    |             ^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:541:17
+  --> tests/ui/use_self.rs:542:17
    |
 LL |                 Foo::Bar => unimplemented!(),
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:542:17
+  --> tests/ui/use_self.rs:543:17
    |
 LL |                 Foo::Baz => unimplemented!(),
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:548:20
+  --> tests/ui/use_self.rs:549:20
    |
 LL |             if let Foo::Bar = self {
    |                    ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:572:17
+  --> tests/ui/use_self.rs:573:17
    |
 LL |                 Something::Num(n) => *n,
    |                 ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:573:17
+  --> tests/ui/use_self.rs:574:17
    |
 LL |                 Something::TupleNums(n, _m) => *n,
    |                 ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:574:17
+  --> tests/ui/use_self.rs:575:17
    |
 LL |                 Something::StructNums { one, two: _ } => *one,
    |                 ^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:580:17
+  --> tests/ui/use_self.rs:581:17
    |
 LL |                 crate::issue8845::Something::Num(n) => *n,
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:581:17
+  --> tests/ui/use_self.rs:582:17
    |
 LL |                 crate::issue8845::Something::TupleNums(n, _m) => *n,
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:582:17
+  --> tests/ui/use_self.rs:583:17
    |
 LL |                 crate::issue8845::Something::StructNums { one, two: _ } => *one,
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:598:17
+  --> tests/ui/use_self.rs:599:17
    |
 LL |             let Foo(x) = self;
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:603:17
+  --> tests/ui/use_self.rs:604:17
    |
 LL |             let crate::issue8845::Foo(x) = self;
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:610:17
+  --> tests/ui/use_self.rs:611:17
    |
 LL |             let Bar { x, .. } = self;
    |                 ^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:615:17
+  --> tests/ui/use_self.rs:616:17
    |
 LL |             let crate::issue8845::Bar { x, .. } = self;
    |                 ^^^^^^^^^^^^^^^^^^^^^ help: use the applicable keyword: `Self`
 
 error: unnecessary structure name repetition
-  --> tests/ui/use_self.rs:654:17
+  --> tests/ui/use_self.rs:655:17
    |
 LL |                 E::A => {},
    |                 ^ help: use the applicable keyword: `Self`
diff --git a/src/tools/clippy/tests/ui/useless_asref.fixed b/src/tools/clippy/tests/ui/useless_asref.fixed
index c98f2928e03..ddbb9255b46 100644
--- a/src/tools/clippy/tests/ui/useless_asref.fixed
+++ b/src/tools/clippy/tests/ui/useless_asref.fixed
@@ -8,6 +8,8 @@
 )]
 
 use std::fmt::Debug;
+use std::rc::{Rc, Weak as RcWeak};
+use std::sync::{Arc, Weak as ArcWeak};
 
 struct FakeAsRef;
 
@@ -180,6 +182,22 @@ mod issue12135 {
     }
 }
 
+fn issue_12528() {
+    struct Foo;
+
+    let opt = Some(Arc::new(Foo));
+    let _ = opt.as_ref().map(Arc::clone);
+
+    let opt = Some(Rc::new(Foo));
+    let _ = opt.as_ref().map(Rc::clone);
+
+    let opt = Some(Arc::downgrade(&Arc::new(Foo)));
+    let _ = opt.as_ref().map(ArcWeak::clone);
+
+    let opt = Some(Rc::downgrade(&Rc::new(Foo)));
+    let _ = opt.as_ref().map(RcWeak::clone);
+}
+
 fn main() {
     not_ok();
     ok();
diff --git a/src/tools/clippy/tests/ui/useless_asref.rs b/src/tools/clippy/tests/ui/useless_asref.rs
index f9d603f116d..b0405e930a2 100644
--- a/src/tools/clippy/tests/ui/useless_asref.rs
+++ b/src/tools/clippy/tests/ui/useless_asref.rs
@@ -8,6 +8,8 @@
 )]
 
 use std::fmt::Debug;
+use std::rc::{Rc, Weak as RcWeak};
+use std::sync::{Arc, Weak as ArcWeak};
 
 struct FakeAsRef;
 
@@ -180,6 +182,22 @@ mod issue12135 {
     }
 }
 
+fn issue_12528() {
+    struct Foo;
+
+    let opt = Some(Arc::new(Foo));
+    let _ = opt.as_ref().map(Arc::clone);
+
+    let opt = Some(Rc::new(Foo));
+    let _ = opt.as_ref().map(Rc::clone);
+
+    let opt = Some(Arc::downgrade(&Arc::new(Foo)));
+    let _ = opt.as_ref().map(ArcWeak::clone);
+
+    let opt = Some(Rc::downgrade(&Rc::new(Foo)));
+    let _ = opt.as_ref().map(RcWeak::clone);
+}
+
 fn main() {
     not_ok();
     ok();
diff --git a/src/tools/clippy/tests/ui/useless_asref.stderr b/src/tools/clippy/tests/ui/useless_asref.stderr
index c7d622ec2dc..5f495c39670 100644
--- a/src/tools/clippy/tests/ui/useless_asref.stderr
+++ b/src/tools/clippy/tests/ui/useless_asref.stderr
@@ -1,5 +1,5 @@
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:48:18
+  --> tests/ui/useless_asref.rs:50:18
    |
 LL |         foo_rstr(rstr.as_ref());
    |                  ^^^^^^^^^^^^^ help: try: `rstr`
@@ -11,103 +11,103 @@ LL | #![deny(clippy::useless_asref)]
    |         ^^^^^^^^^^^^^^^^^^^^^
 
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:50:20
+  --> tests/ui/useless_asref.rs:52:20
    |
 LL |         foo_rslice(rslice.as_ref());
    |                    ^^^^^^^^^^^^^^^ help: try: `rslice`
 
 error: this call to `as_mut` does nothing
-  --> tests/ui/useless_asref.rs:54:21
+  --> tests/ui/useless_asref.rs:56:21
    |
 LL |         foo_mrslice(mrslice.as_mut());
    |                     ^^^^^^^^^^^^^^^^ help: try: `mrslice`
 
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:56:20
+  --> tests/ui/useless_asref.rs:58:20
    |
 LL |         foo_rslice(mrslice.as_ref());
    |                    ^^^^^^^^^^^^^^^^ help: try: `mrslice`
 
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:63:20
+  --> tests/ui/useless_asref.rs:65:20
    |
 LL |         foo_rslice(rrrrrslice.as_ref());
    |                    ^^^^^^^^^^^^^^^^^^^ help: try: `rrrrrslice`
 
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:65:18
+  --> tests/ui/useless_asref.rs:67:18
    |
 LL |         foo_rstr(rrrrrstr.as_ref());
    |                  ^^^^^^^^^^^^^^^^^ help: try: `rrrrrstr`
 
 error: this call to `as_mut` does nothing
-  --> tests/ui/useless_asref.rs:70:21
+  --> tests/ui/useless_asref.rs:72:21
    |
 LL |         foo_mrslice(mrrrrrslice.as_mut());
    |                     ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice`
 
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:72:20
+  --> tests/ui/useless_asref.rs:74:20
    |
 LL |         foo_rslice(mrrrrrslice.as_ref());
    |                    ^^^^^^^^^^^^^^^^^^^^ help: try: `mrrrrrslice`
 
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:76:16
+  --> tests/ui/useless_asref.rs:78:16
    |
 LL |     foo_rrrrmr((&&&&MoreRef).as_ref());
    |                ^^^^^^^^^^^^^^^^^^^^^^ help: try: `(&&&&MoreRef)`
 
 error: this call to `as_mut` does nothing
-  --> tests/ui/useless_asref.rs:126:13
+  --> tests/ui/useless_asref.rs:128:13
    |
 LL |     foo_mrt(mrt.as_mut());
    |             ^^^^^^^^^^^^ help: try: `mrt`
 
 error: this call to `as_ref` does nothing
-  --> tests/ui/useless_asref.rs:128:12
+  --> tests/ui/useless_asref.rs:130:12
    |
 LL |     foo_rt(mrt.as_ref());
    |            ^^^^^^^^^^^^ help: try: `mrt`
 
 error: this call to `as_ref.map(...)` does nothing
-  --> tests/ui/useless_asref.rs:139:13
+  --> tests/ui/useless_asref.rs:141:13
    |
 LL |     let z = x.as_ref().map(String::clone);
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`
 
 error: this call to `as_ref.map(...)` does nothing
-  --> tests/ui/useless_asref.rs:141:13
+  --> tests/ui/useless_asref.rs:143:13
    |
 LL |     let z = x.as_ref().map(|z| z.clone());
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`
 
 error: this call to `as_ref.map(...)` does nothing
-  --> tests/ui/useless_asref.rs:143:13
+  --> tests/ui/useless_asref.rs:145:13
    |
 LL |     let z = x.as_ref().map(|z| String::clone(z));
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.clone()`
 
 error: this call to `as_ref.map(...)` does nothing
-  --> tests/ui/useless_asref.rs:167:9
+  --> tests/ui/useless_asref.rs:169:9
    |
 LL |         x.field.as_ref().map(|v| v.clone());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
 
 error: this call to `as_ref.map(...)` does nothing
-  --> tests/ui/useless_asref.rs:169:9
+  --> tests/ui/useless_asref.rs:171:9
    |
 LL |         x.field.as_ref().map(Clone::clone);
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
 
 error: this call to `as_ref.map(...)` does nothing
-  --> tests/ui/useless_asref.rs:171:9
+  --> tests/ui/useless_asref.rs:173:9
    |
 LL |         x.field.as_ref().map(|v| Clone::clone(v));
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `x.field.clone()`
 
 error: this call to `as_ref.map(...)` does nothing
-  --> tests/ui/useless_asref.rs:176:9
+  --> tests/ui/useless_asref.rs:178:9
    |
 LL |         Some(1).as_ref().map(|&x| x.clone());
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: try: `Some(1).clone()`
diff --git a/src/tools/clippy/triagebot.toml b/src/tools/clippy/triagebot.toml
index d455d967e30..d8131044ff2 100644
--- a/src/tools/clippy/triagebot.toml
+++ b/src/tools/clippy/triagebot.toml
@@ -19,7 +19,7 @@ new_pr = true
 
 [assign]
 contributing_url = "https://github.com/rust-lang/rust-clippy/blob/master/CONTRIBUTING.md"
-users_on_vacation = []
+users_on_vacation = ["y21"]
 
 [assign.owners]
 "/.github" = ["@flip1995"]
diff --git a/src/tools/compiletest/src/raise_fd_limit.rs b/src/tools/compiletest/src/raise_fd_limit.rs
index bc2946e2c13..a4235381beb 100644
--- a/src/tools/compiletest/src/raise_fd_limit.rs
+++ b/src/tools/compiletest/src/raise_fd_limit.rs
@@ -4,7 +4,7 @@
 /// on the number of cores available.
 ///
 /// This fixes issue #7772.
-#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos"))]
+#[cfg(any(target_os = "macos", target_os = "ios", target_os = "watchos", target_os = "visionos"))]
 #[allow(non_camel_case_types)]
 pub unsafe fn raise_fd_limit() {
     use std::cmp;
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index bd2f65925bb..689fdc5dfeb 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -3926,11 +3926,17 @@ impl<'test> TestCx<'test> {
             cmd.env("IS_MSVC", "1")
                 .env("IS_WINDOWS", "1")
                 .env("MSVC_LIB", format!("'{}' -nologo", lib.display()))
-                .env("CC", format!("'{}' {}", self.config.cc, cflags))
-                .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags));
+                // Note: we diverge from legacy run_make and don't lump `CC` the compiler and
+                // default flags together.
+                .env("CC_DEFAULT_FLAGS", &cflags)
+                .env("CC", &self.config.cc)
+                .env("CXX_DEFAULT_FLAGS", &cxxflags)
+                .env("CXX", &self.config.cxx);
         } else {
-            cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags))
-                .env("CXX", format!("{} {}", self.config.cxx, self.config.cxxflags))
+            cmd.env("CC_DEFAULT_FLAGS", &self.config.cflags)
+                .env("CC", &self.config.cc)
+                .env("CXX_DEFAULT_FLAGS", &self.config.cxxflags)
+                .env("CXX", &self.config.cxx)
                 .env("AR", &self.config.ar);
 
             if self.config.target.contains("windows") {
diff --git a/src/tools/miri/README.md b/src/tools/miri/README.md
index 11b77780833..60a1c1fa1dd 100644
--- a/src/tools/miri/README.md
+++ b/src/tools/miri/README.md
@@ -507,6 +507,8 @@ binaries, and as such worth documenting:
   crate currently being compiled.
 * `MIRI_ORIG_RUSTDOC` is set and read by different phases of `cargo-miri` to remember the
   value of `RUSTDOC` from before it was overwritten.
+* `MIRI_REPLACE_LIBRS_IF_NOT_TEST` when set to any value enables a hack that helps bootstrap
+  run the standard library tests in Miri.
 * `MIRI_VERBOSE` when set to any value tells the various `cargo-miri` phases to
   perform verbose logging.
 * `MIRI_HOST_SYSROOT` is set by bootstrap to tell `cargo-miri` which sysroot to use for *host*
diff --git a/src/tools/miri/cargo-miri/src/phases.rs b/src/tools/miri/cargo-miri/src/phases.rs
index 694720ab21f..3f6c484a057 100644
--- a/src/tools/miri/cargo-miri/src/phases.rs
+++ b/src/tools/miri/cargo-miri/src/phases.rs
@@ -3,7 +3,7 @@
 use std::env;
 use std::fs::{self, File};
 use std::io::BufReader;
-use std::path::PathBuf;
+use std::path::{Path, PathBuf};
 use std::process::Command;
 
 use rustc_version::VersionMeta;
@@ -412,9 +412,25 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
     // Arguments are treated very differently depending on whether this crate is
     // for interpretation by Miri, or for use by a build script / proc macro.
     if target_crate {
-        // Forward arguments, but remove "link" from "--emit" to make this a check-only build.
+        // Forward arguments, but patched.
         let emit_flag = "--emit";
+        // This hack helps bootstrap run standard library tests in Miri. The issue is as follows:
+        // when running `cargo miri test` on libcore, cargo builds a local copy of core and makes it
+        // a dependency of the integration test crate. This copy duplicates all the lang items, so
+        // the build fails. (Regular testing avoids this because the sysroot is a literal copy of
+        // what `cargo build` produces, but since Miri builds its own sysroot this does not work for
+        // us.) So we need to make it so that the locally built libcore contains all the items from
+        // `core`, but does not re-define them -- we want to replace the entire crate but a
+        // re-export of the sysroot crate. We do this by swapping out the source file: if
+        // `MIRI_REPLACE_LIBRS_IF_NOT_TEST` is set and we are building a `lib.rs` file, and a
+        // `lib.miri.rs` file exists in the same folder, we build that instead. But crucially we
+        // only do that for the library, not the unit test crate (which would be runnable) or
+        // rustdoc (which would have a different `phase`).
+        let replace_librs = env::var_os("MIRI_REPLACE_LIBRS_IF_NOT_TEST").is_some()
+            && !runnable_crate
+            && phase == RustcPhase::Build;
         while let Some(arg) = args.next() {
+            // Patch `--emit`: remove "link" from "--emit" to make this a check-only build.
             if let Some(val) = arg.strip_prefix(emit_flag) {
                 // Patch this argument. First, extract its value.
                 let val =
@@ -429,13 +445,36 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
                     }
                 }
                 cmd.arg(format!("{emit_flag}={}", val.join(",")));
-            } else if arg == "--extern" {
-                // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files:
-                // https://github.com/rust-lang/miri/issues/1705
+                continue;
+            }
+            // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files:
+            // https://github.com/rust-lang/miri/issues/1705
+            if arg == "--extern" {
                 forward_patched_extern_arg(&mut args, &mut cmd);
-            } else {
-                cmd.arg(arg);
+                continue;
             }
+            // If the REPLACE_LIBRS hack is enabled and we are building a `lib.rs` file, and a
+            // `lib.miri.rs` file exists, then build that instead. We only consider relative paths
+            // as cargo uses those for files in the workspace; dependencies from crates.io get
+            // absolute paths.
+            if replace_librs {
+                let path = Path::new(&arg);
+                if path.is_relative()
+                    && path.file_name().is_some_and(|f| f == "lib.rs")
+                    && path.is_file()
+                {
+                    let miri_rs = Path::new(&arg).with_extension("miri.rs");
+                    if miri_rs.is_file() {
+                        if verbose > 0 {
+                            eprintln!("Performing REPLACE_LIBRS hack: {arg:?} -> {miri_rs:?}");
+                        }
+                        cmd.arg(miri_rs);
+                        continue;
+                    }
+                }
+            }
+            // Fallback: just propagate the argument.
+            cmd.arg(arg);
         }
 
         // During setup, patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does).
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 6b8e1510a6b..fec39ec2b8e 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -18,8 +18,8 @@ use reuse_pool::ReusePool;
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 pub enum ProvenanceMode {
-    /// We support `expose_addr`/`with_exposed_provenance` via "wildcard" provenance.
-    /// However, we want on `with_exposed_provenance` to alert the user of the precision loss.
+    /// We support `expose_provenance`/`with_exposed_provenance` via "wildcard" provenance.
+    /// However, we warn on `with_exposed_provenance` to alert the user of the precision loss.
     Default,
     /// Like `Default`, but without the warning.
     Permissive,
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index c12fe0e086d..6e320b60eec 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -105,24 +105,41 @@ fn try_resolve_did(tcx: TyCtxt<'_>, path: &[&str], namespace: Option<Namespace>)
         (path, None)
     };
 
-    // First find the crate.
-    let krate =
-        tcx.crates(()).iter().find(|&&krate| tcx.crate_name(krate).as_str() == crate_name)?;
-    let mut cur_item = DefId { krate: *krate, index: CRATE_DEF_INDEX };
-    // Then go over the modules.
-    for &segment in modules {
-        cur_item = find_children(tcx, cur_item, segment)
-            .find(|item| tcx.def_kind(item) == DefKind::Mod)?;
-    }
-    // Finally, look up the desired item in this module, if any.
-    match item {
-        Some((item_name, namespace)) =>
-            Some(
-                find_children(tcx, cur_item, item_name)
-                    .find(|item| tcx.def_kind(item).ns() == Some(namespace))?,
-            ),
-        None => Some(cur_item),
+    // There may be more than one crate with this name. We try them all.
+    // (This is particularly relevant when running `std` tests as then there are two `std` crates:
+    // the one in the sysroot and the one locally built by `cargo test`.)
+    // FIXME: can we prefer the one from the sysroot?
+    'crates: for krate in
+        tcx.crates(()).iter().filter(|&&krate| tcx.crate_name(krate).as_str() == crate_name)
+    {
+        let mut cur_item = DefId { krate: *krate, index: CRATE_DEF_INDEX };
+        // Go over the modules.
+        for &segment in modules {
+            let Some(next_item) = find_children(tcx, cur_item, segment)
+                .find(|item| tcx.def_kind(item) == DefKind::Mod)
+            else {
+                continue 'crates;
+            };
+            cur_item = next_item;
+        }
+        // Finally, look up the desired item in this module, if any.
+        match item {
+            Some((item_name, namespace)) => {
+                let Some(item) = find_children(tcx, cur_item, item_name)
+                    .find(|item| tcx.def_kind(item).ns() == Some(namespace))
+                else {
+                    continue 'crates;
+                };
+                return Some(item);
+            }
+            None => {
+                // Just return the module.
+                return Some(cur_item);
+            }
+        }
     }
+    // Item not found in any of the crates with the right name.
+    None
 }
 
 /// Convert a softfloat type to its corresponding hostfloat type.
@@ -968,10 +985,6 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
     fn frame_in_std(&self) -> bool {
         let this = self.eval_context_ref();
-        let Some(start_fn) = this.tcx.lang_items().start_fn() else {
-            // no_std situations
-            return false;
-        };
         let frame = this.frame();
         // Make an attempt to get at the instance of the function this is inlined from.
         let instance: Option<_> = try {
@@ -982,13 +995,15 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         };
         // Fall back to the instance of the function itself.
         let instance = instance.unwrap_or(frame.instance);
-        // Now check if this is in the same crate as start_fn.
-        // As a special exception we also allow unit tests from
-        // <https://github.com/rust-lang/miri-test-libstd/tree/master/std_miri_test> to call these
-        // shims.
+        // Now check the crate it is in. We could try to be clever here and e.g. check if this is
+        // the same crate as `start_fn`, but that would not work for running std tests in Miri, so
+        // we'd need some more hacks anyway. So we just check the name of the crate. If someone
+        // calls their crate `std` then we'll just let them keep the pieces.
         let frame_crate = this.tcx.def_path(instance.def_id()).krate;
-        frame_crate == this.tcx.def_path(start_fn).krate
-            || this.tcx.crate_name(frame_crate).as_str() == "std_miri_test"
+        let crate_name = this.tcx.crate_name(frame_crate);
+        let crate_name = crate_name.as_str();
+        // On miri-test-libstd, the name of the crate is different.
+        crate_name == "std" || crate_name == "std_miri_test"
     }
 
     /// Handler that should be called when unsupported functionality is encountered.
diff --git a/src/tools/miri/src/shims/intrinsics/simd.rs b/src/tools/miri/src/shims/intrinsics/simd.rs
index 9d268f09edb..a2fc4f0f761 100644
--- a/src/tools/miri/src/shims/intrinsics/simd.rs
+++ b/src/tools/miri/src/shims/intrinsics/simd.rs
@@ -514,7 +514,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                     dest.transmute(this.machine.layouts.uint(dest.layout.size).unwrap(), this)?;
                 this.write_int(res, &dest)?;
             }
-            "cast" | "as" | "cast_ptr" | "expose_addr" | "with_exposed_provenance" => {
+            "cast" | "as" | "cast_ptr" | "expose_provenance" | "with_exposed_provenance" => {
                 let [op] = check_arg_count(args)?;
                 let (op, op_len) = this.operand_to_simd(op)?;
                 let (dest, dest_len) = this.mplace_to_simd(dest)?;
@@ -524,7 +524,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                 let unsafe_cast = intrinsic_name == "cast";
                 let safe_cast = intrinsic_name == "as";
                 let ptr_cast = intrinsic_name == "cast_ptr";
-                let expose_cast = intrinsic_name == "expose_addr";
+                let expose_cast = intrinsic_name == "expose_provenance";
                 let from_exposed_cast = intrinsic_name == "with_exposed_provenance";
 
                 for i in 0..dest_len {
@@ -557,7 +557,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
                             this.ptr_to_ptr(&op, dest.layout)?,
                         // Ptr/Int casts
                         (ty::RawPtr(..), ty::Int(_) | ty::Uint(_)) if expose_cast =>
-                            this.pointer_expose_address_cast(&op, dest.layout)?,
+                            this.pointer_expose_provenance_cast(&op, dest.layout)?,
                         (ty::Int(_) | ty::Uint(_), ty::RawPtr(..)) if from_exposed_cast =>
                             this.pointer_with_exposed_provenance_cast(&op, dest.layout)?,
                         // Error otherwise
diff --git a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
index 730859684a0..512473cd894 100644
--- a/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
+++ b/src/tools/miri/tests/fail/provenance/ptr_invalid.rs
@@ -4,6 +4,6 @@
 fn main() {
     let x = 42;
     let xptr = &x as *const i32;
-    let xptr_invalid = std::ptr::without_provenance::<i32>(xptr.expose_addr());
+    let xptr_invalid = std::ptr::without_provenance::<i32>(xptr.expose_provenance());
     let _val = unsafe { *xptr_invalid }; //~ ERROR: is a dangling pointer
 }
diff --git a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
index aa05649d550..608ab718919 100644
--- a/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
+++ b/src/tools/miri/tests/fail/stacked_borrows/exposed_only_ro.rs
@@ -6,7 +6,7 @@
 fn main() {
     let mut x = 0;
     let _fool = &mut x as *mut i32; // this would have fooled the old untagged pointer logic
-    let addr = (&x as *const i32).expose_addr();
+    let addr = (&x as *const i32).expose_provenance();
     let ptr = std::ptr::with_exposed_provenance_mut::<i32>(addr);
     unsafe { *ptr = 0 }; //~ ERROR: /write access using <wildcard> .* no exposed tags have suitable permission in the borrow stack/
 }
diff --git a/src/tools/miri/tests/pass/async-closure-captures.rs b/src/tools/miri/tests/pass/async-closure-captures.rs
new file mode 100644
index 00000000000..cac26bfe146
--- /dev/null
+++ b/src/tools/miri/tests/pass/async-closure-captures.rs
@@ -0,0 +1,125 @@
+// Same as rustc's `tests/ui/async-await/async-closures/captures.rs`, keep in sync
+
+#![feature(async_closure, noop_waker)]
+
+use std::future::Future;
+use std::pin::pin;
+use std::task::*;
+
+pub fn block_on<T>(fut: impl Future<Output = T>) -> T {
+    let mut fut = pin!(fut);
+    let ctx = &mut Context::from_waker(Waker::noop());
+
+    loop {
+        match fut.as_mut().poll(ctx) {
+            Poll::Pending => {}
+            Poll::Ready(t) => break t,
+        }
+    }
+}
+
+fn main() {
+    block_on(async_main());
+}
+
+async fn call<T>(f: &impl async Fn() -> T) -> T {
+    f().await
+}
+
+async fn call_once<T>(f: impl async FnOnce() -> T) -> T {
+    f().await
+}
+
+#[derive(Debug)]
+#[allow(unused)]
+struct Hello(i32);
+
+async fn async_main() {
+    // Capture something by-ref
+    {
+        let x = Hello(0);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(1);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something and consume it (force to `AsyncFnOnce`)
+    {
+        let x = Hello(2);
+        let c = async || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, don't consume it
+    {
+        let x = Hello(3);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(4);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, also consume it (so `AsyncFnOnce`)
+    {
+        let x = Hello(5);
+        let c = async move || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+
+    fn force_fnonce<T>(f: impl async FnOnce() -> T) -> impl async FnOnce() -> T {
+        f
+    }
+
+    // Capture something with `move`, but infer to `AsyncFnOnce`
+    {
+        let x = Hello(6);
+        let c = force_fnonce(async move || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+
+        let x = &Hello(7);
+        let c = force_fnonce(async move || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+    }
+
+    // Capture something by-ref, but infer to `AsyncFnOnce`
+    {
+        let x = Hello(8);
+        let c = force_fnonce(async || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+
+        let x = &Hello(9);
+        let c = force_fnonce(async || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+    }
+}
diff --git a/src/tools/miri/tests/pass/async-closure-captures.stdout b/src/tools/miri/tests/pass/async-closure-captures.stdout
new file mode 100644
index 00000000000..42a7999b2dc
--- /dev/null
+++ b/src/tools/miri/tests/pass/async-closure-captures.stdout
@@ -0,0 +1,14 @@
+Hello(0)
+Hello(0)
+Hello(1)
+Hello(1)
+Hello(2)
+Hello(3)
+Hello(3)
+Hello(4)
+Hello(4)
+Hello(5)
+Hello(6)
+Hello(7)
+Hello(8)
+Hello(9)
diff --git a/src/tools/miri/tests/pass/portable-simd-ptrs.rs b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
index 3b2d221bd8e..096ec78da1a 100644
--- a/src/tools/miri/tests/pass/portable-simd-ptrs.rs
+++ b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
@@ -7,6 +7,6 @@ use std::simd::prelude::*;
 fn main() {
     // Pointer casts
     let _val: Simd<*const u8, 4> = Simd::<*const i32, 4>::splat(ptr::null()).cast();
-    let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_addr();
+    let addrs = Simd::<*const i32, 4>::splat(ptr::null()).expose_provenance();
     let _ptrs = Simd::<*const i32, 4>::with_exposed_provenance(addrs);
 }
diff --git a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
index 8555de986f0..5690d7865bb 100644
--- a/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
+++ b/src/tools/miri/tests/pass/ptr_int_from_exposed.rs
@@ -10,7 +10,7 @@ fn ptr_roundtrip_out_of_bounds() {
     let x: i32 = 3;
     let x_ptr = &x as *const i32;
 
-    let x_usize = x_ptr.wrapping_offset(128).expose_addr();
+    let x_usize = x_ptr.wrapping_offset(128).expose_provenance();
 
     let ptr = ptr::with_exposed_provenance::<i32>(x_usize).wrapping_offset(-128);
     assert_eq!(unsafe { *ptr }, 3);
@@ -24,8 +24,8 @@ fn ptr_roundtrip_confusion() {
     let x_ptr = &x as *const i32;
     let y_ptr = &y as *const i32;
 
-    let x_usize = x_ptr.expose_addr();
-    let y_usize = y_ptr.expose_addr();
+    let x_usize = x_ptr.expose_provenance();
+    let y_usize = y_ptr.expose_provenance();
 
     let ptr = ptr::with_exposed_provenance::<i32>(y_usize);
     let ptr = ptr.with_addr(x_usize);
@@ -37,7 +37,7 @@ fn ptr_roundtrip_imperfect() {
     let x: u8 = 3;
     let x_ptr = &x as *const u8;
 
-    let x_usize = x_ptr.expose_addr() + 128;
+    let x_usize = x_ptr.expose_provenance() + 128;
 
     let ptr = ptr::with_exposed_provenance::<u8>(x_usize).wrapping_offset(-128);
     assert_eq!(unsafe { *ptr }, 3);
@@ -48,7 +48,7 @@ fn ptr_roundtrip_null() {
     let x = &42;
     let x_ptr = x as *const i32;
     let x_null_ptr = x_ptr.with_addr(0); // addr 0, but still the provenance of x
-    let null = x_null_ptr.expose_addr();
+    let null = x_null_ptr.expose_provenance();
     assert_eq!(null, 0);
 
     let x_null_ptr_copy = ptr::with_exposed_provenance::<i32>(null); // just a roundtrip, so has provenance of x (angelically)
diff --git a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
index 5622bf18654..c89d79b42e3 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/int-to-ptr.rs
@@ -17,7 +17,7 @@ fn example(variant: bool) {
     unsafe {
         fn not_so_innocent(x: &mut u32) -> usize {
             let x_raw4 = x as *mut u32;
-            x_raw4.expose_addr()
+            x_raw4.expose_provenance()
         }
 
         let mut c = 42u32;
@@ -26,7 +26,7 @@ fn example(variant: bool) {
         // stack: [..., Unique(1)]
 
         let x_raw2 = x_unique1 as *mut u32;
-        let x_raw2_addr = x_raw2.expose_addr();
+        let x_raw2_addr = x_raw2.expose_provenance();
         // stack: [..., Unique(1), SharedRW(2)]
 
         let x_unique3 = &mut *x_raw2;
diff --git a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
index 6e177a6e4ab..55356814a1a 100644
--- a/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
+++ b/src/tools/miri/tests/pass/stacked-borrows/unknown-bottom-gc.rs
@@ -9,7 +9,7 @@ fn main() {
 
     // Expose the allocation and use the exposed pointer, creating an unknown bottom
     unsafe {
-        let p: *mut u8 = ptr::with_exposed_provenance::<u8>(ptr.expose_addr()) as *mut u8;
+        let p: *mut u8 = ptr::with_exposed_provenance::<u8>(ptr.expose_provenance()) as *mut u8;
         *p = 1;
     }
 
diff --git a/src/tools/run-make-support/src/cc.rs b/src/tools/run-make-support/src/cc.rs
new file mode 100644
index 00000000000..2c9ad4f1700
--- /dev/null
+++ b/src/tools/run-make-support/src/cc.rs
@@ -0,0 +1,202 @@
+use std::env;
+use std::path::Path;
+use std::process::{Command, Output};
+
+use crate::{bin_name, cygpath_windows, handle_failed_output, is_msvc, is_windows, tmp_dir, uname};
+
+/// Construct a new platform-specific C compiler invocation.
+///
+/// WARNING: This means that what flags are accepted by the underlying C compiler is
+/// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
+pub fn cc() -> Cc {
+    Cc::new()
+}
+
+/// A platform-specific C compiler invocation builder. The specific C compiler used is
+/// passed down from compiletest.
+#[derive(Debug)]
+pub struct Cc {
+    cmd: Command,
+}
+
+impl Cc {
+    /// Construct a new platform-specific C compiler invocation.
+    ///
+    /// WARNING: This means that what flags are accepted by the underlying C compile is
+    /// platform- AND compiler-specific. Consult the relevant docs for `gcc`, `clang` and `mvsc`.
+    pub fn new() -> Self {
+        let compiler = env::var("CC").unwrap();
+
+        let mut cmd = Command::new(compiler);
+
+        let default_cflags = env::var("CC_DEFAULT_FLAGS").unwrap();
+        for flag in default_cflags.split(char::is_whitespace) {
+            cmd.arg(flag);
+        }
+
+        Self { cmd }
+    }
+
+    /// Specify path of the input file.
+    pub fn input<P: AsRef<Path>>(&mut self, path: P) -> &mut Self {
+        self.cmd.arg(path.as_ref());
+        self
+    }
+
+    /// Add a *platform-and-compiler-specific* argument. Please consult the docs for the various
+    /// possible C compilers on the various platforms to check which arguments are legal for
+    /// which compiler.
+    pub fn arg(&mut self, flag: &str) -> &mut Self {
+        self.cmd.arg(flag);
+        self
+    }
+
+    /// Add multiple *platform-and-compiler-specific* arguments. Please consult the docs for the
+    /// various possible C compilers on the various platforms to check which arguments are legal
+    /// for which compiler.
+    pub fn args(&mut self, args: &[&str]) -> &mut Self {
+        self.cmd.args(args);
+        self
+    }
+
+    /// Specify `-o` or `-Fe`/`-Fo` depending on platform/compiler. This assumes that the executable
+    /// is under `$TMPDIR`.
+    pub fn out_exe(&mut self, name: &str) -> &mut Self {
+        // Ref: tools.mk (irrelevant lines omitted):
+        //
+        // ```makefile
+        // ifdef IS_MSVC
+        //     OUT_EXE=-Fe:`cygpath -w $(TMPDIR)/$(call BIN,$(1))` \
+        //         -Fo:`cygpath -w $(TMPDIR)/$(1).obj`
+        // else
+        //     OUT_EXE=-o $(TMPDIR)/$(1)
+        // endif
+        // ```
+
+        if is_msvc() {
+            let fe_path = cygpath_windows(tmp_dir().join(bin_name(name)));
+            let fo_path = cygpath_windows(tmp_dir().join(format!("{name}.obj")));
+            self.cmd.arg(format!("-Fe:{fe_path}"));
+            self.cmd.arg(format!("-Fo:{fo_path}"));
+        } else {
+            self.cmd.arg("-o");
+            self.cmd.arg(tmp_dir().join(name));
+        }
+
+        self
+    }
+
+    /// Run the constructed C invocation command and assert that it is successfully run.
+    #[track_caller]
+    pub fn run(&mut self) -> Output {
+        let caller_location = std::panic::Location::caller();
+        let caller_line_number = caller_location.line();
+
+        let output = self.cmd.output().unwrap();
+        if !output.status.success() {
+            handle_failed_output(&format!("{:#?}", self.cmd), output, caller_line_number);
+        }
+        output
+    }
+
+    /// Inspect what the underlying [`Command`] is up to the current construction.
+    pub fn inspect(&mut self, f: impl FnOnce(&Command)) -> &mut Self {
+        f(&self.cmd);
+        self
+    }
+}
+
+/// `EXTRACFLAGS`
+pub fn extra_c_flags() -> Vec<&'static str> {
+    // Adapted from tools.mk (trimmed):
+    //
+    // ```makefile
+    // ifdef IS_WINDOWS
+    //     ifdef IS_MSVC
+    //         EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
+    //     else
+    //         EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
+    //     endif
+    // else
+    //     ifeq ($(UNAME),Darwin)
+    //         EXTRACFLAGS := -lresolv
+    //     else
+    //         ifeq ($(UNAME),FreeBSD)
+    //             EXTRACFLAGS := -lm -lpthread -lgcc_s
+    //         else
+    //             ifeq ($(UNAME),SunOS)
+    //                 EXTRACFLAGS := -lm -lpthread -lposix4 -lsocket -lresolv
+    //             else
+    //                 ifeq ($(UNAME),OpenBSD)
+    //                     EXTRACFLAGS := -lm -lpthread -lc++abi
+    //                 else
+    //                     EXTRACFLAGS := -lm -lrt -ldl -lpthread
+    //                 endif
+    //             endif
+    //         endif
+    //     endif
+    // endif
+    // ```
+
+    if is_windows() {
+        if is_msvc() {
+            vec![
+                "ws2_32.lib",
+                "userenv.lib",
+                "advapi32.lib",
+                "bcrypt.lib",
+                "ntdll.lib",
+                "synchronization.lib",
+            ]
+        } else {
+            vec!["-lws2_32", "-luserenv", "-lbcrypt", "-lntdll", "-lsynchronization"]
+        }
+    } else {
+        match uname() {
+            n if n.contains("Darwin") => vec!["-lresolv"],
+            n if n.contains("FreeBSD") => vec!["-lm", "-lpthread", "-lgcc_s"],
+            n if n.contains("SunOS") => {
+                vec!["-lm", "-lpthread", "-lposix4", "-lsocket", "-lresolv"]
+            }
+            n if n.contains("OpenBSD") => vec!["-lm", "-lpthread", "-lc++abi"],
+            _ => vec!["-lm", "-lrt", "-ldl", "-lpthread"],
+        }
+    }
+}
+
+/// `EXTRACXXFLAGS`
+pub fn extra_cxx_flags() -> Vec<&'static str> {
+    // Adapted from tools.mk (trimmed):
+    //
+    // ```makefile
+    // ifdef IS_WINDOWS
+    //     ifdef IS_MSVC
+    //     else
+    //         EXTRACXXFLAGS := -lstdc++
+    //     endif
+    // else
+    //     ifeq ($(UNAME),Darwin)
+    //         EXTRACXXFLAGS := -lc++
+    //     else
+    //         ifeq ($(UNAME),FreeBSD)
+    //         else
+    //             ifeq ($(UNAME),SunOS)
+    //             else
+    //                 ifeq ($(UNAME),OpenBSD)
+    //                 else
+    //                     EXTRACXXFLAGS := -lstdc++
+    //                 endif
+    //             endif
+    //         endif
+    //     endif
+    // endif
+    // ```
+    if is_windows() {
+        if is_msvc() { vec![] } else { vec!["-lstdc++"] }
+    } else {
+        match uname() {
+            n if n.contains("Darwin") => vec!["-lc++"],
+            _ => vec!["-lstdc++"],
+        }
+    }
+}
diff --git a/src/tools/run-make-support/src/lib.rs b/src/tools/run-make-support/src/lib.rs
index 48fa2bbf1ac..e70acf58571 100644
--- a/src/tools/run-make-support/src/lib.rs
+++ b/src/tools/run-make-support/src/lib.rs
@@ -1,14 +1,16 @@
+pub mod cc;
 pub mod run;
 pub mod rustc;
 pub mod rustdoc;
 
 use std::env;
-use std::path::PathBuf;
-use std::process::Output;
+use std::path::{Path, PathBuf};
+use std::process::{Command, Output};
 
 pub use object;
 pub use wasmparser;
 
+pub use cc::{cc, extra_c_flags, extra_cxx_flags, Cc};
 pub use run::{run, run_fail};
 pub use rustc::{aux_build, rustc, Rustc};
 pub use rustdoc::{bare_rustdoc, rustdoc, Rustdoc};
@@ -18,6 +20,89 @@ pub fn tmp_dir() -> PathBuf {
     env::var_os("TMPDIR").unwrap().into()
 }
 
+/// `TARGET`
+pub fn target() -> String {
+    env::var("TARGET").unwrap()
+}
+
+/// Check if target is windows-like.
+pub fn is_windows() -> bool {
+    env::var_os("IS_WINDOWS").is_some()
+}
+
+/// Check if target uses msvc.
+pub fn is_msvc() -> bool {
+    env::var_os("IS_MSVC").is_some()
+}
+
+/// Construct a path to a static library under `$TMPDIR` given the library name. This will return a
+/// path with `$TMPDIR` joined with platform-and-compiler-specific library name.
+pub fn static_lib(name: &str) -> PathBuf {
+    tmp_dir().join(static_lib_name(name))
+}
+
+/// Construct the static library name based on the platform.
+pub fn static_lib_name(name: &str) -> String {
+    // See tools.mk (irrelevant lines omitted):
+    //
+    // ```makefile
+    // ifeq ($(UNAME),Darwin)
+    //     STATICLIB = $(TMPDIR)/lib$(1).a
+    // else
+    //     ifdef IS_WINDOWS
+    //         ifdef IS_MSVC
+    //             STATICLIB = $(TMPDIR)/$(1).lib
+    //         else
+    //             STATICLIB = $(TMPDIR)/lib$(1).a
+    //         endif
+    //     else
+    //         STATICLIB = $(TMPDIR)/lib$(1).a
+    //     endif
+    // endif
+    // ```
+    assert!(!name.contains(char::is_whitespace), "name cannot contain whitespace");
+
+    if target().contains("msvc") { format!("{name}.lib") } else { format!("lib{name}.a") }
+}
+
+/// Construct the binary name based on platform.
+pub fn bin_name(name: &str) -> String {
+    if is_windows() { format!("{name}.exe") } else { name.to_string() }
+}
+
+/// Use `cygpath -w` on a path to get a Windows path string back. This assumes that `cygpath` is
+/// available on the platform!
+#[track_caller]
+pub fn cygpath_windows<P: AsRef<Path>>(path: P) -> String {
+    let caller_location = std::panic::Location::caller();
+    let caller_line_number = caller_location.line();
+
+    let mut cygpath = Command::new("cygpath");
+    cygpath.arg("-w");
+    cygpath.arg(path.as_ref());
+    let output = cygpath.output().unwrap();
+    if !output.status.success() {
+        handle_failed_output(&format!("{:#?}", cygpath), output, caller_line_number);
+    }
+    let s = String::from_utf8(output.stdout).unwrap();
+    // cygpath -w can attach a newline
+    s.trim().to_string()
+}
+
+/// Run `uname`. This assumes that `uname` is available on the platform!
+#[track_caller]
+pub fn uname() -> String {
+    let caller_location = std::panic::Location::caller();
+    let caller_line_number = caller_location.line();
+
+    let mut uname = Command::new("uname");
+    let output = uname.output().unwrap();
+    if !output.status.success() {
+        handle_failed_output(&format!("{:#?}", uname), output, caller_line_number);
+    }
+    String::from_utf8(output.stdout).unwrap()
+}
+
 fn handle_failed_output(cmd: &str, output: Output, caller_line_number: u32) -> ! {
     if output.status.success() {
         eprintln!("command incorrectly succeeded at line {caller_line_number}");
diff --git a/src/tools/run-make-support/src/run.rs b/src/tools/run-make-support/src/run.rs
index 42dcf54da22..e33ea9d6e40 100644
--- a/src/tools/run-make-support/src/run.rs
+++ b/src/tools/run-make-support/src/run.rs
@@ -2,17 +2,14 @@ use std::env;
 use std::path::{Path, PathBuf};
 use std::process::{Command, Output};
 
-use super::handle_failed_output;
+use crate::is_windows;
 
-fn run_common(bin_name: &str) -> (Command, Output) {
-    let target = env::var("TARGET").unwrap();
-
-    let bin_name =
-        if target.contains("windows") { format!("{}.exe", bin_name) } else { bin_name.to_owned() };
+use super::{bin_name, handle_failed_output};
 
+fn run_common(name: &str) -> (Command, Output) {
     let mut bin_path = PathBuf::new();
     bin_path.push(env::var("TMPDIR").unwrap());
-    bin_path.push(&bin_name);
+    bin_path.push(&bin_name(name));
     let ld_lib_path_envvar = env::var("LD_LIB_PATH_ENVVAR").unwrap();
     let mut cmd = Command::new(bin_path);
     cmd.env(&ld_lib_path_envvar, {
@@ -27,7 +24,7 @@ fn run_common(bin_name: &str) -> (Command, Output) {
         env::join_paths(paths.iter()).unwrap()
     });
 
-    if target.contains("windows") {
+    if is_windows() {
         let mut paths = vec![];
         for p in env::split_paths(&std::env::var("PATH").unwrap_or(String::new())) {
             paths.push(p.to_path_buf());
@@ -42,11 +39,11 @@ fn run_common(bin_name: &str) -> (Command, Output) {
 
 /// Run a built binary and make sure it succeeds.
 #[track_caller]
-pub fn run(bin_name: &str) -> Output {
+pub fn run(name: &str) -> Output {
     let caller_location = std::panic::Location::caller();
     let caller_line_number = caller_location.line();
 
-    let (cmd, output) = run_common(bin_name);
+    let (cmd, output) = run_common(name);
     if !output.status.success() {
         handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
     }
@@ -55,11 +52,11 @@ pub fn run(bin_name: &str) -> Output {
 
 /// Run a built binary and make sure it fails.
 #[track_caller]
-pub fn run_fail(bin_name: &str) -> Output {
+pub fn run_fail(name: &str) -> Output {
     let caller_location = std::panic::Location::caller();
     let caller_line_number = caller_location.line();
 
-    let (cmd, output) = run_common(bin_name);
+    let (cmd, output) = run_common(name);
     if output.status.success() {
         handle_failed_output(&format!("{:#?}", cmd), output, caller_line_number);
     }
diff --git a/src/tools/tidy/src/allowed_run_make_makefiles.txt b/src/tools/tidy/src/allowed_run_make_makefiles.txt
index 40950e6ba44..c3ed1ff6891 100644
--- a/src/tools/tidy/src/allowed_run_make_makefiles.txt
+++ b/src/tools/tidy/src/allowed_run_make_makefiles.txt
@@ -5,7 +5,6 @@ run-make/allocator-shim-circular-deps/Makefile
 run-make/allow-non-lint-warnings-cmdline/Makefile
 run-make/allow-warnings-cmdline-stability/Makefile
 run-make/archive-duplicate-names/Makefile
-run-make/arguments-non-c-like-enum/Makefile
 run-make/atomic-lock-free/Makefile
 run-make/bare-outfile/Makefile
 run-make/branch-protection-check-IBT/Makefile
@@ -86,7 +85,6 @@ run-make/foreign-exceptions/Makefile
 run-make/foreign-rust-exceptions/Makefile
 run-make/fpic/Makefile
 run-make/glibc-staticlib-args/Makefile
-run-make/hir-tree/Makefile
 run-make/inaccessible-temp-dir/Makefile
 run-make/include_bytes_deps/Makefile
 run-make/incr-add-rust-src-component/Makefile
@@ -132,7 +130,6 @@ run-make/issue-53964/Makefile
 run-make/issue-64153/Makefile
 run-make/issue-68794-textrel-on-minimal-lib/Makefile
 run-make/issue-69368/Makefile
-run-make/issue-7349/Makefile
 run-make/issue-83045/Makefile
 run-make/issue-83112-incr-test-moved-file/Makefile
 run-make/issue-84395-lto-embed-bitcode/Makefile
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index b74afa0d3e8..aec2856dbbc 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -56,7 +56,7 @@ pub(crate) const WORKSPACES: &[(&str, ExceptionList, Option<(&[&str], &[&str])>)
         Some((&["rustc_codegen_cranelift"], PERMITTED_CRANELIFT_DEPENDENCIES)),
     ),
     // tidy-alphabetical-start
-    //("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None), // FIXME uncomment once all deps are vendored
+    ("compiler/rustc_codegen_gcc", EXCEPTIONS_GCC, None),
     //("library/backtrace", &[], None), // FIXME uncomment once rust-lang/backtrace#562 has been synced back to the rust repo
     //("library/portable-simd", &[], None), // FIXME uncomment once rust-lang/portable-simd#363 has been synced back to the rust repo
     //("library/stdarch", EXCEPTIONS_STDARCH, None), // FIXME uncomment once rust-lang/stdarch#1462 has been synced back to the rust repo
@@ -164,15 +164,12 @@ const EXCEPTIONS_CRANELIFT: ExceptionList = &[
     // tidy-alphabetical-end
 ];
 
-// FIXME uncomment once all deps are vendored
-/*
 const EXCEPTIONS_GCC: ExceptionList = &[
     // tidy-alphabetical-start
     ("gccjit", "GPL-3.0"),
     ("gccjit_sys", "GPL-3.0"),
     // tidy-alphabetical-end
 ];
-*/
 
 const EXCEPTIONS_BOOTSTRAP: ExceptionList = &[
     ("ryu", "Apache-2.0 OR BSL-1.0"), // through serde. BSL is not acceptble, but we use it under Apache-2.0
diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index f6b1d45ee94..874c15ce41d 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -434,6 +434,7 @@
 "ui/closures/issue-111932.rs",
 "ui/closures/issue-113087.rs",
 "ui/closures/issue-11873.rs",
+"ui/closures/issue-1460.rs",
 "ui/closures/issue-23012-supertrait-signature-inference.rs",
 "ui/closures/issue-25439.rs",
 "ui/closures/issue-41366.rs",
@@ -1007,6 +1008,8 @@
 "ui/fmt/issue-86085.rs",
 "ui/fmt/issue-89173.rs",
 "ui/fmt/issue-91556.rs",
+"ui/fn/issue-1451.rs",
+"ui/fn/issue-1900.rs",
 "ui/fn/issue-3044.rs",
 "ui/fn/issue-3099.rs",
 "ui/fn/issue-3904.rs",
@@ -1129,7 +1132,6 @@
 "ui/generics/issue-98432.rs",
 "ui/higher-ranked/trait-bounds/issue-100689.rs",
 "ui/higher-ranked/trait-bounds/issue-102899.rs",
-"ui/higher-ranked/trait-bounds/issue-30786.rs",
 "ui/higher-ranked/trait-bounds/issue-36139-normalize-closure-sig.rs",
 "ui/higher-ranked/trait-bounds/issue-39292.rs",
 "ui/higher-ranked/trait-bounds/issue-42114.rs",
@@ -1550,7 +1552,6 @@
 "ui/issues/issue-13497-2.rs",
 "ui/issues/issue-13497.rs",
 "ui/issues/issue-13507-2.rs",
-"ui/issues/issue-1362.rs",
 "ui/issues/issue-13620.rs",
 "ui/issues/issue-13665.rs",
 "ui/issues/issue-13703.rs",
@@ -1576,12 +1577,8 @@
 "ui/issues/issue-14399.rs",
 "ui/issues/issue-14421.rs",
 "ui/issues/issue-14422.rs",
-"ui/issues/issue-1448-2.rs",
-"ui/issues/issue-1451.rs",
 "ui/issues/issue-14541.rs",
-"ui/issues/issue-1460.rs",
 "ui/issues/issue-14721.rs",
-"ui/issues/issue-1476.rs",
 "ui/issues/issue-14821.rs",
 "ui/issues/issue-14845.rs",
 "ui/issues/issue-14853.rs",
@@ -1631,7 +1628,6 @@
 "ui/issues/issue-16560.rs",
 "ui/issues/issue-16562.rs",
 "ui/issues/issue-16596.rs",
-"ui/issues/issue-1660.rs",
 "ui/issues/issue-16643.rs",
 "ui/issues/issue-16648.rs",
 "ui/issues/issue-16668.rs",
@@ -1645,7 +1641,6 @@
 "ui/issues/issue-16819.rs",
 "ui/issues/issue-16922-rpass.rs",
 "ui/issues/issue-16939.rs",
-"ui/issues/issue-1696.rs",
 "ui/issues/issue-16966.rs",
 "ui/issues/issue-16994.rs",
 "ui/issues/issue-17001.rs",
@@ -1725,7 +1720,6 @@
 "ui/issues/issue-18952.rs",
 "ui/issues/issue-18959.rs",
 "ui/issues/issue-18988.rs",
-"ui/issues/issue-1900.rs",
 "ui/issues/issue-19001.rs",
 "ui/issues/issue-19037.rs",
 "ui/issues/issue-19086.rs",
@@ -1753,12 +1747,10 @@
 "ui/issues/issue-19482.rs",
 "ui/issues/issue-19499.rs",
 "ui/issues/issue-19601.rs",
-"ui/issues/issue-1962.rs",
 "ui/issues/issue-19631.rs",
 "ui/issues/issue-19632.rs",
 "ui/issues/issue-19692.rs",
 "ui/issues/issue-19734.rs",
-"ui/issues/issue-1974.rs",
 "ui/issues/issue-19811-escape-unicode.rs",
 "ui/issues/issue-19850.rs",
 "ui/issues/issue-19922.rs",
@@ -2856,6 +2848,8 @@
 "ui/lint/unused/issue-92751.rs",
 "ui/lint/unused/issue-96606.rs",
 "ui/lint/use-redundant/issue-92904.rs",
+"ui/loops/issue-1962.rs",
+"ui/loops/issue-1974.rs",
 "ui/loops/issue-43162.rs",
 "ui/loops/issue-50576.rs",
 "ui/loops/issue-69225-SCEVAddExpr-wrap-flag.rs",
@@ -3045,6 +3039,8 @@
 "ui/mismatched_types/issue-118145-unwrap-for-shorthand.rs",
 "ui/mismatched_types/issue-118510.rs",
 "ui/mismatched_types/issue-13033.rs",
+"ui/mismatched_types/issue-1362.rs",
+"ui/mismatched_types/issue-1448-2.rs",
 "ui/mismatched_types/issue-19109.rs",
 "ui/mismatched_types/issue-26480.rs",
 "ui/mismatched_types/issue-35030.rs",
@@ -3860,6 +3856,7 @@
 "ui/stability-attribute/issue-28388-3.rs",
 "ui/stability-attribute/issue-99286-stable-intrinsics.rs",
 "ui/static/auxiliary/issue_24843.rs",
+"ui/static/issue-1660.rs",
 "ui/static/issue-18118-2.rs",
 "ui/static/issue-18118.rs",
 "ui/static/issue-24446.rs",
diff --git a/src/tools/tidy/src/rustdoc_css_themes.rs b/src/tools/tidy/src/rustdoc_css_themes.rs
index 852d6e14e91..af36f9ba58e 100644
--- a/src/tools/tidy/src/rustdoc_css_themes.rs
+++ b/src/tools/tidy/src/rustdoc_css_themes.rs
@@ -74,8 +74,11 @@ fn compare_themes<'a>(
         (noscript_css_line_number, noscript_css_line),
     ) in rustdoc_css_lines.zip(noscript_css_lines)
     {
-        if noscript_css_line.starts_with(":root {")
-            && rustdoc_css_line.starts_with(&format!(r#":root[data-theme="{name}"] {{"#))
+        if noscript_css_line.starts_with(":root, :root:not([data-theme]) {")
+            && (rustdoc_css_line.starts_with(&format!(r#":root[data-theme="{name}"] {{"#))
+                || rustdoc_css_line.starts_with(&format!(
+                    r#":root[data-theme="{name}"], :root:not([data-theme]) {{"#
+                )))
         {
             // selectors are different between rustdoc.css and noscript.css
             // that's why they both exist: one uses JS, the other uses media queries
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index fe27964981e..454811c5fbb 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -17,7 +17,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: usize = 1750;
+const ISSUES_ENTRY_LIMIT: usize = 1733;
 const ROOT_ENTRY_LIMIT: usize = 860;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
diff --git a/tests/assembly/targets/targets-macho.rs b/tests/assembly/targets/targets-macho.rs
index bbdafb76e5a..713129b692c 100644
--- a/tests/assembly/targets/targets-macho.rs
+++ b/tests/assembly/targets/targets-macho.rs
@@ -27,6 +27,14 @@
 //@ revisions: arm64_32_apple_watchos
 //@ [arm64_32_apple_watchos] compile-flags: --target arm64_32-apple-watchos
 //@ [arm64_32_apple_watchos] needs-llvm-components: aarch64
+//@ revisions: aarch64_apple_visionos
+//@ [aarch64_apple_visionos] min-llvm-version: 18
+//@ [aarch64_apple_visionos] compile-flags: --target aarch64-apple-visionos
+//@ [aarch64_apple_visionos] needs-llvm-components: aarch64
+//@ revisions: aarch64_apple_visionos_sim
+//@ [aarch64_apple_visionos_sim] min-llvm-version: 18
+//@ [aarch64_apple_visionos_sim] compile-flags: --target aarch64-apple-visionos-sim
+//@ [aarch64_apple_visionos_sim] needs-llvm-components: aarch64
 //@ revisions: arm64e_apple_darwin
 //@ [arm64e_apple_darwin] compile-flags: --target arm64e-apple-darwin
 //@ [arm64e_apple_darwin] needs-llvm-components: aarch64
diff --git a/tests/auxiliary/rust_test_helpers.c b/tests/auxiliary/rust_test_helpers.c
index 977ea487a98..965df44c676 100644
--- a/tests/auxiliary/rust_test_helpers.c
+++ b/tests/auxiliary/rust_test_helpers.c
@@ -118,6 +118,30 @@ rust_dbg_extern_identity_TwoDoubles(struct TwoDoubles u) {
     return u;
 }
 
+struct FiveU16s {
+    uint16_t one;
+    uint16_t two;
+    uint16_t three;
+    uint16_t four;
+    uint16_t five;
+};
+
+struct FiveU16s
+rust_dbg_extern_return_FiveU16s() {
+    struct FiveU16s s;
+    s.one = 10;
+    s.two = 20;
+    s.three = 30;
+    s.four = 40;
+    s.five = 50;
+    return s;
+}
+
+struct FiveU16s
+rust_dbg_extern_identity_FiveU16s(struct FiveU16s u) {
+    return u;
+}
+
 struct ManyInts {
     int8_t arg1;
     int16_t arg2;
diff --git a/tests/codegen/cast-target-abi.rs b/tests/codegen/cast-target-abi.rs
new file mode 100644
index 00000000000..e6024f03425
--- /dev/null
+++ b/tests/codegen/cast-target-abi.rs
@@ -0,0 +1,280 @@
+// ignore-tidy-linelength
+//@ revisions:aarch64 loongarch64 powerpc64 sparc64
+//@ compile-flags: -O -C no-prepopulate-passes
+
+//@[aarch64] compile-flags: --target aarch64-unknown-linux-gnu
+//@[aarch64] needs-llvm-components: arm
+//@[loongarch64] compile-flags: --target loongarch64-unknown-linux-gnu
+//@[loongarch64] needs-llvm-components: loongarch
+//@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
+//@[powerpc64] needs-llvm-components: powerpc
+//@[sparc64] compile-flags: --target sparc64-unknown-linux-gnu
+//@[sparc64] needs-llvm-components: sparc
+
+// Tests that arguments with `PassMode::Cast` are handled correctly.
+
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
+
+// This struct will be passed as a single `i64` or `i32`.
+// This may be (if `i64)) larger than the Rust layout, which is just `{ i16, i16 }`.
+#[repr(C)]
+pub struct TwoU16s {
+    a: u16,
+    b: u16,
+}
+
+// This struct will be passed as `[2 x i64]`.
+// This is larger than the Rust layout.
+#[repr(C)]
+pub struct FiveU16s {
+    a: u16,
+    b: u16,
+    c: u16,
+    d: u16,
+    e: u16,
+}
+
+// This struct will be passed as `[2 x double]`.
+// This is the same as the Rust layout.
+#[repr(C)]
+pub struct DoubleDouble {
+    f: f64,
+    g: f64,
+}
+
+// On loongarch, this struct will be passed as `{ double, float }`.
+// This is smaller than the Rust layout, which has trailing padding (`{ f64, f32, <f32 padding> }`)
+#[repr(C)]
+pub struct DoubleFloat {
+    f: f64,
+    g: f32,
+}
+
+extern "C" {
+    fn receives_twou16s(x: TwoU16s);
+    fn returns_twou16s() -> TwoU16s;
+
+    fn receives_fiveu16s(x: FiveU16s);
+    fn returns_fiveu16s() -> FiveU16s;
+
+    fn receives_doubledouble(x: DoubleDouble);
+    fn returns_doubledouble() -> DoubleDouble;
+
+    // These functions cause an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620)
+    #[cfg(not(target_arch = "sparc64"))]
+    fn receives_doublefloat(x: DoubleFloat);
+    #[cfg(not(target_arch = "sparc64"))]
+    fn returns_doublefloat() -> DoubleFloat;
+}
+
+// CHECK-LABEL: @call_twou16s
+#[no_mangle]
+pub unsafe fn call_twou16s() {
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // powerpc64:   [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i32]], align [[ABI_ALIGN:4]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+
+    // CHECK: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 4, i1 false)
+    // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // CHECK: call void @receives_twou16s([[ABI_TYPE]] [[ABI_VALUE]])
+    let x = TwoU16s { a: 1, b: 2 };
+    receives_twou16s(x);
+}
+
+// CHECK-LABEL: @return_twou16s
+#[no_mangle]
+pub unsafe fn return_twou16s() -> TwoU16s {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: [[RETVAL:%.+]] = alloca %TwoU16s, align 2
+    // powerpc64: call void @returns_twou16s(ptr {{.+}} [[RETVAL]])
+
+
+    // The other targets copy the cast ABI type to an alloca.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:i64]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+    // sparc64:     [[RUST_ALLOCA:%.+]] = alloca %TwoU16s, align [[RUST_ALIGN:2]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s()
+    // sparc64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_twou16s()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // sparc64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false)
+    // sparc64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 4, i1 false)
+    returns_twou16s()
+}
+
+// CHECK-LABEL: @call_fiveu16s
+#[no_mangle]
+pub unsafe fn call_fiveu16s() {
+    // CHECK: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+
+    // CHECK: [[RUST_ALLOCA:%.+]] = alloca %FiveU16s, align 2
+
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 10, i1 false)
+    // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // CHECK: call void @receives_fiveu16s([[ABI_TYPE]] [[ABI_VALUE]])
+    let x = FiveU16s { a: 1, b: 2, c: 3, d: 4, e: 5 };
+    receives_fiveu16s(x);
+}
+
+// CHECK-LABEL: @return_fiveu16s
+// CHECK-SAME: (ptr {{.+}} sret([10 x i8]) align [[RUST_ALIGN:2]] dereferenceable(10) [[RET_PTR:%.+]])
+#[no_mangle]
+pub unsafe fn return_fiveu16s() -> FiveU16s {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: call void @returns_fiveu16s(ptr {{.+}} [[RET_PTR]])
+
+
+    // The other targets copy the cast ABI type to the sret pointer.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s()
+    // sparc64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_fiveu16s()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // sparc64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false)
+    // sparc64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RET_PTR]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 10, i1 false)
+    returns_fiveu16s()
+}
+
+// CHECK-LABEL: @call_doubledouble
+#[no_mangle]
+pub unsafe fn call_doubledouble() {
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x double\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+    // powerpc64:   [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+
+    // CHECK: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+
+    // CHECK: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false)
+    // CHECK: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // CHECK: call void @receives_doubledouble([[ABI_TYPE]] [[ABI_VALUE]])
+    let x = DoubleDouble { f: 1., g: 2. };
+    receives_doubledouble(x);
+}
+
+// CHECK-LABEL: @return_doubledouble
+#[no_mangle]
+pub unsafe fn return_doubledouble() -> DoubleDouble {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: [[RETVAL:%.+]] = alloca %DoubleDouble, align 8
+    // powerpc64: call void @returns_doubledouble(ptr {{.+}} [[RETVAL]])
+
+
+    // The other targets copy the cast ABI type to an alloca.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x double\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+    // sparc64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, double }]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+    // sparc64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleDouble, align [[RUST_ALIGN:8]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble()
+    // sparc64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doubledouble()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // sparc64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    // sparc64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    returns_doubledouble()
+}
+
+// This test causes an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620)
+#[cfg(not(target_arch = "sparc64"))]
+// aarch64-LABEL:     @call_doublefloat
+// loongarch64-LABEL: @call_doublefloat
+// powerpc64-LABEL:   @call_doublefloat
+#[no_mangle]
+pub unsafe fn call_doublefloat() {
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, float }]], align [[ABI_ALIGN:8]]
+    // powerpc64:   [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+    // powerpc64:   [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 12, i1 false)
+    // powerpc64:   call void @llvm.memcpy.{{.+}}(ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], i64 16, i1 false)
+
+    // aarch64:     [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // powerpc64:   [[ABI_VALUE:%.+]] = load [[ABI_TYPE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]])
+    // loongarch64: call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]])
+    // powerpc64:   call void @receives_doublefloat([[ABI_TYPE]] {{(inreg )?}}[[ABI_VALUE]])
+    let x = DoubleFloat { f: 1., g: 2. };
+    receives_doublefloat(x);
+}
+
+// This test causes an ICE in sparc64 ABI code (https://github.com/rust-lang/rust/issues/122620)
+#[cfg(not(target_arch = "sparc64"))]
+// aarch64-LABEL:     @return_doublefloat
+// loongarch64-LABEL: @return_doublefloat
+// powerpc64-LABEL:   @return_doublefloat
+#[no_mangle]
+pub unsafe fn return_doublefloat() -> DoubleFloat {
+    // powerpc returns this struct via sret pointer, it doesn't use the cast ABI.
+
+    // powerpc64: [[RETVAL:%.+]] = alloca %DoubleFloat, align 8
+    // powerpc64: call void @returns_doublefloat(ptr {{.+}} [[RETVAL]])
+
+
+    // The other targets copy the cast ABI type to an alloca.
+
+    // aarch64:     [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:\[2 x i64\]]], align [[ABI_ALIGN:8]]
+    // loongarch64: [[ABI_ALLOCA:%.+]] = alloca [[ABI_TYPE:{ double, float }]], align [[ABI_ALIGN:8]]
+
+    // aarch64:     [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+    // loongarch64: [[RUST_ALLOCA:%.+]] = alloca %DoubleFloat, align [[RUST_ALIGN:8]]
+
+    // aarch64:     [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doublefloat()
+    // loongarch64: [[ABI_VALUE:%.+]] = call [[ABI_TYPE]] @returns_doublefloat()
+
+    // aarch64:     store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+    // loongarch64: store [[ABI_TYPE]] [[ABI_VALUE]], ptr [[ABI_ALLOCA]], align [[ABI_ALIGN]]
+
+    // aarch64:     call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 16, i1 false)
+    // loongarch64: call void @llvm.memcpy.{{.+}}(ptr align [[RUST_ALIGN]] [[RUST_ALLOCA]], ptr align [[ABI_ALIGN]] [[ABI_ALLOCA]], i64 12, i1 false)
+    returns_doublefloat()
+}
diff --git a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
index 7eda6cf4d57..8b32e902b3f 100644
--- a/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
+++ b/tests/codegen/cffi/ffi-out-of-bounds-loads.rs
@@ -1,8 +1,21 @@
+//@ revisions: linux apple
+//@ compile-flags: -C opt-level=0 -C no-prepopulate-passes
+
+//@[linux] compile-flags: --target x86_64-unknown-linux-gnu
+//@[linux] needs-llvm-components: x86
+//@[apple] compile-flags: --target x86_64-apple-darwin
+//@[apple] needs-llvm-components: x86
+
 // Regression test for #29988
 
-//@ compile-flags: -C no-prepopulate-passes
-//@ only-x86_64
-//@ ignore-windows
+#![feature(no_core, lang_items)]
+#![crate_type = "lib"]
+#![no_std]
+#![no_core]
+
+#[lang="sized"] trait Sized { }
+#[lang="freeze"] trait Freeze { }
+#[lang="copy"] trait Copy { }
 
 #[repr(C)]
 struct S {
@@ -15,11 +28,14 @@ extern "C" {
     fn foo(s: S);
 }
 
-fn main() {
+// CHECK-LABEL: @test
+#[no_mangle]
+pub fn test() {
     let s = S { f1: 1, f2: 2, f3: 3 };
     unsafe {
-        // CHECK: load { i64, i32 }, {{.*}}, align 4
-        // CHECK: call void @foo({ i64, i32 } {{.*}})
+        // CHECK: [[ALLOCA:%.+]] = alloca { i64, i32 }, align 8
+        // CHECK: [[LOAD:%.+]] = load { i64, i32 }, ptr [[ALLOCA]], align 8
+        // CHECK: call void @foo({ i64, i32 } [[LOAD]])
         foo(s);
     }
 }
diff --git a/tests/codegen/no-redundant-item-monomorphization.rs b/tests/codegen/no-redundant-item-monomorphization.rs
new file mode 100644
index 00000000000..466037c3770
--- /dev/null
+++ b/tests/codegen/no-redundant-item-monomorphization.rs
@@ -0,0 +1,33 @@
+// Test to make sure that inner functions within a polymorphic outer function
+// don't get re-codegened when the outer function is monomorphized. The test
+// code monomorphizes the outer functions several times, but the magic constants
+// used in the inner functions should each appear only once in the generated IR.
+
+// issue: rust-lang/rust#7349
+//@ compile-flags: -Cno-prepopulate-passes -Copt-level=0
+
+// CHECK-COUNT-1: ret i32 8675309
+// CHECK-COUNT-1: ret i32 11235813
+
+fn outer<T>() {
+    #[allow(dead_code)]
+    fn inner() -> u32 {
+        8675309
+    }
+    inner();
+}
+
+extern "C" fn outer_foreign<T>() {
+    #[allow(dead_code)]
+    fn inner() -> u32 {
+        11235813
+    }
+    inner();
+}
+
+fn main() {
+    outer::<isize>();
+    outer::<usize>();
+    outer_foreign::<isize>();
+    outer_foreign::<usize>();
+}
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
index ab3d339989b..c5dadf70de9 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-function-types.rs
@@ -34,12 +34,12 @@ pub fn foo12(_: &dyn FnOnce(i32) -> i32, _: &dyn FnOnce(i32) -> i32, _: &dyn FnO
 // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvPFu3i32S_EE"}
 // CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_E"}
 // CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvPFu3i32S_ES0_S0_E"}
-// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEEE"}
-// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_E"}
-// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5paramEu6regionEES3_S3_E"}
-// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEEE"}
-// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_E"}
-// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5paramEu6regionEES3_S3_E"}
-// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEEE"}
-// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_E"}
-// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5paramEu6regionEES3_S3_E"}
+// CHECK: ![[TYPE4]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
+// CHECK: ![[TYPE5]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
+// CHECK: ![[TYPE6]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function2FnIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
+// CHECK: ![[TYPE7]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
+// CHECK: ![[TYPE8]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
+// CHECK: ![[TYPE9]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function5FnMutIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
+// CHECK: ![[TYPE10]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEEE"}
+// CHECK: ![[TYPE11]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_E"}
+// CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnceIu5tupleIu3i32EEu{{[0-9]+}}NtNtNtNtC{{[[:print:]]+}}_4core3ops8function6FnOnce6OutputIS0_ES_u6regionEES5_S5_E"}
diff --git a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
index cc7178e41c7..6d9fe7040f7 100644
--- a/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
+++ b/tests/codegen/sanitizer/cfi/emit-type-metadata-id-itanium-cxx-abi-trait-types.rs
@@ -132,7 +132,7 @@ pub fn foo27(_: &dyn Trait5<Type5, 32>, _: &dyn Trait5<Type5, 32>, _: &dyn Trait
 // CHECK: define{{.*}}5foo27{{.*}}!type ![[TYPE27:[0-9]+]] !type !{{[0-9]+}} !type !{{[0-9]+}} !type !{{[0-9]+}}
 
 // CHECK: ![[TYPE13]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait1u6regionEEE"}
-// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait2Iu5paramEu6regionEEE"}
+// CHECK: ![[TYPE16]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait2Iu3i32Eu6regionEEE"}
 // CHECK: ![[TYPE1]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEEE"}
 // CHECK: ![[TYPE2]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_E"}
 // CHECK: ![[TYPE3]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker4Sendu6regionEES2_S2_E"}
@@ -148,14 +148,14 @@ pub fn foo27(_: &dyn Trait5<Type5, 32>, _: &dyn Trait5<Type5, 32>, _: &dyn Trait
 // CHECK: ![[TYPE12]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait1u{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker{{(4Send|4Sync)}}u{{[0-9]+}}NtNtC{{[[:print:]]+}}_4core6marker{{(4Send|4Sync)}}u6regionEES4_S4_E"}
 // CHECK: ![[TYPE14]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait1u6regionEES2_E"}
 // CHECK: ![[TYPE15]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait1u6regionEES2_S2_E"}
-// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait2Iu5paramEu6regionEES3_E"}
-// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait2Iu5paramEu6regionEES3_S3_E"}
-// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait3Iu5paramEu6regionEEE"}
-// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait3Iu5paramEu6regionEES3_E"}
-// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait3Iu5paramEu6regionEES3_S3_E"}
-// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait4Iu6regionu5paramEu6regionEEE"}
-// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait4Iu6regionu5paramEu6regionEES4_E"}
-// CHECK: ![[TYPE24]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait4Iu6regionu5paramEu6regionEES4_S4_E"}
-// CHECK: ![[TYPE25]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait5Iu5paramLu5usizeEEu6regionEEE"}
-// CHECK: ![[TYPE26]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait5Iu5paramLu5usizeEEu6regionEES5_E"}
-// CHECK: ![[TYPE27]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait5Iu5paramLu5usizeEEu6regionEES5_S5_E"}
+// CHECK: ![[TYPE17]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait2Iu3i32Eu6regionEES3_E"}
+// CHECK: ![[TYPE18]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait2Iu3i32Eu6regionEES3_S3_E"}
+// CHECK: ![[TYPE19]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait3Iu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type3Eu6regionEEE"}
+// CHECK: ![[TYPE20]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait3Iu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type3Eu6regionEES3_E"}
+// CHECK: ![[TYPE21]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait3Iu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type3Eu6regionEES3_S3_E"}
+// CHECK: ![[TYPE22]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait4Iu6regionu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4Eu{{[0-9]+}}NtNtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait46OutputIS_S0_Eu3refIu3i32ES_EEE"}
+// CHECK: ![[TYPE23]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait4Iu6regionu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4Eu{{[0-9]+}}NtNtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait46OutputIS_S0_Eu3refIu3i32ES_EES6_E"}
+// CHECK: ![[TYPE24]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait4Iu6regionu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type4Eu{{[0-9]+}}NtNtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait46OutputIS_S0_Eu3refIu3i32ES_EES6_S6_E"}
+// CHECK: ![[TYPE25]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait5Iu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type5Lu5usize32EEu6regionEEE"}
+// CHECK: ![[TYPE26]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait5Iu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type5Lu5usize32EEu6regionEES5_E"}
+// CHECK: ![[TYPE27]] = !{i64 0, !"_ZTSFvu3refIu3dynIu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}6Trait5Iu{{[0-9]+}}NtC{{[[:print:]]+}}_{{[[:print:]]+}}5Type5Lu5usize32EEu6regionEES5_S5_E"}
diff --git a/tests/incremental/hashes/function_interfaces.rs b/tests/incremental/hashes/function_interfaces.rs
index 4fa2762099c..ab4d578458d 100644
--- a/tests/incremental/hashes/function_interfaces.rs
+++ b/tests/incremental/hashes/function_interfaces.rs
@@ -104,17 +104,17 @@ pub fn order_of_parameters(p2: i64, p1: i32) {}
 // Unsafe ----------------------------------------------------------------------
 
 #[cfg(any(cfail1,cfail4))]
-pub fn make_unsafe() {}
+pub        fn make_unsafe() {}
 
 #[cfg(not(any(cfail1,cfail4)))]
 #[rustc_clean(
     cfg = "cfail2",
-    except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    except = "opt_hir_owner_nodes, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail3")]
 #[rustc_clean(
     cfg = "cfail5",
-    except = "opt_hir_owner_nodes, optimized_mir, typeck, fn_sig"
+    except = "opt_hir_owner_nodes, typeck, fn_sig"
 )]
 #[rustc_clean(cfg = "cfail6")]
 pub unsafe fn make_unsafe() {}
diff --git a/tests/incremental/hashes/inherent_impls.rs b/tests/incremental/hashes/inherent_impls.rs
index 2b0de1edc0c..caea394977a 100644
--- a/tests/incremental/hashes/inherent_impls.rs
+++ b/tests/incremental/hashes/inherent_impls.rs
@@ -348,9 +348,9 @@ impl Foo {
 // Make method unsafe ----------------------------------------------------------
 #[cfg(any(cfail1,cfail4))]
 impl Foo {
-    //------------------------------------------------------------------------------------
+    //----------------------------------------------------------------------
     //--------------------------
-    //------------------------------------------------------------------------------------
+    //----------------------------------------------------------------------
     //--------------------------
     pub        fn make_method_unsafe(&self) { }
 }
@@ -361,9 +361,9 @@ impl Foo {
 #[rustc_clean(cfg="cfail5")]
 #[rustc_clean(cfg="cfail6")]
 impl Foo {
-    #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail2", except="opt_hir_owner_nodes,fn_sig,typeck")]
     #[rustc_clean(cfg="cfail3")]
-    #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck,optimized_mir")]
+    #[rustc_clean(cfg="cfail5", except="opt_hir_owner_nodes,fn_sig,typeck")]
     #[rustc_clean(cfg="cfail6")]
     pub unsafe fn make_method_unsafe(&self) { }
 }
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
index 3b7c4b8796e..ef51b07827f 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-abort.mir
@@ -17,8 +17,6 @@ fn main() -> () {
             let _3: *mut usize;
             scope 3 {
                 debug z => _3;
-                scope 4 {
-                }
             }
         }
     }
diff --git a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
index 3dcddea0353..d1aa9382a2c 100644
--- a/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
+++ b/tests/mir-opt/array_index_is_temporary.main.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
@@ -17,8 +17,6 @@ fn main() -> () {
             let _3: *mut usize;
             scope 3 {
                 debug z => _3;
-                scope 4 {
-                }
             }
         }
     }
diff --git a/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
index 6c3128f8c36..005b3ee3b24 100644
--- a/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
+++ b/tests/mir-opt/asm_unwind_panic_abort.main.AbortUnwindingCalls.after.mir
@@ -3,8 +3,6 @@
 fn main() -> () {
     let mut _0: ();
     let _1: ();
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/box_expr.main.ElaborateDrops.diff b/tests/mir-opt/box_expr.main.ElaborateDrops.diff
index 88b12f19e64..ec40fac2894 100644
--- a/tests/mir-opt/box_expr.main.ElaborateDrops.diff
+++ b/tests/mir-opt/box_expr.main.ElaborateDrops.diff
@@ -15,8 +15,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
index d697ea49231..d2a0fb0cb3c 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
@@ -93,17 +93,13 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body of b()}>, _2: &mut Context<'_>) ->
         debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#3).0: {async fn body of a()});
         let _17: ();
         scope 2 {
-        }
-        scope 3 {
             debug result => _17;
         }
     }
-    scope 4 {
+    scope 3 {
         debug __awaitee => (((*(_1.0: &mut {async fn body of b()})) as variant#4).0: {async fn body of a()});
         let _33: ();
-        scope 5 {
-        }
-        scope 6 {
+        scope 4 {
             debug result => _33;
         }
     }
diff --git a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
index b71b2412cdf..dfa31cfff6b 100644
--- a/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
+++ b/tests/mir-opt/building/match/match_false_edges.main.built.after.mir
@@ -48,7 +48,7 @@ fn main() -> () {
     }
 
     bb2: {
-        falseEdge -> [real: bb15, imaginary: bb6];
+        falseEdge -> [real: bb15, imaginary: bb3];
     }
 
     bb3: {
diff --git a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
index e95a97b5b87..c3497c6989d 100644
--- a/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/building/match/sort_candidates.constant_eq.SimplifyCfg-initial.after.mir
@@ -40,7 +40,7 @@ fn constant_eq(_1: &str, _2: bool) -> u32 {
     }
 
     bb4: {
-        falseEdge -> [real: bb12, imaginary: bb9];
+        falseEdge -> [real: bb12, imaginary: bb7];
     }
 
     bb5: {
@@ -48,7 +48,7 @@ fn constant_eq(_1: &str, _2: bool) -> u32 {
     }
 
     bb6: {
-        falseEdge -> [real: bb16, imaginary: bb3];
+        falseEdge -> [real: bb16, imaginary: bb1];
     }
 
     bb7: {
@@ -60,7 +60,7 @@ fn constant_eq(_1: &str, _2: bool) -> u32 {
     }
 
     bb9: {
-        falseEdge -> [real: bb15, imaginary: bb6];
+        falseEdge -> [real: bb15, imaginary: bb5];
     }
 
     bb10: {
@@ -89,7 +89,7 @@ fn constant_eq(_1: &str, _2: bool) -> u32 {
 
     bb14: {
         StorageDead(_10);
-        falseEdge -> [real: bb5, imaginary: bb9];
+        falseEdge -> [real: bb5, imaginary: bb7];
     }
 
     bb15: {
diff --git a/tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir b/tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir
index 80d3c2e5c23..4a1e4fb9ec5 100644
--- a/tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/building/match/sort_candidates.disjoint_ranges.SimplifyCfg-initial.after.mir
@@ -23,7 +23,7 @@ fn disjoint_ranges(_1: i32, _2: bool) -> u32 {
     }
 
     bb2: {
-        falseEdge -> [real: bb9, imaginary: bb4];
+        falseEdge -> [real: bb9, imaginary: bb3];
     }
 
     bb3: {
@@ -32,7 +32,7 @@ fn disjoint_ranges(_1: i32, _2: bool) -> u32 {
     }
 
     bb4: {
-        falseEdge -> [real: bb12, imaginary: bb6];
+        falseEdge -> [real: bb12, imaginary: bb5];
     }
 
     bb5: {
@@ -69,7 +69,7 @@ fn disjoint_ranges(_1: i32, _2: bool) -> u32 {
 
     bb11: {
         StorageDead(_8);
-        falseEdge -> [real: bb1, imaginary: bb4];
+        falseEdge -> [real: bb1, imaginary: bb3];
     }
 
     bb12: {
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
index 128af9c5602..db758368a13 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_by_subslice.built.after.mir
@@ -16,14 +16,10 @@ fn move_out_by_subslice() -> () {
     scope 1 {
         debug a => _1;
         let _12: [std::boxed::Box<i32>; 2];
-        scope 4 {
+        scope 2 {
             debug _y => _12;
         }
     }
-    scope 2 {
-    }
-    scope 3 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
index d50a6872a41..84cd557715c 100644
--- a/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
+++ b/tests/mir-opt/building/uniform_array_move_out.move_out_from_end.built.after.mir
@@ -16,14 +16,10 @@ fn move_out_from_end() -> () {
     scope 1 {
         debug a => _1;
         let _12: std::boxed::Box<i32>;
-        scope 4 {
+        scope 2 {
             debug _y => _12;
         }
     }
-    scope 2 {
-    }
-    scope 3 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
index 3596671f614..bfefd2b8c95 100644
--- a/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
+++ b/tests/mir-opt/const_promotion_extern_static.FOO.PromoteTemps.diff
@@ -9,8 +9,6 @@
       let mut _4: &i32;
       let _5: *const i32;
 +     let mut _6: &[&i32; 1];
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff b/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff
index a044cfc62e2..3f4958f60e8 100644
--- a/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff
+++ b/tests/mir-opt/const_prop/address_of_pair.fn0.GVN.diff
@@ -14,8 +14,6 @@
               debug ptr => _3;
               let _5: bool;
               scope 3 {
-              }
-              scope 4 {
                   debug ret => _5;
               }
           }
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
index 20fda589c39..826f4c34277 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-abort.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
index f1b90c28e72..0e2ec65652f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.32bit.panic-unwind.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
index 20fda589c39..826f4c34277 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-abort.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
index f1b90c28e72..0e2ec65652f 100644
--- a/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/bad_op_unsafe_oob_for_slices.main.GVN.64bit.panic-unwind.diff
@@ -13,11 +13,9 @@
       let mut _9: &[i32; 3];
       scope 1 {
           debug a => _1;
+          let _5: i32;
           scope 2 {
-              let _5: i32;
-              scope 3 {
-                  debug _b => _5;
-              }
+              debug _b => _5;
           }
       }
   
diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff
index 59ee38f5a2b..a408c197fd1 100644
--- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-abort.diff
@@ -15,8 +15,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff
index 9d87bd809d1..5706a739602 100644
--- a/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/boxes.main.GVN.panic-unwind.diff
@@ -15,8 +15,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff b/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff
index b389080c497..99a6ba7d08a 100644
--- a/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff
+++ b/tests/mir-opt/const_prop/indirect_mutation.bar.GVN.diff
@@ -11,8 +11,6 @@
           debug v => _1;
           let _4: bool;
           scope 2 {
-          }
-          scope 3 {
               debug y => _4;
           }
       }
diff --git a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff
index da5bf1cf42c..f5041365604 100644
--- a/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff
+++ b/tests/mir-opt/const_prop/invalid_constant.main.GVN.diff
@@ -12,24 +12,18 @@
       scope 1 {
           debug _invalid_char => _1;
           let _3: [E; 1];
-          scope 3 {
+          scope 2 {
               debug _invalid_tag => _3;
               let _6: [Empty; 1];
-              scope 5 {
+              scope 3 {
                   debug _enum_without_variants => const [ZeroSized: Empty];
                   let _9: main::Str<"���">;
-                  scope 7 {
+                  scope 4 {
                       debug _non_utf8_str => const Str::<"���">;
                   }
               }
-              scope 6 {
-              }
-          }
-          scope 4 {
           }
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff
index 455c2375eff..6e5ad8d6b81 100644
--- a/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff
+++ b/tests/mir-opt/const_prop/invalid_constant.main.RemoveZsts.diff
@@ -12,26 +12,20 @@
       scope 1 {
           debug _invalid_char => _1;
           let _3: [E; 1];
-          scope 3 {
+          scope 2 {
               debug _invalid_tag => _3;
               let _6: [Empty; 1];
-              scope 5 {
+              scope 3 {
 -                 debug _enum_without_variants => _6;
 +                 debug _enum_without_variants => const [ZeroSized: Empty];
                   let _9: main::Str<"���">;
-                  scope 7 {
+                  scope 4 {
 -                     debug _non_utf8_str => _9;
 +                     debug _non_utf8_str => const Str::<"���">;
                   }
               }
-              scope 6 {
-              }
-          }
-          scope 4 {
           }
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff
index e113f43a56e..31c839f6749 100644
--- a/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff
+++ b/tests/mir-opt/const_prop/mutable_variable_no_prop.main.GVN.diff
@@ -11,8 +11,6 @@
           debug x => _1;
           let _5: u32;
           scope 2 {
-          }
-          scope 3 {
               debug y => _5;
           }
       }
diff --git a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff
index 596eb1a9966..79a95b618d1 100644
--- a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-abort.diff
+++ b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-abort.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const main::FOO;
           _2 = &raw const (*_3);
-          _1 = move _2 as usize (PointerExposeAddress);
+          _1 = move _2 as usize (PointerExposeProvenance);
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_4);
diff --git a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff
index 995f281ecf5..9d1bcd92fef 100644
--- a/tests/mir-opt/const_prop/pointer_expose_address.main.GVN.panic-unwind.diff
+++ b/tests/mir-opt/const_prop/pointer_expose_provenance.main.GVN.panic-unwind.diff
@@ -19,7 +19,7 @@
           StorageLive(_3);
           _3 = const main::FOO;
           _2 = &raw const (*_3);
-          _1 = move _2 as usize (PointerExposeAddress);
+          _1 = move _2 as usize (PointerExposeProvenance);
           StorageDead(_2);
           StorageDead(_3);
           StorageLive(_4);
diff --git a/tests/mir-opt/const_prop/pointer_expose_address.rs b/tests/mir-opt/const_prop/pointer_expose_provenance.rs
index a6b4f8857c3..840a4d65f3d 100644
--- a/tests/mir-opt/const_prop/pointer_expose_address.rs
+++ b/tests/mir-opt/const_prop/pointer_expose_provenance.rs
@@ -4,12 +4,12 @@
 #[inline(never)]
 fn read(_: usize) { }
 
-// EMIT_MIR pointer_expose_address.main.GVN.diff
+// EMIT_MIR pointer_expose_provenance.main.GVN.diff
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: [[ptr:_.*]] = const main::FOO;
     // CHECK: [[ref:_.*]] = &raw const (*[[ptr]]);
-    // CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeAddress);
+    // CHECK: [[x:_.*]] = move [[ref]] as usize (PointerExposeProvenance);
     // CHECK: = read([[x]])
     const FOO: &i32 = &1;
     let x = FOO as *const i32 as usize;
diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff
index 2f76e74a3f8..e5786bcf701 100644
--- a/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff
+++ b/tests/mir-opt/const_prop/reify_fn_ptr.main.GVN.diff
@@ -14,7 +14,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = main as fn() (PointerCoercion(ReifyFnPointer));
-          _2 = move _3 as usize (PointerExposeAddress);
+          _2 = move _3 as usize (PointerExposeProvenance);
           StorageDead(_3);
           _1 = move _2 as *const fn() (PointerWithExposedProvenance);
           StorageDead(_2);
diff --git a/tests/mir-opt/const_prop/reify_fn_ptr.rs b/tests/mir-opt/const_prop/reify_fn_ptr.rs
index 4e897d22768..55dca24f3d2 100644
--- a/tests/mir-opt/const_prop/reify_fn_ptr.rs
+++ b/tests/mir-opt/const_prop/reify_fn_ptr.rs
@@ -4,7 +4,7 @@
 fn main() {
     // CHECK-LABEL: fn main(
     // CHECK: [[ptr:_.*]] = main as fn() (PointerCoercion(ReifyFnPointer));
-    // CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeAddress);
+    // CHECK: [[addr:_.*]] = move [[ptr]] as usize (PointerExposeProvenance);
     // CHECK: [[back:_.*]] = move [[addr]] as *const fn() (PointerWithExposedProvenance);
     let _ = main as usize as *const fn();
 }
diff --git a/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff
index 47dfb421ebc..2b38e88ae4c 100644
--- a/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.from_char.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff
index 47dfb421ebc..2b38e88ae4c 100644
--- a/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.from_char.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff
index f0c6f55f775..45c48e9046e 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff
index f0c6f55f775..45c48e9046e 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_bool.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff
index 03a7706401f..b4fe64d0aff 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff
index 03a7706401f..b4fe64d0aff 100644
--- a/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.invalid_char.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff
index 5e0c076b981..ab3481a3be5 100644
--- a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.32bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff
index 5e0c076b981..ab3481a3be5 100644
--- a/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.less_as_i8.GVN.64bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
index c6a428019d8..febb6bfb0a4 100644
--- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.32bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
index c6a428019d8..febb6bfb0a4 100644
--- a/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.undef_union_as_integer.GVN.64bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff
index 2ef83abfac0..7a289563c50 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff
index 2ef83abfac0..7a289563c50 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.GVN.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff
index b2e91014625..3364782022d 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff
index b2e91014625..3364782022d 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_direct.GVN.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff
index 0ff31b1a981..a7020793237 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff
index 0ff31b1a981..a7020793237 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_mut.GVN.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff
index 430d16c97a6..d44b0872035 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.32bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff
index 430d16c97a6..d44b0872035 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_ref.GVN.64bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff b/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff
index f9d002f96ab..069ff906ec5 100644
--- a/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.valid_char.GVN.32bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff b/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff
index f9d002f96ab..069ff906ec5 100644
--- a/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.valid_char.GVN.64bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff
index ffb0c4b23fb..ef30ac2fc8c 100644
--- a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-abort.diff
@@ -14,13 +14,11 @@
           scope 2 {
               debug b => _3;
               let _5: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _5;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
index 66a0f49cfb9..a743a3e829a 100644
--- a/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.demiraw.CopyProp.panic-unwind.diff
@@ -14,13 +14,11 @@
           scope 2 {
               debug b => _3;
               let _5: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _5;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff
index 0777a913523..2de6f85ce64 100644
--- a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff
+++ b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-abort.diff
@@ -13,13 +13,11 @@
           scope 2 {
               debug b => _3;
               let _4: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _4;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
index f5a512b8995..2afec4898bc 100644
--- a/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
+++ b/tests/mir-opt/copy-prop/reborrow.miraw.CopyProp.panic-unwind.diff
@@ -13,13 +13,11 @@
           scope 2 {
               debug b => _3;
               let _4: *mut u8;
-              scope 4 {
+              scope 3 {
 -                 debug c => _4;
 +                 debug c => _2;
               }
           }
-          scope 3 {
-          }
       }
   
       bb0: {
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
index 21cf745b680..44e73b56098 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
index ee58a974480..6cef8b692ba 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.32bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
index 9fc9c8ed409..6efccded993 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
index 30d93347afd..a705d0064cb 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.DataflowConstProp.64bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
index 3a46edbc849..f9c854ca3f4 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
index 3c71214c35f..333726689d7 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.32bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
index 4557e7b26d6..e1841760077 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-abort.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
index 5ab2d5e0fdc..7aa02556ec5 100644
--- a/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/default_boxed_slice.main.GVN.64bit.panic-unwind.diff
@@ -17,33 +17,27 @@
           scope 4 (inlined Unique::<[bool; 0]>::dangling) {
               let mut _5: std::ptr::NonNull<[bool; 0]>;
               scope 5 (inlined NonNull::<[bool; 0]>::dangling) {
+                  let _6: *mut [bool; 0];
                   scope 6 {
-                      let _6: *mut [bool; 0];
-                      scope 7 {
+                      debug ptr => _6;
+                      scope 10 (inlined NonNull::<[bool; 0]>::new_unchecked) {
                           debug ptr => _6;
-                          scope 12 (inlined NonNull::<[bool; 0]>::new_unchecked) {
-                              debug ptr => _6;
-                              let mut _8: bool;
-                              let _9: ();
-                              let mut _10: *mut ();
-                              let mut _11: *const [bool; 0];
-                              scope 13 {
-                                  scope 14 (inlined core::ub_checks::check_language_ub) {
-                                      scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
-                                      }
-                                  }
+                          let mut _8: bool;
+                          let _9: ();
+                          let mut _10: *mut ();
+                          let mut _11: *const [bool; 0];
+                          scope 11 (inlined core::ub_checks::check_language_ub) {
+                              scope 12 (inlined core::ub_checks::check_language_ub::runtime) {
                               }
                           }
                       }
-                      scope 8 (inlined dangling_mut::<[bool; 0]>) {
-                          let mut _7: usize;
-                          scope 9 (inlined align_of::<[bool; 0]>) {
-                          }
-                          scope 10 (inlined without_provenance_mut::<[bool; 0]>) {
-                              debug addr => _7;
-                              scope 11 {
-                              }
-                          }
+                  }
+                  scope 7 (inlined dangling_mut::<[bool; 0]>) {
+                      let mut _7: usize;
+                      scope 8 (inlined align_of::<[bool; 0]>) {
+                      }
+                      scope 9 (inlined without_provenance_mut::<[bool; 0]>) {
+                          debug addr => _7;
                       }
                   }
               }
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff
index 9b0093c454e..a5e40990751 100644
--- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-abort.diff
@@ -9,14 +9,12 @@
       let mut _5: *mut u8;
       scope 1 {
           debug x => _1;
+          let _3: *mut u8;
           let _6: u8;
           scope 2 {
-              let _3: *mut u8;
-              scope 3 {
-                  debug p => _3;
-              }
+              debug p => _3;
           }
-          scope 4 {
+          scope 3 {
               debug x1 => _6;
           }
       }
diff --git a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
index 635a214251b..ce2178ddbee 100644
--- a/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
+++ b/tests/mir-opt/dataflow-const-prop/sibling_ptr.main.DataflowConstProp.panic-unwind.diff
@@ -9,14 +9,12 @@
       let mut _5: *mut u8;
       scope 1 {
           debug x => _1;
+          let _3: *mut u8;
           let _6: u8;
           scope 2 {
-              let _3: *mut u8;
-              scope 3 {
-                  debug p => _3;
-              }
+              debug p => _3;
           }
-          scope 4 {
+          scope 3 {
               debug x1 => _6;
           }
       }
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff
index 52f096ac0e4..a5529253762 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff
index 52f096ac0e4..a5529253762 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.from_char.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn from_char() -> i32 {
       let mut _0: i32;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 'R' as i32 (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff
index 3972eb209a1..a66d8dbe844 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff
index 3972eb209a1..a66d8dbe844 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_bool.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_bool() -> bool {
       let mut _0: bool;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const -1_i8 as bool (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff
index dd737017ffd..4f3f3e03d75 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff
index dd737017ffd..4f3f3e03d75 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.invalid_char.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn invalid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const core::num::<impl i32>::MAX as char (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff
index 6091e169e8e..44dd4017409 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.32bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff
index 6091e169e8e..44dd4017409 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.less_as_i8.DataflowConstProp.64bit.diff
@@ -4,8 +4,6 @@
   fn less_as_i8() -> i8 {
       let mut _0: i8;
       let mut _1: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff
index fb28aa8f6d9..14a34a1ce38 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.32bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff
index fb28aa8f6d9..14a34a1ce38 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.undef_union_as_integer.DataflowConstProp.64bit.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: undef_union_as_integer::Union32;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
index 5d17c47ae66..258e2b454eb 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
index 5d17c47ae66..258e2b454eb 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff
index c8d4d6edba1..a0b4fb2f5e4 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff
index c8d4d6edba1..a0b4fb2f5e4 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_direct.DataflowConstProp.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff
index 2ffaeea72db..ef461423c32 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.32bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff
index 2ffaeea72db..ef461423c32 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_mut.DataflowConstProp.64bit.diff
@@ -8,8 +8,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff
index 31fcaafc5bc..c8910029a03 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.32bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff
index 31fcaafc5bc..c8910029a03 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_ref.DataflowConstProp.64bit.diff
@@ -7,8 +7,6 @@
       scope 1 {
           debug x => _1;
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff
index 402ef754a64..580c5044bb8 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.32bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff
index 402ef754a64..580c5044bb8 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.valid_char.DataflowConstProp.64bit.diff
@@ -3,8 +3,6 @@
   
   fn valid_char() -> char {
       let mut _0: char;
-      scope 1 {
-      }
   
       bb0: {
 -         _0 = const 82_u32 as char (Transmute);
diff --git a/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
index 9b0dc6b6af6..56d5c24ae1d 100644
--- a/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
+++ b/tests/mir-opt/dead-store-elimination/provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
@@ -19,12 +19,12 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = _1;
-          _2 = move _3 as usize (PointerExposeAddress);
+          _2 = move _3 as usize (PointerExposeProvenance);
           StorageDead(_3);
           StorageLive(_4);
           StorageLive(_5);
           _5 = _1;
-          _4 = move _5 as isize (PointerExposeAddress);
+          _4 = move _5 as isize (PointerExposeProvenance);
           StorageDead(_5);
           _0 = const ();
           StorageDead(_4);
diff --git a/tests/mir-opt/dead-store-elimination/provenance_soundness.rs b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs
index 96268cd957e..20517a00489 100644
--- a/tests/mir-opt/dead-store-elimination/provenance_soundness.rs
+++ b/tests/mir-opt/dead-store-elimination/provenance_soundness.rs
@@ -5,8 +5,8 @@
 // EMIT_MIR provenance_soundness.pointer_to_int.DeadStoreElimination-initial.diff
 fn pointer_to_int(p: *mut i32) {
     // CHECK-LABEL: fn pointer_to_int(
-    // CHECK: {{_.*}} = {{.*}} as usize (PointerExposeAddress);
-    // CHECK: {{_.*}} = {{.*}} as isize (PointerExposeAddress);
+    // CHECK: {{_.*}} = {{.*}} as usize (PointerExposeProvenance);
+    // CHECK: {{_.*}} = {{.*}} as isize (PointerExposeProvenance);
     let _x = p as usize;
     let _y = p as isize;
 }
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
index 0af3faf28f0..570ec129f06 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-abort.diff
@@ -8,13 +8,11 @@
       let mut _3: u32;
       scope 1 {
           debug un => _1;
-          scope 2 {
-          }
-          scope 4 (inlined std::mem::drop::<u32>) {
+          scope 3 (inlined std::mem::drop::<u32>) {
               debug _x => _3;
           }
       }
-      scope 3 (inlined val) {
+      scope 2 (inlined val) {
       }
   
       bb0: {
diff --git a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
index 0af3faf28f0..570ec129f06 100644
--- a/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
+++ b/tests/mir-opt/dest-prop/union.main.DestinationPropagation.panic-unwind.diff
@@ -8,13 +8,11 @@
       let mut _3: u32;
       scope 1 {
           debug un => _1;
-          scope 2 {
-          }
-          scope 4 (inlined std::mem::drop::<u32>) {
+          scope 3 (inlined std::mem::drop::<u32>) {
               debug _x => _3;
           }
       }
-      scope 3 (inlined val) {
+      scope 2 (inlined val) {
       }
   
       bb0: {
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
index 46bf13985da..906835530d8 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-abort.diff
@@ -37,17 +37,9 @@
           debug z => _8;
           let _13: *mut u32;
           scope 2 {
-          }
-          scope 3 {
-          }
-          scope 4 {
               debug z => _13;
               let _18: &u32;
-              scope 5 {
-              }
-              scope 6 {
-              }
-              scope 7 {
+              scope 3 {
                   debug z => _18;
               }
           }
diff --git a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
index 3e731ead859..006b5da646c 100644
--- a/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.dereferences.GVN.panic-unwind.diff
@@ -37,17 +37,9 @@
           debug z => _8;
           let _13: *mut u32;
           scope 2 {
-          }
-          scope 3 {
-          }
-          scope 4 {
               debug z => _13;
               let _18: &u32;
-              scope 5 {
-              }
-              scope 6 {
-              }
-              scope 7 {
+              scope 3 {
                   debug z => _18;
               }
           }
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
index f3f9073909e..2389d98b5b3 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-abort.diff
@@ -69,17 +69,15 @@
                   debug u => _29;
                   let _41: &*const u8;
                   let _42: &*const u8;
-                  scope 7 {
+                  scope 6 {
                       debug left_val => _41;
                       debug right_val => _42;
                       let _47: core::panicking::AssertKind;
-                      scope 8 {
+                      scope 7 {
                           debug kind => _47;
                       }
                   }
               }
-              scope 6 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
index 383152cce5e..50715d748e7 100644
--- a/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.slices.GVN.panic-unwind.diff
@@ -69,17 +69,15 @@
                   debug u => _29;
                   let _41: &*const u8;
                   let _42: &*const u8;
-                  scope 7 {
+                  scope 6 {
                       debug left_val => _41;
                       debug right_val => _42;
                       let _47: core::panicking::AssertKind;
-                      scope 8 {
+                      scope 7 {
                           debug kind => _47;
                       }
                   }
               }
-              scope 6 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
index 3ecd4650d81..ba9e507560d 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-abort.diff
@@ -175,18 +175,16 @@
           let _135: &mut u64;
           scope 2 {
               debug b => _135;
+              let _145: *const u64;
               let _163: &u64;
               scope 3 {
-                  let _145: *const u64;
+                  debug c => _145;
+                  let _154: *mut u64;
                   scope 4 {
-                      debug c => _145;
-                      let _154: *mut u64;
-                      scope 5 {
-                          debug d => _154;
-                      }
+                      debug d => _154;
                   }
               }
-              scope 6 {
+              scope 5 {
                   debug e => _163;
               }
           }
diff --git a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
index bf448280b1e..41c01536130 100644
--- a/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.subexpression_elimination.GVN.panic-unwind.diff
@@ -175,18 +175,16 @@
           let _135: &mut u64;
           scope 2 {
               debug b => _135;
+              let _145: *const u64;
               let _163: &u64;
               scope 3 {
-                  let _145: *const u64;
+                  debug c => _145;
+                  let _154: *mut u64;
                   scope 4 {
-                      debug c => _145;
-                      let _154: *mut u64;
-                      scope 5 {
-                          debug d => _154;
-                      }
+                      debug d => _154;
                   }
               }
-              scope 6 {
+              scope 5 {
                   debug e => _163;
               }
           }
diff --git a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff
index 11cd43fc0e0..07c4c7663c1 100644
--- a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-abort.diff
@@ -33,13 +33,9 @@
       scope 1 {
           debug a => _1;
           let _3: *const [u8];
-          scope 3 {
+          scope 2 {
               debug b => _3;
           }
-          scope 4 {
-          }
-      }
-      scope 2 {
       }
   
       bb0: {
diff --git a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff
index c77cd07c60c..df0f93f1077 100644
--- a/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn.wide_ptr_integer.GVN.panic-unwind.diff
@@ -33,13 +33,9 @@
       scope 1 {
           debug a => _1;
           let _3: *const [u8];
-          scope 3 {
+          scope 2 {
               debug b => _3;
           }
-          scope 4 {
-          }
-      }
-      scope 2 {
       }
   
       bb0: {
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
index 86e6aae1191..c5ee0d9c44d 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-abort.diff
@@ -7,12 +7,10 @@
       let mut _2: E;
       let mut _3: &U;
       let _4: U;
+      let mut _5: &U;
       scope 1 {
           debug i => _1;
       }
-      scope 2 {
-          let mut _5: &U;
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
index 86e6aae1191..c5ee0d9c44d 100644
--- a/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
+++ b/tests/mir-opt/gvn_uninhabited.f.GVN.panic-unwind.diff
@@ -7,12 +7,10 @@
       let mut _2: E;
       let mut _3: &U;
       let _4: U;
+      let mut _5: &U;
       scope 1 {
           debug i => _1;
       }
-      scope 2 {
-          let mut _5: &U;
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
index ea9c360aa7b..dc0004105a7 100644
--- a/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/asm_unwind.main.Inline.panic-unwind.diff
@@ -8,8 +8,6 @@
 +         let _2: D;
 +         scope 2 {
 +             debug _d => const D;
-+             scope 3 {
-+             }
 +         }
 +     }
   
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
index a38b8246bde..859082c3111 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-abort.diff
@@ -15,13 +15,11 @@
 +     }
 +     scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) {
 +         debug pointer => _3;
-+         scope 4 {
-+             scope 5 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
-+                 debug pointer => _3;
-+             }
++         scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
++             debug pointer => _3;
 +         }
 +     }
-+     scope 6 (inlined g::{closure#0}) {
++     scope 5 (inlined g::{closure#0}) {
 +         debug a => _5;
 +         let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8};
 +         let mut _7: u32;
diff --git a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
index dc6628ab44c..44b06c34972 100644
--- a/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_coroutine.main.Inline.panic-unwind.diff
@@ -15,13 +15,11 @@
 +     }
 +     scope 3 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new) {
 +         debug pointer => _3;
-+         scope 4 {
-+             scope 5 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
-+                 debug pointer => _3;
-+             }
++         scope 4 (inlined Pin::<&mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8}>::new_unchecked) {
++             debug pointer => _3;
 +         }
 +     }
-+     scope 6 (inlined g::{closure#0}) {
++     scope 5 (inlined g::{closure#0}) {
 +         debug a => _5;
 +         let mut _6: &mut {coroutine@$DIR/inline_coroutine.rs:19:5: 19:8};
 +         let mut _7: u32;
diff --git a/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
index e38daba27fc..158cc973779 100644
--- a/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
+++ b/tests/mir-opt/inline/inline_instruction_set.default.Inline.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined instruction_set_default) {
 +     }
 +     scope 2 (inlined inline_always_and_using_inline_asm) {
-+         scope 3 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
index 4fcd49994f0..2a36ccaab11 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-abort.diff
@@ -8,18 +8,14 @@
       let _3: ();
       let mut _4: *mut std::vec::Vec<A>;
       let mut _5: *mut std::option::Option<B>;
-      scope 1 {
-+         scope 3 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
-+             let mut _6: &mut std::vec::Vec<A>;
-+             let mut _7: ();
-+         }
-      }
-      scope 2 {
-+         scope 4 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
-+             let mut _8: isize;
-+             let mut _9: isize;
-+         }
-      }
++     scope 1 (inlined std::ptr::drop_in_place::<Vec<A>> - shim(Some(Vec<A>))) {
++         let mut _6: &mut std::vec::Vec<A>;
++         let mut _7: ();
++     }
++     scope 2 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
++         let mut _8: isize;
++         let mut _9: isize;
++     }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
index 4270ae00b66..e11561076e6 100644
--- a/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/inline_shims.drop.Inline.panic-unwind.diff
@@ -8,14 +8,10 @@
       let _3: ();
       let mut _4: *mut std::vec::Vec<A>;
       let mut _5: *mut std::option::Option<B>;
-      scope 1 {
-      }
-      scope 2 {
-+         scope 3 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
-+             let mut _6: isize;
-+             let mut _7: isize;
-+         }
-      }
++     scope 1 (inlined std::ptr::drop_in_place::<Option<B>> - shim(Some(Option<B>))) {
++         let mut _6: isize;
++         let mut _7: isize;
++     }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
index 51e506142a9..cc1b8b9b70f 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-abort.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
index 053ccc077a4..f244f378bce 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.Inline.panic-unwind.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
index 2be887e9b5a..c96983c18cb 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-abort.mir
@@ -7,8 +7,6 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
index 2be887e9b5a..c96983c18cb 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shl_unsigned_smaller.PreCodegen.after.panic-unwind.mir
@@ -7,8 +7,6 @@ fn unchecked_shl_unsigned_smaller(_1: u16, _2: u32) -> u16 {
     scope 1 (inlined core::num::<impl u16>::unchecked_shl) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
index 816d03b4405..74518db370f 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-abort.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
index d4121f89baf..aab04624f6c 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.Inline.panic-unwind.diff
@@ -10,8 +10,6 @@
 +     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
 +         debug self => _3;
 +         debug rhs => _4;
-+         scope 2 {
-+         }
 +     }
   
       bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir
index 4696112175e..1dd8cb27314 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-abort.mir
@@ -7,8 +7,6 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 {
     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir
index 4696112175e..1dd8cb27314 100644
--- a/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unchecked_shifts.unchecked_shr_signed_bigger.PreCodegen.after.panic-unwind.mir
@@ -7,8 +7,6 @@ fn unchecked_shr_signed_bigger(_1: i64, _2: u32) -> i64 {
     scope 1 (inlined core::num::<impl i64>::unchecked_shr) {
         debug self => _1;
         debug rhs => _2;
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
index 028040edc85..814eda10459 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-abort.diff
@@ -11,15 +11,11 @@
 +         scope 2 {
 +             debug val => _0;
 +         }
-+         scope 3 {
-+             scope 4 (inlined unreachable_unchecked) {
-+                 let mut _4: bool;
-+                 let _5: ();
-+                 scope 5 {
-+                 }
-+                 scope 6 (inlined core::ub_checks::check_language_ub) {
-+                     scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-+                     }
++         scope 3 (inlined unreachable_unchecked) {
++             let mut _4: bool;
++             let _5: ();
++             scope 4 (inlined core::ub_checks::check_language_ub) {
++                 scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
 +                 }
 +             }
 +         }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
index 484fd37248c..d5d69074382 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.Inline.panic-unwind.diff
@@ -11,15 +11,11 @@
 +         scope 2 {
 +             debug val => _0;
 +         }
-+         scope 3 {
-+             scope 4 (inlined unreachable_unchecked) {
-+                 let mut _4: bool;
-+                 let _5: ();
-+                 scope 5 {
-+                 }
-+                 scope 6 (inlined core::ub_checks::check_language_ub) {
-+                     scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-+                     }
++         scope 3 (inlined unreachable_unchecked) {
++             let mut _4: bool;
++             let _5: ();
++             scope 4 (inlined core::ub_checks::check_language_ub) {
++                 scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
 +                 }
 +             }
 +         }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
index d629336d385..7c24a97166c 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-abort.mir
@@ -9,13 +9,9 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
         scope 2 {
             debug val => _0;
         }
-        scope 3 {
-            scope 4 (inlined unreachable_unchecked) {
-                scope 5 {
-                }
-                scope 6 (inlined core::ub_checks::check_language_ub) {
-                    scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-                    }
+        scope 3 (inlined unreachable_unchecked) {
+            scope 4 (inlined core::ub_checks::check_language_ub) {
+                scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
         }
diff --git a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
index d629336d385..7c24a97166c 100644
--- a/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/inline/unwrap_unchecked.unwrap_unchecked.PreCodegen.after.panic-unwind.mir
@@ -9,13 +9,9 @@ fn unwrap_unchecked(_1: Option<T>) -> T {
         scope 2 {
             debug val => _0;
         }
-        scope 3 {
-            scope 4 (inlined unreachable_unchecked) {
-                scope 5 {
-                }
-                scope 6 (inlined core::ub_checks::check_language_ub) {
-                    scope 7 (inlined core::ub_checks::check_language_ub::runtime) {
-                    }
+        scope 3 (inlined unreachable_unchecked) {
+            scope 4 (inlined core::ub_checks::check_language_ub) {
+                scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
         }
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
index 0243e31cb1a..f8cceacd7e6 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-abort.diff
@@ -18,9 +18,9 @@
           let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
           scope 2 {
               debug fut => _4;
-              scope 4 {
+              scope 3 {
               }
-+             scope 7 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
++             scope 6 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
 +                 debug _task_context => _31;
 +                 debug self => ((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})).0: ActionPermit<'_, T>);
 +                 let _11: ActionPermit<'_, T>;
@@ -51,32 +51,28 @@
 +                 let mut _38: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _39: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()};
-+                 scope 8 {
++                 scope 7 {
 +                     debug self => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).0: ActionPermit<'_, T>);
 +                     let mut _15: std::future::Ready<()>;
-+                     scope 9 {
++                     scope 8 {
 +                         debug __awaitee => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).1: std::future::Ready<()>);
 +                         let _26: ();
-+                         scope 10 {
-+                         }
-+                         scope 11 {
++                         scope 9 {
 +                             debug result => _26;
 +                         }
 +                     }
-+                     scope 12 (inlined ready::<()>) {
++                     scope 10 (inlined ready::<()>) {
 +                         debug t => _14;
 +                         let mut _41: std::option::Option<()>;
 +                     }
 +                 }
 +             }
           }
-          scope 3 {
-+             scope 6 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
-+                 debug pointer => _5;
-+             }
-          }
++         scope 5 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
++             debug pointer => _5;
++         }
       }
-+     scope 5 (inlined ActionPermit::<'_, T>::perform) {
++     scope 4 (inlined ActionPermit::<'_, T>::perform) {
 +         debug self => _3;
 +     }
   
diff --git a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
index 96a93cdda3d..fd080d22d3a 100644
--- a/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
+++ b/tests/mir-opt/inline_coroutine_body.run2-{closure#0}.Inline.panic-unwind.diff
@@ -18,9 +18,9 @@
           let _4: std::pin::Pin<&mut {async fn body of ActionPermit<'_, T>::perform()}>;
           scope 2 {
               debug fut => _4;
-              scope 4 {
+              scope 3 {
               }
-+             scope 7 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
++             scope 6 (inlined ActionPermit::<'_, T>::perform::{closure#0}) {
 +                 debug _task_context => _31;
 +                 debug self => ((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})).0: ActionPermit<'_, T>);
 +                 let _11: ActionPermit<'_, T>;
@@ -53,32 +53,28 @@
 +                 let mut _40: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _41: &mut {async fn body of ActionPermit<'_, T>::perform()};
 +                 let mut _42: &mut {async fn body of ActionPermit<'_, T>::perform()};
-+                 scope 8 {
++                 scope 7 {
 +                     debug self => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).0: ActionPermit<'_, T>);
 +                     let mut _15: std::future::Ready<()>;
-+                     scope 9 {
++                     scope 8 {
 +                         debug __awaitee => (((*(_8.0: &mut {async fn body of ActionPermit<'_, T>::perform()})) as variant#3).1: std::future::Ready<()>);
 +                         let _26: ();
-+                         scope 10 {
-+                         }
-+                         scope 11 {
++                         scope 9 {
 +                             debug result => _26;
 +                         }
 +                     }
-+                     scope 12 (inlined ready::<()>) {
++                     scope 10 (inlined ready::<()>) {
 +                         debug t => _14;
 +                         let mut _43: std::option::Option<()>;
 +                     }
 +                 }
 +             }
           }
-          scope 3 {
-+             scope 6 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
-+                 debug pointer => _5;
-+             }
-          }
++         scope 5 (inlined Pin::<&mut {async fn body of ActionPermit<'_, T>::perform()}>::new_unchecked) {
++             debug pointer => _5;
++         }
       }
-+     scope 5 (inlined ActionPermit::<'_, T>::perform) {
++     scope 4 (inlined ActionPermit::<'_, T>::perform) {
 +         debug self => _3;
 +     }
   
diff --git a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff
index f3402fde05b..6d6c9c9a7a1 100644
--- a/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff
+++ b/tests/mir-opt/instsimplify/ub_check.unwrap_unchecked.InstSimplify.diff
@@ -5,23 +5,17 @@
       debug x => _1;
       let mut _0: i32;
       let mut _2: std::option::Option<i32>;
-      scope 1 {
-          scope 2 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
-              debug self => _2;
-              let mut _3: isize;
-              scope 3 {
-                  debug val => _0;
-              }
-              scope 4 {
-                  scope 5 (inlined unreachable_unchecked) {
-                      let mut _4: bool;
-                      let _5: ();
-                      scope 6 {
-                      }
-                      scope 7 (inlined core::ub_checks::check_language_ub) {
-                          scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
-                          }
-                      }
+      scope 1 (inlined #[track_caller] Option::<i32>::unwrap_unchecked) {
+          debug self => _2;
+          let mut _3: isize;
+          scope 2 {
+              debug val => _0;
+          }
+          scope 3 (inlined unreachable_unchecked) {
+              let mut _4: bool;
+              let _5: ();
+              scope 4 (inlined core::ub_checks::check_language_ub) {
+                  scope 5 (inlined core::ub_checks::check_language_ub::runtime) {
                   }
               }
           }
diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir
index b4f21240939..53912adc003 100644
--- a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir
+++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-abort.mir
@@ -4,8 +4,6 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: !;
     let mut _2: ();
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
index 1851747f0a6..50416300094 100644
--- a/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
+++ b/tests/mir-opt/issue_104451_unwindable_intrinsics.main.AbortUnwindingCalls.after.panic-unwind.mir
@@ -4,8 +4,6 @@ fn main() -> () {
     let mut _0: ();
     let mut _1: !;
     let mut _2: ();
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_1);
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
index 91dee82fde0..3104baa5fdb 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
@@ -15,15 +15,13 @@ fn test() -> Option<Box<u32>> {
     let mut _11: std::option::Option<std::convert::Infallible>;
     let _12: u32;
     scope 1 {
-    }
-    scope 2 {
         debug residual => _9;
-        scope 3 {
+        scope 2 {
         }
     }
-    scope 4 {
+    scope 3 {
         debug val => _12;
-        scope 5 {
+        scope 4 {
         }
     }
 
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
index ff7fc74ff61..da33c830115 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
@@ -15,15 +15,13 @@ fn test() -> Option<Box<u32>> {
     let mut _11: std::option::Option<std::convert::Infallible>;
     let _12: u32;
     scope 1 {
-    }
-    scope 2 {
         debug residual => _9;
-        scope 3 {
+        scope 2 {
         }
     }
-    scope 4 {
+    scope 3 {
         debug val => _12;
-        scope 5 {
+        scope 4 {
         }
     }
 
diff --git a/tests/mir-opt/issue_72181.main.built.after.mir b/tests/mir-opt/issue_72181.main.built.after.mir
index cff20702bf7..fa101512d72 100644
--- a/tests/mir-opt/issue_72181.main.built.after.mir
+++ b/tests/mir-opt/issue_72181.main.built.after.mir
@@ -15,8 +15,6 @@ fn main() -> () {
             debug f => _2;
             scope 3 {
             }
-            scope 4 {
-            }
         }
     }
 
diff --git a/tests/mir-opt/issue_72181_1.main.built.after.mir b/tests/mir-opt/issue_72181_1.main.built.after.mir
index d35aada95f8..ae0dc9a0b6a 100644
--- a/tests/mir-opt/issue_72181_1.main.built.after.mir
+++ b/tests/mir-opt/issue_72181_1.main.built.after.mir
@@ -14,8 +14,6 @@ fn main() -> () {
     scope 1 {
         debug v => _2;
     }
-    scope 2 {
-    }
 
     bb0: {
         StorageLive(_2);
diff --git a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
index f11c993340f..25ed1b4d0c7 100644
--- a/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
+++ b/tests/mir-opt/issues/issue_75439.foo.MatchBranchSimplification.diff
@@ -10,15 +10,11 @@
       let mut _6: u32;
       scope 1 {
           debug dwords => _2;
-          scope 3 {
+          scope 2 {
               debug ip => _4;
               let _4: u32;
-              scope 4 {
-              }
           }
       }
-      scope 2 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
index 80a42263643..e9d4352014f 100644
--- a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
+++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-abort.diff
@@ -12,8 +12,6 @@
           let _2: *mut i32;
           scope 2 {
               debug a => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
index 80a42263643..e9d4352014f 100644
--- a/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
+++ b/tests/mir-opt/jump_threading.mutable_ref.JumpThreading.panic-unwind.diff
@@ -12,8 +12,6 @@
           let _2: *mut i32;
           scope 2 {
               debug a => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
index f9f73bf991d..633a344a2ed 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-abort.diff
@@ -14,8 +14,6 @@
           let _5: *const [u8];
           scope 2 {
               debug arr => _5;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
index f9f73bf991d..633a344a2ed 100644
--- a/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
+++ b/tests/mir-opt/lower_array_len.array_len_raw.NormalizeArrayLen.panic-unwind.diff
@@ -14,8 +14,6 @@
           let _5: *const [u8];
           scope 2 {
               debug arr => _5;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff
index 79635f23e8e..6c1f457cb5f 100644
--- a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-abort.diff
@@ -4,8 +4,6 @@
   fn assume() -> () {
       let mut _0: ();
       let _1: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff
index 79635f23e8e..6c1f457cb5f 100644
--- a/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.assume.LowerIntrinsics.panic-unwind.diff
@@ -4,8 +4,6 @@
   fn assume() -> () {
       let mut _0: ();
       let _1: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff
index 6de5f2c4f07..96b66af66a2 100644
--- a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-abort.diff
@@ -18,8 +18,6 @@
           let mut _2: ();
           scope 2 {
               debug dst => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff
index 6de5f2c4f07..96b66af66a2 100644
--- a/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.f_copy_nonoverlapping.LowerIntrinsics.panic-unwind.diff
@@ -18,8 +18,6 @@
           let mut _2: ();
           scope 2 {
               debug dst => _2;
-              scope 3 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff
index 147c48a3c01..781104be290 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: i32;
       let mut _2: *const i32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff
index 147c48a3c01..781104be290 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_primitive.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: i32;
       let mut _2: *const i32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff
index b2cf3cc1cca..56c357b3776 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: Never;
       let mut _2: *const Never;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff
index b2cf3cc1cca..56c357b3776 100644
--- a/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.read_via_copy_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug r => _1;
       let mut _0: Never;
       let mut _2: *const Never;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
index 3b4051e4ae2..6e542c4b5a7 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug c => _1;
       let mut _0: i8;
       let mut _2: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
index 3b4051e4ae2..6e542c4b5a7 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_inhabited.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug c => _1;
       let mut _0: i8;
       let mut _2: std::cmp::Ordering;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
index 91276a1b5c4..ab4646370f1 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: *const T;
       let mut _2: &T;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
index 91276a1b5c4..ab4646370f1 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_ref_dst.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: *const T;
       let mut _2: &T;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
index 792c77d575b..6d3ad348988 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: Never;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
index 792c77d575b..6d3ad348988 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       debug u => _1;
       let mut _0: Never;
       let mut _2: ();
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff
index f5646e7f1e9..2b715ac1d63 100644
--- a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-abort.diff
@@ -5,8 +5,6 @@
       let mut _0: !;
       let _1: ();
       let mut _2: !;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff
index f5646e7f1e9..2b715ac1d63 100644
--- a/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.unreachable.LowerIntrinsics.panic-unwind.diff
@@ -5,8 +5,6 @@
       let mut _0: !;
       let _1: ();
       let mut _2: !;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff
index ddc8cf9a3d9..cc9177c9002 100644
--- a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-abort.diff
@@ -7,8 +7,6 @@
       let mut _0: ();
       let mut _3: *mut std::string::String;
       let mut _4: std::string::String;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff
index ddc8cf9a3d9..cc9177c9002 100644
--- a/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.write_via_move_string.LowerIntrinsics.panic-unwind.diff
@@ -7,8 +7,6 @@
       let mut _0: ();
       let mut _3: *mut std::string::String;
       let mut _4: std::string::String;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_3);
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 307f7105dd2..ba333ba1a58 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -60,11 +60,11 @@
       }
   
 -     bb5: {
--         falseEdge -> [real: bb13, imaginary: bb3];
+-         falseEdge -> [real: bb13, imaginary: bb2];
 -     }
 - 
 -     bb6: {
--         falseEdge -> [real: bb8, imaginary: bb5];
+-         falseEdge -> [real: bb8, imaginary: bb1];
 -     }
 - 
 -     bb7: {
@@ -127,7 +127,7 @@
           StorageDead(_9);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb1, imaginary: bb5];
+-         falseEdge -> [real: bb1, imaginary: bb1];
 +         goto -> bb1;
       }
   
@@ -184,7 +184,7 @@
           StorageDead(_12);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb2, imaginary: bb3];
+-         falseEdge -> [real: bb2, imaginary: bb2];
 +         goto -> bb2;
       }
   
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 307f7105dd2..ba333ba1a58 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -60,11 +60,11 @@
       }
   
 -     bb5: {
--         falseEdge -> [real: bb13, imaginary: bb3];
+-         falseEdge -> [real: bb13, imaginary: bb2];
 -     }
 - 
 -     bb6: {
--         falseEdge -> [real: bb8, imaginary: bb5];
+-         falseEdge -> [real: bb8, imaginary: bb1];
 -     }
 - 
 -     bb7: {
@@ -127,7 +127,7 @@
           StorageDead(_9);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb1, imaginary: bb5];
+-         falseEdge -> [real: bb1, imaginary: bb1];
 +         goto -> bb1;
       }
   
@@ -184,7 +184,7 @@
           StorageDead(_12);
           StorageDead(_8);
           StorageDead(_6);
--         falseEdge -> [real: bb2, imaginary: bb3];
+-         falseEdge -> [real: bb2, imaginary: bb2];
 +         goto -> bb2;
       }
   
diff --git a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir
index 656934fce42..845673601b2 100644
--- a/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/checked_ops.checked_shl.PreCodegen.after.mir
@@ -21,13 +21,9 @@ fn checked_shl(_1: u32, _2: u32) -> Option<u32> {
                 debug self => _1;
                 debug rhs => _2;
                 let mut _3: u32;
-                scope 5 {
-                    scope 6 (inlined core::num::<impl u32>::unchecked_shl) {
-                        debug self => _1;
-                        debug rhs => _3;
-                        scope 7 {
-                        }
-                    }
+                scope 5 (inlined core::num::<impl u32>::unchecked_shl) {
+                    debug self => _1;
+                    debug rhs => _3;
                 }
             }
         }
diff --git a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
index ebe846e8a51..518fedffc16 100644
--- a/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
@@ -5,10 +5,8 @@ fn ub_if_b(_1: Thing) -> Thing {
     let mut _0: Thing;
     let mut _2: isize;
     scope 1 (inlined unreachable_unchecked) {
-        scope 2 {
-        }
-        scope 3 (inlined core::ub_checks::check_language_ub) {
-            scope 4 (inlined core::ub_checks::check_language_ub::runtime) {
+        scope 2 (inlined core::ub_checks::check_language_ub) {
+            scope 3 (inlined core::ub_checks::check_language_ub::runtime) {
             }
         }
     }
diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
index 0b5ed6ee169..cdb7eea74fb 100644
--- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir
@@ -26,10 +26,8 @@ fn int_range(_1: usize, _2: usize) -> () {
                 let mut _12: usize;
                 scope 6 {
                     debug old => _11;
-                    scope 7 {
-                    }
                 }
-                scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
+                scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     debug self => _6;
                     debug other => _7;
                     let mut _8: usize;
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
index 26919dd98dd..c744787fce2 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-abort.mir
@@ -8,21 +8,15 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
         debug dest => _1;
         debug src => _2;
         scope 2 {
-            scope 3 {
-                debug result => _0;
-                scope 6 (inlined std::ptr::write::<u32>) {
-                    debug dst => _1;
-                    debug src => _2;
-                    scope 7 {
-                    }
-                }
-            }
-            scope 4 (inlined std::ptr::read::<u32>) {
-                debug src => _1;
-                scope 5 {
-                }
+            debug result => _0;
+            scope 4 (inlined std::ptr::write::<u32>) {
+                debug dst => _1;
+                debug src => _2;
             }
         }
+        scope 3 (inlined std::ptr::read::<u32>) {
+            debug src => _1;
+        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
index 26919dd98dd..c744787fce2 100644
--- a/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/mem_replace.mem_replace.PreCodegen.after.panic-unwind.mir
@@ -8,21 +8,15 @@ fn mem_replace(_1: &mut u32, _2: u32) -> u32 {
         debug dest => _1;
         debug src => _2;
         scope 2 {
-            scope 3 {
-                debug result => _0;
-                scope 6 (inlined std::ptr::write::<u32>) {
-                    debug dst => _1;
-                    debug src => _2;
-                    scope 7 {
-                    }
-                }
-            }
-            scope 4 (inlined std::ptr::read::<u32>) {
-                debug src => _1;
-                scope 5 {
-                }
+            debug result => _0;
+            scope 4 (inlined std::ptr::write::<u32>) {
+                debug dst => _1;
+                debug src => _2;
             }
         }
+        scope 3 (inlined std::ptr::read::<u32>) {
+            debug src => _1;
+        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
index ed965770adb..002d55ad9d9 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -29,10 +29,8 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
                 let mut _13: u32;
                 scope 6 {
                     debug old => _12;
-                    scope 7 {
-                    }
                 }
-                scope 8 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+                scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: u32;
diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index a7ee9be19bd..d5021ac84d2 100644
--- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -29,10 +29,8 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
                 let mut _13: u32;
                 scope 6 {
                     debug old => _12;
-                    scope 7 {
-                    }
                 }
-                scope 8 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+                scope 7 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: u32;
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
index f674f6a3009..7faae1d863c 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir
@@ -14,10 +14,8 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
             let mut _8: u32;
             scope 3 {
                 debug old => _7;
-                scope 4 {
-                }
             }
-            scope 5 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+            scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                 debug self => _2;
                 debug other => _3;
                 let mut _4: u32;
diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
index a5029dcad3a..37f00533b60 100644
--- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir
@@ -14,10 +14,8 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
             let mut _8: u32;
             scope 3 {
                 debug old => _7;
-                scope 4 {
-                }
             }
-            scope 5 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
+            scope 4 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
                 debug self => _2;
                 debug other => _3;
                 let mut _4: u32;
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
index bcc540ae6fc..e5490955a36 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-abort.mir
@@ -9,8 +9,6 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         debug index => _2;
         let mut _3: *mut [u32];
         let mut _4: *mut [u32];
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
index 1fe7da7d2fd..810fee9a149 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_get_unchecked_mut_range.PreCodegen.after.panic-unwind.mir
@@ -9,8 +9,6 @@ fn slice_get_unchecked_mut_range(_1: &mut [u32], _2: std::ops::Range<usize>) ->
         debug index => _2;
         let mut _3: *mut [u32];
         let mut _4: *mut [u32];
-        scope 2 {
-        }
     }
 
     bb0: {
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index f698e15d302..1ec85906385 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -37,52 +37,42 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
         debug self => _13;
-        scope 20 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index eae9f5909e6..70cdf3f41c2 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -37,52 +37,42 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
         debug self => _13;
-        scope 20 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 158ae0de890..d8252e7267a 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -34,46 +34,36 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
         debug self => _13;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index ac9e31a0da8..b3904dc70a6 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -34,46 +34,36 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
         debug self => _13;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
index 543e8918e39..5ab88c9b855 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir
@@ -35,10 +35,8 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let mut _13: usize;
                 scope 7 {
                     debug old => _12;
-                    scope 8 {
-                    }
                 }
-                scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
+                scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: usize;
diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
index a16e9cd9e51..513651090a8 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir
@@ -35,10 +35,8 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 let mut _13: usize;
                 scope 7 {
                     debug old => _12;
-                    scope 8 {
-                    }
                 }
-                scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
+                scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
                     debug self => _7;
                     debug other => _8;
                     let mut _9: usize;
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index 9550df012f8..091c8a0e968 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -19,7 +19,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _20;
         }
-        scope 22 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             debug self => _16;
             let mut _17: &mut std::slice::Iter<'_, T>;
         }
@@ -39,52 +39,42 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
         debug self => _13;
-        scope 20 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index d75aabd12fc..1873d452f34 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -19,7 +19,7 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
         scope 2 {
             debug x => _20;
         }
-        scope 22 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
+        scope 17 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
             debug self => _16;
             let mut _17: &mut std::slice::Iter<'_, T>;
         }
@@ -39,52 +39,42 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                 let _7: std::ptr::NonNull<T>;
                 scope 6 {
                     debug ptr => _7;
+                    let _11: *const T;
                     scope 7 {
-                        let _11: *const T;
-                        scope 8 {
-                            debug end_or_len => _11;
-                        }
-                        scope 14 (inlined without_provenance::<T>) {
-                            debug addr => _3;
-                            scope 15 {
-                            }
-                        }
-                        scope 16 (inlined NonNull::<T>::as_ptr) {
-                            debug self => _7;
-                        }
-                        scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
-                            debug self => _9;
-                            debug count => _3;
-                            scope 18 {
-                            }
-                        }
+                        debug end_or_len => _11;
+                    }
+                    scope 11 (inlined without_provenance::<T>) {
+                        debug addr => _3;
+                    }
+                    scope 12 (inlined NonNull::<T>::as_ptr) {
+                        debug self => _7;
+                    }
+                    scope 13 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
+                        debug self => _9;
+                        debug count => _3;
                     }
                 }
-                scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
+                scope 8 (inlined <NonNull<[T]> as From<&[T]>>::from) {
                     debug reference => _1;
                     let mut _4: *const [T];
-                    scope 10 {
-                    }
                 }
-                scope 11 (inlined NonNull::<[T]>::cast::<T>) {
+                scope 9 (inlined NonNull::<[T]>::cast::<T>) {
                     debug self => _5;
                     let mut _6: *const T;
-                    scope 12 {
-                        scope 13 (inlined NonNull::<[T]>::as_ptr) {
-                            debug self => _5;
-                        }
+                    scope 10 (inlined NonNull::<[T]>::as_ptr) {
+                        debug self => _5;
                     }
                 }
             }
         }
     }
-    scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
+    scope 14 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
         debug self => _13;
-        scope 20 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
+        scope 15 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
             debug iter => _13;
         }
     }
-    scope 21 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
+    scope 16 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
         debug self => _14;
     }
 
diff --git a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
index 747028e128f..859097d3966 100644
--- a/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.mut_raw_then_mut_shr.ReferencePropagation.diff
@@ -25,8 +25,6 @@
                       let _7: i32;
                       scope 5 {
                           debug a => _7;
-                          scope 6 {
-                          }
                       }
                   }
               }
diff --git a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
index ce5ddbfdd12..1e6a168f756 100644
--- a/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation_const_ptr.ReferencePropagation.diff
@@ -6,218 +6,196 @@
       debug multiple => _2;
       let mut _0: ();
       let _3: ();
+      let _4: usize;
       let _7: ();
       let mut _8: ();
       let _9: ();
+      let _10: usize;
       let mut _13: *const usize;
       let _15: ();
       let mut _16: ();
       let _17: ();
+      let _18: usize;
       let _22: ();
       let mut _23: &*const usize;
       let _24: ();
+      let _25: usize;
       let _29: ();
       let mut _30: *mut *const usize;
       let _31: ();
+      let _32: usize;
       let _35: ();
       let mut _36: *const usize;
       let _37: ();
+      let _38: usize;
       let _44: ();
       let mut _45: *const usize;
       let _46: ();
+      let _47: *const T;
       let _49: ();
       let mut _50: ();
       let _51: ();
+      let _52: *const T;
       let mut _53: *const T;
       let _55: ();
       let mut _56: ();
       let _57: ();
+      let _58: usize;
       let _62: ();
       let mut _63: ();
       let _64: ();
+      let _65: usize;
       let _69: ();
       let mut _70: ();
+      let _71: usize;
       let _75: ();
       let mut _76: ();
       scope 1 {
-          let _4: usize;
+          debug a => _4;
+          let _5: *const usize;
           scope 2 {
-              debug a => _4;
-              let _5: *const usize;
+              debug b => _5;
+              let _6: usize;
               scope 3 {
-                  debug b => _5;
-                  let _6: usize;
-                  scope 4 {
-                      debug c => _6;
-                  }
+                  debug c => _6;
               }
           }
       }
-      scope 5 {
-          let _10: usize;
-          scope 6 {
-              debug a => _10;
-              let _11: usize;
-              scope 7 {
-                  debug a2 => _11;
-                  let mut _12: *const usize;
-                  scope 8 {
-                      debug b => _12;
-                      let _14: usize;
-                      scope 9 {
-                          debug c => _14;
-                      }
+      scope 4 {
+          debug a => _10;
+          let _11: usize;
+          scope 5 {
+              debug a2 => _11;
+              let mut _12: *const usize;
+              scope 6 {
+                  debug b => _12;
+                  let _14: usize;
+                  scope 7 {
+                      debug c => _14;
                   }
               }
           }
       }
-      scope 10 {
-          let _18: usize;
-          scope 11 {
-              debug a => _18;
-              let _19: *const usize;
-              scope 12 {
-                  debug b => _19;
-                  let _20: &*const usize;
-                  scope 13 {
-                      debug d => _20;
-                      let _21: usize;
-                      scope 14 {
-                          debug c => _21;
-                      }
+      scope 8 {
+          debug a => _18;
+          let _19: *const usize;
+          scope 9 {
+              debug b => _19;
+              let _20: &*const usize;
+              scope 10 {
+                  debug d => _20;
+                  let _21: usize;
+                  scope 11 {
+                      debug c => _21;
                   }
               }
           }
       }
-      scope 15 {
-          let _25: usize;
-          scope 16 {
-              debug a => _25;
-              let mut _26: *const usize;
-              scope 17 {
-                  debug b => _26;
-                  let _27: *mut *const usize;
-                  scope 18 {
-                      debug d => _27;
-                      let _28: usize;
-                      scope 19 {
-                          debug c => _28;
-                      }
+      scope 12 {
+          debug a => _25;
+          let mut _26: *const usize;
+          scope 13 {
+              debug b => _26;
+              let _27: *mut *const usize;
+              scope 14 {
+                  debug d => _27;
+                  let _28: usize;
+                  scope 15 {
+                      debug c => _28;
                   }
               }
           }
       }
-      scope 20 {
-          let _32: usize;
-          scope 21 {
-              debug a => _32;
-              let _33: *const usize;
-              scope 22 {
-                  debug b => _33;
-                  let _34: usize;
-                  scope 23 {
-                      debug c => _34;
-                  }
+      scope 16 {
+          debug a => _32;
+          let _33: *const usize;
+          scope 17 {
+              debug b => _33;
+              let _34: usize;
+              scope 18 {
+                  debug c => _34;
               }
           }
       }
-      scope 24 {
-          let _38: usize;
-          scope 25 {
-              debug a => _38;
-              let _39: *const usize;
-              scope 26 {
-                  debug b1 => _39;
-                  let _40: usize;
-                  scope 27 {
-                      debug c => _40;
-                      let _41: *const usize;
-                      scope 28 {
-                          debug b2 => _41;
-                          let _42: usize;
-                          scope 29 {
-                              debug c2 => _42;
-                              let _43: *const usize;
-                              scope 30 {
-                                  debug b3 => _43;
-                              }
+      scope 19 {
+          debug a => _38;
+          let _39: *const usize;
+          scope 20 {
+              debug b1 => _39;
+              let _40: usize;
+              scope 21 {
+                  debug c => _40;
+                  let _41: *const usize;
+                  scope 22 {
+                      debug b2 => _41;
+                      let _42: usize;
+                      scope 23 {
+                          debug c2 => _42;
+                          let _43: *const usize;
+                          scope 24 {
+                              debug b3 => _43;
                           }
                       }
                   }
               }
           }
       }
-      scope 31 {
-          let _47: *const T;
-          scope 32 {
--             debug a => _47;
-+             debug a => _1;
-              let _48: T;
-              scope 33 {
-                  debug b => _48;
-              }
+      scope 25 {
+-         debug a => _47;
++         debug a => _1;
+          let _48: T;
+          scope 26 {
+              debug b => _48;
           }
       }
-      scope 34 {
-          let _52: *const T;
-          scope 35 {
-              debug a => _52;
-              let _54: T;
-              scope 36 {
-                  debug b => _54;
-              }
+      scope 27 {
+          debug a => _52;
+          let _54: T;
+          scope 28 {
+              debug b => _54;
           }
       }
-      scope 37 {
-          let _58: usize;
-          scope 38 {
-              debug a => _58;
-              let _59: *const usize;
-              scope 39 {
-                  debug b => _59;
-                  let _60: *const usize;
-                  scope 40 {
-                      debug c => _60;
-                      let _61: usize;
-                      scope 41 {
-                          debug e => _61;
-                      }
+      scope 29 {
+          debug a => _58;
+          let _59: *const usize;
+          scope 30 {
+              debug b => _59;
+              let _60: *const usize;
+              scope 31 {
+                  debug c => _60;
+                  let _61: usize;
+                  scope 32 {
+                      debug e => _61;
                   }
               }
           }
       }
-      scope 42 {
-          let _65: usize;
-          scope 43 {
-              debug a => _65;
-              let _66: *const usize;
-              scope 44 {
-                  debug b => _66;
-                  let _67: &*const usize;
-                  scope 45 {
-                      debug d => _67;
-                      let _68: usize;
-                      scope 46 {
-                          debug c => _68;
-                      }
+      scope 33 {
+          debug a => _65;
+          let _66: *const usize;
+          scope 34 {
+              debug b => _66;
+              let _67: &*const usize;
+              scope 35 {
+                  debug d => _67;
+                  let _68: usize;
+                  scope 36 {
+                      debug c => _68;
                   }
               }
           }
       }
-      scope 47 {
-          let _71: usize;
-          scope 48 {
-              debug a => _71;
-              let mut _72: *const usize;
-              scope 49 {
-                  debug b => _72;
-                  let _73: &mut *const usize;
-                  scope 50 {
-                      debug d => _73;
-                      let _74: usize;
-                      scope 51 {
-                          debug c => _74;
-                      }
+      scope 37 {
+          debug a => _71;
+          let mut _72: *const usize;
+          scope 38 {
+              debug b => _72;
+              let _73: &mut *const usize;
+              scope 39 {
+                  debug d => _73;
+                  let _74: usize;
+                  scope 40 {
+                      debug c => _74;
                   }
               }
           }
diff --git a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
index b6b2acc0b43..5629d04f1b1 100644
--- a/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.reference_propagation_mut_ptr.ReferencePropagation.diff
@@ -6,197 +6,177 @@
       debug multiple => _2;
       let mut _0: ();
       let _3: ();
+      let mut _4: usize;
       let _7: ();
       let mut _8: ();
       let _9: ();
+      let mut _10: usize;
       let mut _13: *mut usize;
       let _15: ();
       let mut _16: ();
       let _17: ();
+      let mut _18: usize;
       let _22: ();
       let mut _23: &*mut usize;
       let _24: ();
+      let mut _25: usize;
       let _29: ();
       let mut _30: *mut *mut usize;
       let _31: ();
+      let mut _32: usize;
       let _35: ();
       let mut _36: *mut usize;
       let _37: ();
+      let mut _38: usize;
       let _44: ();
       let mut _45: *mut usize;
       let _46: ();
+      let _47: *mut T;
       let _49: ();
       let mut _50: ();
       let _51: ();
+      let _52: *mut T;
       let mut _53: *mut T;
       let _55: ();
       let mut _56: ();
       let _57: ();
+      let mut _58: usize;
       let _62: ();
       let mut _63: ();
+      let mut _64: usize;
       let _68: ();
       let mut _69: ();
       scope 1 {
-          let mut _4: usize;
+          debug a => _4;
+          let _5: *mut usize;
           scope 2 {
-              debug a => _4;
-              let _5: *mut usize;
+              debug b => _5;
+              let _6: usize;
               scope 3 {
-                  debug b => _5;
-                  let _6: usize;
-                  scope 4 {
-                      debug c => _6;
-                  }
+                  debug c => _6;
               }
           }
       }
-      scope 5 {
-          let mut _10: usize;
-          scope 6 {
-              debug a => _10;
-              let mut _11: usize;
-              scope 7 {
-                  debug a2 => _11;
-                  let mut _12: *mut usize;
-                  scope 8 {
-                      debug b => _12;
-                      let _14: usize;
-                      scope 9 {
-                          debug c => _14;
-                      }
+      scope 4 {
+          debug a => _10;
+          let mut _11: usize;
+          scope 5 {
+              debug a2 => _11;
+              let mut _12: *mut usize;
+              scope 6 {
+                  debug b => _12;
+                  let _14: usize;
+                  scope 7 {
+                      debug c => _14;
                   }
               }
           }
       }
-      scope 10 {
-          let mut _18: usize;
-          scope 11 {
-              debug a => _18;
-              let _19: *mut usize;
-              scope 12 {
-                  debug b => _19;
-                  let _20: &*mut usize;
-                  scope 13 {
-                      debug d => _20;
-                      let _21: usize;
-                      scope 14 {
-                          debug c => _21;
-                      }
+      scope 8 {
+          debug a => _18;
+          let _19: *mut usize;
+          scope 9 {
+              debug b => _19;
+              let _20: &*mut usize;
+              scope 10 {
+                  debug d => _20;
+                  let _21: usize;
+                  scope 11 {
+                      debug c => _21;
                   }
               }
           }
       }
-      scope 15 {
-          let mut _25: usize;
-          scope 16 {
-              debug a => _25;
-              let mut _26: *mut usize;
-              scope 17 {
-                  debug b => _26;
-                  let _27: *mut *mut usize;
-                  scope 18 {
-                      debug d => _27;
-                      let _28: usize;
-                      scope 19 {
-                          debug c => _28;
-                      }
+      scope 12 {
+          debug a => _25;
+          let mut _26: *mut usize;
+          scope 13 {
+              debug b => _26;
+              let _27: *mut *mut usize;
+              scope 14 {
+                  debug d => _27;
+                  let _28: usize;
+                  scope 15 {
+                      debug c => _28;
                   }
               }
           }
       }
-      scope 20 {
-          let mut _32: usize;
-          scope 21 {
-              debug a => _32;
-              let _33: *mut usize;
-              scope 22 {
-                  debug b => _33;
-                  let _34: usize;
-                  scope 23 {
-                      debug c => _34;
-                  }
+      scope 16 {
+          debug a => _32;
+          let _33: *mut usize;
+          scope 17 {
+              debug b => _33;
+              let _34: usize;
+              scope 18 {
+                  debug c => _34;
               }
           }
       }
-      scope 24 {
-          let mut _38: usize;
-          scope 25 {
-              debug a => _38;
-              let _39: *mut usize;
-              scope 26 {
-                  debug b1 => _39;
-                  let _40: usize;
-                  scope 27 {
-                      debug c => _40;
-                      let _41: *mut usize;
-                      scope 28 {
-                          debug b2 => _41;
-                          let _42: usize;
-                          scope 29 {
-                              debug c2 => _42;
-                              let _43: *mut usize;
-                              scope 30 {
-                                  debug b3 => _43;
-                              }
+      scope 19 {
+          debug a => _38;
+          let _39: *mut usize;
+          scope 20 {
+              debug b1 => _39;
+              let _40: usize;
+              scope 21 {
+                  debug c => _40;
+                  let _41: *mut usize;
+                  scope 22 {
+                      debug b2 => _41;
+                      let _42: usize;
+                      scope 23 {
+                          debug c2 => _42;
+                          let _43: *mut usize;
+                          scope 24 {
+                              debug b3 => _43;
                           }
                       }
                   }
               }
           }
       }
-      scope 31 {
-          let _47: *mut T;
-          scope 32 {
--             debug a => _47;
-+             debug a => _1;
-              let _48: T;
-              scope 33 {
-                  debug b => _48;
-              }
+      scope 25 {
+-         debug a => _47;
++         debug a => _1;
+          let _48: T;
+          scope 26 {
+              debug b => _48;
           }
       }
-      scope 34 {
-          let _52: *mut T;
-          scope 35 {
-              debug a => _52;
-              let _54: T;
-              scope 36 {
-                  debug b => _54;
-              }
+      scope 27 {
+          debug a => _52;
+          let _54: T;
+          scope 28 {
+              debug b => _54;
           }
       }
-      scope 37 {
-          let mut _58: usize;
-          scope 38 {
-              debug a => _58;
-              let _59: *mut usize;
-              scope 39 {
-                  debug b => _59;
-                  let _60: &*mut usize;
-                  scope 40 {
-                      debug d => _60;
-                      let _61: usize;
-                      scope 41 {
-                          debug c => _61;
-                      }
+      scope 29 {
+          debug a => _58;
+          let _59: *mut usize;
+          scope 30 {
+              debug b => _59;
+              let _60: &*mut usize;
+              scope 31 {
+                  debug d => _60;
+                  let _61: usize;
+                  scope 32 {
+                      debug c => _61;
                   }
               }
           }
       }
-      scope 42 {
-          let mut _64: usize;
-          scope 43 {
-              debug a => _64;
-              let mut _65: *mut usize;
-              scope 44 {
-                  debug b => _65;
-                  let _66: &mut *mut usize;
-                  scope 45 {
-                      debug d => _66;
-                      let _67: usize;
-                      scope 46 {
-                          debug c => _67;
-                      }
+      scope 33 {
+          debug a => _64;
+          let mut _65: *mut usize;
+          scope 34 {
+              debug b => _65;
+              let _66: &mut *mut usize;
+              scope 35 {
+                  debug d => _66;
+                  let _67: usize;
+                  scope 36 {
+                      debug c => _67;
                   }
               }
           }
diff --git a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
index b4912a918ba..a5427cea1f8 100644
--- a/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
+++ b/tests/mir-opt/reference_prop.unique_with_copies.ReferencePropagation.diff
@@ -12,16 +12,12 @@
       scope 1 {
 -         debug y => _1;
 +         debug y => _3;
-          scope 5 {
-          }
       }
       scope 2 {
           debug a => _2;
           let _3: *mut i32;
           scope 3 {
               debug x => _3;
-              scope 4 {
-              }
           }
       }
   
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir
index 7124b4c1cd8..f9d58ea60a3 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-abort.mir
@@ -36,22 +36,18 @@ fn array_casts() -> () {
             debug p => _2;
             let _8: [usize; 2];
             scope 3 {
-            }
-            scope 4 {
                 debug x => _8;
                 let _9: *const usize;
-                scope 5 {
+                scope 4 {
                     debug p => _9;
                     let _20: &usize;
                     let _21: &usize;
                     let mut _34: &usize;
-                    scope 6 {
-                    }
-                    scope 7 {
+                    scope 5 {
                         debug left_val => _20;
                         debug right_val => _21;
                         let _26: core::panicking::AssertKind;
-                        scope 8 {
+                        scope 6 {
                             debug kind => _26;
                         }
                     }
diff --git a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
index be04757f2a3..b0b70cd5d91 100644
--- a/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
+++ b/tests/mir-opt/retag.array_casts.SimplifyCfg-pre-optimizations.after.panic-unwind.mir
@@ -36,22 +36,18 @@ fn array_casts() -> () {
             debug p => _2;
             let _8: [usize; 2];
             scope 3 {
-            }
-            scope 4 {
                 debug x => _8;
                 let _9: *const usize;
-                scope 5 {
+                scope 4 {
                     debug p => _9;
                     let _20: &usize;
                     let _21: &usize;
                     let mut _34: &usize;
-                    scope 6 {
-                    }
-                    scope 7 {
+                    scope 5 {
                         debug left_val => _20;
                         debug right_val => _21;
                         let _26: core::panicking::AssertKind;
-                        scope 8 {
+                        scope 6 {
                             debug kind => _26;
                         }
                     }
diff --git a/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff
index 9ebee3df62c..cc5c642407e 100644
--- a/tests/mir-opt/simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff
@@ -1,7 +1,7 @@
-- // MIR for `expose_addr` before SimplifyLocals-before-const-prop
-+ // MIR for `expose_addr` after SimplifyLocals-before-const-prop
+- // MIR for `expose_provenance` before SimplifyLocals-before-const-prop
++ // MIR for `expose_provenance` after SimplifyLocals-before-const-prop
   
-  fn expose_addr(_1: *const usize) -> () {
+  fn expose_provenance(_1: *const usize) -> () {
       debug p => _1;
       let mut _0: ();
       let _2: usize;
@@ -11,7 +11,7 @@
           StorageLive(_2);
           StorageLive(_3);
           _3 = _1;
-          _2 = move _3 as usize (PointerExposeAddress);
+          _2 = move _3 as usize (PointerExposeProvenance);
           StorageDead(_3);
           StorageDead(_2);
           _0 = const ();
diff --git a/tests/mir-opt/simplify_locals.rs b/tests/mir-opt/simplify_locals.rs
index f95e9185f44..756679e77e3 100644
--- a/tests/mir-opt/simplify_locals.rs
+++ b/tests/mir-opt/simplify_locals.rs
@@ -63,8 +63,8 @@ fn t4() -> u32 {
     unsafe { X + 1 }
 }
 
-// EMIT_MIR simplify_locals.expose_addr.SimplifyLocals-before-const-prop.diff
-fn expose_addr(p: *const usize) {
+// EMIT_MIR simplify_locals.expose_provenance.SimplifyLocals-before-const-prop.diff
+fn expose_provenance(p: *const usize) {
     // Used pointer to address cast. Has a side effect of exposing the provenance.
     p as usize;
 }
@@ -78,5 +78,5 @@ fn main() {
     t2();
     t3();
     t4();
-    expose_addr(&0);
+    expose_provenance(&0);
 }
diff --git a/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
index a903e8d789e..526ff2f25cf 100644
--- a/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t1.SimplifyLocals-before-const-prop.diff
@@ -5,8 +5,6 @@
       let mut _0: ();
 -     let _1: u32;
 -     let mut _2: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
 -         StorageLive(_1);
diff --git a/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
index e72e71a13a2..a88f6d40115 100644
--- a/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t2.SimplifyLocals-before-const-prop.diff
@@ -5,8 +5,6 @@
       let mut _0: ();
 -     let _1: &mut u32;
 -     let mut _2: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
 -         StorageLive(_1);
diff --git a/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
index 37c367c82ca..5d45d7ac781 100644
--- a/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t3.SimplifyLocals-before-const-prop.diff
@@ -6,8 +6,6 @@
 -     let _1: u32;
 -     let mut _2: &mut u32;
 -     let mut _3: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
 -         StorageLive(_1);
diff --git a/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
index 006e3c4232d..4f4855dbaaf 100644
--- a/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
+++ b/tests/mir-opt/simplify_locals.t4.SimplifyLocals-before-const-prop.diff
@@ -5,8 +5,6 @@
       let mut _0: u32;
       let mut _1: u32;
       let mut _2: *mut u32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_1);
diff --git a/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff b/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff
index 6c99d3efd29..2f8dfcc5d63 100644
--- a/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff
+++ b/tests/mir-opt/sroa/structs.unions.ScalarReplacementOfAggregates.diff
@@ -6,8 +6,6 @@
       let mut _0: u32;
       let mut _2: unions::Repr;
       let mut _3: f32;
-      scope 1 {
-      }
   
       bb0: {
           StorageLive(_2);
diff --git a/tests/mir-opt/tls_access.main.PreCodegen.after.mir b/tests/mir-opt/tls_access.main.PreCodegen.after.mir
index 43c7051f027..1c59e938423 100644
--- a/tests/mir-opt/tls_access.main.PreCodegen.after.mir
+++ b/tests/mir-opt/tls_access.main.PreCodegen.after.mir
@@ -3,12 +3,10 @@
 fn main() -> () {
     let mut _0: ();
     let _1: *mut u8;
+    let _2: &u8;
     let mut _3: *mut u8;
     scope 1 {
-        let _2: &u8;
-        scope 2 {
-            debug a => _2;
-        }
+        debug a => _2;
     }
 
     bb0: {
diff --git a/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
index 89f7016fee4..240f409817d 100644
--- a/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
+++ b/tests/mir-opt/uninhabited_enum.process_never.SimplifyLocals-final.after.mir
@@ -7,8 +7,6 @@ fn process_never(_1: *const !) -> () {
     scope 1 {
         debug _input => _2;
     }
-    scope 2 {
-    }
 
     bb0: {
         unreachable;
diff --git a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
index 51905f982b8..51514ba5e5d 100644
--- a/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
+++ b/tests/mir-opt/uninhabited_enum.process_void.SimplifyLocals-final.after.mir
@@ -6,8 +6,6 @@ fn process_void(_1: *const Void) -> () {
     scope 1 {
         debug _input => _1;
     }
-    scope 2 {
-    }
 
     bb0: {
         return;
diff --git a/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir b/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir
index 8edc7b5df88..f0311422c17 100644
--- a/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/unnamed-fields/field_access.bar.SimplifyCfg-initial.after.mir
@@ -11,8 +11,6 @@ fn bar(_1: Bar) -> () {
     let mut _7: bool;
     let _8: ();
     let mut _9: [u8; 1];
-    scope 1 {
-    }
 
     bb0: {
         StorageLive(_2);
diff --git a/tests/run-make/arguments-non-c-like-enum/Makefile b/tests/run-make/arguments-non-c-like-enum/Makefile
deleted file mode 100644
index 0c8d8bf3acc..00000000000
--- a/tests/run-make/arguments-non-c-like-enum/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-# ignore-cross-compile
-include ../tools.mk
-
-all:
-	$(RUSTC) --crate-type=staticlib nonclike.rs
-	$(CC) test.c $(call STATICLIB,nonclike) $(call OUT_EXE,test) \
-		$(EXTRACFLAGS) $(EXTRACXXFLAGS)
-	$(call RUN,test)
diff --git a/tests/run-make/arguments-non-c-like-enum/rmake.rs b/tests/run-make/arguments-non-c-like-enum/rmake.rs
new file mode 100644
index 00000000000..624a7fb2251
--- /dev/null
+++ b/tests/run-make/arguments-non-c-like-enum/rmake.rs
@@ -0,0 +1,20 @@
+//! Check that non-trivial `repr(C)` enum in Rust has valid C layout.
+//@ ignore-cross-compile
+
+extern crate run_make_support;
+
+use run_make_support::{cc, extra_c_flags, extra_cxx_flags, run, rustc, static_lib};
+
+pub fn main() {
+    use std::path::Path;
+
+    rustc().input("nonclike.rs").crate_type("staticlib").run();
+    cc().input("test.c")
+        .input(static_lib("nonclike"))
+        .out_exe("test")
+        .args(&extra_c_flags())
+        .args(&extra_cxx_flags())
+        .inspect(|cmd| eprintln!("{cmd:?}"))
+        .run();
+    run("test");
+}
diff --git a/tests/run-make/hir-tree/Makefile b/tests/run-make/hir-tree/Makefile
deleted file mode 100644
index b0450ea4bc5..00000000000
--- a/tests/run-make/hir-tree/Makefile
+++ /dev/null
@@ -1,8 +0,0 @@
-include ../tools.mk
-
-# Test that hir-tree output doesn't crash and includes
-# the string constant we would expect to see.
-
-all:
-	$(RUSTC) -o $(TMPDIR)/input.hir -Z unpretty=hir-tree input.rs
-	$(CGREP) '"Hello, Rustaceans!\n"' < $(TMPDIR)/input.hir
diff --git a/tests/run-make/hir-tree/input.rs b/tests/run-make/hir-tree/input.rs
deleted file mode 100644
index 9d1a4e9e47d..00000000000
--- a/tests/run-make/hir-tree/input.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
-    println!("Hello, Rustaceans!");
-}
diff --git a/tests/run-make/issue-7349/Makefile b/tests/run-make/issue-7349/Makefile
deleted file mode 100644
index dc073b77fe1..00000000000
--- a/tests/run-make/issue-7349/Makefile
+++ /dev/null
@@ -1,11 +0,0 @@
-include ../tools.mk
-
-# Test to make sure that inner functions within a polymorphic outer function
-# don't get re-codegened when the outer function is monomorphized.  The test
-# code monomorphizes the outer functions several times, but the magic constants
-# used in the inner functions should each appear only once in the generated IR.
-
-all:
-	$(RUSTC) foo.rs --emit=llvm-ir
-	[ "$$(grep -c 'ret i32 8675309' "$(TMPDIR)/foo.ll")" -eq "1" ]
-	[ "$$(grep -c 'ret i32 11235813' "$(TMPDIR)/foo.ll")" -eq "1" ]
diff --git a/tests/run-make/issue-7349/foo.rs b/tests/run-make/issue-7349/foo.rs
deleted file mode 100644
index 246a1259580..00000000000
--- a/tests/run-make/issue-7349/foo.rs
+++ /dev/null
@@ -1,22 +0,0 @@
-fn outer<T>() {
-    #[allow(dead_code)]
-    fn inner() -> u32 {
-        8675309
-    }
-    inner();
-}
-
-extern "C" fn outer_foreign<T>() {
-    #[allow(dead_code)]
-    fn inner() -> u32 {
-        11235813
-    }
-    inner();
-}
-
-fn main() {
-    outer::<isize>();
-    outer::<usize>();
-    outer_foreign::<isize>();
-    outer_foreign::<usize>();
-}
diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml
index 3239e54a866..61b2e8880c6 100644
--- a/tests/rustdoc-gui/anchors.goml
+++ b/tests/rustdoc-gui/anchors.goml
@@ -1,4 +1,5 @@
 // This test is to ensure that the anchors (`§`) have the expected color and position.
+include: "utils.goml"
 
 define-function: (
     "check-colors",
@@ -8,10 +9,7 @@ define-function: (
         // This is needed to ensure that the text color is computed.
         show-text: true
 
-        // Setting the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        // We reload the page so the local storage settings are being used.
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         assert-css: ("#toggle-all-docs", {"color": |main_color|})
         assert-css: (".main-heading h1 a:nth-of-type(1)", {"color": |main_heading_color|})
diff --git a/tests/rustdoc-gui/code-color.goml b/tests/rustdoc-gui/code-color.goml
index e17af5e7f1f..661709aa1ce 100644
--- a/tests/rustdoc-gui/code-color.goml
+++ b/tests/rustdoc-gui/code-color.goml
@@ -2,6 +2,7 @@
 // check that the rule isn't applied on other "<code>" elements.
 //
 // While we're at it, we also check it for the other themes.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
 // If the text isn't displayed, the browser doesn't compute color style correctly...
 show-text: true
@@ -10,10 +11,7 @@ define-function: (
     "check-colors",
     [theme, doc_code_color, doc_inline_code_color],
     block {
-        // Set the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        // We reload the page so the local storage settings are being used.
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".docblock pre > code", {"color": |doc_code_color|}, ALL)
         assert-css: (".docblock > p > code", {"color": |doc_inline_code_color|}, ALL)
     },
diff --git a/tests/rustdoc-gui/codeblock-tooltip.goml b/tests/rustdoc-gui/codeblock-tooltip.goml
index 19e3927f642..654589c3eba 100644
--- a/tests/rustdoc-gui/codeblock-tooltip.goml
+++ b/tests/rustdoc-gui/codeblock-tooltip.goml
@@ -1,4 +1,5 @@
 // Checking the colors of the codeblocks tooltips.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
 show-text: true
 
@@ -6,9 +7,7 @@ define-function: (
     "check-colors",
     [theme, background, color, border],
     block {
-        // Setting the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         // compile_fail block
         assert-css: (
diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml
index cb7bdaab4c8..fc80932caba 100644
--- a/tests/rustdoc-gui/docblock-code-block-line-number.goml
+++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml
@@ -1,4 +1,5 @@
 // Checks that the setting "line numbers" is working as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
 
 // Otherwise, we can't check text color
@@ -13,14 +14,10 @@ define-function: (
     [theme, color],
     block {
         // We now set the setting to show the line numbers on code examples.
-        set-local-storage: {
-            "rustdoc-theme": |theme|,
-            "rustdoc-use-system-theme": "false",
-            "rustdoc-line-numbers": "true"
-        }
-        // We reload to make the line numbers appear and change theme.
-        reload:
-        // We wait for them to be added into the DOM by the JS...
+        set-local-storage: {"rustdoc-line-numbers": "true"}
+        // Page will be reloaded in "switch-theme".
+        call-function: ("switch-theme", {"theme": |theme|})
+        // We wait for the line numbers to be added into the DOM by the JS...
         wait-for: "pre.example-line-numbers"
         // If the test didn't fail, it means that it was found!
         assert-css: (
diff --git a/tests/rustdoc-gui/docblock-details.goml b/tests/rustdoc-gui/docblock-details.goml
index 4b8f5b54fac..b8fc58ef1e4 100644
--- a/tests/rustdoc-gui/docblock-details.goml
+++ b/tests/rustdoc-gui/docblock-details.goml
@@ -1,8 +1,8 @@
 // This ensures that the `<details>`/`<summary>` elements are displayed as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/details/struct.Details.html"
 show-text: true
-set-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
-reload:
+call-function: ("switch-theme", {"theme": "dark"})
 
 // We first check that the headers in the `.top-doc` doc block still have their
 // bottom border.
diff --git a/tests/rustdoc-gui/docblock-table.goml b/tests/rustdoc-gui/docblock-table.goml
index db6d065a4b3..a73f4aaa767 100644
--- a/tests/rustdoc-gui/docblock-table.goml
+++ b/tests/rustdoc-gui/docblock-table.goml
@@ -1,4 +1,5 @@
 // This test checks the appearance of the tables in the doc comments.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/doc_block_table/struct.DocBlockTable.html#method.func"
 
 compare-elements-css: (".impl-items .docblock table th", ".top-doc .docblock table th", ["border"])
@@ -8,8 +9,7 @@ define-function: (
     "check-colors",
     [theme, border_color, zebra_stripe_color],
     block {
-        set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".top-doc .docblock table tbody tr:nth-child(1)", {
             "background-color": "rgba(0, 0, 0, 0)",
         })
diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml
index 2a181c0669f..81346fc12d0 100644
--- a/tests/rustdoc-gui/headers-color.goml
+++ b/tests/rustdoc-gui/headers-color.goml
@@ -1,5 +1,7 @@
 // This test check for headings text and background colors for the different themes.
 
+include: "utils.goml"
+
 define-function: (
     "check-colors",
     [theme, color, code_header_color, focus_background_color, headings_color],
@@ -7,8 +9,7 @@ define-function: (
         go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
         // This is needed so that the text color is computed.
         show-text: true
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (
             ".impl",
             {"color": |color|, "background-color": "rgba(0, 0, 0, 0)"},
diff --git a/tests/rustdoc-gui/headings.goml b/tests/rustdoc-gui/headings.goml
index cdc61e36be2..94d80a3e3df 100644
--- a/tests/rustdoc-gui/headings.goml
+++ b/tests/rustdoc-gui/headings.goml
@@ -11,6 +11,7 @@
 // 18px  1.125em
 // 16px  1rem
 // 14px  0.875rem
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html"
 
 assert-css: (".main-heading h1", {"font-size": "24px"})
@@ -158,8 +159,8 @@ define-function: (
     "check-colors",
     [theme, heading_color, small_heading_color, heading_border_color],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
+
         assert-css: (
             ".top-doc .docblock h2",
             {"color": |heading_color|, "border-bottom": "1px solid " + |heading_border_color|},
@@ -222,8 +223,7 @@ define-function: (
     "check-since-color",
     [theme],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".since", {"color": "#808080"}, ALL)
     },
 )
diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml
index 9a7247a737b..09d33af139c 100644
--- a/tests/rustdoc-gui/help-page.goml
+++ b/tests/rustdoc-gui/help-page.goml
@@ -1,4 +1,5 @@
 // This test ensures that opening the help page in its own tab works.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/help.html"
 set-window-size: (1000, 1000) // Try desktop size first.
 wait-for: "#help"
@@ -19,10 +20,7 @@ define-function: (
     "check-colors",
     [theme, color, background, box_shadow],
     block {
-        // Setting the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        // We reload the page so the local storage settings are being used.
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: ("#help kbd", {
             "color": |color|,
             "background-color": |background|,
diff --git a/tests/rustdoc-gui/highlight-colors.goml b/tests/rustdoc-gui/highlight-colors.goml
index 48bef319d42..65fb3e1285e 100644
--- a/tests/rustdoc-gui/highlight-colors.goml
+++ b/tests/rustdoc-gui/highlight-colors.goml
@@ -1,4 +1,5 @@
 // This test checks the highlight colors in the source code pages.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
 show-text: true
 
@@ -22,8 +23,7 @@ define-function: (
         doc_comment,
     ],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: ("pre.rust .kw", {"color": |kw|}, ALL)
         assert-css: ("pre.rust .kw-2", {"color": |kw2|}, ALL)
         assert-css: ("pre.rust .prelude-ty", {"color": |prelude_ty|}, ALL)
diff --git a/tests/rustdoc-gui/item-decl-colors.goml b/tests/rustdoc-gui/item-decl-colors.goml
index e68d206a511..18545f03567 100644
--- a/tests/rustdoc-gui/item-decl-colors.goml
+++ b/tests/rustdoc-gui/item-decl-colors.goml
@@ -1,5 +1,7 @@
 // This test ensures that the color of the items in the type decl are working as expected.
 
+include: "utils.goml"
+
 // We need to disable this check because `trait.impl/test_docs/trait.TraitWithoutGenerics.js`
 // doesn't exist.
 fail-on-request-error: false
@@ -21,8 +23,8 @@ define-function: (
         go-to: "file://" + |DOC_PATH| + "/test_docs/struct.WithGenerics.html"
         show-text: true
 
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
+
         assert-css: (".item-decl .code-attribute", {"color": |attr_color|}, ALL)
         assert-css: (".item-decl .trait", {"color": |trait_color|}, ALL)
         // We need to add `code` here because otherwise it would select the parent too.
diff --git a/tests/rustdoc-gui/item-decl-comment-highlighting.goml b/tests/rustdoc-gui/item-decl-comment-highlighting.goml
index 056b6a5b1e8..3ffbbe1c40f 100644
--- a/tests/rustdoc-gui/item-decl-comment-highlighting.goml
+++ b/tests/rustdoc-gui/item-decl-comment-highlighting.goml
@@ -1,4 +1,5 @@
 // This test checks that comments in item declarations are highlighted.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/private/enum.Enum.html"
 show-text: true
 
@@ -7,8 +8,7 @@ define-function: (
     [theme, url, comment_color],
     block {
         go-to: |url|
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".item-decl .comment", {"color": |comment_color|}, ALL)
     }
 )
diff --git a/tests/rustdoc-gui/javascript-disabled.goml b/tests/rustdoc-gui/javascript-disabled.goml
index a0872d553af..a7579ef7ec1 100644
--- a/tests/rustdoc-gui/javascript-disabled.goml
+++ b/tests/rustdoc-gui/javascript-disabled.goml
@@ -3,4 +3,18 @@
 javascript: false
 
 go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
+show-text: true
 assert-css: (".sub", {"display": "none"})
+
+// Even though JS is disabled, we should still have themes applied. Links are never black-colored
+// if styles are applied so we check that they are not.
+assert-css-false: ("a.src", {"color": "#000"})
+
+javascript: true
+fail-on-request-error: false
+block-network-request: "*.js"
+reload:
+
+// JS is enabled but wasn't loaded, we should still have the light theme applied. Links are never
+// black-colored if styles are applied so we check that they are not.
+assert-css-false: ("a.src", {"color": "#000"})
diff --git a/tests/rustdoc-gui/jump-to-def-background.goml b/tests/rustdoc-gui/jump-to-def-background.goml
index ae9c0c560cf..71320360740 100644
--- a/tests/rustdoc-gui/jump-to-def-background.goml
+++ b/tests/rustdoc-gui/jump-to-def-background.goml
@@ -1,14 +1,12 @@
 // We check the background color on the jump to definition links in the src code page.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/src/link_to_definition/lib.rs.html"
 
 define-function: (
     "check-background-color",
     [theme, background_color],
     block {
-        // Set the theme.
-        set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }
-        // We reload the page so the local storage settings are being used.
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (
             "body.src .example-wrap pre.rust a",
             {"background-color": |background_color|},
diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml
index a1fb619a5d3..ad1b5e801ca 100644
--- a/tests/rustdoc-gui/links-color.goml
+++ b/tests/rustdoc-gui/links-color.goml
@@ -1,4 +1,5 @@
 // This test checks links colors.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 
 // This is needed so that the text color is computed.
@@ -9,11 +10,7 @@ define-function: (
     [theme, mod, macro, struct, enum, trait, fn, type, union, keyword,
      sidebar, sidebar_current, sidebar_current_background],
     block {
-        set-local-storage: {
-            "rustdoc-theme": |theme|,
-            "rustdoc-use-system-theme": "false",
-        }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         // Checking results colors.
         assert-css: (".item-table .mod", {"color": |mod|}, ALL)
         assert-css: (".item-table .macro", {"color": |macro|}, ALL)
diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml
index 0b1c6622596..34fafe9a141 100644
--- a/tests/rustdoc-gui/notable-trait.goml
+++ b/tests/rustdoc-gui/notable-trait.goml
@@ -1,4 +1,5 @@
 // This test checks the position of the `i` for the notable traits.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html"
 show-text: true
 // We start with a wide screen.
@@ -128,10 +129,7 @@ define-function: (
         // This is needed to ensure that the text color is computed.
         show-text: true
 
-        // Setting the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        // We reload the page so the local storage settings are being used.
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         assert-css: (
              "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']",
diff --git a/tests/rustdoc-gui/pocket-menu.goml b/tests/rustdoc-gui/pocket-menu.goml
index b16150cd0d3..ec31f492abe 100644
--- a/tests/rustdoc-gui/pocket-menu.goml
+++ b/tests/rustdoc-gui/pocket-menu.goml
@@ -1,4 +1,5 @@
 // This test ensures that the "pocket menus" are working as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // First we check that the help menu doesn't exist yet.
 assert-false: "#help-button .popover"
@@ -33,11 +34,7 @@ define-function: (
     "check-popover-colors",
     [theme, border_color],
     block {
-        set-local-storage: {
-            "rustdoc-theme": |theme|,
-            "rustdoc-use-system-theme": "false",
-        }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         click: "#help-button"
         assert-css: (
diff --git a/tests/rustdoc-gui/run-on-hover.goml b/tests/rustdoc-gui/run-on-hover.goml
index 19b15afbac3..087dd3374f8 100644
--- a/tests/rustdoc-gui/run-on-hover.goml
+++ b/tests/rustdoc-gui/run-on-hover.goml
@@ -2,6 +2,7 @@
 // Playground. That button is hidden until the user hovers over the code block.
 // This test checks that it is hidden, and that it shows on hover. It also
 // checks for its color.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html"
 show-text: true
 
@@ -9,8 +10,7 @@ define-function: (
     "check-run-button",
     [theme, color, background, hover_color, hover_background],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".test-arrow", {"visibility": "hidden"})
         move-cursor-to: ".example-wrap"
         assert-css: (".test-arrow", {
diff --git a/tests/rustdoc-gui/rust-logo.goml b/tests/rustdoc-gui/rust-logo.goml
index a3b420e5eb9..7a999fa854c 100644
--- a/tests/rustdoc-gui/rust-logo.goml
+++ b/tests/rustdoc-gui/rust-logo.goml
@@ -1,4 +1,5 @@
 // This test ensures that the correct style is applied to the rust logo in the sidebar.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/staged_api/index.html"
 
 define-function: (
@@ -8,14 +9,12 @@ define-function: (
         // Going to the doc page.
         go-to: "file://" + |DOC_PATH| + "/staged_api/index.html"
         // Changing theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".rust-logo", {"filter": |filter|})
         // Now we check that the non-rust logos don't have a CSS filter set.
         go-to: "file://" + |DOC_PATH| + "/huge_logo/index.html"
         // Changing theme on the new page (again...).
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         // Check there is no rust logo
         assert-false: ".rust-logo"
         // Check there is no filter.
diff --git a/tests/rustdoc-gui/scrape-examples-color.goml b/tests/rustdoc-gui/scrape-examples-color.goml
index b1675a5f1fd..588ba08a60c 100644
--- a/tests/rustdoc-gui/scrape-examples-color.goml
+++ b/tests/rustdoc-gui/scrape-examples-color.goml
@@ -1,4 +1,5 @@
 // Check that scrape example code blocks have the expected colors.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
 show-text: true
 
@@ -7,8 +8,7 @@ define-function: (
     [theme, highlight, highlight_focus, help_border, help_color, help_hover_border,
      help_hover_color],
     block {
-        set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         wait-for: ".more-examples-toggle"
         assert-css: (".scraped-example .example-wrap .rust span.highlight:not(.focus)", {
             "background-color": |highlight|,
@@ -66,8 +66,7 @@ define-function: (
     "check-background",
     [theme, background_color_start, background_color_end],
     block {
-        set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".scraped-example:not(.expanded) .code-wrapper::before", {
             "background-image": "linear-gradient(" + |background_color_start| + ", " +
                 |background_color_end| + ")",
diff --git a/tests/rustdoc-gui/scrape-examples-toggle.goml b/tests/rustdoc-gui/scrape-examples-toggle.goml
index ea645d28924..a9d37048188 100644
--- a/tests/rustdoc-gui/scrape-examples-toggle.goml
+++ b/tests/rustdoc-gui/scrape-examples-toggle.goml
@@ -1,4 +1,5 @@
 // This tests checks that the "scraped examples" toggle is working as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html"
 
 // Checking the color of the toggle line.
@@ -7,8 +8,7 @@ define-function: (
     "check-color",
     [theme, toggle_line_color, toggle_line_hover_color],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         // Clicking "More examples..." will open additional examples
         assert-attribute-false: (".more-examples-toggle", {"open": ""})
diff --git a/tests/rustdoc-gui/search-error.goml b/tests/rustdoc-gui/search-error.goml
index d3de77b5635..4dc60669c7a 100644
--- a/tests/rustdoc-gui/search-error.goml
+++ b/tests/rustdoc-gui/search-error.goml
@@ -1,4 +1,5 @@
 // Checks that the crate search filtering is handled correctly and changes the results.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=sa'%3Bda'%3Bds"
 show-text: true
 
@@ -6,11 +7,7 @@ define-function: (
     "check-colors",
     [theme, error_background],
     block {
-        // Setting the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        // We reload the page so the local storage settings are being used.
-        reload:
-
+        call-function: ("switch-theme", {"theme": |theme|})
         wait-for: "#search .error code"
         assert-css: ("#search .error code", {"background-color": |error_background|})
     }
diff --git a/tests/rustdoc-gui/search-filter.goml b/tests/rustdoc-gui/search-filter.goml
index 8c50322fcd4..d6421599a20 100644
--- a/tests/rustdoc-gui/search-filter.goml
+++ b/tests/rustdoc-gui/search-filter.goml
@@ -1,4 +1,5 @@
 // Checks that the crate search filtering is handled correctly and changes the results.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 show-text: true
 write-into: (".search-input", "test")
@@ -59,8 +60,7 @@ assert-text: (".search-results-title", "Results in all crates", STARTS_WITH)
 
 // Checking the display of the crate filter.
 // We start with the light theme.
-set-local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
-reload:
+call-function: ("switch-theme", {"theme": "light"})
 
 set-timeout: 2000
 wait-for: "#crate-search"
diff --git a/tests/rustdoc-gui/search-form-elements.goml b/tests/rustdoc-gui/search-form-elements.goml
index 2fc66259291..63d2ceb3e7c 100644
--- a/tests/rustdoc-gui/search-form-elements.goml
+++ b/tests/rustdoc-gui/search-form-elements.goml
@@ -1,4 +1,5 @@
 // This test ensures that the elements in ".search-form" have the expected display.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 show-text: true
 
@@ -9,11 +10,7 @@ define-function: (
         menu_button_border, menu_button_a_color, menu_button_a_border_hover, menu_a_color,
     ],
     block {
-        set-local-storage: {
-            "rustdoc-theme": |theme|,
-            "rustdoc-use-system-theme": "false",
-        }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (
             ".search-input",
             {
diff --git a/tests/rustdoc-gui/search-no-result.goml b/tests/rustdoc-gui/search-no-result.goml
index dda50ec3fb6..2e89278b46c 100644
--- a/tests/rustdoc-gui/search-no-result.goml
+++ b/tests/rustdoc-gui/search-no-result.goml
@@ -1,4 +1,5 @@
 // The goal of this test is to check the color of the "no result" links.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=sdkfskjfsdks"
 show-text: true
 
@@ -6,9 +7,7 @@ define-function: (
     "check-no-result",
     [theme, link, link_hover],
     block {
-        // Changing theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         wait-for: "#results"
         assert: ".search-failed.active"
         assert-css: ("#results a", {"color": |link|}, ALL)
diff --git a/tests/rustdoc-gui/search-reexport.goml b/tests/rustdoc-gui/search-reexport.goml
index 2e7c967d5c3..fa9eedeceac 100644
--- a/tests/rustdoc-gui/search-reexport.goml
+++ b/tests/rustdoc-gui/search-reexport.goml
@@ -1,8 +1,8 @@
 // Checks that the reexports are present in the search index, can have
 // doc aliases and are highligted when their ID is the hash of the page.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-set-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
-reload:
+call-function: ("switch-theme", {"theme": "dark"})
 // First we check that the reexport has the correct ID and no background color.
 assert-text: ("//*[@id='reexport.TheStdReexport']", "pub use ::std as TheStdReexport;")
 assert-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgba(0, 0, 0, 0)"})
diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml
index 1a19ea2d843..d4da23fa156 100644
--- a/tests/rustdoc-gui/search-result-color.goml
+++ b/tests/rustdoc-gui/search-result-color.goml
@@ -1,5 +1,6 @@
 // The goal of this test is to ensure the color of the text is the one expected.
 
+include: "utils.goml"
 define-function: (
     "check-result-color",
     [result_kind, color, hover_color],
@@ -43,11 +44,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/index.html?search=coo"
 show-text: true
 
 // Ayu theme
-set-local-storage: {
-    "rustdoc-theme": "ayu",
-    "rustdoc-use-system-theme": "false",
-}
-reload:
+call-function: ("switch-theme", {"theme": "ayu"})
 
 // Waiting for the search results to appear...
 wait-for: "#search-tabs"
@@ -155,11 +152,7 @@ assert-css: (
 )
 
 // Dark theme
-set-local-storage: {
-    "rustdoc-theme": "dark",
-    "rustdoc-use-system-theme": "false",
-}
-reload:
+call-function: ("switch-theme", {"theme": "dark"})
 
 // Waiting for the search results to appear...
 wait-for: "#search-tabs"
@@ -255,8 +248,7 @@ assert-css: (
 )
 
 // Light theme
-set-local-storage: {"rustdoc-theme": "light", "rustdoc-use-system-theme": "false"}
-reload:
+call-function: ("switch-theme", {"theme": "light"})
 
 // Waiting for the search results to appear...
 wait-for: "#search-tabs"
@@ -360,8 +352,7 @@ define-function: (
     "check-alias",
     [theme, alias, grey],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         write-into: (".search-input", "thisisanalias")
         // To be SURE that the search will be run.
         press-key: 'Enter'
diff --git a/tests/rustdoc-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml
index b1a5548808e..3ca46f3c569 100644
--- a/tests/rustdoc-gui/search-result-display.goml
+++ b/tests/rustdoc-gui/search-result-display.goml
@@ -1,5 +1,6 @@
 // ignore-tidy-linelength
 // Checks that the search results have the expected width.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 set-window-size: (900, 1000)
 write-into: (".search-input", "test")
@@ -71,8 +72,7 @@ define-function: (
     "check-filter",
     [theme, border, filter, hover_border, hover_filter],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         wait-for: "#crate-search"
         assert-css: ("#crate-search", {"border": "1px solid " + |border|})
         assert-css: ("#crate-search-div::after", {"filter": |filter|})
diff --git a/tests/rustdoc-gui/search-tab.goml b/tests/rustdoc-gui/search-tab.goml
index c33866593c3..4329726398c 100644
--- a/tests/rustdoc-gui/search-tab.goml
+++ b/tests/rustdoc-gui/search-tab.goml
@@ -1,4 +1,5 @@
 // Checking the colors of the search tab headers.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/fn.foo.html?search=foo"
 show-text: true
 
@@ -8,9 +9,7 @@ define-function: (
      border_bottom_selected, border_bottom_hover, border_top, border_top_selected,
      border_top_hover],
     block {
-        // Setting the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         // These two commands are used to be sure the search will be run.
         focus: ".search-input"
diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml
index 0bb21c28cb5..56d0f8624e8 100644
--- a/tests/rustdoc-gui/settings.goml
+++ b/tests/rustdoc-gui/settings.goml
@@ -1,5 +1,6 @@
 // This test ensures that the settings menu display is working as expected and that
 // the settings page is also rendered as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 show-text: true // needed when we check for colors below.
 // First, we check that the settings page doesn't exist.
@@ -35,8 +36,7 @@ wait-for: "#alternative-display #search"
 assert: "#main-content.hidden"
 
 // Now let's check the content of the settings menu.
-set-local-storage: {"rustdoc-theme": "dark", "rustdoc-use-system-theme": "false"}
-reload:
+call-function: ("switch-theme", {"theme": "dark"})
 click: "#settings-menu"
 wait-for: "#settings"
 
diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml
index 0edffc51a81..57c45555a76 100644
--- a/tests/rustdoc-gui/sidebar-links-color.goml
+++ b/tests/rustdoc-gui/sidebar-links-color.goml
@@ -1,4 +1,5 @@
 // This test checks links colors in sidebar before and after hover.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
 
 // This is needed so that the text color is computed.
@@ -13,8 +14,7 @@ define-function: (
         type_hover_background, keyword, keyword_hover, keyword_hover_background,
     ],
     block {
-        set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         // Struct
         assert-css: (
             ".sidebar .block.struct li:not(.current) a",
diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml
index 8843de8d7e9..b4ff483c180 100644
--- a/tests/rustdoc-gui/sidebar-mobile.goml
+++ b/tests/rustdoc-gui/sidebar-mobile.goml
@@ -1,6 +1,7 @@
 // This test ensure that the sidebar isn't "hidden" on mobile but instead moved out of the viewport.
 // This is especially important for devices for "text-first" content (like for users with
 // sight issues).
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
 // Switching to "mobile view" by reducing the width to 600px.
 set-window-size: (600, 600)
@@ -59,7 +60,7 @@ define-function: (
     "check-colors",
     [theme, color, background],
     block {
-        set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
+        call-function: ("switch-theme", {"theme": |theme|})
         reload:
 
         // Open the sidebar menu.
diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml
index 41c8e45f4a6..3bfbe820b8d 100644
--- a/tests/rustdoc-gui/sidebar-source-code-display.goml
+++ b/tests/rustdoc-gui/sidebar-source-code-display.goml
@@ -1,4 +1,5 @@
 // This test ensures that the elements in the sidebar are displayed correctly.
+include: "utils.goml"
 javascript: false
 go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
 // Since the javascript is disabled, there shouldn't be a toggle.
@@ -34,8 +35,7 @@ define-function: (
         theme, color, color_hover, background, background_hover, background_toggle,
     ],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         wait-for-css: (".src .sidebar > *", {"visibility": "visible"})
         assert-css: (
             "#src-sidebar details[open] > .files a.selected",
diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml
index 3f7ef643d18..ef0b5ab38b1 100644
--- a/tests/rustdoc-gui/sidebar-source-code.goml
+++ b/tests/rustdoc-gui/sidebar-source-code.goml
@@ -1,5 +1,6 @@
 // The goal of this test is to ensure that the sidebar is working as expected in the source
 // code pages.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
 show-text: true
 
@@ -8,11 +9,7 @@ define-function: (
     "check-colors",
     [theme, color, background_color],
     block {
-        set-local-storage: {
-            "rustdoc-theme": |theme|,
-            "rustdoc-use-system-theme": "false",
-        }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         // Checking results colors.
         assert-css: (".src .sidebar", {
             "color": |color|,
diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml
index 115b1eb323c..452545958f9 100644
--- a/tests/rustdoc-gui/sidebar.goml
+++ b/tests/rustdoc-gui/sidebar.goml
@@ -1,4 +1,5 @@
 // Checks multiple things on the sidebar display (width of its elements, colors, etc).
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 assert-property: (".sidebar", {"clientWidth": "200"})
 show-text: true
@@ -8,11 +9,7 @@ define-function: (
     "check-colors",
     [theme, color, background_color],
     block {
-        set-local-storage: {
-            "rustdoc-theme": |theme|,
-            "rustdoc-use-system-theme": "false",
-        }
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         // Checking results colors.
         assert-css: (".sidebar", {
             "color": |color|,
@@ -46,9 +43,7 @@ call-function: (
     }
 )
 
-set-local-storage: {"rustdoc-theme": "light"}
-// We reload the page so the local storage settings are being used.
-reload:
+call-function: ("switch-theme", {"theme": "light"})
 
 assert-text: (".sidebar > .sidebar-crate > h2 > a", "test_docs")
 // Crate root has no "location" element
diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml
index e29d123d227..619d2b37d8d 100644
--- a/tests/rustdoc-gui/source-code-page.goml
+++ b/tests/rustdoc-gui/source-code-page.goml
@@ -1,4 +1,5 @@
 // Checks that the interactions with the source code pages are working as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/src/test_docs/lib.rs.html"
 show-text: true
 // Check that we can click on the line number.
@@ -23,8 +24,7 @@ define-function: (
     "check-colors",
     [theme, color, background_color, highlight_color, highlight_background_color],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (
             ".src-line-numbers > a:not(.line-highlighted)",
             {"color": |color|, "background-color": |background_color|},
diff --git a/tests/rustdoc-gui/stab-badge.goml b/tests/rustdoc-gui/stab-badge.goml
index 46df0946c45..3568d7a3e48 100644
--- a/tests/rustdoc-gui/stab-badge.goml
+++ b/tests/rustdoc-gui/stab-badge.goml
@@ -1,12 +1,13 @@
 // All stability badges should have rounded corners and colored backgrounds.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 show-text: true
 define-function: (
     "check-badge",
     [theme, background, color],
     block {
-        set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|}
         go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+        call-function: ("switch-theme", {"theme": |theme|})
         assert: ".docblock .stab"
         assert: ".item-table .stab"
         assert-css: (".stab", {
diff --git a/tests/rustdoc-gui/target.goml b/tests/rustdoc-gui/target.goml
index 0f8f7709363..82bd34ed274 100644
--- a/tests/rustdoc-gui/target.goml
+++ b/tests/rustdoc-gui/target.goml
@@ -1,4 +1,5 @@
 // Check that the targeted element has the expected styles.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/lib2/struct.Foo.html#method.a_method"
 show-text: true
 
@@ -9,8 +10,7 @@ define-function: (
     "check-style",
     [theme, background, border],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: ("#method\.a_method:target", {
             "background-color": |background|,
             "border-right": "3px solid " + |border|,
diff --git a/tests/rustdoc-gui/theme-change.goml b/tests/rustdoc-gui/theme-change.goml
index fdaf9d6289a..58987110509 100644
--- a/tests/rustdoc-gui/theme-change.goml
+++ b/tests/rustdoc-gui/theme-change.goml
@@ -1,7 +1,7 @@
 // Ensures that the theme change is working as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
-set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
-reload:
+call-function: ("switch-theme", {"theme": "dark"})
 
 store-value: (background_light, "white")
 store-value: (background_dark, "#353535")
@@ -68,8 +68,7 @@ assert: "#preferred-light-theme.setting-line.hidden"
 
 // Ensures that the custom theme feature is working as expected.
 go-to: "file://" + |DOC_PATH| + "/theme_css/index.html"
-set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": "dark"}
-reload:
+call-function: ("switch-theme", {"theme": "dark"})
 
 store-value: (background_light, "white")
 store-value: (background_dark, "#353535")
diff --git a/tests/rustdoc-gui/theme-in-history.goml b/tests/rustdoc-gui/theme-in-history.goml
index 42c5b5e6e69..71cc64ac600 100644
--- a/tests/rustdoc-gui/theme-in-history.goml
+++ b/tests/rustdoc-gui/theme-in-history.goml
@@ -1,12 +1,10 @@
 // Ensures that the theme is working when going back in history.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
+
 // Set the theme to dark.
-set-local-storage: {
-    "rustdoc-theme": "dark",
-    "rustdoc-use-system-theme": "false",
-}
-// We reload the page so the local storage settings are being used.
-reload:
+call-function: ("switch-theme", {"theme": "dark"})
+
 assert-css: ("body", { "background-color": "#353535" })
 assert-local-storage: { "rustdoc-theme": "dark" }
 
diff --git a/tests/rustdoc-gui/toggle-docs.goml b/tests/rustdoc-gui/toggle-docs.goml
index cfd18bd2e14..1235ee4b754 100644
--- a/tests/rustdoc-gui/toggle-docs.goml
+++ b/tests/rustdoc-gui/toggle-docs.goml
@@ -1,4 +1,5 @@
 // Checks that the documentation toggles have the correct position, style and work as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 assert-attribute: ("#main-content > details.top-doc", {"open": ""})
 assert-text: ("#toggle-all-docs", "[−]")
@@ -51,10 +52,7 @@ define-function: (
     "check-color",
     [theme, filter],
     block {
-        // Setting the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        // We reload the page so the local storage settings are being used.
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         assert-css: ("details.toggle > summary::before", {
             "opacity": "0.5",
diff --git a/tests/rustdoc-gui/unsafe-fn.goml b/tests/rustdoc-gui/unsafe-fn.goml
index 83503121a04..b8b2e1e27f5 100644
--- a/tests/rustdoc-gui/unsafe-fn.goml
+++ b/tests/rustdoc-gui/unsafe-fn.goml
@@ -1,4 +1,5 @@
 // Check position and color of the `<sup>` for unsafe elements.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
 // If the text isn't displayed, the browser doesn't compute color style correctly...
 show-text: true
@@ -15,10 +16,7 @@ define-function: (
     // `color` is the expected color of the `<sup>` element.
     [theme, color],
     block {
-        // Set the theme.
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        // We reload the page so the local storage settings are being used.
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
         assert-css: (".item-name sup", {"color": |color|})
     },
 )
diff --git a/tests/rustdoc-gui/utils.goml b/tests/rustdoc-gui/utils.goml
new file mode 100644
index 00000000000..d9f8726ec53
--- /dev/null
+++ b/tests/rustdoc-gui/utils.goml
@@ -0,0 +1,11 @@
+// This file contains code to be re-used by other tests.
+define-function: (
+    "switch-theme",
+    [theme],
+    block {
+        // Set the theme.
+        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
+        // We reload the page so the local storage settings are being used.
+        reload:
+    },
+)
diff --git a/tests/rustdoc-gui/warning-block.goml b/tests/rustdoc-gui/warning-block.goml
index a5a47f868db..34207ed5805 100644
--- a/tests/rustdoc-gui/warning-block.goml
+++ b/tests/rustdoc-gui/warning-block.goml
@@ -1,4 +1,5 @@
 // Test to check that the "warning blocks" are displayed as expected.
+include: "utils.goml"
 go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html"
 show-text: true
 
@@ -7,8 +8,7 @@ define-function: (
     "check-warning",
     [theme, color, border_color],
     block {
-        set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"}
-        reload:
+        call-function: ("switch-theme", {"theme": |theme|})
 
         // The IDs are added directly into the DOM to make writing this test easier.
         assert-css: ("#doc-warning-1", {
diff --git a/tests/ui/abi/extern/extern-pass-FiveU16s.rs b/tests/ui/abi/extern/extern-pass-FiveU16s.rs
new file mode 100644
index 00000000000..5f1307beb28
--- /dev/null
+++ b/tests/ui/abi/extern/extern-pass-FiveU16s.rs
@@ -0,0 +1,30 @@
+//@ run-pass
+#![allow(improper_ctypes)]
+
+// Test a foreign function that accepts and returns a struct by value.
+
+// FiveU16s in particular is interesting because it is larger than a single 64 bit or 32 bit
+// register, which are used as cast destinations on some targets, but does not evenly divide those
+// sizes, causing there to be padding in the last element.
+
+#[derive(Copy, Clone, PartialEq, Debug)]
+pub struct FiveU16s {
+    one: u16,
+    two: u16,
+    three: u16,
+    four: u16,
+    five: u16,
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    pub fn rust_dbg_extern_identity_FiveU16s(v: FiveU16s) -> FiveU16s;
+}
+
+pub fn main() {
+    unsafe {
+        let x = FiveU16s { one: 22, two: 23, three: 24, four: 25, five: 26 };
+        let y = rust_dbg_extern_identity_FiveU16s(x);
+        assert_eq!(x, y);
+    }
+}
diff --git a/tests/ui/abi/extern/extern-return-FiveU16s.rs b/tests/ui/abi/extern/extern-return-FiveU16s.rs
new file mode 100644
index 00000000000..d8ae8b2661c
--- /dev/null
+++ b/tests/ui/abi/extern/extern-return-FiveU16s.rs
@@ -0,0 +1,26 @@
+//@ run-pass
+#![allow(improper_ctypes)]
+
+pub struct FiveU16s {
+    one: u16,
+    two: u16,
+    three: u16,
+    four: u16,
+    five: u16,
+}
+
+#[link(name = "rust_test_helpers", kind = "static")]
+extern "C" {
+    pub fn rust_dbg_extern_return_FiveU16s() -> FiveU16s;
+}
+
+pub fn main() {
+    unsafe {
+        let y = rust_dbg_extern_return_FiveU16s();
+        assert_eq!(y.one, 10);
+        assert_eq!(y.two, 20);
+        assert_eq!(y.three, 30);
+        assert_eq!(y.four, 40);
+        assert_eq!(y.five, 50);
+    }
+}
diff --git a/tests/ui/asm/x86_64/goto.mirunsafeck.stderr b/tests/ui/asm/x86_64/goto.mirunsafeck.stderr
deleted file mode 100644
index fe189c14f0a..00000000000
--- a/tests/ui/asm/x86_64/goto.mirunsafeck.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-warning: unreachable statement
-  --> $DIR/goto.rs:99:9
-   |
-LL | /         asm!(
-LL | |             "jmp {}",
-LL | |             label {
-LL | |                 return;
-LL | |             },
-LL | |             options(noreturn)
-LL | |         );
-   | |_________- any code following this expression is unreachable
-LL |           unreachable!();
-   |           ^^^^^^^^^^^^^^ unreachable statement
-   |
-note: the lint level is defined here
-  --> $DIR/goto.rs:89:8
-   |
-LL | #[warn(unreachable_code)]
-   |        ^^^^^^^^^^^^^^^^
-   = note: this warning originates in the macro `unreachable` (in Nightly builds, run with -Z macro-backtrace for more info)
-
-warning: 1 warning emitted
-
diff --git a/tests/ui/asm/x86_64/goto.rs b/tests/ui/asm/x86_64/goto.rs
index 6a567efbb2c..6c14bb57ac6 100644
--- a/tests/ui/asm/x86_64/goto.rs
+++ b/tests/ui/asm/x86_64/goto.rs
@@ -1,8 +1,6 @@
 //@ only-x86_64
 //@ run-pass
 //@ needs-asm-support
-//@ revisions: mirunsafeck thirunsafeck
-//@ [thirunsafeck]compile-flags: -Z thir-unsafeck
 
 #![deny(unreachable_code)]
 #![feature(asm_goto)]
diff --git a/tests/ui/asm/x86_64/goto.thirunsafeck.stderr b/tests/ui/asm/x86_64/goto.stderr
index fe189c14f0a..27e227d71a5 100644
--- a/tests/ui/asm/x86_64/goto.thirunsafeck.stderr
+++ b/tests/ui/asm/x86_64/goto.stderr
@@ -1,5 +1,5 @@
 warning: unreachable statement
-  --> $DIR/goto.rs:99:9
+  --> $DIR/goto.rs:97:9
    |
 LL | /         asm!(
 LL | |             "jmp {}",
@@ -13,7 +13,7 @@ LL |           unreachable!();
    |           ^^^^^^^^^^^^^^ unreachable statement
    |
 note: the lint level is defined here
-  --> $DIR/goto.rs:89:8
+  --> $DIR/goto.rs:87:8
    |
 LL | #[warn(unreachable_code)]
    |        ^^^^^^^^^^^^^^^^
diff --git a/tests/ui/async-await/async-closures/captures.rs b/tests/ui/async-await/async-closures/captures.rs
new file mode 100644
index 00000000000..0a9d0529bf5
--- /dev/null
+++ b/tests/ui/async-await/async-closures/captures.rs
@@ -0,0 +1,116 @@
+//@ aux-build:block-on.rs
+//@ edition:2021
+//@ run-pass
+//@ check-run-results
+
+// Same as miri's `tests/pass/async-closure-captures.rs`, keep in sync
+
+#![feature(async_closure)]
+
+extern crate block_on;
+
+fn main() {
+    block_on::block_on(async_main());
+}
+
+async fn call<T>(f: &impl async Fn() -> T) -> T {
+    f().await
+}
+
+async fn call_once<T>(f: impl async FnOnce() -> T) -> T {
+    f().await
+}
+
+#[derive(Debug)]
+#[allow(unused)]
+struct Hello(i32);
+
+async fn async_main() {
+    // Capture something by-ref
+    {
+        let x = Hello(0);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(1);
+        let c = async || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something and consume it (force to `AsyncFnOnce`)
+    {
+        let x = Hello(2);
+        let c = async || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, don't consume it
+    {
+        let x = Hello(3);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+
+        let x = &Hello(4);
+        let c = async move || {
+            println!("{x:?}");
+        };
+        call(&c).await;
+        call_once(c).await;
+    }
+
+    // Capture something with `move`, also consume it (so `AsyncFnOnce`)
+    {
+        let x = Hello(5);
+        let c = async move || {
+            println!("{x:?}");
+            drop(x);
+        };
+        call_once(c).await;
+    }
+
+    fn force_fnonce<T>(f: impl async FnOnce() -> T) -> impl async FnOnce() -> T {
+        f
+    }
+
+    // Capture something with `move`, but infer to `AsyncFnOnce`
+    {
+        let x = Hello(6);
+        let c = force_fnonce(async move || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+
+        let x = &Hello(7);
+        let c = force_fnonce(async move || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+    }
+
+    // Capture something by-ref, but infer to `AsyncFnOnce`
+    {
+        let x = Hello(8);
+        let c = force_fnonce(async || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+
+        let x = &Hello(9);
+        let c = force_fnonce(async || {
+            println!("{x:?}");
+        });
+        call_once(c).await;
+    }
+}
diff --git a/tests/ui/async-await/async-closures/captures.run.stdout b/tests/ui/async-await/async-closures/captures.run.stdout
new file mode 100644
index 00000000000..42a7999b2dc
--- /dev/null
+++ b/tests/ui/async-await/async-closures/captures.run.stdout
@@ -0,0 +1,14 @@
+Hello(0)
+Hello(0)
+Hello(1)
+Hello(1)
+Hello(2)
+Hello(3)
+Hello(3)
+Hello(4)
+Hello(4)
+Hello(5)
+Hello(6)
+Hello(7)
+Hello(8)
+Hello(9)
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.rs b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
index 8502bb6e2d4..3d6f856874f 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.rs
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
@@ -2,18 +2,22 @@
 
 #![feature(async_closure)]
 
-fn main() {
-    fn needs_async_fn(_: impl async Fn()) {}
+fn needs_async_fn(_: impl async Fn()) {}
 
+fn a() {
     let mut x = 1;
     needs_async_fn(async || {
-        //~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
+        //~^ ERROR cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
         x += 1;
     });
+}
 
+fn b() {
     let x = String::new();
     needs_async_fn(move || async move {
         //~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
         println!("{x}");
     });
 }
+
+fn main() {}
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
index d0f1948e48f..e56389b3202 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
@@ -1,26 +1,5 @@
-error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
-  --> $DIR/wrong-fn-kind.rs:9:20
-   |
-LL |       needs_async_fn(async || {
-   |       -------------- -^^^^^^^
-   |       |              |
-   |  _____|______________this closure implements `async FnMut`, not `async Fn`
-   | |     |
-   | |     required by a bound introduced by this call
-LL | |
-LL | |         x += 1;
-   | |         - closure is `async FnMut` because it mutates the variable `x` here
-LL | |     });
-   | |_____- the requirement to implement `async Fn` derives from here
-   |
-note: required by a bound in `needs_async_fn`
-  --> $DIR/wrong-fn-kind.rs:6:31
-   |
-LL |     fn needs_async_fn(_: impl async Fn()) {}
-   |                               ^^^^^^^^^^ required by this bound in `needs_async_fn`
-
 error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
-  --> $DIR/wrong-fn-kind.rs:15:20
+  --> $DIR/wrong-fn-kind.rs:17:20
    |
 LL |       needs_async_fn(move || async move {
    |       -------------- -^^^^^^
@@ -35,11 +14,29 @@ LL | |     });
    | |_____- the requirement to implement `async Fn` derives from here
    |
 note: required by a bound in `needs_async_fn`
-  --> $DIR/wrong-fn-kind.rs:6:31
+  --> $DIR/wrong-fn-kind.rs:5:27
+   |
+LL | fn needs_async_fn(_: impl async Fn()) {}
+   |                           ^^^^^^^^^^ required by this bound in `needs_async_fn`
+
+error[E0596]: cannot borrow `x` as mutable, as it is a captured variable in a `Fn` closure
+  --> $DIR/wrong-fn-kind.rs:9:29
    |
-LL |     fn needs_async_fn(_: impl async Fn()) {}
-   |                               ^^^^^^^^^^ required by this bound in `needs_async_fn`
+LL |   fn needs_async_fn(_: impl async Fn()) {}
+   |                        --------------- change this to accept `FnMut` instead of `Fn`
+...
+LL |       needs_async_fn(async || {
+   |  _____--------------_--------_^
+   | |     |              |
+   | |     |              in this closure
+   | |     expects `Fn` instead of `FnMut`
+LL | |
+LL | |         x += 1;
+   | |         - mutable borrow occurs due to use of `x` in closure
+LL | |     });
+   | |_____^ cannot borrow as mutable
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0525`.
+Some errors have detailed explanations: E0525, E0596.
+For more information about an error, try `rustc --explain E0525`.
diff --git a/tests/ui/async-await/coroutine-desc.stderr b/tests/ui/async-await/coroutine-desc.stderr
index e4cb0915a10..1f1e303ea4c 100644
--- a/tests/ui/async-await/coroutine-desc.stderr
+++ b/tests/ui/async-await/coroutine-desc.stderr
@@ -5,6 +5,7 @@ LL |     fun(async {}, async {});
    |     --- --------  ^^^^^^^^ expected `async` block, found a different `async` block
    |     |   |
    |     |   the expected `async` block
+   |     |   expected all arguments to be this `async` block type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected `async` block `{async block@$DIR/coroutine-desc.rs:10:9: 10:17}`
@@ -13,14 +14,18 @@ note: function defined here
   --> $DIR/coroutine-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                                -----
+   |    ^^^ -                       -----  ----- this parameter needs to match the `async` block type of `f1`
+   |        |                       |
+   |        |                       `f2` needs to match the `async` block type of this parameter
+   |        `f1` and `f2` all reference this parameter F
 
 error[E0308]: mismatched types
   --> $DIR/coroutine-desc.rs:12:16
    |
 LL |     fun(one(), two());
-   |     ---        ^^^^^ expected future, found a different future
-   |     |
+   |     --- -----  ^^^^^ expected future, found a different future
+   |     |   |
+   |     |   expected all arguments to be this future type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = help: consider `await`ing on both `Future`s
@@ -29,15 +34,19 @@ note: function defined here
   --> $DIR/coroutine-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                                -----
+   |    ^^^ -                       -----  ----- this parameter needs to match the future type of `f1`
+   |        |                       |
+   |        |                       `f2` needs to match the future type of this parameter
+   |        `f1` and `f2` all reference this parameter F
 
 error[E0308]: mismatched types
   --> $DIR/coroutine-desc.rs:14:26
    |
 LL |     fun((async || {})(), (async || {})());
-   |     ---           --     ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
-   |     |             |
-   |     |             the expected `async` closure body
+   |     --- ---------------  ^^^^^^^^^^^^^^^ expected `async` closure body, found a different `async` closure body
+   |     |   |         |
+   |     |   |         the expected `async` closure body
+   |     |   expected all arguments to be this `async` closure body type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected `async` closure body `{async closure body@$DIR/coroutine-desc.rs:14:19: 14:21}`
@@ -46,7 +55,10 @@ note: function defined here
   --> $DIR/coroutine-desc.rs:8:4
    |
 LL | fn fun<F: Future<Output = ()>>(f1: F, f2: F) {}
-   |    ^^^                                -----
+   |    ^^^ -                       -----  ----- this parameter needs to match the `async` closure body type of `f1`
+   |        |                       |
+   |        |                       `f2` needs to match the `async` closure body type of this parameter
+   |        `f1` and `f2` all reference this parameter F
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index cf18503b74b..31553371101 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -190,7 +190,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_os = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -263,7 +263,7 @@ LL | #[cfg(target_os = "linuz")] // testing that we suggest `linux`
    |                   |
    |                   help: there is a expected value with a similar name: `"linux"`
    |
-   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm`
+   = note: expected values for `target_os` are: `aix`, `android`, `cuda`, `dragonfly`, `emscripten`, `espidf`, `freebsd`, `fuchsia`, `haiku`, `hermit`, `horizon`, `hurd`, `illumos`, `ios`, `l4re`, `linux`, `macos`, `netbsd`, `none`, `nto`, `openbsd`, `psp`, `redox`, `solaris`, `solid_asp3`, `teeos`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/unstable-book/compiler-flags/check-cfg.html> for more information about checking conditional configuration
 
 warning: 27 warnings emitted
diff --git a/tests/ui/issues/issue-1460.rs b/tests/ui/closures/issue-1460.rs
index c201f026bca..c201f026bca 100644
--- a/tests/ui/issues/issue-1460.rs
+++ b/tests/ui/closures/issue-1460.rs
diff --git a/tests/ui/issues/issue-1460.stderr b/tests/ui/closures/issue-1460.stderr
index d4a8c8955e2..d4a8c8955e2 100644
--- a/tests/ui/issues/issue-1460.stderr
+++ b/tests/ui/closures/issue-1460.stderr
diff --git a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
index 498ef33d52e..46723c5a297 100644
--- a/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
+++ b/tests/ui/coercion/coerce-reborrow-multi-arg-fail.stderr
@@ -2,8 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/coerce-reborrow-multi-arg-fail.rs:4:18
    |
 LL |     test(&mut 7, &7);
-   |     ----         ^^ types differ in mutability
-   |     |
+   |     ---- ------  ^^ types differ in mutability
+   |     |    |
+   |     |    expected all arguments to be this `&mut {integer}` type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected mutable reference `&mut {integer}`
@@ -12,7 +13,10 @@ note: function defined here
   --> $DIR/coerce-reborrow-multi-arg-fail.rs:1:4
    |
 LL | fn test<T>(_a: T, _b: T) {}
-   |    ^^^^           -----
+   |    ^^^^ -  -----  ----- this parameter needs to match the `&mut {integer}` type of `_a`
+   |         |  |
+   |         |  `_b` needs to match the `&mut {integer}` type of this parameter
+   |         `_a` and `_b` all reference this parameter T
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr
new file mode 100644
index 00000000000..5eef3256b2c
--- /dev/null
+++ b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr
@@ -0,0 +1,27 @@
+error[E0726]: implicit elided lifetime not allowed here
+  --> $DIR/skip-reporting-if-references-err.rs:10:9
+   |
+LL | impl<T> ToUnit for T {}
+   |         ^^^^^^ expected lifetime parameter
+   |
+help: indicate the anonymous lifetime
+   |
+LL | impl<T> ToUnit<'_> for T {}
+   |               ++++
+
+error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
+  --> $DIR/skip-reporting-if-references-err.rs:15:29
+   |
+LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {}
+   |                             ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()`
+
+error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
+  --> $DIR/skip-reporting-if-references-err.rs:15:18
+   |
+LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {}
+   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0726.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/coherence/skip-reporting-if-references-err.next.stderr b/tests/ui/coherence/skip-reporting-if-references-err.next.stderr
new file mode 100644
index 00000000000..5de4cf626e4
--- /dev/null
+++ b/tests/ui/coherence/skip-reporting-if-references-err.next.stderr
@@ -0,0 +1,14 @@
+error[E0726]: implicit elided lifetime not allowed here
+  --> $DIR/skip-reporting-if-references-err.rs:10:9
+   |
+LL | impl<T> ToUnit for T {}
+   |         ^^^^^^ expected lifetime parameter
+   |
+help: indicate the anonymous lifetime
+   |
+LL | impl<T> ToUnit<'_> for T {}
+   |               ++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0726`.
diff --git a/tests/ui/coherence/skip-reporting-if-references-err.rs b/tests/ui/coherence/skip-reporting-if-references-err.rs
new file mode 100644
index 00000000000..f9eaa498232
--- /dev/null
+++ b/tests/ui/coherence/skip-reporting-if-references-err.rs
@@ -0,0 +1,19 @@
+// Regression test for #121006.
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
+//@[next] compile-flags: -Znext-solver
+
+trait ToUnit<'a> {
+    type Unit;
+}
+
+impl<T> ToUnit for T {}
+//~^ ERROR implicit elided lifetime not allowed here
+
+trait Overlap {}
+impl<U> Overlap for fn(U) {}
+impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {}
+//[current]~^ ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
+//[current]~| ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
+
+fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.rs b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
new file mode 100644
index 00000000000..56b8acbf88c
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.rs
@@ -0,0 +1,18 @@
+#![feature(generic_const_exprs, type_alias_impl_trait)]
+#![allow(incomplete_features)]
+
+type Foo = impl Sized;
+
+fn with_bound<const N: usize>() -> Foo
+where
+    [u8; (N / 2) as usize]: Sized,
+{
+    let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
+    //~^ ERROR mismatched types
+    //~| ERROR non-primitive cast: `usize` as `Foo`
+    todo!()
+}
+
+fn main() {
+    with_bound::<4>();
+}
diff --git a/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
new file mode 100644
index 00000000000..e9fb8c0f403
--- /dev/null
+++ b/tests/ui/const-generics/generic_const_exprs/opaque_type.stderr
@@ -0,0 +1,22 @@
+error[E0308]: mismatched types
+  --> $DIR/opaque_type.rs:10:17
+   |
+LL | type Foo = impl Sized;
+   |            ---------- the found opaque type
+...
+LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
+   |                 ^^^^^^^^^^^^^^ expected `usize`, found opaque type
+   |
+   = note:     expected type `usize`
+           found opaque type `Foo`
+
+error[E0605]: non-primitive cast: `usize` as `Foo`
+  --> $DIR/opaque_type.rs:10:17
+   |
+LL |     let _: [u8; (N / 2) as Foo] = [0; (N / 2) as usize];
+   |                 ^^^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0308, E0605.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/opaque_types.rs b/tests/ui/const-generics/opaque_types.rs
new file mode 100644
index 00000000000..ccf70f4fb37
--- /dev/null
+++ b/tests/ui/const-generics/opaque_types.rs
@@ -0,0 +1,13 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Sized;
+//~^ ERROR: cycle
+//~| ERROR: cycle
+
+fn foo<const C: Foo>() {}
+//~^ ERROR: `Foo` is forbidden as the type of a const generic parameter
+
+fn main() {
+    foo::<42>();
+    //~^ ERROR: mismatched types
+}
diff --git a/tests/ui/const-generics/opaque_types.stderr b/tests/ui/const-generics/opaque_types.stderr
new file mode 100644
index 00000000000..f03bca69a8b
--- /dev/null
+++ b/tests/ui/const-generics/opaque_types.stderr
@@ -0,0 +1,125 @@
+error[E0308]: mismatched types
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL | type Foo = impl Sized;
+   |            ---------- the expected opaque type
+...
+LL |     foo::<42>();
+   |           ^^ expected opaque type, found integer
+   |
+   = note: expected opaque type `Foo`
+                     found type `{integer}`
+
+error[E0391]: cycle detected when computing type of `Foo::{opaque#0}`
+  --> $DIR/opaque_types.rs:3:12
+   |
+LL | type Foo = impl Sized;
+   |            ^^^^^^^^^^
+   |
+note: ...which requires computing type of opaque `Foo::{opaque#0}`...
+  --> $DIR/opaque_types.rs:3:12
+   |
+LL | type Foo = impl Sized;
+   |            ^^^^^^^^^^
+note: ...which requires type-checking `main`...
+  --> $DIR/opaque_types.rs:10:1
+   |
+LL | fn main() {
+   | ^^^^^^^^^
+note: ...which requires evaluating type-level constant...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires const-evaluating + checking `main::{constant#0}`...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires caching mir of `main::{constant#0}` for CTFE...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires elaborating drops for `main::{constant#0}`...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+   = note: ...which requires normalizing `Foo`...
+   = note: ...which again requires computing type of `Foo::{opaque#0}`, completing the cycle
+note: cycle used when checking that `Foo::{opaque#0}` is well-formed
+  --> $DIR/opaque_types.rs:3:12
+   |
+LL | type Foo = impl Sized;
+   |            ^^^^^^^^^^
+   = 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: `Foo` is forbidden as the type of a const generic parameter
+  --> $DIR/opaque_types.rs:7:17
+   |
+LL | fn foo<const C: Foo>() {}
+   |                 ^^^
+   |
+   = note: the only supported types are integers, `bool` and `char`
+
+error[E0391]: cycle detected when computing type of opaque `Foo::{opaque#0}`
+  --> $DIR/opaque_types.rs:3:12
+   |
+LL | type Foo = impl Sized;
+   |            ^^^^^^^^^^
+   |
+note: ...which requires type-checking `main`...
+  --> $DIR/opaque_types.rs:10:1
+   |
+LL | fn main() {
+   | ^^^^^^^^^
+note: ...which requires evaluating type-level constant...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires const-evaluating + checking `main::{constant#0}`...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires caching mir of `main::{constant#0}` for CTFE...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires elaborating drops for `main::{constant#0}`...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires borrow-checking `main::{constant#0}`...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires promoting constants in MIR for `main::{constant#0}`...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+note: ...which requires const checking `main::{constant#0}`...
+  --> $DIR/opaque_types.rs:11:11
+   |
+LL |     foo::<42>();
+   |           ^^
+   = note: ...which requires computing whether `Foo` is freeze...
+   = note: ...which requires evaluating trait selection obligation `Foo: core::marker::Freeze`...
+   = note: ...which again requires computing type of opaque `Foo::{opaque#0}`, completing the cycle
+note: cycle used when computing type of `Foo::{opaque#0}`
+  --> $DIR/opaque_types.rs:3:12
+   |
+LL | type Foo = impl Sized;
+   |            ^^^^^^^^^^
+   = 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 4 previous errors
+
+Some errors have detailed explanations: E0308, E0391.
+For more information about an error, try `rustc --explain E0308`.
diff --git a/tests/ui/const-generics/opaque_types2.rs b/tests/ui/const-generics/opaque_types2.rs
new file mode 100644
index 00000000000..fd57438bb61
--- /dev/null
+++ b/tests/ui/const-generics/opaque_types2.rs
@@ -0,0 +1,17 @@
+#![feature(type_alias_impl_trait)]
+
+type Foo = impl Sized;
+
+fn foo<const C: u32>() {}
+
+const C: Foo = 42;
+
+fn bar()
+where
+    Foo:,
+{
+    foo::<C>();
+    //~^ ERROR: mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/const-generics/opaque_types2.stderr b/tests/ui/const-generics/opaque_types2.stderr
new file mode 100644
index 00000000000..2fb1669b7bf
--- /dev/null
+++ b/tests/ui/const-generics/opaque_types2.stderr
@@ -0,0 +1,15 @@
+error[E0308]: mismatched types
+  --> $DIR/opaque_types2.rs:13:11
+   |
+LL | type Foo = impl Sized;
+   |            ---------- the found opaque type
+...
+LL |     foo::<C>();
+   |           ^ expected `u32`, found opaque type
+   |
+   = note:     expected type `u32`
+           found opaque type `Foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/extern/issue-95829.stderr b/tests/ui/extern/issue-95829.stderr
index b902f0ef8f5..16504d1f0c9 100644
--- a/tests/ui/extern/issue-95829.stderr
+++ b/tests/ui/extern/issue-95829.stderr
@@ -16,17 +16,12 @@ LL | |     }
    = note: for more information, visit https://doc.rust-lang.org/std/keyword.extern.html
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/issue-95829.rs:4:14
+  --> $DIR/issue-95829.rs:4:5
    |
 LL | extern {
    | ------ in this `extern` block
 LL |     async fn L() {
-   |              ^
-   |
-help: remove the qualifiers
-   |
-LL |     fn L() {
-   |     ~~
+   |     ^^^^^ help: remove this qualifier
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/feature-gates/feature-gate-f128.stderr b/tests/ui/feature-gates/feature-gate-f128.e2015.stderr
index 299375c9aed..771aee79dce 100644
--- a/tests/ui/feature-gates/feature-gate-f128.stderr
+++ b/tests/ui/feature-gates/feature-gate-f128.e2015.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:3:10
+  --> $DIR/feature-gate-f128.rs:7:10
    |
 LL | const A: f128 = 10.0;
    |          ^^^^
@@ -9,7 +9,7 @@ LL | const A: f128 = 10.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:6:12
+  --> $DIR/feature-gate-f128.rs:10:12
    |
 LL |     let a: f128 = 100.0;
    |            ^^^^
@@ -19,7 +19,7 @@ LL |     let a: f128 = 100.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:11:11
+  --> $DIR/feature-gate-f128.rs:15:11
    |
 LL | fn foo(a: f128) {}
    |           ^^^^
@@ -29,7 +29,7 @@ LL | fn foo(a: f128) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:14:8
+  --> $DIR/feature-gate-f128.rs:18:8
    |
 LL |     a: f128,
    |        ^^^^
@@ -39,7 +39,7 @@ LL |     a: f128,
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f128` is unstable
-  --> $DIR/feature-gate-f128.rs:7:13
+  --> $DIR/feature-gate-f128.rs:11:13
    |
 LL |     let b = 0.0f128;
    |             ^^^^^^^
diff --git a/tests/ui/feature-gates/feature-gate-f128.e2018.stderr b/tests/ui/feature-gates/feature-gate-f128.e2018.stderr
new file mode 100644
index 00000000000..771aee79dce
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-f128.e2018.stderr
@@ -0,0 +1,53 @@
+error[E0658]: the type `f128` is unstable
+  --> $DIR/feature-gate-f128.rs:7:10
+   |
+LL | const A: f128 = 10.0;
+   |          ^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f128)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f128` is unstable
+  --> $DIR/feature-gate-f128.rs:10:12
+   |
+LL |     let a: f128 = 100.0;
+   |            ^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f128)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f128` is unstable
+  --> $DIR/feature-gate-f128.rs:15:11
+   |
+LL | fn foo(a: f128) {}
+   |           ^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f128)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f128` is unstable
+  --> $DIR/feature-gate-f128.rs:18:8
+   |
+LL |     a: f128,
+   |        ^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f128)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f128` is unstable
+  --> $DIR/feature-gate-f128.rs:11:13
+   |
+LL |     let b = 0.0f128;
+   |             ^^^^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f128)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-f128.rs b/tests/ui/feature-gates/feature-gate-f128.rs
index 7f60fb6afa0..d25b6dde4ee 100644
--- a/tests/ui/feature-gates/feature-gate-f128.rs
+++ b/tests/ui/feature-gates/feature-gate-f128.rs
@@ -1,3 +1,7 @@
+//@ revisions: e2015 e2018
+//
+//@[e2018] edition:2018
+
 #![allow(unused)]
 
 const A: f128 = 10.0; //~ ERROR the type `f128` is unstable
diff --git a/tests/ui/feature-gates/feature-gate-f16.stderr b/tests/ui/feature-gates/feature-gate-f16.e2015.stderr
index e54b54a47bd..2bb3b59465a 100644
--- a/tests/ui/feature-gates/feature-gate-f16.stderr
+++ b/tests/ui/feature-gates/feature-gate-f16.e2015.stderr
@@ -1,5 +1,5 @@
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:3:10
+  --> $DIR/feature-gate-f16.rs:7:10
    |
 LL | const A: f16 = 10.0;
    |          ^^^
@@ -9,7 +9,7 @@ LL | const A: f16 = 10.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:6:12
+  --> $DIR/feature-gate-f16.rs:10:12
    |
 LL |     let a: f16 = 100.0;
    |            ^^^
@@ -19,7 +19,7 @@ LL |     let a: f16 = 100.0;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:11:11
+  --> $DIR/feature-gate-f16.rs:15:11
    |
 LL | fn foo(a: f16) {}
    |           ^^^
@@ -29,7 +29,7 @@ LL | fn foo(a: f16) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:14:8
+  --> $DIR/feature-gate-f16.rs:18:8
    |
 LL |     a: f16,
    |        ^^^
@@ -39,7 +39,7 @@ LL |     a: f16,
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: the type `f16` is unstable
-  --> $DIR/feature-gate-f16.rs:7:13
+  --> $DIR/feature-gate-f16.rs:11:13
    |
 LL |     let b = 0.0f16;
    |             ^^^^^^
diff --git a/tests/ui/feature-gates/feature-gate-f16.e2018.stderr b/tests/ui/feature-gates/feature-gate-f16.e2018.stderr
new file mode 100644
index 00000000000..2bb3b59465a
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-f16.e2018.stderr
@@ -0,0 +1,53 @@
+error[E0658]: the type `f16` is unstable
+  --> $DIR/feature-gate-f16.rs:7:10
+   |
+LL | const A: f16 = 10.0;
+   |          ^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f16)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f16` is unstable
+  --> $DIR/feature-gate-f16.rs:10:12
+   |
+LL |     let a: f16 = 100.0;
+   |            ^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f16)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f16` is unstable
+  --> $DIR/feature-gate-f16.rs:15:11
+   |
+LL | fn foo(a: f16) {}
+   |           ^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f16)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f16` is unstable
+  --> $DIR/feature-gate-f16.rs:18:8
+   |
+LL |     a: f16,
+   |        ^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f16)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error[E0658]: the type `f16` is unstable
+  --> $DIR/feature-gate-f16.rs:11:13
+   |
+LL |     let b = 0.0f16;
+   |             ^^^^^^
+   |
+   = note: see issue #116909 <https://github.com/rust-lang/rust/issues/116909> for more information
+   = help: add `#![feature(f16)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-f16.rs b/tests/ui/feature-gates/feature-gate-f16.rs
index 31d8f87f3ba..af906d71f5f 100644
--- a/tests/ui/feature-gates/feature-gate-f16.rs
+++ b/tests/ui/feature-gates/feature-gate-f16.rs
@@ -1,3 +1,7 @@
+//@ revisions: e2015 e2018
+//
+//@[e2018] edition:2018
+
 #![allow(unused)]
 
 const A: f16 = 10.0; //~ ERROR the type `f16` is unstable
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
deleted file mode 100644
index 03071c351a4..00000000000
--- a/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.rs
+++ /dev/null
@@ -1,10 +0,0 @@
-//@ 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
deleted file mode 100644
index c14d19381c8..00000000000
--- a/tests/ui/feature-gates/feature-gate-proc_macro_byte_character.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-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
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs b/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs
deleted file mode 100644
index 1750fe952f5..00000000000
--- a/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs
+++ /dev/null
@@ -1,11 +0,0 @@
-//@ edition: 2021
-//@ force-host
-#![crate_type = "proc-macro"]
-
-extern crate proc_macro;
-
-use proc_macro::Literal;
-
-fn test() {
-    Literal::c_string(c"a"); //~ ERROR use of unstable library feature 'proc_macro_c_str_literals'
-}
diff --git a/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr b/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr
deleted file mode 100644
index 9bba1d50ce3..00000000000
--- a/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0658]: use of unstable library feature 'proc_macro_c_str_literals'
-  --> $DIR/feature-gate-proc_macro_c_str_literals.rs:10:5
-   |
-LL |     Literal::c_string(c"a");
-   |     ^^^^^^^^^^^^^^^^^
-   |
-   = note: see issue #119750 <https://github.com/rust-lang/rust/issues/119750> for more information
-   = help: add `#![feature(proc_macro_c_str_literals)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs b/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs
new file mode 100644
index 00000000000..ed5db56e0e8
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.rs
@@ -0,0 +1,14 @@
+pub fn main() {
+    if let Some(Some(&x)) = &Some(&Some(0)) {
+        //~^ ERROR: mismatched types [E0308]
+        let _: u32 = x;
+    }
+    if let Some(&Some(x)) = &Some(Some(0)) {
+        //~^ ERROR: mismatched types [E0308]
+        let _: u32 = x;
+    }
+    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+        //~^ ERROR: mismatched types [E0308]
+        let _: u32 = x;
+    }
+}
diff --git a/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr b/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr
new file mode 100644
index 00000000000..0f0051325cd
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-ref_pat_everywhere.stderr
@@ -0,0 +1,49 @@
+error[E0308]: mismatched types
+  --> $DIR/feature-gate-ref_pat_everywhere.rs:2:22
+   |
+LL |     if let Some(Some(&x)) = &Some(&Some(0)) {
+   |                      ^^     --------------- this expression has type `&Option<&Option<{integer}>>`
+   |                      |
+   |                      expected integer, found `&_`
+   |
+   = note:   expected type `{integer}`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL |     if let Some(Some(x)) = &Some(&Some(0)) {
+   |                      ~
+
+error[E0308]: mismatched types
+  --> $DIR/feature-gate-ref_pat_everywhere.rs:6:17
+   |
+LL |     if let Some(&Some(x)) = &Some(Some(0)) {
+   |                 ^^^^^^^^    -------------- this expression has type `&Option<Option<{integer}>>`
+   |                 |
+   |                 expected `Option<{integer}>`, found `&_`
+   |
+   = note:   expected enum `Option<{integer}>`
+           found reference `&_`
+
+error[E0308]: mismatched types
+  --> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
+   |
+LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+   |                      ^^^^^^     ----------------------- this expression has type `&mut Option<&mut Option<{integer}>>`
+   |                      |
+   |                      expected integer, found `&mut _`
+   |
+   = note:           expected type `{integer}`
+           found mutable reference `&mut _`
+note: to declare a mutable binding use: `mut x`
+  --> $DIR/feature-gate-ref_pat_everywhere.rs:10:22
+   |
+LL |     if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+   |                      ^^^^^^
+help: consider removing `&mut` from the pattern
+   |
+LL |     if let Some(Some(x)) = &mut Some(&mut Some(0)) {
+   |                      ~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/fn/fn-item-lifetime-bounds.rs b/tests/ui/fn/fn-item-lifetime-bounds.rs
deleted file mode 100644
index b80b7eade23..00000000000
--- a/tests/ui/fn/fn-item-lifetime-bounds.rs
+++ /dev/null
@@ -1,37 +0,0 @@
-//@ check-pass
-//@ known-bug: #84533
-
-// Should fail. Lifetimes are checked correctly when `foo` is called, but NOT
-// when only the lifetime parameters are instantiated.
-
-use std::marker::PhantomData;
-
-#[allow(dead_code)]
-fn foo<'b, 'a>() -> PhantomData<&'b &'a ()> {
-    PhantomData
-}
-
-#[allow(dead_code)]
-#[allow(path_statements)]
-fn caller<'b, 'a>() {
-    foo::<'b, 'a>;
-}
-
-// In contrast to above, below code correctly does NOT compile.
-// fn caller<'b, 'a>() {
-//     foo::<'b, 'a>();
-// }
-
-// error: lifetime may not live long enough
-//   --> src/main.rs:22:5
-//   |
-// 21 | fn caller<'b, 'a>() {
-//   |           --  -- lifetime `'a` defined here
-//   |           |
-//   |           lifetime `'b` defined here
-// 22 |     foo::<'b, 'a>();
-//   |     ^^^^^^^^^^^^^^^ requires that `'a` must outlive `'b`
-//   |
-//   = help: consider adding the following bound: `'a: 'b`
-
-fn main() {}
diff --git a/tests/ui/fn/fn-item-type.stderr b/tests/ui/fn/fn-item-type.stderr
index da90b8b81c8..76cdbcceac8 100644
--- a/tests/ui/fn/fn-item-type.stderr
+++ b/tests/ui/fn/fn-item-type.stderr
@@ -2,8 +2,9 @@ error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:22:19
    |
 LL |     eq(foo::<u8>, bar::<u8>);
-   |     --            ^^^^^^^^^ expected fn item, found a different fn item
-   |     |
+   |     -- ---------  ^^^^^^^^^ expected fn item, found a different fn item
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {foo::<u8>}`
@@ -13,15 +14,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:29:19
    |
 LL |     eq(foo::<u8>, foo::<i8>);
-   |     --            ^^^^^^^^^ expected `u8`, found `i8`
-   |     |
+   |     -- ---------  ^^^^^^^^^ expected `u8`, found `i8`
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {foo::<u8>}`
@@ -31,15 +36,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:34:23
    |
 LL |     eq(bar::<String>, bar::<Vec<u8>>);
-   |     --                ^^^^^^^^^^^^^^ expected `String`, found `Vec<u8>`
-   |     |
+   |     -- -------------  ^^^^^^^^^^^^^^ expected `String`, found `Vec<u8>`
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {bar::<String>}`
@@ -49,15 +58,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn(isize) -> isize`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:40:26
    |
 LL |     eq(<u8 as Foo>::foo, <u16 as Foo>::foo);
-   |     --                   ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16`
-   |     |
+   |     -- ----------------  ^^^^^^^^^^^^^^^^^ expected `u8`, found `u16`
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn() {<u8 as Foo>::foo}`
@@ -67,15 +80,19 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
    = help: consider casting both fn items to fn pointers using `as fn()`
 
 error[E0308]: mismatched types
   --> $DIR/fn-item-type.rs:45:19
    |
 LL |     eq(foo::<u8>, bar::<u8> as fn(isize) -> isize);
-   |     --            ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
-   |     |
+   |     -- ---------  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer
+   |     |  |
+   |     |  expected all arguments to be this fn item type because they need to match the type of this parameter
    |     arguments to this function are incorrect
    |
    = note: expected fn item `fn(_) -> _ {foo::<u8>}`
@@ -85,7 +102,10 @@ note: function defined here
   --> $DIR/fn-item-type.rs:11:4
    |
 LL | fn eq<T>(x: T, y: T) {}
-   |    ^^          ----
+   |    ^^ -  ----  ---- this parameter needs to match the fn item type of `x`
+   |       |  |
+   |       |  `y` needs to match the fn item type of this parameter
+   |       `x` and `y` all reference this parameter T
 
 error: aborting due to 5 previous errors
 
diff --git a/tests/ui/issues/issue-1451.rs b/tests/ui/fn/issue-1451.rs
index 735b766bd0c..735b766bd0c 100644
--- a/tests/ui/issues/issue-1451.rs
+++ b/tests/ui/fn/issue-1451.rs
diff --git a/tests/ui/issues/issue-1900.rs b/tests/ui/fn/issue-1900.rs
index 761bd317027..761bd317027 100644
--- a/tests/ui/issues/issue-1900.rs
+++ b/tests/ui/fn/issue-1900.rs
diff --git a/tests/ui/issues/issue-1900.stderr b/tests/ui/fn/issue-1900.stderr
index 31fd46c8e2a..31fd46c8e2a 100644
--- a/tests/ui/issues/issue-1900.stderr
+++ b/tests/ui/fn/issue-1900.stderr
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
index 06ffff057f9..d913b2e91ca 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.next.stderr
@@ -6,7 +6,7 @@ LL |     cmp_eq
    |
    = note: cannot satisfy `_: Scalar`
 note: required by a bound in `cmp_eq`
-  --> $DIR/ambig-hr-projection-issue-93340.rs:9:22
+  --> $DIR/ambig-hr-projection-issue-93340.rs:10:22
    |
 LL | fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O {
    |                      ^^^^^^ required by this bound in `cmp_eq`
@@ -15,34 +15,6 @@ help: consider specifying the generic arguments
 LL |     cmp_eq::<A, B, O>
    |           +++++++++++
 
-error[E0275]: overflow evaluating the requirement `impl for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>) -> O == for<'a, 'b> fn(..., ...) -> ... {cmp_eq::<..., ..., ...>}`
-  --> $DIR/ambig-hr-projection-issue-93340.rs:16:5
-   |
-LL |     cmp_eq
-   |     ^^^^^^
-
-error[E0275]: overflow evaluating the requirement `impl for<'a, 'b> Fn(<A as Scalar>::RefType<'a>, <B as Scalar>::RefType<'b>) -> O == for<'a, 'b> fn(..., ...) -> ... {cmp_eq::<..., ..., ...>}`
-  --> $DIR/ambig-hr-projection-issue-93340.rs:16:5
-   |
-LL |     cmp_eq
-   |     ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error[E0275]: overflow evaluating the requirement `for<'a, 'b> fn(<O as Scalar>::RefType<'a>, <_ as Scalar>::RefType<'b>) -> _ {cmp_eq::<O, ..., ...>} <: ...`
-  --> $DIR/ambig-hr-projection-issue-93340.rs:14:51
-   |
-LL |   ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
-   |  ___________________________________________________^
-LL | |
-LL | |     cmp_eq
-LL | |
-LL | |
-LL | |
-LL | | }
-   | |_^
-
-error: aborting due to 4 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0275, E0283.
-For more information about an error, try `rustc --explain E0275`.
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
index df2ec4ab182..d913b2e91ca 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.old.stderr
@@ -6,7 +6,7 @@ LL |     cmp_eq
    |
    = note: cannot satisfy `_: Scalar`
 note: required by a bound in `cmp_eq`
-  --> $DIR/ambig-hr-projection-issue-93340.rs:9:22
+  --> $DIR/ambig-hr-projection-issue-93340.rs:10:22
    |
 LL | fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefType<'b>) -> O {
    |                      ^^^^^^ required by this bound in `cmp_eq`
diff --git a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
index 4d8ea9d8d48..acfebad38db 100644
--- a/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
+++ b/tests/ui/generic-associated-types/ambig-hr-projection-issue-93340.rs
@@ -1,4 +1,5 @@
 //@ revisions: old next
+//@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 pub trait Scalar: 'static {
     type RefType<'a>: ScalarRef<'a>;
@@ -12,11 +13,8 @@ fn cmp_eq<'a, 'b, A: Scalar, B: Scalar, O: Scalar>(a: A::RefType<'a>, b: B::RefT
 
 fn build_expression<A: Scalar, B: Scalar, O: Scalar>(
 ) -> impl Fn(A::RefType<'_>, B::RefType<'_>) -> O {
-    //[next]~^ ERROR overflow evaluating the requirement
     cmp_eq
     //~^ ERROR type annotations needed
-    //[next]~| ERROR overflow evaluating the requirement
-    //[next]~| ERROR overflow evaluating the requirement
 }
 
 fn main() {}
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs
new file mode 100644
index 00000000000..b448f0bdc77
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.rs
@@ -0,0 +1,28 @@
+// cc #119820
+
+trait Trait {}
+
+impl<T: Trait> Trait for &T {}
+impl Trait for u32 {}
+
+fn hr_bound<T>()
+where
+    for<'a> &'a T: Trait,
+{
+}
+
+fn foo<T>()
+where
+    T: Trait,
+    for<'a> &'a &'a T: Trait,
+{
+    // We get a universe error when using the `param_env` candidate
+    // but are able to successfully use the impl candidate. Without
+    // the leak check both candidates may apply and we prefer the
+    // `param_env` candidate in winnowing.
+    hr_bound::<&T>();
+    //~^ ERROR the parameter type `T` may not live long enough
+    //~| ERROR implementation of `Trait` is not general enough
+}
+
+fn main() {}
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr
new file mode 100644
index 00000000000..febe252d7d1
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-1.stderr
@@ -0,0 +1,26 @@
+error[E0310]: the parameter type `T` may not live long enough
+  --> $DIR/candidate-from-env-universe-err-1.rs:23:5
+   |
+LL |     hr_bound::<&T>();
+   |     ^^^^^^^^^^^^^^
+   |     |
+   |     the parameter type `T` must be valid for the static lifetime...
+   |     ...so that the type `T` will meet its required lifetime bounds
+   |
+help: consider adding an explicit lifetime bound
+   |
+LL |     T: Trait + 'static,
+   |              +++++++++
+
+error: implementation of `Trait` is not general enough
+  --> $DIR/candidate-from-env-universe-err-1.rs:23:5
+   |
+LL |     hr_bound::<&T>();
+   |     ^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
+   |
+   = note: `Trait` would have to be implemented for the type `&'0 &T`, for any lifetime `'0`...
+   = note: ...but `Trait` is actually implemented for the type `&'1 &'1 T`, for some specific lifetime `'1`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0310`.
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr
new file mode 100644
index 00000000000..22ce87c0248
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.current.stderr
@@ -0,0 +1,25 @@
+error: lifetime may not live long enough
+  --> $DIR/candidate-from-env-universe-err-2.rs:14:5
+   |
+LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
+   |           -- lifetime `'a` defined here
+LL |     impl_hr::<T>();
+   |     ^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+   |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+  --> $DIR/candidate-from-env-universe-err-2.rs:11:19
+   |
+LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of `Trait` is not general enough
+  --> $DIR/candidate-from-env-universe-err-2.rs:14:5
+   |
+LL |     impl_hr::<T>();
+   |     ^^^^^^^^^^^^ implementation of `Trait` is not general enough
+   |
+   = note: `T` must implement `Trait<'0, '_>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Trait<'1, '_>`, for some specific lifetime `'1`
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr
new file mode 100644
index 00000000000..a61bc748bea
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.next.stderr
@@ -0,0 +1,19 @@
+error[E0277]: the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
+  --> $DIR/candidate-from-env-universe-err-2.rs:14:5
+   |
+LL |     impl_hr::<T>();
+   |     ^^^^^^^^^^^^^^ the trait `for<'a> Trait<'a, '_>` is not implemented for `T`
+   |
+note: required by a bound in `impl_hr`
+  --> $DIR/candidate-from-env-universe-err-2.rs:11:19
+   |
+LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impl_hr`
+help: consider further restricting this bound
+   |
+LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static> + for<'a> Trait<'a, '_>>() {
+   |                                                              +++++++++++++++++++++++
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr
new file mode 100644
index 00000000000..29a72b1c1b6
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.old.stderr
@@ -0,0 +1,26 @@
+error: lifetime may not live long enough
+  --> $DIR/candidate-from-env-universe-err-2.rs:14:5
+   |
+LL | fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
+   |           -- lifetime `'a` defined here
+LL |     impl_hr::<T>();
+   |     ^^^^^^^^^^^^ requires that `'a` must outlive `'static`
+   |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+  --> $DIR/candidate-from-env-universe-err-2.rs:11:19
+   |
+LL | fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/candidate-from-env-universe-err-2.rs:14:5
+   |
+LL |     impl_hr::<T>();
+   |     ^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected trait `for<'a> Trait<'a, '_>`
+              found trait `for<'b> Trait<'_, 'b>`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs
new file mode 100644
index 00000000000..56fa70469cc
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-2.rs
@@ -0,0 +1,20 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+
+// cc #119820
+
+trait Trait<'a, 'b> {}
+
+trait OtherTrait<'b> {}
+impl<'a, 'b, T: OtherTrait<'b>> Trait<'a, 'b> for T {}
+
+fn impl_hr<'b, T: for<'a> Trait<'a, 'b>>() {}
+
+fn not_hr<'a, T: for<'b> Trait<'a, 'b> + OtherTrait<'static>>() {
+    impl_hr::<T>();
+    //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a, '_>` is not satisfied
+    //[current]~^^ERROR lifetime may not live long enough
+    //[current]~| ERROR implementation of `Trait` is not general enough
+}
+
+fn main() {}
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr
new file mode 100644
index 00000000000..bb0b2de788e
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.current.stderr
@@ -0,0 +1,54 @@
+error: implementation of `Trait` is not general enough
+  --> $DIR/candidate-from-env-universe-err-project.rs:28:5
+   |
+LL |     trait_bound::<T>();
+   |     ^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
+   |
+   = note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Trait<'static>`
+
+error: implementation of `Trait` is not general enough
+  --> $DIR/candidate-from-env-universe-err-project.rs:39:5
+   |
+LL |     projection_bound::<T>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Trait` is not general enough
+   |
+   = note: `T` must implement `Trait<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Trait<'static>`
+
+error[E0308]: mismatched types
+  --> $DIR/candidate-from-env-universe-err-project.rs:39:5
+   |
+LL |     projection_bound::<T>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected associated type `<T as Trait<'static>>::Assoc`
+              found associated type `<T as Trait<'a>>::Assoc`
+note: the lifetime requirement is introduced here
+  --> $DIR/candidate-from-env-universe-err-project.rs:18:42
+   |
+LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
+   |                                          ^^^^^^^^^^^^^
+
+error[E0308]: mismatched types
+  --> $DIR/candidate-from-env-universe-err-project.rs:55:30
+   |
+LL |     let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected associated type `<T as Trait<'static>>::Assoc`
+              found associated type `<T as Trait<'a>>::Assoc`
+
+error[E0308]: mismatched types
+  --> $DIR/candidate-from-env-universe-err-project.rs:55:30
+   |
+LL |     let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected associated type `<T as Trait<'static>>::Assoc`
+              found associated type `<T as Trait<'a>>::Assoc`
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr
new file mode 100644
index 00000000000..2804d5bbe94
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.next.stderr
@@ -0,0 +1,67 @@
+error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
+  --> $DIR/candidate-from-env-universe-err-project.rs:28:19
+   |
+LL |     trait_bound::<T>();
+   |                   ^ the trait `for<'a> Trait<'a>` is not implemented for `T`
+   |
+note: required by a bound in `trait_bound`
+  --> $DIR/candidate-from-env-universe-err-project.rs:17:19
+   |
+LL | fn trait_bound<T: for<'a> Trait<'a>>() {}
+   |                   ^^^^^^^^^^^^^^^^^ required by this bound in `trait_bound`
+help: consider further restricting this bound
+   |
+LL | fn function1<T: Trait<'static> + for<'a> Trait<'a>>() {
+   |                                +++++++++++++++++++
+
+error[E0277]: the trait bound `for<'a> T: Trait<'a>` is not satisfied
+  --> $DIR/candidate-from-env-universe-err-project.rs:39:24
+   |
+LL |     projection_bound::<T>();
+   |                        ^ the trait `for<'a> Trait<'a>` is not implemented for `T`
+   |
+note: required by a bound in `projection_bound`
+  --> $DIR/candidate-from-env-universe-err-project.rs:18:24
+   |
+LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
+   |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `projection_bound`
+help: consider further restricting this bound
+   |
+LL | fn function2<T: Trait<'static, Assoc = usize> + for<'a> Trait<'a>>() {
+   |                                               +++++++++++++++++++
+
+error[E0271]: type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
+  --> $DIR/candidate-from-env-universe-err-project.rs:39:24
+   |
+LL |     projection_bound::<T>();
+   |                        ^ type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
+   |
+note: types differ
+  --> $DIR/candidate-from-env-universe-err-project.rs:14:18
+   |
+LL |     type Assoc = usize;
+   |                  ^^^^^
+note: required by a bound in `projection_bound`
+  --> $DIR/candidate-from-env-universe-err-project.rs:18:42
+   |
+LL | fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
+   |                                          ^^^^^^^^^^^^^ required by this bound in `projection_bound`
+
+error: higher-ranked subtype error
+  --> $DIR/candidate-from-env-universe-err-project.rs:55:30
+   |
+LL |     let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: higher-ranked subtype error
+  --> $DIR/candidate-from-env-universe-err-project.rs:55:30
+   |
+LL |     let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error: aborting due to 5 previous errors
+
+Some errors have detailed explanations: E0271, E0277.
+For more information about an error, try `rustc --explain E0271`.
diff --git a/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs
new file mode 100644
index 00000000000..2f53bd019b7
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/candidate-from-env-universe-err-project.rs
@@ -0,0 +1,62 @@
+//@ revisions: next current
+//@[next] compile-flags: -Znext-solver
+
+// cc #119820 the previous behavior here was inconsistent as we discarded
+// the where-bound candidate for trait goals due to the leak check, but did
+// not do so for projection candidates and during normalization.
+//
+// This results in an inconsistency between `Trait` and `Projection` goals as
+// normalizing always constraints the normalized-to term.
+trait Trait<'a> {
+    type Assoc;
+}
+impl<'a, T> Trait<'a> for T {
+    type Assoc = usize;
+}
+
+fn trait_bound<T: for<'a> Trait<'a>>() {}
+fn projection_bound<T: for<'a> Trait<'a, Assoc = usize>>() {}
+
+// We use a function with a trivial where-bound which is more
+// restrictive than the impl.
+fn function1<T: Trait<'static>>() {
+    // err
+    //
+    // Proving `for<'a> T: Trait<'a>` using the where-bound does not
+    // result in a leak check failure even though it does not apply.
+    // We prefer env candidates over impl candidatescausing this to succeed.
+    trait_bound::<T>();
+    //[next]~^ ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
+    //[current]~^^ ERROR implementation of `Trait` is not general enough
+}
+
+fn function2<T: Trait<'static, Assoc = usize>>() {
+    // err
+    //
+    // Proving the `Projection` goal `for<'a> T: Trait<'a, Assoc = usize>`
+    // does not use the leak check when trying the where-bound, causing us
+    // to prefer it over the impl, resulting in a placeholder error.
+    projection_bound::<T>();
+    //[next]~^ ERROR type mismatch resolving `<T as Trait<'a>>::Assoc == usize`
+    //[next]~| ERROR the trait bound `for<'a> T: Trait<'a>` is not satisfied
+    //[current]~^^^ ERROR implementation of `Trait` is not general enough
+    //[current]~| ERROR mismatched types
+}
+
+fn function3<T: Trait<'static, Assoc = usize>>() {
+    // err
+    //
+    // Trying to normalize the type `for<'a> fn(<T as Trait<'a>>::Assoc)`
+    // only gets to `<T as Trait<'a>>::Assoc` once `'a` has been already
+    // instantiated, causing us to prefer the where-bound over the impl
+    // resulting in a placeholder error. Even if were were to also use the
+    // leak check during candidate selection for normalization, this
+    // case would still not compile.
+    let _higher_ranked_norm: for<'a> fn(<T as Trait<'a>>::Assoc) = |_| ();
+    //[next]~^ ERROR higher-ranked subtype error
+    //[next]~| ERROR higher-ranked subtype error
+    //[current]~^^^ ERROR mismatched types
+    //[current]~| ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/higher-ranked/leak-check-in-selection.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-1.rs
index 46a0dccb441..46a0dccb441 100644
--- a/tests/ui/higher-ranked/leak-check-in-selection.rs
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-1.rs
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr
new file mode 100644
index 00000000000..a840304e49c
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.next.stderr
@@ -0,0 +1,23 @@
+error[E0283]: type annotations needed
+  --> $DIR/leak-check-in-selection-2.rs:16:5
+   |
+LL |     impls_trait::<(), _>();
+   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
+   |
+note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found
+  --> $DIR/leak-check-in-selection-2.rs:9:1
+   |
+LL | impl<'a> Trait<&'a str, &'a str> for () {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | impl<'a> Trait<&'a str, String> for () {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `impls_trait`
+  --> $DIR/leak-check-in-selection-2.rs:13:19
+   |
+LL | fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr
new file mode 100644
index 00000000000..a840304e49c
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.old.stderr
@@ -0,0 +1,23 @@
+error[E0283]: type annotations needed
+  --> $DIR/leak-check-in-selection-2.rs:16:5
+   |
+LL |     impls_trait::<(), _>();
+   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `U` declared on the function `impls_trait`
+   |
+note: multiple `impl`s satisfying `for<'a> (): Trait<&'a str, _>` found
+  --> $DIR/leak-check-in-selection-2.rs:9:1
+   |
+LL | impl<'a> Trait<&'a str, &'a str> for () {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL |
+LL | impl<'a> Trait<&'a str, String> for () {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `impls_trait`
+  --> $DIR/leak-check-in-selection-2.rs:13:19
+   |
+LL | fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
+   |                   ^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_trait`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs
new file mode 100644
index 00000000000..48dd569f201
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-2.rs
@@ -0,0 +1,18 @@
+//@ revisions: old next
+//@[next] compile-flags: -Znext-solver
+
+// cc #119820
+
+trait Trait<T, U> {}
+
+// using this impl results in a higher-ranked region error.
+impl<'a> Trait<&'a str, &'a str> for () {}
+
+impl<'a> Trait<&'a str, String> for () {}
+
+fn impls_trait<T: for<'a> Trait<&'a str, U>, U>() {}
+
+fn main() {
+    impls_trait::<(), _>();
+    //~^ ERROR type annotations needed
+}
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr
new file mode 100644
index 00000000000..8a8118dea85
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.next.stderr
@@ -0,0 +1,35 @@
+error[E0283]: type annotations needed
+  --> $DIR/leak-check-in-selection-3.rs:18:5
+   |
+LL |     impls_leak::<Box<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak`
+   |
+note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
+  --> $DIR/leak-check-in-selection-3.rs:9:1
+   |
+LL | impl Leak<'_> for Box<u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl Leak<'static> for Box<u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `impls_leak`
+  --> $DIR/leak-check-in-selection-3.rs:12:18
+   |
+LL | fn impls_leak<T: for<'a> Leak<'a>>() {}
+   |                  ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak`
+
+error[E0283]: type annotations needed
+  --> $DIR/leak-check-in-selection-3.rs:35:5
+   |
+LL |     impls_indirect_leak::<Box<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak`
+   |
+   = note: cannot satisfy `for<'a> Box<_>: IndirectLeak<'a>`
+note: required by a bound in `impls_indirect_leak`
+  --> $DIR/leak-check-in-selection-3.rs:25:27
+   |
+LL | fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {}
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr
new file mode 100644
index 00000000000..662a0653740
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.old.stderr
@@ -0,0 +1,48 @@
+error[E0283]: type annotations needed
+  --> $DIR/leak-check-in-selection-3.rs:18:5
+   |
+LL |     impls_leak::<Box<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_leak`
+   |
+note: multiple `impl`s satisfying `for<'a> Box<_>: Leak<'a>` found
+  --> $DIR/leak-check-in-selection-3.rs:9:1
+   |
+LL | impl Leak<'_> for Box<u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl Leak<'static> for Box<u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required by a bound in `impls_leak`
+  --> $DIR/leak-check-in-selection-3.rs:12:18
+   |
+LL | fn impls_leak<T: for<'a> Leak<'a>>() {}
+   |                  ^^^^^^^^^^^^^^^^ required by this bound in `impls_leak`
+
+error[E0283]: type annotations needed
+  --> $DIR/leak-check-in-selection-3.rs:35:5
+   |
+LL |     impls_indirect_leak::<Box<_>>();
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `T` declared on the function `impls_indirect_leak`
+   |
+note: multiple `impl`s satisfying `Box<_>: Leak<'_>` found
+  --> $DIR/leak-check-in-selection-3.rs:9:1
+   |
+LL | impl Leak<'_> for Box<u32> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^
+LL | impl Leak<'static> for Box<u16> {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+note: required for `Box<_>` to implement `for<'a> IndirectLeak<'a>`
+  --> $DIR/leak-check-in-selection-3.rs:23:23
+   |
+LL | impl<'a, T: Leak<'a>> IndirectLeak<'a> for T {}
+   |             --------  ^^^^^^^^^^^^^^^^     ^
+   |             |
+   |             unsatisfied trait bound introduced here
+note: required by a bound in `impls_indirect_leak`
+  --> $DIR/leak-check-in-selection-3.rs:25:27
+   |
+LL | fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {}
+   |                           ^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `impls_indirect_leak`
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0283`.
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs
new file mode 100644
index 00000000000..9e99b6c527d
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-3.rs
@@ -0,0 +1,39 @@
+//@ revisions: old next
+//@[next] compile-flags: -Znext-solver
+
+// cc #119820, the previous behavior here was inconsistent,
+// using the leak check to guide inference for `for<'a> Box<_>: Leak<'a>`
+// but not for `for<'a> Box<_>: IndirectLeak<'a>`
+
+trait Leak<'a> {}
+impl Leak<'_> for Box<u32> {}
+impl Leak<'static> for Box<u16> {}
+
+fn impls_leak<T: for<'a> Leak<'a>>() {}
+fn direct() {
+    // ok
+    //
+    // The `Box<u16>` impls fails the leak check,
+    // meaning that we apply the `Box<u32>` impl.
+    impls_leak::<Box<_>>();
+    //~^ ERROR type annotations needed
+}
+
+trait IndirectLeak<'a> {}
+impl<'a, T: Leak<'a>> IndirectLeak<'a> for T {}
+
+fn impls_indirect_leak<T: for<'a> IndirectLeak<'a>>() {}
+fn indirect() {
+    // error: type annotations needed
+    //
+    // While the `Box<u16>` impl would fail the leak check
+    // we have already instantiated the binder while applying
+    // the generic `IndirectLeak` impl, so during candidate
+    // selection of `Leak` we do not detect the placeholder error.
+    // Evaluation of `Box<_>: Leak<'!a>` is therefore ambiguous,
+    // resulting in `for<'a> Box<_>: Leak<'a>` also being ambiguous.
+    impls_indirect_leak::<Box<_>>();
+    //~^ ERROR type annotations needed
+}
+
+fn main() {}
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-4-hr-nested.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-4-hr-nested.rs
new file mode 100644
index 00000000000..8d87bdd064a
--- /dev/null
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-4-hr-nested.rs
@@ -0,0 +1,29 @@
+//@ revisions: old next
+//@[next] compile-flags: -Znext-solver
+//@ check-pass
+
+// cc #119820. While the leak check does not consider the binder
+// of the current goal, leaks from higher-ranked nested goals are
+// considered.
+//
+// We enter and exit the binder of the nested goal while evaluating
+// the candidate.
+
+trait LeakCheckFailure<'a> {}
+impl LeakCheckFailure<'static> for () {}
+
+trait Trait<T> {}
+impl Trait<u32> for () where for<'a> (): LeakCheckFailure<'a> {}
+impl Trait<u16> for () {}
+fn impls_trait<T: Trait<U>, U>() {}
+fn main() {
+    // ok
+    //
+    // It does not matter whether candidate assembly
+    // considers the placeholders from higher-ranked goal.
+    //
+    // Either `for<'a> (): LeakCheckFailure<'a>` has no applicable
+    // candidate or it has a single applicable candidate which then later
+    // results in an error. This allows us to infer `U` to `u16`.
+    impls_trait::<(), _>()
+}
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-30786.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs
index ffb2b306ae7..799df8cae9f 100644
--- a/tests/ui/higher-ranked/trait-bounds/issue-30786.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.rs
@@ -1,6 +1,6 @@
 //@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
 
-// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
+// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T>`
 // should act as assertion that item does not borrow from its stream;
 // but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
 // have such an item.
@@ -97,10 +97,6 @@ where
 
 impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
 
-fn identity<T>(x: &T) -> &T {
-    x
-}
-
 fn variant1() {
     let source = Repeat(10);
 
@@ -118,19 +114,7 @@ fn variant1() {
     // guess.
     let map = source.mapx(|x: &_| x);
     let filter = map.filterx(|x: &_| true);
-    //~^ ERROR the method
-}
-
-fn variant2() {
-    let source = Repeat(10);
-
-    // Here, we use a function, which is not subject to the vagaries
-    // of closure signature inference. In this case, we get the error
-    // on `countx` as, I think, the test originally expected.
-    let map = source.mapx(identity);
-    let filter = map.filterx(|x: &_| true);
-    let count = filter.countx();
-    //~^ ERROR the method
+    //~^ ERROR the method `filterx` exists for struct
 }
 
 fn main() {}
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr
new file mode 100644
index 00000000000..ae364de8cc0
--- /dev/null
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-1.stderr
@@ -0,0 +1,27 @@
+error[E0599]: the method `filterx` exists for struct `Map<Repeat, {closure@hrtb-doesnt-borrow-self-1.rs:115:27}>`, but its trait bounds were not satisfied
+  --> $DIR/hrtb-doesnt-borrow-self-1.rs:116:22
+   |
+LL | pub struct Map<S, F> {
+   | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
+...
+LL |     let filter = map.filterx(|x: &_| true);
+   |                      ^^^^^^^ method cannot be called due to unsatisfied trait bounds
+   |
+note: the following trait bounds were not satisfied:
+      `&'a mut &Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:115:27: 115:34}>: Stream`
+      `&'a mut &mut Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:115:27: 115:34}>: Stream`
+      `&'a mut Map<Repeat, {closure@$DIR/hrtb-doesnt-borrow-self-1.rs:115:27: 115:34}>: Stream`
+  --> $DIR/hrtb-doesnt-borrow-self-1.rs:98:50
+   |
+LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `StreamExt` defines an item `filterx`, perhaps you need to implement it
+  --> $DIR/hrtb-doesnt-borrow-self-1.rs:66:1
+   |
+LL | pub trait StreamExt
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs
new file mode 100644
index 00000000000..92e2e7f796e
--- /dev/null
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.rs
@@ -0,0 +1,116 @@
+//@ normalize-stderr-test: "long-type-\d+" -> "long-type-hash"
+
+// rust-lang/rust#30786: the use of `for<'b> &'b mut A: Stream<Item=T`
+// should act as assertion that item does not borrow from its stream;
+// but an earlier buggy rustc allowed `.map(|x: &_| x)` which does
+// have such an item.
+//
+// This tests double-checks that we do not allow such behavior to leak
+// through again.
+
+pub trait Stream {
+    type Item;
+    fn next(self) -> Option<Self::Item>;
+}
+
+// Example stream
+pub struct Repeat(u64);
+
+impl<'a> Stream for &'a mut Repeat {
+    type Item = &'a u64;
+    fn next(self) -> Option<Self::Item> {
+        Some(&self.0)
+    }
+}
+
+pub struct Map<S, F> {
+    stream: S,
+    func: F,
+}
+
+impl<'a, A, F, T> Stream for &'a mut Map<A, F>
+where
+    &'a mut A: Stream,
+    F: FnMut(<&'a mut A as Stream>::Item) -> T,
+{
+    type Item = T;
+    fn next(self) -> Option<T> {
+        match self.stream.next() {
+            Some(item) => Some((self.func)(item)),
+            None => None,
+        }
+    }
+}
+
+pub struct Filter<S, F> {
+    stream: S,
+    func: F,
+}
+
+impl<'a, A, F, T> Stream for &'a mut Filter<A, F>
+where
+    for<'b> &'b mut A: Stream<Item = T>, // <---- BAD
+    F: FnMut(&T) -> bool,
+{
+    type Item = <&'a mut A as Stream>::Item;
+    fn next(self) -> Option<Self::Item> {
+        while let Some(item) = self.stream.next() {
+            if (self.func)(&item) {
+                return Some(item);
+            }
+        }
+        None
+    }
+}
+
+pub trait StreamExt
+where
+    for<'b> &'b mut Self: Stream,
+{
+    fn mapx<F>(self, func: F) -> Map<Self, F>
+    where
+        Self: Sized,
+        for<'a> &'a mut Map<Self, F>: Stream,
+    {
+        Map { func: func, stream: self }
+    }
+
+    fn filterx<F>(self, func: F) -> Filter<Self, F>
+    where
+        Self: Sized,
+        for<'a> &'a mut Filter<Self, F>: Stream,
+    {
+        Filter { func: func, stream: self }
+    }
+
+    fn countx(mut self) -> usize
+    where
+        Self: Sized,
+    {
+        let mut count = 0;
+        while let Some(_) = self.next() {
+            count += 1;
+        }
+        count
+    }
+}
+
+impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+
+fn identity<T>(x: &T) -> &T {
+    x
+}
+
+fn variant2() {
+    let source = Repeat(10);
+
+    // Here, we use a function, which is not subject to the vagaries
+    // of closure signature inference. In this case, we get the error
+    // on `countx` as, I think, the test originally expected.
+    let map = source.mapx(identity);
+    let filter = map.filterx(|x: &_| true);
+    let count = filter.countx();
+    //~^ ERROR the method
+}
+
+fn main() {}
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr
new file mode 100644
index 00000000000..eeb4e12fa8b
--- /dev/null
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-doesnt-borrow-self-2.stderr
@@ -0,0 +1,27 @@
+error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64) -> &u64 {identity::<u64>}>, {closure@hrtb-doesnt-borrow-self-2.rs:111:30}>`, but its trait bounds were not satisfied
+  --> $DIR/hrtb-doesnt-borrow-self-2.rs:112:24
+   |
+LL | pub struct Filter<S, F> {
+   | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt`
+...
+LL |     let count = filter.countx();
+   |                        ^^^^^^ method cannot be called due to unsatisfied trait bounds
+   |
+note: the following trait bounds were not satisfied:
+      `&'a mut &Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream`
+      `&'a mut &mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream`
+      `&'a mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/hrtb-doesnt-borrow-self-2.rs:111:30: 111:37}>: Stream`
+  --> $DIR/hrtb-doesnt-borrow-self-2.rs:98:50
+   |
+LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
+   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
+   = help: items from traits can only be used if the trait is implemented and in scope
+note: `StreamExt` defines an item `countx`, perhaps you need to implement it
+  --> $DIR/hrtb-doesnt-borrow-self-2.rs:66:1
+   |
+LL | pub trait StreamExt
+   | ^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
index e10da26665e..be19bf85bd2 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits-transitive.stderr
@@ -1,23 +1,11 @@
-error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:26
+error: implementation of `Bar` is not general enough
+  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:47:5
    |
 LL |     want_bar_for_any_ccx(b);
-   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
-   |     |
-   |     required by a bound introduced by this call
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
    |
-note: required by a bound in `want_bar_for_any_ccx`
-  --> $DIR/hrtb-higher-ranker-supertraits-transitive.rs:32:15
-   |
-LL | fn want_bar_for_any_ccx<B>(b: &B)
-   |    -------------------- required by a bound in this function
-LL |     where B : for<'ccx> Bar<'ccx>
-   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
-help: consider further restricting this bound
-   |
-LL |     where B : Qux + for<'ccx> Bar<'ccx>
-   |                   +++++++++++++++++++++
+   = note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Bar<'static>`
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
index 33e0ec4635b..70ce580258d 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.rs
@@ -1,43 +1,37 @@
 // Test a trait (`Bar`) with a higher-ranked supertrait.
+#![allow(unconditional_recursion)]
 
-trait Foo<'tcx>
-{
+trait Foo<'tcx> {
     fn foo(&'tcx self) -> &'tcx isize;
 }
 
-trait Bar<'ccx>
-    : for<'tcx> Foo<'tcx>
-{
+trait Bar<'ccx>: for<'tcx> Foo<'tcx> {
     fn bar(&'ccx self) -> &'ccx isize;
 }
 
-fn want_foo_for_some_tcx<'x,F>(f: &'x F)
-    where F : Foo<'x>
-{
+fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) {
     want_foo_for_some_tcx(f);
-    want_foo_for_any_tcx(f); //~ ERROR not satisfied
+    want_foo_for_any_tcx(f);
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR implementation of `Foo` is not general enough
 }
 
-fn want_foo_for_any_tcx<F>(f: &F) //~ WARN cannot return without recursing
-    where F : for<'tcx> Foo<'tcx>
-{
+fn want_foo_for_any_tcx<F: for<'tcx> Foo<'tcx>>(f: &F) {
     want_foo_for_some_tcx(f);
     want_foo_for_any_tcx(f);
 }
 
-fn want_bar_for_some_ccx<'x,B>(b: &B)
-    where B : Bar<'x>
-{
+fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) {
     want_foo_for_some_tcx(b);
     want_foo_for_any_tcx(b);
 
     want_bar_for_some_ccx(b);
-    want_bar_for_any_ccx(b); //~ ERROR not satisfied
+    want_bar_for_any_ccx(b);
+    //~^ ERROR lifetime may not live long enough
+    //~| ERROR implementation of `Bar` is not general enough
 }
 
-fn want_bar_for_any_ccx<B>(b: &B) //~ WARN cannot return without recursing
-    where B : for<'ccx> Bar<'ccx>
-{
+fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) {
     want_foo_for_some_tcx(b);
     want_foo_for_any_tcx(b);
 
diff --git a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
index f220ba6f338..dd760926ea1 100644
--- a/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
+++ b/tests/ui/higher-ranked/trait-bounds/hrtb-higher-ranker-supertraits.stderr
@@ -1,68 +1,50 @@
-error[E0277]: the trait bound `for<'tcx> F: Foo<'tcx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:18:26
+error: lifetime may not live long enough
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:14:5
    |
+LL | fn want_foo_for_some_tcx<'x, F: Foo<'x>>(f: &'x F) {
+   |                          -- lifetime `'x` defined here
+LL |     want_foo_for_some_tcx(f);
 LL |     want_foo_for_any_tcx(f);
-   |     -------------------- ^ the trait `for<'tcx> Foo<'tcx>` is not implemented for `F`
-   |     |
-   |     required by a bound introduced by this call
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
    |
-note: required by a bound in `want_foo_for_any_tcx`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:22:15
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:19:28
    |
-LL | fn want_foo_for_any_tcx<F>(f: &F)
-   |    -------------------- required by a bound in this function
-LL |     where F : for<'tcx> Foo<'tcx>
-   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_foo_for_any_tcx`
-help: consider further restricting this bound
-   |
-LL |     where F : Foo<'x> + for<'tcx> Foo<'tcx>
-   |                       +++++++++++++++++++++
+LL | fn want_foo_for_any_tcx<F: for<'tcx> Foo<'tcx>>(f: &F) {
+   |                            ^^^^^^^^^^^^^^^^^^^
 
-error[E0277]: the trait bound `for<'ccx> B: Bar<'ccx>` is not satisfied
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:35:26
-   |
-LL |     want_bar_for_any_ccx(b);
-   |     -------------------- ^ the trait `for<'ccx> Bar<'ccx>` is not implemented for `B`
-   |     |
-   |     required by a bound introduced by this call
+error: implementation of `Foo` is not general enough
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:14:5
    |
-note: required by a bound in `want_bar_for_any_ccx`
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:39:15
-   |
-LL | fn want_bar_for_any_ccx<B>(b: &B)
-   |    -------------------- required by a bound in this function
-LL |     where B : for<'ccx> Bar<'ccx>
-   |               ^^^^^^^^^^^^^^^^^^^ required by this bound in `want_bar_for_any_ccx`
-help: consider further restricting this bound
+LL |     want_foo_for_any_tcx(f);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Foo` is not general enough
    |
-LL |     where B : Bar<'x> + for<'ccx> Bar<'ccx>
-   |                       +++++++++++++++++++++
+   = note: `F` must implement `Foo<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Foo<'1>`, for some specific lifetime `'1`
 
-warning: function cannot return without recursing
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:21:1
+error: lifetime may not live long enough
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:29:5
    |
-LL | / fn want_foo_for_any_tcx<F>(f: &F)
-LL | |     where F : for<'tcx> Foo<'tcx>
-   | |_________________________________^ cannot return without recursing
+LL | fn want_bar_for_some_ccx<'x, B: Bar<'x>>(b: &B) {
+   |                          -- lifetime `'x` defined here
 ...
-LL |       want_foo_for_any_tcx(f);
-   |       ----------------------- recursive call site
+LL |     want_bar_for_any_ccx(b);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ requires that `'x` must outlive `'static`
+   |
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:34:28
    |
-   = help: a `loop` may express intention better if this is on purpose
-   = note: `#[warn(unconditional_recursion)]` on by default
+LL | fn want_bar_for_any_ccx<B: for<'ccx> Bar<'ccx>>(b: &B) {
+   |                            ^^^^^^^^^^^^^^^^^^^
 
-warning: function cannot return without recursing
-  --> $DIR/hrtb-higher-ranker-supertraits.rs:38:1
+error: implementation of `Bar` is not general enough
+  --> $DIR/hrtb-higher-ranker-supertraits.rs:29:5
    |
-LL | / fn want_bar_for_any_ccx<B>(b: &B)
-LL | |     where B : for<'ccx> Bar<'ccx>
-   | |_________________________________^ cannot return without recursing
-...
-LL |       want_bar_for_any_ccx(b);
-   |       ----------------------- recursive call site
+LL |     want_bar_for_any_ccx(b);
+   |     ^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
    |
-   = help: a `loop` may express intention better if this is on purpose
+   = note: `B` must implement `Bar<'0>`, for any lifetime `'0`...
+   = note: ...but it actually implements `Bar<'1>`, for some specific lifetime `'1`
 
-error: aborting due to 2 previous errors; 2 warnings emitted
+error: aborting due to 4 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr b/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
deleted file mode 100644
index 699a4ecc42b..00000000000
--- a/tests/ui/higher-ranked/trait-bounds/issue-30786.stderr
+++ /dev/null
@@ -1,51 +0,0 @@
-error[E0599]: the method `filterx` exists for struct `Map<Repeat, {closure@issue-30786.rs:119:27}>`, but its trait bounds were not satisfied
-  --> $DIR/issue-30786.rs:120:22
-   |
-LL | pub struct Map<S, F> {
-   | -------------------- method `filterx` not found for this struct because it doesn't satisfy `_: StreamExt`
-...
-LL |     let filter = map.filterx(|x: &_| true);
-   |                      ^^^^^^^ method cannot be called on `Map<Repeat, {closure@issue-30786.rs:119:27}>` due to unsatisfied trait bounds
-   |
-note: the following trait bounds were not satisfied:
-      `&'a mut &Map<Repeat, {closure@$DIR/issue-30786.rs:119:27: 119:34}>: Stream`
-      `&'a mut &mut Map<Repeat, {closure@$DIR/issue-30786.rs:119:27: 119:34}>: Stream`
-      `&'a mut Map<Repeat, {closure@$DIR/issue-30786.rs:119:27: 119:34}>: Stream`
-  --> $DIR/issue-30786.rs:98:50
-   |
-LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
-   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
-   = help: items from traits can only be used if the trait is implemented and in scope
-note: `StreamExt` defines an item `filterx`, perhaps you need to implement it
-  --> $DIR/issue-30786.rs:66:1
-   |
-LL | pub trait StreamExt
-   | ^^^^^^^^^^^^^^^^^^^
-
-error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, fn(&u64) -> &u64 {identity::<u64>}>, {closure@issue-30786.rs:131:30}>`, but its trait bounds were not satisfied
-  --> $DIR/issue-30786.rs:132:24
-   |
-LL | pub struct Filter<S, F> {
-   | ----------------------- method `countx` not found for this struct because it doesn't satisfy `_: StreamExt`
-...
-LL |     let count = filter.countx();
-   |                        ^^^^^^ method cannot be called due to unsatisfied trait bounds
-   |
-note: the following trait bounds were not satisfied:
-      `&'a mut &Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/issue-30786.rs:131:30: 131:37}>: Stream`
-      `&'a mut &mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/issue-30786.rs:131:30: 131:37}>: Stream`
-      `&'a mut Filter<Map<Repeat, for<'a> fn(&'a u64) -> &'a u64 {identity::<u64>}>, {closure@$DIR/issue-30786.rs:131:30: 131:37}>: Stream`
-  --> $DIR/issue-30786.rs:98:50
-   |
-LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
-   |         ---------     -                          ^^^^^^ unsatisfied trait bound introduced here
-   = help: items from traits can only be used if the trait is implemented and in scope
-note: `StreamExt` defines an item `countx`, perhaps you need to implement it
-  --> $DIR/issue-30786.rs:66:1
-   |
-LL | pub trait StreamExt
-   | ^^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
index ab21dae7dc5..7a51037324f 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.rs
@@ -14,6 +14,7 @@ impl<'a, I: 'a + Iterable> Iterable for &'a I {
     //~^ ERROR binding for associated type `Item` references lifetime `'missing`
     //~| ERROR binding for associated type `Item` references lifetime `'missing`
     //~| ERROR `()` is not an iterator
+    //~| WARNING impl trait in impl method signature does not match trait method signature
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
index d8a2eef94a1..67c4df0f3a9 100644
--- a/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
+++ b/tests/ui/impl-trait/in-trait/span-bug-issue-121457.stderr
@@ -32,7 +32,24 @@ LL |     fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missin
    |
    = help: the trait `Iterator` is not implemented for `()`
 
-error: aborting due to 4 previous errors
+warning: impl trait in impl method signature does not match trait method signature
+  --> $DIR/span-bug-issue-121457.rs:13:51
+   |
+LL |     fn iter(&self) -> impl Iterator;
+   |                       ------------- return type from trait method defined here
+...
+LL |     fn iter(&self) -> impl for<'missing> Iterator<Item = Self::Item<'missing>> {}
+   |                                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^ this bound is stronger than that defined on the trait
+   |
+   = note: add `#[allow(refining_impl_trait)]` if it is intended for this to be part of the public API of this crate
+   = note: we are soliciting feedback, see issue #121718 <https://github.com/rust-lang/rust/issues/121718> for more information
+   = note: `#[warn(refining_impl_trait_reachable)]` on by default
+help: replace the return type so that it matches the trait
+   |
+LL |     fn iter(&self) -> impl Iterator {}
+   |                       ~~~~~~~~~~~~~
+
+error: aborting due to 4 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0195, E0277, E0582.
 For more information about an error, try `rustc --explain E0195`.
diff --git a/tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.rs b/tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.rs
new file mode 100644
index 00000000000..0e07d21b2f5
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.rs
@@ -0,0 +1,11 @@
+// Don't panic when iterating through the `hir::Map::parent_iter` of an RPITIT.
+
+pub trait Foo {
+    fn demo() -> impl Foo
+    //~^ ERROR the trait bound `String: Copy` is not satisfied
+    where
+        String: Copy;
+    //~^ ERROR the trait bound `String: Copy` is not satisfied
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.stderr b/tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.stderr
new file mode 100644
index 00000000000..8ff8f12cdf4
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/synthetic-hir-has-parent.stderr
@@ -0,0 +1,27 @@
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/synthetic-hir-has-parent.rs:7:9
+   |
+LL |         String: Copy;
+   |         ^^^^^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+   = help: see issue #48214
+help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+   |
+LL + #![feature(trivial_bounds)]
+   |
+
+error[E0277]: the trait bound `String: Copy` is not satisfied
+  --> $DIR/synthetic-hir-has-parent.rs:4:18
+   |
+LL |     fn demo() -> impl Foo
+   |                  ^^^^^^^^ the trait `Copy` is not implemented for `String`
+   |
+   = help: see issue #48214
+help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+   |
+LL + #![feature(trivial_bounds)]
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/impl-trait/nested_impl_trait.rs b/tests/ui/impl-trait/nested_impl_trait.rs
index 760102794c3..502b2af2bc6 100644
--- a/tests/ui/impl-trait/nested_impl_trait.rs
+++ b/tests/ui/impl-trait/nested_impl_trait.rs
@@ -5,7 +5,7 @@ fn fine(x: impl Into<u32>) -> impl Into<u32> { x }
 
 fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
 //~^ ERROR nested `impl Trait` is not allowed
-//~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
+//~| ERROR the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
 
 fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
 //~^ ERROR nested `impl Trait` is not allowed
@@ -18,7 +18,7 @@ struct X;
 impl X {
     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
     //~^ ERROR nested `impl Trait` is not allowed
-    //~| ERROR the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
+    //~| ERROR the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
 }
 
 fn allowed_in_assoc_type() -> impl Iterator<Item=impl Fn()> {
diff --git a/tests/ui/impl-trait/nested_impl_trait.stderr b/tests/ui/impl-trait/nested_impl_trait.stderr
index 83d1347aff4..1f9a2a5e9d6 100644
--- a/tests/ui/impl-trait/nested_impl_trait.stderr
+++ b/tests/ui/impl-trait/nested_impl_trait.stderr
@@ -42,20 +42,20 @@ LL | fn bad_in_fn_syntax(x: fn() -> impl Into<impl Debug>) {}
    |
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
-error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
+error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
   --> $DIR/nested_impl_trait.rs:6:46
    |
 LL | fn bad_in_ret_position(x: impl Into<u32>) -> impl Into<impl Debug> { x }
-   |                                              ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`, which is required by `impl Into<u32>: Into<impl Debug>`
+   |                                              ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
    |
    = help: the trait `Into<U>` is implemented for `T`
    = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
 
-error[E0277]: the trait bound `impl Debug: From<impl Into<u32>>` is not satisfied
+error[E0277]: the trait bound `impl Into<u32>: Into<impl Debug>` is not satisfied
   --> $DIR/nested_impl_trait.rs:19:34
    |
 LL |     fn bad(x: impl Into<u32>) -> impl Into<impl Debug> { x }
-   |                                  ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Debug`, which is required by `impl Into<u32>: Into<impl Debug>`
+   |                                  ^^^^^^^^^^^^^^^^^^^^^ the trait `From<impl Into<u32>>` is not implemented for `impl Into<u32>`, which is required by `impl Into<u32>: Into<impl Debug>`
    |
    = help: the trait `Into<U>` is implemented for `T`
    = note: required for `impl Into<u32>` to implement `Into<impl Debug>`
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
index 755d12d7448..c0b399746ea 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.next.stderr
@@ -1,5 +1,5 @@
 error[E0282]: type annotations needed
-  --> $DIR/recursive-coroutine-boxed.rs:12:23
+  --> $DIR/recursive-coroutine-boxed.rs:14:23
    |
 LL |         let mut gen = Box::pin(foo());
    |                       ^^^^^^^^ cannot infer type of the type parameter `T` declared on the struct `Box`
@@ -12,12 +12,28 @@ help: consider specifying the generic argument
 LL |         let mut gen = Box::<T>::pin(foo());
    |                          +++++
 
-error[E0282]: type annotations needed
-  --> $DIR/recursive-coroutine-boxed.rs:9:13
+error[E0308]: mismatched types
+  --> $DIR/recursive-coroutine-boxed.rs:13:5
+   |
+LL |   fn foo() -> impl Coroutine<Yield = (), Return = ()> {
+   |               ---------------------------------------
+   |               |
+   |               the expected opaque type
+   |               expected `impl Coroutine<Yield = (), Return = ()>` because of return type
+...
+LL | /     || {
+LL | |         let mut gen = Box::pin(foo());
+LL | |
+LL | |         let mut r = gen.as_mut().resume(());
+...  |
+LL | |         }
+LL | |     }
+   | |_____^ types differ
    |
-LL | fn foo() -> impl Coroutine<Yield = (), Return = ()> {
-   |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for opaque type `impl Coroutine<Yield = (), Return = ()>`
+   = note: expected opaque type `impl Coroutine<Yield = (), Return = ()>`
+                found coroutine `{coroutine@$DIR/recursive-coroutine-boxed.rs:13:5: 13:7}`
 
 error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0282`.
+Some errors have detailed explanations: E0282, E0308.
+For more information about an error, try `rustc --explain E0282`.
diff --git a/tests/ui/impl-trait/recursive-coroutine-boxed.rs b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
index 3b8ffb92090..02c75be0f3a 100644
--- a/tests/ui/impl-trait/recursive-coroutine-boxed.rs
+++ b/tests/ui/impl-trait/recursive-coroutine-boxed.rs
@@ -7,8 +7,10 @@
 use std::ops::{Coroutine, CoroutineState};
 
 fn foo() -> impl Coroutine<Yield = (), Return = ()> {
-    //[next]~^ ERROR type annotations needed
-    || {
+    // FIXME(-Znext-solver): this fails with a mismatched types as the
+    // hidden type of the opaque ends up as {type error}. We should not
+    // emit errors for such goals.
+    || { //[next]~ ERROR mismatched types
         let mut gen = Box::pin(foo());
         //[next]~^ ERROR type annotations needed
         let mut r = gen.as_mut().resume(());
diff --git a/tests/ui/implied-bounds/issue-100690.rs b/tests/ui/implied-bounds/issue-100690.rs
index ea33c9f423b..041c687ec94 100644
--- a/tests/ui/implied-bounds/issue-100690.rs
+++ b/tests/ui/implied-bounds/issue-100690.rs
@@ -4,11 +4,8 @@
 use std::io;
 
 fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
-//~^ NOTE required by a bound in this
 where
     F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
-    //~^ NOTE required by this bound in `real_dispatch`
-    //~| NOTE required by a bound in `real_dispatch`
 {
     todo!()
 }
@@ -35,10 +32,10 @@ impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandl
         F: FnOnce(&mut UIView<'a, T>) -> Result<(), io::Error> + Send + 'static,
     {
         real_dispatch(f)
-        //~^ ERROR expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
-        //~| NOTE expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F`
-        //~| NOTE expected a closure with arguments
-        //~| NOTE required by a bound introduced by this call
+        //~^ ERROR lifetime may not live long enough
+        //~| ERROR implementation of `FnOnce` is not general enough
+        //~| ERROR mismatched types
+        //
     }
 }
 
diff --git a/tests/ui/implied-bounds/issue-100690.stderr b/tests/ui/implied-bounds/issue-100690.stderr
index df069d875ce..2cfd028f255 100644
--- a/tests/ui/implied-bounds/issue-100690.stderr
+++ b/tests/ui/implied-bounds/issue-100690.stderr
@@ -1,22 +1,41 @@
-error[E0277]: expected a `FnOnce(&mut UIView<'_, T>)` closure, found `F`
-  --> $DIR/issue-100690.rs:37:23
+error: lifetime may not live long enough
+  --> $DIR/issue-100690.rs:34:9
    |
+LL | impl<'a, T: 'a> Handle<'a, T, UIView<'a, T>, Result<(), io::Error>> for TUIHandle<T> {
+   |      -- lifetime `'a` defined here
+...
 LL |         real_dispatch(f)
-   |         ------------- ^ expected an `FnOnce(&mut UIView<'_, T>)` closure, found `F`
-   |         |
-   |         required by a bound introduced by this call
+   |         ^^^^^^^^^^^^^^^^ requires that `'a` must outlive `'static`
    |
-   = note: expected a closure with arguments `(&mut UIView<'a, _>,)`
-              found a closure with arguments `(&mut UIView<'_, _>,)`
-note: required by a bound in `real_dispatch`
-  --> $DIR/issue-100690.rs:9:8
+note: due to current limitations in the borrow checker, this implies a `'static` lifetime
+  --> $DIR/issue-100690.rs:8:8
+   |
+LL |     F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
+   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: implementation of `FnOnce` is not general enough
+  --> $DIR/issue-100690.rs:34:9
+   |
+LL |         real_dispatch(f)
+   |         ^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
+   |
+   = note: `F` must implement `FnOnce<(&mut UIView<'0, T>,)>`, for any lifetime `'0`...
+   = note: ...but it actually implements `FnOnce<(&mut UIView<'1, T>,)>`, for some specific lifetime `'1`
+
+error[E0308]: mismatched types
+  --> $DIR/issue-100690.rs:34:9
+   |
+LL |         real_dispatch(f)
+   |         ^^^^^^^^^^^^^^^^ one type is more general than the other
+   |
+   = note: expected associated type `<F as FnOnce<(&mut UIView<'_, T>,)>>::Output`
+              found associated type `<F as FnOnce<(&mut UIView<'_, T>,)>>::Output`
+note: the lifetime requirement is introduced here
+  --> $DIR/issue-100690.rs:8:34
    |
-LL | fn real_dispatch<T, F>(f: F) -> Result<(), io::Error>
-   |    ------------- required by a bound in this function
-...
 LL |     F: FnOnce(&mut UIView<T>) -> Result<(), io::Error> + Send + 'static,
-   |        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ required by this bound in `real_dispatch`
+   |                                  ^^^^^^^^^^^^^^^^^^^^^
 
-error: aborting due to 1 previous error
+error: aborting due to 3 previous errors
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/issues/issue-1476.rs b/tests/ui/issues/issue-1476.rs
deleted file mode 100644
index 138570a93c4..00000000000
--- a/tests/ui/issues/issue-1476.rs
+++ /dev/null
@@ -1,3 +0,0 @@
-fn main() {
-    println!("{}", x); //~ ERROR cannot find value `x` in this scope
-}
diff --git a/tests/ui/issues/issue-1476.stderr b/tests/ui/issues/issue-1476.stderr
deleted file mode 100644
index e30dbfd205b..00000000000
--- a/tests/ui/issues/issue-1476.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0425]: cannot find value `x` in this scope
-  --> $DIR/issue-1476.rs:2:20
-   |
-LL |     println!("{}", x);
-   |                    ^ not found in this scope
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/issues/issue-1696.rs b/tests/ui/issues/issue-1696.rs
deleted file mode 100644
index 08002ad3c58..00000000000
--- a/tests/ui/issues/issue-1696.rs
+++ /dev/null
@@ -1,8 +0,0 @@
-//@ run-pass
-use std::collections::HashMap;
-
-pub fn main() {
-    let mut m = HashMap::new();
-    m.insert(b"foo".to_vec(), b"bar".to_vec());
-    println!("{:?}", m);
-}
diff --git a/tests/ui/layout/ice-non-last-unsized-field-issue-121473.rs b/tests/ui/layout/ice-non-last-unsized-field-issue-121473.rs
new file mode 100644
index 00000000000..737a7ffbc29
--- /dev/null
+++ b/tests/ui/layout/ice-non-last-unsized-field-issue-121473.rs
@@ -0,0 +1,79 @@
+// Regression test for #121473
+// Checks that no ICE occurs when `size_of`
+// is applied to a struct that has an unsized
+// field which is not its last field
+
+use std::mem::size_of;
+
+pub struct BadStruct {
+    pub field1: i32,
+    pub field2: str, // Unsized field that is not the last field
+    //~^ ERROR the size for values of type `str` cannot be known at compilation time
+    pub field3: [u8; 16],
+}
+
+enum BadEnum1 {
+    Variant1 {
+        field1: i32,
+        field2: str, // Unsized
+        //~^ ERROR the size for values of type `str` cannot be known at compilation time
+        field3: [u8; 16],
+    },
+}
+
+enum BadEnum2 {
+    Variant1(
+        i32,
+        str, // Unsized
+        //~^ ERROR the size for values of type `str` cannot be known at compilation time
+        [u8; 16]
+    ),
+}
+
+enum BadEnumMultiVariant {
+    Variant1(i32),
+    Variant2 {
+        field1: i32,
+        field2: str, // Unsized
+        //~^ ERROR the size for values of type `str` cannot be known at compilation time
+        field3: [u8; 16],
+    },
+    Variant3
+}
+
+union BadUnion {
+    field1: i32,
+    field2: str, // Unsized
+    //~^ ERROR the size for values of type `str` cannot be known at compilation time
+    //~| ERROR field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+    field3: [u8; 16],
+}
+
+// Used to test that projection type fields that normalize
+// to a sized type do not cause problems
+struct StructWithProjections<'a>
+{
+    field1: <&'a [i32] as IntoIterator>::IntoIter,
+    field2: i32
+}
+
+pub fn main() {
+    let _a = &size_of::<BadStruct>();
+    assert_eq!(size_of::<BadStruct>(), 21);
+
+    let _a = &size_of::<BadEnum1>();
+    assert_eq!(size_of::<BadEnum1>(), 21);
+
+    let _a = &size_of::<BadEnum2>();
+    assert_eq!(size_of::<BadEnum2>(), 21);
+
+    let _a = &size_of::<BadEnumMultiVariant>();
+    assert_eq!(size_of::<BadEnumMultiVariant>(), 21);
+
+    let _a = &size_of::<BadUnion>();
+    assert_eq!(size_of::<BadUnion>(), 21);
+
+    let _a = &size_of::<StructWithProjections>();
+    assert_eq!(size_of::<StructWithProjections>(), 21);
+    let _a = StructWithProjections { field1: [1, 3].iter(), field2: 3 };
+}
diff --git a/tests/ui/layout/ice-non-last-unsized-field-issue-121473.stderr b/tests/ui/layout/ice-non-last-unsized-field-issue-121473.stderr
new file mode 100644
index 00000000000..626be7ac283
--- /dev/null
+++ b/tests/ui/layout/ice-non-last-unsized-field-issue-121473.stderr
@@ -0,0 +1,106 @@
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/ice-non-last-unsized-field-issue-121473.rs:10:17
+   |
+LL |     pub field2: str, // Unsized field that is not the last field
+   |                 ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: only the last field of a struct may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |     pub field2: &str, // Unsized field that is not the last field
+   |                 +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |     pub field2: Box<str>, // Unsized field that is not the last field
+   |                 ++++   +
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/ice-non-last-unsized-field-issue-121473.rs:18:17
+   |
+LL |         field2: str, // Unsized
+   |                 ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: no field of an enum variant may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |         field2: &str, // Unsized
+   |                 +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |         field2: Box<str>, // Unsized
+   |                 ++++   +
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/ice-non-last-unsized-field-issue-121473.rs:27:9
+   |
+LL |         str, // Unsized
+   |         ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: no field of an enum variant may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |         &str, // Unsized
+   |         +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |         Box<str>, // Unsized
+   |         ++++   +
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/ice-non-last-unsized-field-issue-121473.rs:37:17
+   |
+LL |         field2: str, // Unsized
+   |                 ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: no field of an enum variant may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |         field2: &str, // Unsized
+   |                 +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |         field2: Box<str>, // Unsized
+   |                 ++++   +
+
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/ice-non-last-unsized-field-issue-121473.rs:46:13
+   |
+LL |     field2: str, // Unsized
+   |             ^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = note: no field of a union may have a dynamically sized type
+   = help: change the field's type to have a statically known size
+help: borrowed types always have a statically known size
+   |
+LL |     field2: &str, // Unsized
+   |             +
+help: the `Box` type always has a statically known size and allocates its contents in the heap
+   |
+LL |     field2: Box<str>, // Unsized
+   |             ++++   +
+
+error[E0740]: field must implement `Copy` or be wrapped in `ManuallyDrop<...>` to be used in a union
+  --> $DIR/ice-non-last-unsized-field-issue-121473.rs:46:5
+   |
+LL |     field2: str, // Unsized
+   |     ^^^^^^^^^^^
+   |
+   = note: union fields must not have drop side-effects, which is currently enforced via either `Copy` or `ManuallyDrop<...>`
+help: wrap the field type in `ManuallyDrop<...>`
+   |
+LL |     field2: std::mem::ManuallyDrop<str>, // Unsized
+   |             +++++++++++++++++++++++   +
+
+error: aborting due to 6 previous errors
+
+Some errors have detailed explanations: E0277, E0740.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
index aa151fe2d21..390028b349e 100644
--- a/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
+++ b/tests/ui/lint/lint-strict-provenance-lossy-casts.stderr
@@ -4,7 +4,7 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
 LL |     let addr: usize = &x as *const u8 as usize;
    |                       ^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 note: the lint level is defined here
   --> $DIR/lint-strict-provenance-lossy-casts.rs:2:9
    |
@@ -21,7 +21,7 @@ error: under strict provenance it is considered bad style to cast pointer `*cons
 LL |     let addr_32bit = &x as *const u8 as u32;
    |                      ^^^^^^^^^^^^^^^^^^^^^^
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 help: use `.addr()` to obtain the address of a pointer
    |
 LL |     let addr_32bit = (&x as *const u8).addr() as u32;
@@ -35,7 +35,7 @@ LL |     let ptr_addr = ptr as usize;
    |                       |
    |                       help: use `.addr()` to obtain the address of a pointer: `.addr()`
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 
 error: under strict provenance it is considered bad style to cast pointer `*const u8` to integer `u32`
   --> $DIR/lint-strict-provenance-lossy-casts.rs:16:26
@@ -45,7 +45,7 @@ LL |     let ptr_addr_32bit = ptr as u32;
    |                             |
    |                             help: use `.addr()` to obtain the address of a pointer: `.addr() as u32`
    |
-   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_addr()` instead
+   = help: if you can't comply with strict provenance and need to expose the pointer provenance you can use `.expose_provenance()` instead
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/lint/non_local_definitions.rs b/tests/ui/lint/non_local_definitions.rs
index eee582a6f11..0b43e19d1e9 100644
--- a/tests/ui/lint/non_local_definitions.rs
+++ b/tests/ui/lint/non_local_definitions.rs
@@ -4,7 +4,6 @@
 //@ rustc-env:CARGO_CRATE_NAME=non_local_def
 
 #![feature(inline_const)]
-#![warn(non_local_definitions)]
 
 extern crate non_local_macro;
 
@@ -282,7 +281,6 @@ struct Cat;
 
 fn meow() {
     impl From<Cat> for () {
-    //~^ WARN non-local `impl` definition
         fn from(_: Cat) -> () {
             todo!()
         }
@@ -374,6 +372,72 @@ fn rawr() {
             todo!()
         }
     }
+
+    #[derive(Debug)]
+    struct Elephant;
+
+    impl From<Wrap<Wrap<Elephant>>> for () {
+    //~^ WARN non-local `impl` definition
+        fn from(_: Wrap<Wrap<Elephant>>) -> Self {
+            todo!()
+        }
+    }
+}
+
+pub trait StillNonLocal {}
+
+impl StillNonLocal for &str {}
+
+fn only_global() {
+    struct Foo;
+    impl StillNonLocal for &Foo {}
+    //~^ WARN non-local `impl` definition
+}
+
+struct GlobalSameFunction;
+
+fn same_function() {
+    struct Local1(GlobalSameFunction);
+    impl From<Local1> for GlobalSameFunction {
+    //~^ WARN non-local `impl` definition
+        fn from(x: Local1) -> GlobalSameFunction {
+            x.0
+        }
+    }
+
+    struct Local2(GlobalSameFunction);
+    impl From<Local2> for GlobalSameFunction {
+    //~^ WARN non-local `impl` definition
+        fn from(x: Local2) -> GlobalSameFunction {
+            x.0
+        }
+    }
+}
+
+struct GlobalDifferentFunction;
+
+fn diff_foo() {
+    struct Local(GlobalDifferentFunction);
+
+    impl From<Local> for GlobalDifferentFunction {
+    // FIXME(Urgau): Should warn but doesn't since we currently consider
+    // the other impl to be "global", but that's not the case for the type-system
+        fn from(x: Local) -> GlobalDifferentFunction {
+            x.0
+        }
+    }
+}
+
+fn diff_bar() {
+    struct Local(GlobalDifferentFunction);
+
+    impl From<Local> for GlobalDifferentFunction {
+    // FIXME(Urgau): Should warn but doesn't since we currently consider
+    // the other impl to be "global", but that's not the case for the type-system
+        fn from(x: Local) -> GlobalDifferentFunction {
+            x.0
+        }
+    }
 }
 
 macro_rules! m {
@@ -404,3 +468,24 @@ fn bitflags() {
         impl Flags {}
     };
 }
+
+// https://github.com/rust-lang/rust/issues/121621#issuecomment-1976826895
+fn commonly_reported() {
+    struct Local(u8);
+    impl From<Local> for u8 {
+        fn from(x: Local) -> u8 {
+            x.0
+        }
+    }
+}
+
+// https://github.com/rust-lang/rust/issues/121621#issue-2153187542
+pub trait Serde {}
+
+impl Serde for &[u8] {}
+impl Serde for &str {}
+
+fn serde() {
+    struct Thing;
+    impl Serde for &Thing {}
+}
diff --git a/tests/ui/lint/non_local_definitions.stderr b/tests/ui/lint/non_local_definitions.stderr
index ef74e262f9d..8ae04f2c2e8 100644
--- a/tests/ui/lint/non_local_definitions.stderr
+++ b/tests/ui/lint/non_local_definitions.stderr
@@ -1,5 +1,5 @@
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:37:5
+  --> $DIR/non_local_definitions.rs:36:5
    |
 LL | const Z: () = {
    |       - help: use a const-anon item to suppress this lint: `_`
@@ -8,61 +8,57 @@ LL |     impl Uto for &Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `Z`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
-note: the lint level is defined here
-  --> $DIR/non_local_definitions.rs:7:9
-   |
-LL | #![warn(non_local_definitions)]
-   |         ^^^^^^^^^^^^^^^^^^^^^
+   = note: `#[warn(non_local_definitions)]` on by default
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:47:5
+  --> $DIR/non_local_definitions.rs:46:5
    |
 LL |     impl Uto for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:55:9
+  --> $DIR/non_local_definitions.rs:54:9
    |
 LL |         impl Uto for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:64:5
+  --> $DIR/non_local_definitions.rs:63:5
    |
 LL |     impl Uto2 for Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current static `A`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:72:5
+  --> $DIR/non_local_definitions.rs:71:5
    |
 LL |     impl Uto3 for Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `B`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:76:5
+  --> $DIR/non_local_definitions.rs:75:5
    |
 LL |     macro_rules! m0 { () => { } };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -73,7 +69,7 @@ LL |     macro_rules! m0 { () => { } };
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:88:5
+  --> $DIR/non_local_definitions.rs:87:5
    |
 LL |     macro_rules! m { () => { } };
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +80,7 @@ LL |     macro_rules! m { () => { } };
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:91:5
+  --> $DIR/non_local_definitions.rs:90:5
    |
 LL | /     impl Test {
 LL | |
@@ -93,12 +89,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:97:9
+  --> $DIR/non_local_definitions.rs:96:9
    |
 LL | /         impl Test {
 LL | |
@@ -107,12 +103,12 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:106:9
+  --> $DIR/non_local_definitions.rs:105:9
    |
 LL | /         impl Test {
 LL | |
@@ -121,12 +117,12 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current inline constant `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:115:9
+  --> $DIR/non_local_definitions.rs:114:9
    |
 LL | /         impl Test {
 LL | |
@@ -135,12 +131,12 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current constant `_` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:123:5
+  --> $DIR/non_local_definitions.rs:122:5
    |
 LL | /     impl Display for Test {
 LL | |
@@ -151,221 +147,221 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:130:5
+  --> $DIR/non_local_definitions.rs:129:5
    |
 LL |     impl dyn Uto5 {}
    |     ^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:133:5
+  --> $DIR/non_local_definitions.rs:132:5
    |
 LL |     impl<T: Uto5> Uto5 for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:136:5
+  --> $DIR/non_local_definitions.rs:135:5
    |
 LL |     impl Uto5 for &dyn Uto5 {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:139:5
+  --> $DIR/non_local_definitions.rs:138:5
    |
 LL |     impl Uto5 for *mut Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:142:5
+  --> $DIR/non_local_definitions.rs:141:5
    |
 LL |     impl Uto5 for *mut [Test] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:145:5
+  --> $DIR/non_local_definitions.rs:144:5
    |
 LL |     impl Uto5 for [Test; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:148:5
+  --> $DIR/non_local_definitions.rs:147:5
    |
 LL |     impl Uto5 for (Test,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:151:5
+  --> $DIR/non_local_definitions.rs:150:5
    |
 LL |     impl Uto5 for fn(Test) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:154:5
+  --> $DIR/non_local_definitions.rs:153:5
    |
 LL |     impl Uto5 for fn() -> Test {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:158:9
+  --> $DIR/non_local_definitions.rs:157:9
    |
 LL |         impl Uto5 for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:165:9
+  --> $DIR/non_local_definitions.rs:164:9
    |
 LL |         impl Uto5 for &Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:172:9
+  --> $DIR/non_local_definitions.rs:171:9
    |
 LL |         impl Uto5 for &(Test,) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:179:9
+  --> $DIR/non_local_definitions.rs:178:9
    |
 LL |         impl Uto5 for &(Test,Test) {}
    |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:187:5
+  --> $DIR/non_local_definitions.rs:186:5
    |
 LL |     impl Uto5 for *mut InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:189:5
+  --> $DIR/non_local_definitions.rs:188:5
    |
 LL |     impl Uto5 for *mut [InsideMain] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:191:5
+  --> $DIR/non_local_definitions.rs:190:5
    |
 LL |     impl Uto5 for [InsideMain; 8] {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:193:5
+  --> $DIR/non_local_definitions.rs:192:5
    |
 LL |     impl Uto5 for (InsideMain,) {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:195:5
+  --> $DIR/non_local_definitions.rs:194:5
    |
 LL |     impl Uto5 for fn(InsideMain) -> () {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:197:5
+  --> $DIR/non_local_definitions.rs:196:5
    |
 LL |     impl Uto5 for fn() -> InsideMain {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:211:9
+  --> $DIR/non_local_definitions.rs:210:9
    |
 LL | /         impl Display for InsideMain {
 LL | |
@@ -376,12 +372,12 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:218:9
+  --> $DIR/non_local_definitions.rs:217:9
    |
 LL | /         impl InsideMain {
 LL | |
@@ -393,12 +389,12 @@ LL | |         }
    | |_________^
    |
    = help: move this `impl` block outside the of the current function `inside_inside` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:222:17
+  --> $DIR/non_local_definitions.rs:221:17
    |
 LL |                 macro_rules! m2 { () => { } };
    |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -409,62 +405,62 @@ LL |                 macro_rules! m2 { () => { } };
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:232:5
+  --> $DIR/non_local_definitions.rs:231:5
    |
 LL |     impl<T: Uto6> Uto3 for Vec<T> { }
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `main`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:241:5
+  --> $DIR/non_local_definitions.rs:240:5
    |
 LL |     impl Uto7 for Test where Local: std::any::Any {}
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `bad`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:244:5
+  --> $DIR/non_local_definitions.rs:243:5
    |
 LL |     impl<T> Uto8 for T {}
    |     ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current function `bad`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:252:9
+  --> $DIR/non_local_definitions.rs:251:9
    |
 LL |         impl Uto9 for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current closure `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:259:9
+  --> $DIR/non_local_definitions.rs:258:9
    |
 LL |         impl Uto10 for Test {}
    |         ^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant expression `<unnameable>` and up 2 bodies
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:273:5
+  --> $DIR/non_local_definitions.rs:272:5
    |
 LL | /     impl Default for UwU<OwO> {
 LL | |
@@ -475,28 +471,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `fun`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
-   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
-   = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
-
-warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:284:5
-   |
-LL | /     impl From<Cat> for () {
-LL | |
-LL | |         fn from(_: Cat) -> () {
-LL | |             todo!()
-LL | |         }
-LL | |     }
-   | |_____^
-   |
-   = help: move this `impl` block outside the of the current function `meow`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:293:5
+  --> $DIR/non_local_definitions.rs:291:5
    |
 LL | /     impl AsRef<Cat> for () {
 LL | |
@@ -505,12 +485,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `meow`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:304:5
+  --> $DIR/non_local_definitions.rs:302:5
    |
 LL | /     impl PartialEq<B> for G {
 LL | |
@@ -521,12 +501,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `fun2`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:321:5
+  --> $DIR/non_local_definitions.rs:319:5
    |
 LL | /     impl PartialEq<Dog> for &Dog {
 LL | |
@@ -537,12 +517,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `woof`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:328:5
+  --> $DIR/non_local_definitions.rs:326:5
    |
 LL | /     impl PartialEq<()> for Dog {
 LL | |
@@ -553,12 +533,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `woof`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:335:5
+  --> $DIR/non_local_definitions.rs:333:5
    |
 LL | /     impl PartialEq<()> for &Dog {
 LL | |
@@ -569,12 +549,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `woof`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:342:5
+  --> $DIR/non_local_definitions.rs:340:5
    |
 LL | /     impl PartialEq<Dog> for () {
 LL | |
@@ -585,12 +565,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `woof`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:364:5
+  --> $DIR/non_local_definitions.rs:362:5
    |
 LL | /     impl From<Wrap<Wrap<Lion>>> for () {
 LL | |
@@ -601,12 +581,12 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `rawr`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:371:5
+  --> $DIR/non_local_definitions.rs:369:5
    |
 LL | /     impl From<()> for Wrap<Lion> {
 LL | |
@@ -617,12 +597,71 @@ LL | |     }
    | |_____^
    |
    = help: move this `impl` block outside the of the current function `rawr`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
+   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
+
+warning: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:379:5
+   |
+LL | /     impl From<Wrap<Wrap<Elephant>>> for () {
+LL | |
+LL | |         fn from(_: Wrap<Wrap<Elephant>>) -> Self {
+LL | |             todo!()
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = help: move this `impl` block outside the of the current function `rawr`
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
+   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
+
+warning: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:393:5
+   |
+LL |     impl StillNonLocal for &Foo {}
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = help: move this `impl` block outside the of the current function `only_global`
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
+   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
+
+warning: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:401:5
+   |
+LL | /     impl From<Local1> for GlobalSameFunction {
+LL | |
+LL | |         fn from(x: Local1) -> GlobalSameFunction {
+LL | |             x.0
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = help: move this `impl` block outside the of the current function `same_function`
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
+   = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
+   = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
+
+warning: non-local `impl` definition, they should be avoided as they go against expectation
+  --> $DIR/non_local_definitions.rs:409:5
+   |
+LL | /     impl From<Local2> for GlobalSameFunction {
+LL | |
+LL | |         fn from(x: Local2) -> GlobalSameFunction {
+LL | |             x.0
+LL | |         }
+LL | |     }
+   | |_____^
+   |
+   = help: move this `impl` block outside the of the current function `same_function`
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:384:13
+  --> $DIR/non_local_definitions.rs:448:13
    |
 LL |             impl MacroTrait for OutsideStruct {}
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -631,26 +670,26 @@ LL | m!();
    | ---- in this macro invocation
    |
    = help: move this `impl` block outside the of the current function `my_func`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
    = note: this warning originates in the macro `m` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: non-local `impl` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:394:1
+  --> $DIR/non_local_definitions.rs:458:1
    |
 LL | non_local_macro::non_local_impl!(CargoUpdate);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
    = help: move this `impl` block outside the of the current constant `_IMPL_DEBUG`
-   = note: an `impl` definition is non-local if it is nested inside an item and neither the type nor the trait are at the same nesting level as the `impl` block
+   = note: an `impl` definition is non-local if it is nested inside an item and may impact type checking outside of that item. This can be the case if neither the trait or the self type are at the same nesting level as the `impl`
    = note: one exception to the rule are anon-const (`const _: () = { ... }`) at top-level module and anon-const at the same nesting as the trait or type
    = note: this lint may become deny-by-default in the edition 2024 and higher, see the tracking issue <https://github.com/rust-lang/rust/issues/120363>
    = note: the macro `non_local_macro::non_local_impl` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro`
    = note: this warning originates in the macro `non_local_macro::non_local_impl` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 warning: non-local `macro_rules!` definition, they should be avoided as they go against expectation
-  --> $DIR/non_local_definitions.rs:397:1
+  --> $DIR/non_local_definitions.rs:461:1
    |
 LL | non_local_macro::non_local_macro_rules!(my_macro);
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -662,5 +701,5 @@ LL | non_local_macro::non_local_macro_rules!(my_macro);
    = note: the macro `non_local_macro::non_local_macro_rules` may come from an old version of the `non_local_macro` crate, try updating your dependency with `cargo update -p non_local_macro`
    = note: this warning originates in the macro `non_local_macro::non_local_macro_rules` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-warning: 52 warnings emitted
+warning: 55 warnings emitted
 
diff --git a/tests/ui/issues/issue-1962.fixed b/tests/ui/loops/issue-1962.fixed
index f0002be4bea..f0002be4bea 100644
--- a/tests/ui/issues/issue-1962.fixed
+++ b/tests/ui/loops/issue-1962.fixed
diff --git a/tests/ui/issues/issue-1962.rs b/tests/ui/loops/issue-1962.rs
index 9c8fb500ba3..9c8fb500ba3 100644
--- a/tests/ui/issues/issue-1962.rs
+++ b/tests/ui/loops/issue-1962.rs
diff --git a/tests/ui/issues/issue-1962.stderr b/tests/ui/loops/issue-1962.stderr
index db235d47303..db235d47303 100644
--- a/tests/ui/issues/issue-1962.stderr
+++ b/tests/ui/loops/issue-1962.stderr
diff --git a/tests/ui/issues/issue-1974.rs b/tests/ui/loops/issue-1974.rs
index ea67b2541de..ea67b2541de 100644
--- a/tests/ui/issues/issue-1974.rs
+++ b/tests/ui/loops/issue-1974.rs
diff --git a/tests/ui/match/postfix-match/match-after-as.rs b/tests/ui/match/postfix-match/match-after-as.rs
new file mode 100644
index 00000000000..7c648bfcf03
--- /dev/null
+++ b/tests/ui/match/postfix-match/match-after-as.rs
@@ -0,0 +1,7 @@
+#![feature(postfix_match)]
+
+fn main() {
+    1 as i32.match {};
+    //~^ ERROR cast cannot be followed by a postfix match
+    //~| ERROR non-exhaustive patterns
+}
diff --git a/tests/ui/match/postfix-match/match-after-as.stderr b/tests/ui/match/postfix-match/match-after-as.stderr
new file mode 100644
index 00000000000..68e4762b8d9
--- /dev/null
+++ b/tests/ui/match/postfix-match/match-after-as.stderr
@@ -0,0 +1,28 @@
+error: cast cannot be followed by a postfix match
+  --> $DIR/match-after-as.rs:4:5
+   |
+LL |     1 as i32.match {};
+   |     ^^^^^^^^
+   |
+help: try surrounding the expression in parentheses
+   |
+LL |     (1 as i32).match {};
+   |     +        +
+
+error[E0004]: non-exhaustive patterns: type `i32` is non-empty
+  --> $DIR/match-after-as.rs:4:5
+   |
+LL |     1 as i32.match {};
+   |     ^^^^^^^^
+   |
+   = note: the matched value is of type `i32`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
+   |
+LL ~     1 as i32.match {
+LL +         _ => todo!(),
+LL ~     };
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs b/tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs
new file mode 100644
index 00000000000..9dd7a7893ec
--- /dev/null
+++ b/tests/ui/match/ref_pat_everywhere-mutability-mismatch.rs
@@ -0,0 +1,16 @@
+#![allow(incomplete_features)]
+#![feature(ref_pat_everywhere)]
+pub fn main() {
+    if let Some(&x) = Some(0) {
+        //~^ ERROR: mismatched types [E0308]
+        let _: u32 = x;
+    }
+    if let &Some(x) = &mut Some(0) {
+        //~^ ERROR: mismatched types [E0308]
+        let _: u32 = x;
+    }
+    if let Some(&x) = &mut Some(0) {
+        //~^ ERROR: mismatched types [E0308]
+        let _: u32 = x;
+    }
+}
diff --git a/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr b/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr
new file mode 100644
index 00000000000..d512ea5f957
--- /dev/null
+++ b/tests/ui/match/ref_pat_everywhere-mutability-mismatch.stderr
@@ -0,0 +1,44 @@
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:4:17
+   |
+LL |     if let Some(&x) = Some(0) {
+   |                 ^^    ------- this expression has type `Option<{integer}>`
+   |                 |
+   |                 expected integer, found `&_`
+   |
+   = note:   expected type `{integer}`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL |     if let Some(x) = Some(0) {
+   |                 ~
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:8:12
+   |
+LL |     if let &Some(x) = &mut Some(0) {
+   |            ^^^^^^^^   ------------ this expression has type `&mut Option<{integer}>`
+   |            |
+   |            types differ in mutability
+   |
+   = note: expected mutable reference `&mut Option<{integer}>`
+                      found reference `&_`
+
+error[E0308]: mismatched types
+  --> $DIR/ref_pat_everywhere-mutability-mismatch.rs:12:17
+   |
+LL |     if let Some(&x) = &mut Some(0) {
+   |                 ^^    ------------ this expression has type `&mut Option<{integer}>`
+   |                 |
+   |                 expected integer, found `&_`
+   |
+   = note:   expected type `{integer}`
+           found reference `&_`
+help: consider removing `&` from the pattern
+   |
+LL |     if let Some(x) = &mut Some(0) {
+   |                 ~
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/match/ref_pat_everywhere.rs b/tests/ui/match/ref_pat_everywhere.rs
new file mode 100644
index 00000000000..b3daca48409
--- /dev/null
+++ b/tests/ui/match/ref_pat_everywhere.rs
@@ -0,0 +1,18 @@
+//@ run-pass
+#![allow(incomplete_features)]
+#![feature(ref_pat_everywhere)]
+
+pub fn main() {
+    if let Some(Some(&x)) = &Some(&Some(0)) {
+        let _: u32 = x;
+    }
+    if let Some(&Some(x)) = &Some(Some(0)) {
+        let _: u32 = x;
+    }
+    if let Some(Some(&mut x)) = &mut Some(&mut Some(0)) {
+        let _: u32 = x;
+    }
+    if let Some(Some(&x)) = &Some(&mut Some(0)) {
+        let _: u32 = x;
+    }
+}
diff --git a/tests/ui/methods/opaque_param_in_ufc.rs b/tests/ui/methods/opaque_param_in_ufc.rs
new file mode 100644
index 00000000000..a4b27a0131f
--- /dev/null
+++ b/tests/ui/methods/opaque_param_in_ufc.rs
@@ -0,0 +1,30 @@
+#![feature(type_alias_impl_trait)]
+struct Foo<T>(T);
+
+impl Foo<u32> {
+    fn method() {}
+    fn method2(self) {}
+}
+
+type Bar = impl Sized;
+
+fn bar() -> Bar {
+    42_u32
+}
+
+impl Foo<Bar> {
+    fn foo() -> Bar {
+        Self::method();
+        //~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
+        Foo::<Bar>::method();
+        //~^ ERROR: no function or associated item named `method` found for struct `Foo<Bar>`
+        let x = Foo(bar());
+        Foo::method2(x);
+        let x = Self(bar());
+        Self::method2(x);
+        //~^ ERROR: no function or associated item named `method2` found for struct `Foo<Bar>`
+        todo!()
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/methods/opaque_param_in_ufc.stderr b/tests/ui/methods/opaque_param_in_ufc.stderr
new file mode 100644
index 00000000000..7e5bbbac8a9
--- /dev/null
+++ b/tests/ui/methods/opaque_param_in_ufc.stderr
@@ -0,0 +1,36 @@
+error[E0599]: no function or associated item named `method` found for struct `Foo<Bar>` in the current scope
+  --> $DIR/opaque_param_in_ufc.rs:17:15
+   |
+LL | struct Foo<T>(T);
+   | ------------- function or associated item `method` not found for this struct
+...
+LL |         Self::method();
+   |               ^^^^^^ function or associated item not found in `Foo<Bar>`
+   |
+   = note: the function or associated item was found for
+           - `Foo<u32>`
+
+error[E0599]: no function or associated item named `method` found for struct `Foo<Bar>` in the current scope
+  --> $DIR/opaque_param_in_ufc.rs:19:21
+   |
+LL | struct Foo<T>(T);
+   | ------------- function or associated item `method` not found for this struct
+...
+LL |         Foo::<Bar>::method();
+   |                     ^^^^^^ function or associated item not found in `Foo<Bar>`
+   |
+   = note: the function or associated item was found for
+           - `Foo<u32>`
+
+error[E0599]: no function or associated item named `method2` found for struct `Foo<Bar>` in the current scope
+  --> $DIR/opaque_param_in_ufc.rs:24:15
+   |
+LL | struct Foo<T>(T);
+   | ------------- function or associated item `method2` not found for this struct
+...
+LL |         Self::method2(x);
+   |               ^^^^^^^ function or associated item not found in `Foo<Bar>`
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0599`.
diff --git a/tests/ui/mir/const_eval_select_cycle.rs b/tests/ui/mir/const_eval_select_cycle.rs
new file mode 100644
index 00000000000..0b84455b2f7
--- /dev/null
+++ b/tests/ui/mir/const_eval_select_cycle.rs
@@ -0,0 +1,18 @@
+// Regression test for #122659
+//@ build-pass
+//@ compile-flags: -O --crate-type=lib
+
+#![feature(core_intrinsics)]
+#![feature(const_eval_select)]
+
+use std::intrinsics::const_eval_select;
+
+#[inline]
+pub const fn f() {
+    const_eval_select((), g, g)
+}
+
+#[inline]
+pub const fn g() {
+    const_eval_select((), f, f)
+}
diff --git a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs
new file mode 100644
index 00000000000..2bd10e762d9
--- /dev/null
+++ b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.rs
@@ -0,0 +1,14 @@
+fn foo<T>(a: T, b: T) {}
+fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
+fn foo_multi_generics<S, T>(a: T, b: T, c: T, d: T, e: T, f: S, g: S) {}
+
+fn main() {
+    foo(1, 2.);
+    //~^  ERROR mismatched types
+    foo_multi_same("a", "b", false, true, (), 32);
+    //~^  ERROR arguments to this function are incorrect
+    foo_multi_generics("a", "b", "c", true, false, 32, 2.);
+    //~^  ERROR arguments to this function are incorrect
+    foo_multi_same("a", 1, 2, "d", "e", 32);
+    //~^  ERROR arguments to this function are incorrect
+}
diff --git a/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
new file mode 100644
index 00000000000..a845dfabe93
--- /dev/null
+++ b/tests/ui/mismatched_types/generic-mismatch-reporting-issue-116615.stderr
@@ -0,0 +1,97 @@
+error[E0308]: mismatched types
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:6:12
+   |
+LL |     foo(1, 2.);
+   |     --- -  ^^ expected integer, found floating-point number
+   |     |   |
+   |     |   expected all arguments to be this integer type because they need to match the type of this parameter
+   |     arguments to this function are incorrect
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:1:4
+   |
+LL | fn foo<T>(a: T, b: T) {}
+   |    ^^^ -  ----  ---- this parameter needs to match the integer type of `a`
+   |        |  |
+   |        |  `b` needs to match the integer type of this parameter
+   |        `a` and `b` all reference this parameter T
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:8:5
+   |
+LL |     foo_multi_same("a", "b", false, true, (), 32);
+   |     ^^^^^^^^^^^^^^ ---  ---  -----  ----  -- expected `&str`, found `()`
+   |                    |    |    |      |
+   |                    |    |    |      expected `&str`, found `bool`
+   |                    |    |    expected `&str`, found `bool`
+   |                    |    expected some other arguments to be an `&str` type to match the type of this parameter
+   |                    expected some other arguments to be an `&str` type to match the type of this parameter
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:2:4
+   |
+LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
+   |    ^^^^^^^^^^^^^^ -  ----  ----  ----  ----  ----  ------
+   |                   |  |     |     |     |     |
+   |                   |  |     |     |     |     this parameter needs to match the `&str` type of `a` and `b`
+   |                   |  |     |     |     this parameter needs to match the `&str` type of `a` and `b`
+   |                   |  |     |     this parameter needs to match the `&str` type of `a` and `b`
+   |                   |  |     `c`, `d` and `e` need to match the `&str` type of this parameter
+   |                   |  `c`, `d` and `e` need to match the `&str` type of this parameter
+   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter T
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:10:5
+   |
+LL |     foo_multi_generics("a", "b", "c", true, false, 32, 2.);
+   |     ^^^^^^^^^^^^^^^^^^ ---  ---  ---  ----  -----  --  -- expected integer, found floating-point number
+   |                        |    |    |    |     |      |
+   |                        |    |    |    |     |      expected some other arguments to be an integer type to match the type of this parameter
+   |                        |    |    |    |     expected `&str`, found `bool`
+   |                        |    |    |    expected `&str`, found `bool`
+   |                        |    |    expected some other arguments to be an `&str` type to match the type of this parameter
+   |                        |    expected some other arguments to be an `&str` type to match the type of this parameter
+   |                        expected some other arguments to be an `&str` type to match the type of this parameter
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:3:4
+   |
+LL | fn foo_multi_generics<S, T>(a: T, b: T, c: T, d: T, e: T, f: S, g: S) {}
+   |    ^^^^^^^^^^^^^^^^^^ -  -  ----  ----  ----  ----  ----  ----  ---- this parameter needs to match the integer type of `f`
+   |                       |  |  |     |     |     |     |     |
+   |                       |  |  |     |     |     |     |     `g` needs to match the integer type of this parameter
+   |                       |  |  |     |     |     |     this parameter needs to match the `&str` type of `a`, `b` and `c`
+   |                       |  |  |     |     |     this parameter needs to match the `&str` type of `a`, `b` and `c`
+   |                       |  |  |     |     `d` and `e` need to match the `&str` type of this parameter
+   |                       |  |  |     `d` and `e` need to match the `&str` type of this parameter
+   |                       |  |  `d` and `e` need to match the `&str` type of this parameter
+   |                       |  `a`, `b`, `c`, `d` and `e` all reference this parameter T
+   |                       `f` and `g` all reference this parameter S
+
+error[E0308]: arguments to this function are incorrect
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:12:5
+   |
+LL |     foo_multi_same("a", 1, 2, "d", "e", 32);
+   |     ^^^^^^^^^^^^^^ ---  -  -  ---  --- expected some other arguments to be an `&str` type to match the type of this parameter
+   |                    |    |  |  |
+   |                    |    |  |  expected some other arguments to be an `&str` type to match the type of this parameter
+   |                    |    |  expected `&str`, found integer
+   |                    |    expected `&str`, found integer
+   |                    expected some other arguments to be an `&str` type to match the type of this parameter
+   |
+note: function defined here
+  --> $DIR/generic-mismatch-reporting-issue-116615.rs:2:4
+   |
+LL | fn foo_multi_same<T>(a: T, b: T, c: T, d: T, e: T, f: i32) {}
+   |    ^^^^^^^^^^^^^^ -  ----  ----  ----  ----  ----  ------
+   |                   |  |     |     |     |     |
+   |                   |  |     |     |     |     `b` and `c` need to match the `&str` type of this parameter
+   |                   |  |     |     |     `b` and `c` need to match the `&str` type of this parameter
+   |                   |  |     |     this parameter needs to match the `&str` type of `a`, `d` and `e`
+   |                   |  |     this parameter needs to match the `&str` type of `a`, `d` and `e`
+   |                   |  `b` and `c` need to match the `&str` type of this parameter
+   |                   `a`, `b`, `c`, `d` and `e` all reference this parameter T
+
+error: aborting due to 4 previous errors
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/issues/issue-1362.rs b/tests/ui/mismatched_types/issue-1362.rs
index 6fd43f50e4d..6fd43f50e4d 100644
--- a/tests/ui/issues/issue-1362.rs
+++ b/tests/ui/mismatched_types/issue-1362.rs
diff --git a/tests/ui/issues/issue-1362.stderr b/tests/ui/mismatched_types/issue-1362.stderr
index 6f6fdff6678..6f6fdff6678 100644
--- a/tests/ui/issues/issue-1362.stderr
+++ b/tests/ui/mismatched_types/issue-1362.stderr
diff --git a/tests/ui/issues/issue-1448-2.rs b/tests/ui/mismatched_types/issue-1448-2.rs
index 829e81b9c24..829e81b9c24 100644
--- a/tests/ui/issues/issue-1448-2.rs
+++ b/tests/ui/mismatched_types/issue-1448-2.rs
diff --git a/tests/ui/issues/issue-1448-2.stderr b/tests/ui/mismatched_types/issue-1448-2.stderr
index a6f1daefe63..a6f1daefe63 100644
--- a/tests/ui/issues/issue-1448-2.stderr
+++ b/tests/ui/mismatched_types/issue-1448-2.stderr
diff --git a/tests/ui/nll/match-cfg-fake-edges.rs b/tests/ui/nll/match-cfg-fake-edges.rs
index 1afc7931a6b..e349c2c8e2a 100644
--- a/tests/ui/nll/match-cfg-fake-edges.rs
+++ b/tests/ui/nll/match-cfg-fake-edges.rs
@@ -3,10 +3,46 @@
 
 #![feature(if_let_guard)]
 
+#[rustfmt::skip]
+fn all_patterns_are_tested() {
+    // Even though `x` is never actually moved out of, we don't want borrowck results to be based on
+    // whether MIR lowering reveals which patterns are unreachable.
+    let x = String::new();
+    match true {
+        _ => {},
+        _ => drop(x),
+    }
+    // Borrowck must not know the second arm is never run.
+    drop(x); //~ ERROR use of moved value
+
+    let x = String::new();
+    if let _ = true { //~ WARN irrefutable
+    } else {
+        drop(x)
+    }
+    // Borrowck must not know the else branch is never run.
+    drop(x); //~ ERROR use of moved value
+
+    let x = (String::new(), String::new());
+    match x {
+        (y, _) | (_, y) => (),
+    }
+    &x.0; //~ ERROR borrow of moved value
+    // Borrowck must not know the second pattern never matches.
+    &x.1; //~ ERROR borrow of moved value
+
+    let x = (String::new(), String::new());
+    let ((y, _) | (_, y)) = x;
+    &x.0; //~ ERROR borrow of moved value
+    // Borrowck must not know the second pattern never matches.
+    &x.1; //~ ERROR borrow of moved value
+}
+
+#[rustfmt::skip]
 fn guard_always_precedes_arm(y: i32) {
-    let mut x;
     // x should always be initialized, as the only way to reach the arm is
     // through the guard.
+    let mut x;
     match y {
         0 | 2 if { x = 2; true } => x,
         _ => 2,
@@ -14,56 +50,69 @@ fn guard_always_precedes_arm(y: i32) {
 
     let mut x;
     match y {
+        _ => 2,
+        0 | 2 if { x = 2; true } => x,
+    };
+
+    let mut x;
+    match y {
         0 | 2 if let Some(()) = { x = 2; Some(()) } => x,
         _ => 2,
     };
 }
 
+#[rustfmt::skip]
 fn guard_may_be_skipped(y: i32) {
+    // Even though x *is* always initialized, we don't want to have borrowck results be based on
+    // whether MIR lowering reveals which patterns are exhaustive.
+    let x;
+    match y {
+        _ if { x = 2; true } => {},
+        // Borrowck must not know the guard is always run.
+        _ => drop(x), //~ ERROR used binding `x` is possibly-uninitialized
+    };
+
     let x;
-    // Even though x *is* always initialized, we don't want to have borrowck
-    // results be based on whether patterns are exhaustive.
     match y {
         _ if { x = 2; true } => 1,
-        _ if {
-            x; //~ ERROR E0381
-            false
-        } => 2,
+        // Borrowck must not know the guard is always run.
+        _ if { x; false } => 2, //~ ERROR used binding `x` isn't initialized
         _ => 3,
     };
 
     let x;
     match y {
         _ if let Some(()) = { x = 2; Some(()) } => 1,
-        _ if let Some(()) = {
-            x; //~ ERROR E0381
-            None
-        } => 2,
+        _ if let Some(()) = { x; None } => 2, //~ ERROR used binding `x` isn't initialized
         _ => 3,
     };
 }
 
+#[rustfmt::skip]
 fn guard_may_be_taken(y: bool) {
-    let x = String::new();
     // Even though x *is* never moved before the use, we don't want to have
     // borrowck results be based on whether patterns are disjoint.
+    let x = String::new();
+    match y {
+        false if { drop(x); true } => {},
+        // Borrowck must not know the guard is not run in the `true` case.
+        true => drop(x), //~ ERROR use of moved value: `x`
+        false => {},
+    };
+
+    // Fine in the other order.
+    let x = String::new();
     match y {
-        false if { drop(x); true } => 1,
-        true => {
-            x; //~ ERROR use of moved value: `x`
-            2
-        }
-        false => 3,
+        true => drop(x),
+        false if { drop(x); true } => {},
+        false => {},
     };
 
     let x = String::new();
     match y {
-        false if let Some(()) = { drop(x); Some(()) } => 1,
-        true => {
-            x; //~ ERROR use of moved value: `x`
-            2
-        }
-        false => 3,
+        false if let Some(()) = { drop(x); Some(()) } => {},
+        true => drop(x), //~ ERROR use of moved value: `x`
+        false => {},
     };
 }
 
diff --git a/tests/ui/nll/match-cfg-fake-edges.stderr b/tests/ui/nll/match-cfg-fake-edges.stderr
index a6261345cea..d692ded36fa 100644
--- a/tests/ui/nll/match-cfg-fake-edges.stderr
+++ b/tests/ui/nll/match-cfg-fake-edges.stderr
@@ -1,14 +1,128 @@
-error[E0381]: used binding `x` isn't initialized
-  --> $DIR/match-cfg-fake-edges.rs:29:13
+warning: irrefutable `if let` pattern
+  --> $DIR/match-cfg-fake-edges.rs:19:8
+   |
+LL |     if let _ = true {
+   |        ^^^^^^^^^^^^
+   |
+   = note: this pattern will always match, so the `if let` is useless
+   = help: consider replacing the `if let` with a `let`
+   = note: `#[warn(irrefutable_let_patterns)]` on by default
+
+error[E0382]: use of moved value: `x`
+  --> $DIR/match-cfg-fake-edges.rs:16:10
+   |
+LL |     let x = String::new();
+   |         - move occurs because `x` has type `String`, which does not implement the `Copy` trait
+...
+LL |         _ => drop(x),
+   |                   - value moved here
+...
+LL |     drop(x);
+   |          ^ value used here after move
+   |
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL |         _ => drop(x.clone()),
+   |                    ++++++++
+
+error[E0382]: use of moved value: `x`
+  --> $DIR/match-cfg-fake-edges.rs:24:10
+   |
+LL |     let x = String::new();
+   |         - move occurs because `x` has type `String`, which does not implement the `Copy` trait
+...
+LL |         drop(x)
+   |              - value moved here
+...
+LL |     drop(x);
+   |          ^ value used here after move
+   |
+help: consider cloning the value if the performance cost is acceptable
+   |
+LL |         drop(x.clone())
+   |               ++++++++
+
+error[E0382]: borrow of moved value: `x.0`
+  --> $DIR/match-cfg-fake-edges.rs:30:5
+   |
+LL |         (y, _) | (_, y) => (),
+   |          - value moved here
+LL |     }
+LL |     &x.0;
+   |     ^^^^ value borrowed here after move
+   |
+   = note: move occurs because `x.0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |         (ref y, _) | (_, y) => (),
+   |          +++
+
+error[E0382]: borrow of moved value: `x.1`
+  --> $DIR/match-cfg-fake-edges.rs:32:5
+   |
+LL |         (y, _) | (_, y) => (),
+   |                      - value moved here
+...
+LL |     &x.1;
+   |     ^^^^ value borrowed here after move
+   |
+   = note: move occurs because `x.1` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |         (y, _) | (_, ref y) => (),
+   |                      +++
+
+error[E0382]: borrow of moved value: `x.0`
+  --> $DIR/match-cfg-fake-edges.rs:36:5
+   |
+LL |     let ((y, _) | (_, y)) = x;
+   |           - value moved here
+LL |     &x.0;
+   |     ^^^^ value borrowed here after move
+   |
+   = note: move occurs because `x.0` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |     let ((ref y, _) | (_, y)) = x;
+   |           +++
+
+error[E0382]: borrow of moved value: `x.1`
+  --> $DIR/match-cfg-fake-edges.rs:38:5
+   |
+LL |     let ((y, _) | (_, y)) = x;
+   |                       - value moved here
+...
+LL |     &x.1;
+   |     ^^^^ value borrowed here after move
+   |
+   = note: move occurs because `x.1` has type `String`, which does not implement the `Copy` trait
+help: borrow this binding in the pattern to avoid moving the value
+   |
+LL |     let ((y, _) | (_, ref y)) = x;
+   |                       +++
+
+error[E0381]: used binding `x` is possibly-uninitialized
+  --> $DIR/match-cfg-fake-edges.rs:72:19
    |
 LL |     let x;
    |         - binding declared here but left uninitialized
 ...
+LL |         _ => drop(x),
+   |         -         ^ `x` used here but it is possibly-uninitialized
+   |         |
+   |         if this pattern is matched, `x` is not initialized
+
+error[E0381]: used binding `x` isn't initialized
+  --> $DIR/match-cfg-fake-edges.rs:79:16
+   |
+LL |     let x;
+   |         - binding declared here but left uninitialized
+LL |     match y {
 LL |         _ if { x = 2; true } => 1,
    |                ----- binding initialized here in some conditions
-LL |         _ if {
-LL |             x;
-   |             ^ `x` used here but it isn't initialized
+LL |         // Borrowck must not know the guard is always run.
+LL |         _ if { x; false } => 2,
+   |                ^ `x` used here but it isn't initialized
    |
 help: consider assigning a value
    |
@@ -16,16 +130,15 @@ LL |     let x = 0;
    |           +++
 
 error[E0381]: used binding `x` isn't initialized
-  --> $DIR/match-cfg-fake-edges.rs:39:13
+  --> $DIR/match-cfg-fake-edges.rs:86:31
    |
 LL |     let x;
    |         - binding declared here but left uninitialized
 LL |     match y {
 LL |         _ if let Some(()) = { x = 2; Some(()) } => 1,
    |                               ----- binding initialized here in some conditions
-LL |         _ if let Some(()) = {
-LL |             x;
-   |             ^ `x` used here but it isn't initialized
+LL |         _ if let Some(()) = { x; None } => 2,
+   |                               ^ `x` used here but it isn't initialized
    |
 help: consider assigning a value
    |
@@ -33,40 +146,39 @@ LL |     let x = 0;
    |           +++
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/match-cfg-fake-edges.rs:53:13
+  --> $DIR/match-cfg-fake-edges.rs:99:22
    |
 LL |     let x = String::new();
    |         - move occurs because `x` has type `String`, which does not implement the `Copy` trait
-...
-LL |         false if { drop(x); true } => 1,
+LL |     match y {
+LL |         false if { drop(x); true } => {},
    |                         - value moved here
-LL |         true => {
-LL |             x;
-   |             ^ value used here after move
+LL |         // Borrowck must not know the guard is not run in the `true` case.
+LL |         true => drop(x),
+   |                      ^ value used here after move
    |
 help: consider cloning the value if the performance cost is acceptable
    |
-LL |         false if { drop(x.clone()); true } => 1,
+LL |         false if { drop(x.clone()); true } => {},
    |                          ++++++++
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/match-cfg-fake-edges.rs:63:13
+  --> $DIR/match-cfg-fake-edges.rs:114:22
    |
 LL |     let x = String::new();
    |         - move occurs because `x` has type `String`, which does not implement the `Copy` trait
 LL |     match y {
-LL |         false if let Some(()) = { drop(x); Some(()) } => 1,
+LL |         false if let Some(()) = { drop(x); Some(()) } => {},
    |                                        - value moved here
-LL |         true => {
-LL |             x;
-   |             ^ value used here after move
+LL |         true => drop(x),
+   |                      ^ value used here after move
    |
 help: consider cloning the value if the performance cost is acceptable
    |
-LL |         false if let Some(()) = { drop(x.clone()); Some(()) } => 1,
+LL |         false if let Some(()) = { drop(x.clone()); Some(()) } => {},
    |                                         ++++++++
 
-error: aborting due to 4 previous errors
+error: aborting due to 11 previous errors; 1 warning emitted
 
 Some errors have detailed explanations: E0381, E0382.
 For more information about an error, try `rustc --explain E0381`.
diff --git a/tests/ui/nll/match-cfg-fake-edges2.rs b/tests/ui/nll/match-cfg-fake-edges2.rs
index 48f95e03b78..ac90fb9cd1e 100644
--- a/tests/ui/nll/match-cfg-fake-edges2.rs
+++ b/tests/ui/nll/match-cfg-fake-edges2.rs
@@ -5,13 +5,20 @@ fn all_previous_tests_may_be_done(y: &mut (bool, bool)) {
     let r = &mut y.1;
     // We don't actually test y.1 to select the second arm, but we don't want
     // borrowck results to be based on the order we match patterns.
-    match y { //~ ERROR cannot use `y.1` because it was mutably borrowed
-        (false, true) => 1,
-        (true, _) => {
-            r;
-            2
-        }
-        (false, _) => 3,
+    match y {
+        //~^ ERROR cannot use `y.1` because it was mutably borrowed
+        (false, true) => {}
+        // Borrowck must not know we don't test `y.1` when `y.0` is `true`.
+        (true, _) => drop(r),
+        (false, _) => {}
+    };
+
+    // Fine in the other order.
+    let r = &mut y.1;
+    match y {
+        (true, _) => drop(r),
+        (false, true) => {}
+        (false, _) => {}
     };
 }
 
diff --git a/tests/ui/nll/match-cfg-fake-edges2.stderr b/tests/ui/nll/match-cfg-fake-edges2.stderr
index 639cba1406a..0a228d62b92 100644
--- a/tests/ui/nll/match-cfg-fake-edges2.stderr
+++ b/tests/ui/nll/match-cfg-fake-edges2.stderr
@@ -7,8 +7,8 @@ LL |     let r = &mut y.1;
 LL |     match y {
    |     ^^^^^^^ use of borrowed `y.1`
 ...
-LL |             r;
-   |             - borrow later used here
+LL |         (true, _) => drop(r),
+   |                           - borrow later used here
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/fn-header-semantic-fail.rs b/tests/ui/parser/fn-header-semantic-fail.rs
index 25d7c3f35fc..6ed173b6854 100644
--- a/tests/ui/parser/fn-header-semantic-fail.rs
+++ b/tests/ui/parser/fn-header-semantic-fail.rs
@@ -48,6 +48,9 @@ fn main() {
         const fn fe3(); //~ ERROR functions in `extern` blocks cannot have qualifiers
         extern "C" fn fe4(); //~ ERROR functions in `extern` blocks cannot have qualifiers
         const async unsafe extern "C" fn fe5(); //~ ERROR functions in `extern` blocks
-        //~^ ERROR functions cannot be both `const` and `async`
+        //~| ERROR functions in `extern` blocks
+        //~| ERROR functions in `extern` blocks
+        //~| ERROR functions in `extern` blocks
+        //~| ERROR functions cannot be both `const` and `async`
     }
 }
diff --git a/tests/ui/parser/fn-header-semantic-fail.stderr b/tests/ui/parser/fn-header-semantic-fail.stderr
index 696d8e01b63..cfc54839eb7 100644
--- a/tests/ui/parser/fn-header-semantic-fail.stderr
+++ b/tests/ui/parser/fn-header-semantic-fail.stderr
@@ -71,73 +71,75 @@ LL |         const async unsafe extern "C" fn fi5() {}
    |         `const` because of this
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:46:18
+  --> $DIR/fn-header-semantic-fail.rs:46:9
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
 LL |         async fn fe1();
-   |                  ^^^
-   |
-help: remove the qualifiers
-   |
-LL |         fn fe1();
-   |         ~~
+   |         ^^^^^ help: remove this qualifier
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:47:19
+  --> $DIR/fn-header-semantic-fail.rs:47:9
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
 LL |         async fn fe1();
 LL |         unsafe fn fe2();
-   |                   ^^^
-   |
-help: remove the qualifiers
-   |
-LL |         fn fe2();
-   |         ~~
+   |         ^^^^^^ help: remove this qualifier
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:48:18
+  --> $DIR/fn-header-semantic-fail.rs:48:9
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
 ...
 LL |         const fn fe3();
-   |                  ^^^
-   |
-help: remove the qualifiers
-   |
-LL |         fn fe3();
-   |         ~~
+   |         ^^^^^ help: remove this qualifier
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:49:23
+  --> $DIR/fn-header-semantic-fail.rs:49:9
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
 ...
 LL |         extern "C" fn fe4();
-   |                       ^^^
-   |
-help: remove the qualifiers
+   |         ^^^^^^^^^^ help: remove this qualifier
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:50:21
    |
-LL |         fn fe4();
-   |         ~~
+LL |     extern "C" {
+   |     ---------- in this `extern` block
+...
+LL |         const async unsafe extern "C" fn fe5();
+   |                     ^^^^^^ help: remove this qualifier
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/fn-header-semantic-fail.rs:50:42
+  --> $DIR/fn-header-semantic-fail.rs:50:15
    |
 LL |     extern "C" {
    |     ---------- in this `extern` block
 ...
 LL |         const async unsafe extern "C" fn fe5();
-   |                                          ^^^
+   |               ^^^^^ help: remove this qualifier
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:50:9
    |
-help: remove the qualifiers
+LL |     extern "C" {
+   |     ---------- in this `extern` block
+...
+LL |         const async unsafe extern "C" fn fe5();
+   |         ^^^^^ help: remove this qualifier
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/fn-header-semantic-fail.rs:50:28
    |
-LL |         fn fe5();
-   |         ~~
+LL |     extern "C" {
+   |     ---------- in this `extern` block
+...
+LL |         const async unsafe extern "C" fn fe5();
+   |                            ^^^^^^^^^^ help: remove this qualifier
 
 error: functions cannot be both `const` and `async`
   --> $DIR/fn-header-semantic-fail.rs:50:9
@@ -148,6 +150,6 @@ LL |         const async unsafe extern "C" fn fe5();
    |         |     `async` because of this
    |         `const` because of this
 
-error: aborting due to 14 previous errors
+error: aborting due to 17 previous errors
 
 For more information about this error, try `rustc --explain E0379`.
diff --git a/tests/ui/parser/no-const-fn-in-extern-block.rs b/tests/ui/parser/no-const-fn-in-extern-block.rs
index 1993124edc3..d6c578681cc 100644
--- a/tests/ui/parser/no-const-fn-in-extern-block.rs
+++ b/tests/ui/parser/no-const-fn-in-extern-block.rs
@@ -3,6 +3,7 @@ extern "C" {
     //~^ ERROR functions in `extern` blocks cannot have qualifiers
     const unsafe fn bar();
     //~^ ERROR functions in `extern` blocks cannot have qualifiers
+    //~| ERROR functions in `extern` blocks cannot have qualifiers
 }
 
 fn main() {}
diff --git a/tests/ui/parser/no-const-fn-in-extern-block.stderr b/tests/ui/parser/no-const-fn-in-extern-block.stderr
index 4ac0e265501..948ce669112 100644
--- a/tests/ui/parser/no-const-fn-in-extern-block.stderr
+++ b/tests/ui/parser/no-const-fn-in-extern-block.stderr
@@ -1,29 +1,28 @@
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/no-const-fn-in-extern-block.rs:2:14
+  --> $DIR/no-const-fn-in-extern-block.rs:2:5
    |
 LL | extern "C" {
    | ---------- in this `extern` block
 LL |     const fn foo();
-   |              ^^^
-   |
-help: remove the qualifiers
-   |
-LL |     fn foo();
-   |     ~~
+   |     ^^^^^ help: remove this qualifier
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/no-const-fn-in-extern-block.rs:4:21
+  --> $DIR/no-const-fn-in-extern-block.rs:4:11
    |
 LL | extern "C" {
    | ---------- in this `extern` block
 ...
 LL |     const unsafe fn bar();
-   |                     ^^^
-   |
-help: remove the qualifiers
+   |           ^^^^^^ help: remove this qualifier
+
+error: functions in `extern` blocks cannot have qualifiers
+  --> $DIR/no-const-fn-in-extern-block.rs:4:5
    |
-LL |     fn bar();
-   |     ~~
+LL | extern "C" {
+   | ---------- in this `extern` block
+...
+LL |     const unsafe fn bar();
+   |     ^^^^^ help: remove this qualifier
 
-error: aborting due to 2 previous errors
+error: aborting due to 3 previous errors
 
diff --git a/tests/ui/parser/unsafe-foreign-mod-2.stderr b/tests/ui/parser/unsafe-foreign-mod-2.stderr
index 7cc2de141ae..fc05184f018 100644
--- a/tests/ui/parser/unsafe-foreign-mod-2.stderr
+++ b/tests/ui/parser/unsafe-foreign-mod-2.stderr
@@ -11,18 +11,13 @@ LL | extern "C" unsafe {
    |            ^^^^^^
 
 error: functions in `extern` blocks cannot have qualifiers
-  --> $DIR/unsafe-foreign-mod-2.rs:4:15
+  --> $DIR/unsafe-foreign-mod-2.rs:4:5
    |
 LL | extern "C" unsafe {
    | ----------------- in this `extern` block
 ...
 LL |     unsafe fn foo();
-   |               ^^^
-   |
-help: remove the qualifiers
-   |
-LL |     fn foo();
-   |     ~~
+   |     ^^^^^^ help: remove this qualifier
 
 error: aborting due to 3 previous errors
 
diff --git a/tests/ui/pattern/usefulness/unions.rs b/tests/ui/pattern/usefulness/unions.rs
new file mode 100644
index 00000000000..80a7f36a09a
--- /dev/null
+++ b/tests/ui/pattern/usefulness/unions.rs
@@ -0,0 +1,35 @@
+fn main() {
+    #[derive(Copy, Clone)]
+    union U8AsBool {
+        n: u8,
+        b: bool,
+    }
+
+    let x = U8AsBool { n: 1 };
+    unsafe {
+        match x {
+            // exhaustive
+            U8AsBool { n: 2 } => {}
+            U8AsBool { b: true } => {}
+            U8AsBool { b: false } => {}
+        }
+        match x {
+            // exhaustive
+            U8AsBool { b: true } => {}
+            U8AsBool { n: 0 } => {}
+            U8AsBool { n: 1.. } => {}
+        }
+        match x {
+            //~^ ERROR non-exhaustive patterns: `U8AsBool { n: 0_u8 }` and `U8AsBool { b: false }` not covered
+            U8AsBool { b: true } => {}
+            U8AsBool { n: 1.. } => {}
+        }
+        // Our approach can report duplicate witnesses sometimes.
+        match (x, true) {
+            //~^ ERROR non-exhaustive patterns: `(U8AsBool { n: 0_u8 }, false)`, `(U8AsBool { b: false }, false)`, `(U8AsBool { n: 0_u8 }, false)` and 1 more not covered
+            (U8AsBool { b: true }, true) => {}
+            (U8AsBool { b: false }, true) => {}
+            (U8AsBool { n: 1.. }, true) => {}
+        }
+    }
+}
diff --git a/tests/ui/pattern/usefulness/unions.stderr b/tests/ui/pattern/usefulness/unions.stderr
new file mode 100644
index 00000000000..4b397dc25db
--- /dev/null
+++ b/tests/ui/pattern/usefulness/unions.stderr
@@ -0,0 +1,34 @@
+error[E0004]: non-exhaustive patterns: `U8AsBool { n: 0_u8 }` and `U8AsBool { b: false }` not covered
+  --> $DIR/unions.rs:22:15
+   |
+LL |         match x {
+   |               ^ patterns `U8AsBool { n: 0_u8 }` and `U8AsBool { b: false }` not covered
+   |
+note: `U8AsBool` defined here
+  --> $DIR/unions.rs:3:11
+   |
+LL |     union U8AsBool {
+   |           ^^^^^^^^
+   = note: the matched value is of type `U8AsBool`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
+   |
+LL ~             U8AsBool { n: 1.. } => {},
+LL +             U8AsBool { n: 0_u8 } | U8AsBool { b: false } => todo!()
+   |
+
+error[E0004]: non-exhaustive patterns: `(U8AsBool { n: 0_u8 }, false)`, `(U8AsBool { b: false }, false)`, `(U8AsBool { n: 0_u8 }, false)` and 1 more not covered
+  --> $DIR/unions.rs:28:15
+   |
+LL |         match (x, true) {
+   |               ^^^^^^^^^ patterns `(U8AsBool { n: 0_u8 }, false)`, `(U8AsBool { b: false }, false)`, `(U8AsBool { n: 0_u8 }, false)` and 1 more not covered
+   |
+   = note: the matched value is of type `(U8AsBool, bool)`
+help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
+   |
+LL ~             (U8AsBool { n: 1.. }, true) => {},
+LL +             _ => todo!()
+   |
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/tests/ui/privacy/generic_struct_field_projection.rs b/tests/ui/privacy/generic_struct_field_projection.rs
new file mode 100644
index 00000000000..c5bb1233c27
--- /dev/null
+++ b/tests/ui/privacy/generic_struct_field_projection.rs
@@ -0,0 +1,38 @@
+//! To determine all the types that need to be private when looking at `Struct`, we
+//! used to invoke `predicates_of` to also look at types in `where` bounds.
+//! Unfortunately this also computes the inferred outlives bounds, which means for
+//! every field we check that if it is of type `&'a T` then `T: 'a` and if it is of
+//! struct type, we check that the struct satisfies its lifetime parameters by looking
+//! at its inferred outlives bounds. This means we end up with a `<Foo as Trait>::Assoc: 'a`
+//! in the outlives bounds of `Struct`. While this is trivially provable, privacy
+//! only sees `Foo` and `Trait` and determines that `Foo` is private and then errors.
+//! So now we invoke `explicit_predicates_of` to make sure we only care about user-written
+//! predicates.
+
+//@ check-pass
+
+mod baz {
+    struct Foo;
+
+    pub trait Trait {
+        type Assoc;
+    }
+
+    impl Trait for Foo {
+        type Assoc = ();
+    }
+
+    pub struct Bar<'a, T: Trait> {
+        source: &'a T::Assoc,
+    }
+
+    pub struct Baz<'a> {
+        mode: Bar<'a, Foo>,
+    }
+}
+
+pub struct Struct<'a> {
+    lexer: baz::Baz<'a>,
+}
+
+fn main() {}
diff --git a/tests/ui/proc-macro/auxiliary/api/mod.rs b/tests/ui/proc-macro/auxiliary/api/mod.rs
index 199d097336a..45ef6922d28 100644
--- a/tests/ui/proc-macro/auxiliary/api/mod.rs
+++ b/tests/ui/proc-macro/auxiliary/api/mod.rs
@@ -5,8 +5,6 @@
 #![crate_type = "proc-macro"]
 #![crate_name = "proc_macro_api_tests"]
 #![feature(proc_macro_span)]
-#![feature(proc_macro_byte_character)]
-#![feature(proc_macro_c_str_literals)]
 #![deny(dead_code)] // catch if a test function is never called
 
 extern crate proc_macro;
diff --git a/tests/ui/proc-macro/bad-projection.rs b/tests/ui/proc-macro/bad-projection.rs
index e633191bd31..0769a7f08c1 100644
--- a/tests/ui/proc-macro/bad-projection.rs
+++ b/tests/ui/proc-macro/bad-projection.rs
@@ -15,4 +15,5 @@ pub fn uwu() -> <() as Project>::Assoc {}
 //~^ ERROR the trait bound `(): Project` is not satisfied
 //~| ERROR the trait bound `(): Project` is not satisfied
 //~| ERROR the trait bound `(): Project` is not satisfied
+//~| ERROR the trait bound `(): Project` is not satisfied
 //~| ERROR function is expected to take 1 argument, but it takes 0 arguments
diff --git a/tests/ui/proc-macro/bad-projection.stderr b/tests/ui/proc-macro/bad-projection.stderr
index 8e0d8461849..2e8668f60de 100644
--- a/tests/ui/proc-macro/bad-projection.stderr
+++ b/tests/ui/proc-macro/bad-projection.stderr
@@ -36,6 +36,18 @@ LL | trait Project {
    | ^^^^^^^^^^^^^
 
 error[E0277]: the trait bound `(): Project` is not satisfied
+  --> $DIR/bad-projection.rs:14:1
+   |
+LL | pub fn uwu() -> <() as Project>::Assoc {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Project` is not implemented for `()`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/bad-projection.rs:9:1
+   |
+LL | trait Project {
+   | ^^^^^^^^^^^^^
+
+error[E0277]: the trait bound `(): Project` is not satisfied
   --> $DIR/bad-projection.rs:14:40
    |
 LL | pub fn uwu() -> <() as Project>::Assoc {}
@@ -47,7 +59,7 @@ help: this trait has no implementations, consider adding one
 LL | trait Project {
    | ^^^^^^^^^^^^^
 
-error: aborting due to 4 previous errors
+error: aborting due to 5 previous errors
 
 Some errors have detailed explanations: E0277, E0593.
 For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/resolve/primitive-f16-f128-shadowed-mod.rs b/tests/ui/resolve/primitive-f16-f128-shadowed-mod.rs
new file mode 100644
index 00000000000..93f51820101
--- /dev/null
+++ b/tests/ui/resolve/primitive-f16-f128-shadowed-mod.rs
@@ -0,0 +1,19 @@
+//@ compile-flags: --crate-type=lib
+//@ check-pass
+//@ revisions: e2015 e2018
+//
+//@[e2018] edition:2018
+
+// Verify that gates for the `f16` and `f128` features do not apply to user modules
+// See <https://github.com/rust-lang/rust/issues/123282>
+
+mod f16 {
+    pub fn a16() {}
+}
+
+mod f128 {
+    pub fn a128() {}
+}
+
+pub use f128::a128;
+pub use f16::a16;
diff --git a/tests/ui/resolve/primitive-f16-f128-shadowed.rs b/tests/ui/resolve/primitive-f16-f128-shadowed.rs
index ed3fb44b256..38c7e15bf5a 100644
--- a/tests/ui/resolve/primitive-f16-f128-shadowed.rs
+++ b/tests/ui/resolve/primitive-f16-f128-shadowed.rs
@@ -1,5 +1,8 @@
 //@ compile-flags: --crate-type=lib
 //@ check-pass
+//@ revisions: e2015 e2018
+//
+//@[e2018] edition:2018
 
 // Verify that gates for the `f16` and `f128` features do not apply to user types
 
diff --git a/tests/ui/sanitizer/cfi-closures.rs b/tests/ui/sanitizer/cfi-closures.rs
index 54f1cc035bc..9f9002da674 100644
--- a/tests/ui/sanitizer/cfi-closures.rs
+++ b/tests/ui/sanitizer/cfi-closures.rs
@@ -15,7 +15,6 @@
 
 #![feature(fn_traits)]
 #![feature(unboxed_closures)]
-#![feature(cfg_sanitize)]
 
 fn foo<'a, T>() -> Box<dyn Fn(&'a T) -> &'a T> {
     Box::new(|x| x)
@@ -72,12 +71,20 @@ fn use_closure<C>(call: extern "rust-call" fn(&C, ()) -> i32, f: &C) -> i32 {
 }
 
 #[test]
-// FIXME after KCFI reify support is added, remove this
-// It will appear to work if you test locally, set -C opt-level=0 to see it fail.
-#[cfg_attr(sanitize = "kcfi", ignore)]
 fn closure_addr_taken() {
     let x = 3i32;
     let f = || x;
     let call = Fn::<()>::call;
     use_closure(call, &f);
 }
+
+fn use_closure_once<C>(call: extern "rust-call" fn(C, ()) -> i32, f: C) -> i32 {
+    call(f, ())
+}
+
+#[test]
+fn closure_once_addr_taken() {
+    let g = || 3;
+    let call2 = FnOnce::<()>::call_once;
+    use_closure_once(call2, g);
+}
diff --git a/tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs b/tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs
index 273b8785fae..8f79de11748 100644
--- a/tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs
+++ b/tests/ui/sanitizer/cfi-method-fn-ptr-cast.rs
@@ -1,11 +1,41 @@
 // Verifies that casting a method to a function pointer works.
-//
-// FIXME(#122848): Remove only-linux when fixed.
+
+//@ revisions: cfi kcfi
+// FIXME(#122848) Remove only-linux once OSX CFI binaries work
 //@ only-linux
-//@ needs-sanitizer-cfi
-//@ compile-flags: -Clto -Copt-level=0 -Cprefer-dynamic=off -Ctarget-feature=-crt-static -Zsanitizer=cfi
+//@ [cfi] needs-sanitizer-cfi
+//@ [kcfi] needs-sanitizer-kcfi
+//@ compile-flags: -C target-feature=-crt-static
+//@ [cfi] compile-flags: -C opt-level=0 -C codegen-units=1 -C lto
+//@ [cfi] compile-flags: -C prefer-dynamic=off
+//@ [cfi] compile-flags: -Z sanitizer=cfi
+//@ [kcfi] compile-flags: -Z sanitizer=kcfi
+//@ [kcfi] compile-flags: -C panic=abort -C prefer-dynamic=off
 //@ run-pass
 
+trait Foo {
+    fn foo(&self);
+    fn bar(&self);
+}
+
+struct S;
+
+impl Foo for S {
+    fn foo(&self) {}
+    #[track_caller]
+    fn bar(&self) {}
+}
+
+struct S2 {
+    f: fn(&S)
+}
+
+impl S2 {
+    fn foo(&self, s: &S) {
+        (self.f)(s)
+    }
+}
+
 trait Trait1 {
     fn foo(&self);
 }
@@ -20,4 +50,8 @@ fn main() {
     let type1 = Type1 {};
     let f = <Type1 as Trait1>::foo;
     f(&type1);
+    // Check again with different optimization barriers
+    S2 { f: <S as Foo>::foo }.foo(&S);
+    // Check mismatched #[track_caller]
+    S2 { f: <S as Foo>::bar }.foo(&S)
 }
diff --git a/tests/ui/self/arbitrary-self-opaque.rs b/tests/ui/self/arbitrary-self-opaque.rs
new file mode 100644
index 00000000000..99357dde3e1
--- /dev/null
+++ b/tests/ui/self/arbitrary-self-opaque.rs
@@ -0,0 +1,12 @@
+#![feature(type_alias_impl_trait)]
+struct Foo;
+
+type Bar = impl Sized;
+//~^ ERROR unconstrained opaque type
+
+impl Foo {
+    fn foo(self: Bar) {}
+    //~^ ERROR: invalid `self` parameter type: Bar
+}
+
+fn main() {}
diff --git a/tests/ui/self/arbitrary-self-opaque.stderr b/tests/ui/self/arbitrary-self-opaque.stderr
new file mode 100644
index 00000000000..6b5db8d8493
--- /dev/null
+++ b/tests/ui/self/arbitrary-self-opaque.stderr
@@ -0,0 +1,20 @@
+error: unconstrained opaque type
+  --> $DIR/arbitrary-self-opaque.rs:4:12
+   |
+LL | type Bar = impl Sized;
+   |            ^^^^^^^^^^
+   |
+   = note: `Bar` must be used in combination with a concrete type within the same module
+
+error[E0307]: invalid `self` parameter type: Bar
+  --> $DIR/arbitrary-self-opaque.rs:8:18
+   |
+LL |     fn foo(self: Bar) {}
+   |                  ^^^
+   |
+   = note: type of `self` must be `Self` or a type that dereferences to it
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0307`.
diff --git a/tests/ui/simd/intrinsic/ptr-cast.rs b/tests/ui/simd/intrinsic/ptr-cast.rs
index 62820346241..0490734b48a 100644
--- a/tests/ui/simd/intrinsic/ptr-cast.rs
+++ b/tests/ui/simd/intrinsic/ptr-cast.rs
@@ -4,7 +4,7 @@
 
 extern "rust-intrinsic" {
     fn simd_cast_ptr<T, U>(x: T) -> U;
-    fn simd_expose_addr<T, U>(x: T) -> U;
+    fn simd_expose_provenance<T, U>(x: T) -> U;
     fn simd_with_exposed_provenance<T, U>(x: T) -> U;
 }
 
@@ -22,7 +22,7 @@ fn main() {
         // change constness and type
         let const_ptrs: V<*const u8> = simd_cast_ptr(ptrs);
 
-        let exposed_addr: V<usize> = simd_expose_addr(const_ptrs);
+        let exposed_addr: V<usize> = simd_expose_provenance(const_ptrs);
 
         let with_exposed_provenance: V<*mut i8> = simd_with_exposed_provenance(exposed_addr);
 
diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque.rs b/tests/ui/specialization/min_specialization/impl-on-opaque.rs
new file mode 100644
index 00000000000..7531dcaccf2
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/impl-on-opaque.rs
@@ -0,0 +1,31 @@
+// Test that specializing on opaque types is allowed
+
+//@ check-pass
+
+#![feature(min_specialization, type_alias_impl_trait)]
+
+trait SpecTrait<U> {
+    fn f();
+}
+
+impl<U> SpecTrait<U> for () {
+    default fn f() {}
+}
+
+type Opaque = impl Tuple;
+
+trait Tuple {}
+
+impl Tuple for () {}
+
+impl SpecTrait<Opaque> for () {
+    fn f() {}
+}
+
+impl SpecTrait<u32> for () {
+    fn f() {}
+}
+
+fn foo() -> Opaque {}
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque2.rs b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs
new file mode 100644
index 00000000000..0cd8be84ed3
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/impl-on-opaque2.rs
@@ -0,0 +1,28 @@
+// Test that specializing on opaque types is allowed
+
+#![feature(min_specialization, type_alias_impl_trait)]
+
+trait SpecTrait<U, V> {
+    fn f();
+}
+
+impl<U> SpecTrait<U, ()> for () {
+    default fn f() {}
+}
+
+type Opaque = impl Tuple;
+
+trait Tuple {}
+
+impl Tuple for () {}
+
+// FIXME: this passes if we use `<(), ()>` here instead of `<(), Opaque>`,
+// even though there can't be more overlap from the opaque version
+impl SpecTrait<(), Opaque> for () {
+    //~^ ERROR: conflicting implementations
+    fn f() {}
+}
+
+fn foo() -> Opaque {}
+
+fn main() {}
diff --git a/tests/ui/specialization/min_specialization/impl-on-opaque2.stderr b/tests/ui/specialization/min_specialization/impl-on-opaque2.stderr
new file mode 100644
index 00000000000..3c0bc8f8f83
--- /dev/null
+++ b/tests/ui/specialization/min_specialization/impl-on-opaque2.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `SpecTrait<(), ()>` for type `()`
+  --> $DIR/impl-on-opaque2.rs:21:1
+   |
+LL | impl<U> SpecTrait<U, ()> for () {
+   | ------------------------------- first implementation here
+...
+LL | impl SpecTrait<(), Opaque> for () {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/issues/issue-1660.rs b/tests/ui/static/issue-1660.rs
index a114a908313..a114a908313 100644
--- a/tests/ui/issues/issue-1660.rs
+++ b/tests/ui/static/issue-1660.rs
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr
new file mode 100644
index 00000000000..c54a1c42bad
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.current.stderr
@@ -0,0 +1,17 @@
+error[E0308]: mismatched types
+  --> $DIR/illegal-upcast-from-impl-opaque.rs:26:5
+   |
+LL | type Foo = impl Sized;
+   |            ---------- the found opaque type
+LL |
+LL | fn illegal(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
+   |                                         ----------------------- expected `&dyn Super<Assoc = i32>` because of return type
+LL |     x
+   |     ^ expected trait `Super`, found trait `Sub`
+   |
+   = note: expected reference `&dyn Super<Assoc = i32>`
+              found reference `&dyn Sub<Assoc = Foo>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr
new file mode 100644
index 00000000000..3c2bc0b9190
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.next.stderr
@@ -0,0 +1,14 @@
+error: internal compiler error: error performing operation: query type op
+  --> $DIR/illegal-upcast-from-impl-opaque.rs:25:1
+   |
+LL | fn illegal(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+note: 
+  --> $DIR/illegal-upcast-from-impl-opaque.rs:25:1
+   |
+LL | fn illegal(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+query stack during panic:
+end of query stack
diff --git a/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs
new file mode 100644
index 00000000000..f344474054a
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/illegal-upcast-from-impl-opaque.rs
@@ -0,0 +1,29 @@
+//@ revisions: current next
+//@[next] compile-flags: -Znext-solver
+//@[next] failure-status: 101
+//@[next] known-bug: unknown
+//@[next] normalize-stderr-test "note: .*\n\n" -> ""
+//@[next] normalize-stderr-test "thread 'rustc' panicked.*\n.*\n" -> ""
+//@[next] normalize-stderr-test "(error: internal compiler error: [^:]+):\d+:\d+: " -> "$1:LL:CC: "
+//@[next] normalize-stderr-test "delayed at .*" -> ""
+//@[next] rustc-env:RUST_BACKTRACE=0
+
+#![feature(trait_upcasting, type_alias_impl_trait)]
+
+trait Super {
+    type Assoc;
+}
+
+trait Sub: Super {}
+
+impl<T: ?Sized> Super for T {
+    type Assoc = i32;
+}
+
+type Foo = impl Sized;
+
+fn illegal(x: &dyn Sub<Assoc = Foo>) -> &dyn Super<Assoc = i32> {
+    x //[current]~ mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/unpretty/hir-tree.rs b/tests/ui/unpretty/hir-tree.rs
new file mode 100644
index 00000000000..3388c60c425
--- /dev/null
+++ b/tests/ui/unpretty/hir-tree.rs
@@ -0,0 +1,10 @@
+//@ build-pass
+//@ compile-flags: -o - -Zunpretty=hir-tree
+//@ check-stdout
+//@ dont-check-compiler-stdout
+//@ dont-check-compiler-stderr
+//@ regex-error-pattern: Hello, Rustaceans!
+
+fn main() {
+    println!("Hello, Rustaceans!");
+}
diff --git a/tests/ui/wf/wf-fn-def-check-sig-1.rs b/tests/ui/wf/wf-fn-def-check-sig-1.rs
new file mode 100644
index 00000000000..6d9e1f38f8d
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-1.rs
@@ -0,0 +1,44 @@
+// Regression test for #84533.
+
+use std::marker::PhantomData;
+
+fn foo<'b, 'a>() -> PhantomData<&'b &'a ()> {
+    PhantomData
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+    let f = foo::<'b, 'a>;
+    f.baz(x)
+    //~^ ERROR lifetime may not live long enough
+}
+
+trait Foo<'a, 'b, T: ?Sized> {
+    fn baz(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, R, F, T: ?Sized> Foo<'a, 'b, T> for F
+where
+    F: Fn() -> R,
+    R: ProofForConversion<'a, 'b, T>,
+{
+    fn baz(self, s: &'a T) -> &'b T {
+        self().convert(s)
+    }
+}
+
+trait ProofForConversion<'a, 'b, T: ?Sized> {
+    fn convert(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, T: ?Sized> ProofForConversion<'a, 'b, T> for PhantomData<&'b &'a ()> {
+    fn convert(self, s: &'a T) -> &'b T {
+        s
+    }
+}
+
+fn main() {
+    let d;
+    {
+        let x = "Hello World".to_string();
+        d = extend_lifetime(&x);
+    }
+    println!("{}", d);
+}
diff --git a/tests/ui/wf/wf-fn-def-check-sig-1.stderr b/tests/ui/wf/wf-fn-def-check-sig-1.stderr
new file mode 100644
index 00000000000..a93449ad3c6
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-1.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/wf-fn-def-check-sig-1.rs:11:5
+   |
+LL | fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+LL |     let f = foo::<'b, 'a>;
+LL |     f.baz(x)
+   |     ^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/wf/wf-fn-def-check-sig-2.rs b/tests/ui/wf/wf-fn-def-check-sig-2.rs
new file mode 100644
index 00000000000..51740dca8e9
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-2.rs
@@ -0,0 +1,44 @@
+// Regression test for #84533 involving higher-ranked regions
+// in the return type.
+use std::marker::PhantomData;
+
+fn foo<'c, 'b, 'a>(_: &'c ()) -> (&'c (), PhantomData<&'b &'a ()>) {
+    (&(), PhantomData)
+}
+
+fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+    let f = foo;
+    f.baz(x)
+    //~^ ERROR lifetime may not live long enough
+}
+
+trait Foo<'a, 'b, T: ?Sized> {
+    fn baz(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, R, F, T: ?Sized> Foo<'a, 'b, T> for F
+where
+    F: for<'c> Fn(&'c ()) -> (&'c (), R),
+    R: ProofForConversion<'a, 'b, T>,
+{
+    fn baz(self, s: &'a T) -> &'b T {
+        self(&()).1.convert(s)
+    }
+}
+
+trait ProofForConversion<'a, 'b, T: ?Sized> {
+    fn convert(self, s: &'a T) -> &'b T;
+}
+impl<'a, 'b, T: ?Sized> ProofForConversion<'a, 'b, T> for PhantomData<&'b &'a ()> {
+    fn convert(self, s: &'a T) -> &'b T {
+        s
+    }
+}
+
+fn main() {
+    let d;
+    {
+        let x = "Hello World".to_string();
+        d = extend_lifetime(&x);
+    }
+    println!("{}", d);
+}
diff --git a/tests/ui/wf/wf-fn-def-check-sig-2.stderr b/tests/ui/wf/wf-fn-def-check-sig-2.stderr
new file mode 100644
index 00000000000..404d3cc4513
--- /dev/null
+++ b/tests/ui/wf/wf-fn-def-check-sig-2.stderr
@@ -0,0 +1,15 @@
+error: lifetime may not live long enough
+  --> $DIR/wf-fn-def-check-sig-2.rs:11:5
+   |
+LL | fn extend_lifetime<'a, 'b, T: ?Sized>(x: &'a T) -> &'b T {
+   |                    --  -- lifetime `'b` defined here
+   |                    |
+   |                    lifetime `'a` defined here
+LL |     let f = foo;
+LL |     f.baz(x)
+   |     ^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to 1 previous error
+
diff --git a/triagebot.toml b/triagebot.toml
index 55f0d32398f..b96225c4520 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -286,6 +286,11 @@ trigger_files = [
     "library/std/src/os/windows"
 ]
 
+[autolabel."O-visionos"]
+trigger_files = [
+    "library/std/src/os/visionos"
+]
+
 [autolabel."T-bootstrap"]
 trigger_files = [
     "x.py",
@@ -469,11 +474,11 @@ message = "Some changes occurred in need_type_info.rs"
 cc = ["@lcnr"]
 
 [mentions."compiler/rustc_middle/src/ty/relate.rs"]
-message = "Type relation code was changed"
+message = "changes to the core type system"
 cc = ["@compiler-errors", "@lcnr"]
 
 [mentions."compiler/rustc_infer/src/infer/relate"]
-message = "Type relation code was changed"
+message = "changes to the core type system"
 cc = ["@compiler-errors", "@lcnr"]
 
 [mentions."compiler/rustc_middle/src/mir/interpret"]
@@ -484,6 +489,10 @@ cc = ["@rust-lang/miri"]
 message = "Some changes occurred to MIR optimizations"
 cc = ["@rust-lang/wg-mir-opt"]
 
+[mentions."compiler/rustc_trait_selection/src/traits/wf.rs"]
+message = "changes to the core type system"
+cc = ["@compiler-errors", "@lcnr"]
+
 [mentions."compiler/rustc_trait_selection/src/traits/const_evaluatable.rs"]
 message = "Some changes occurred in `const_evaluatable.rs`"
 cc = ["@BoxyUwU"]
@@ -527,7 +536,12 @@ cc = ["@Nadrieril"]
 message = "Some changes occurred in exhaustiveness checking"
 cc = ["@Nadrieril"]
 
+[mentions."compiler/rustc_session/src/config/cfg.rs"]
+message = "Some changes occurred in cfg and check-cfg configuration"
+cc = ["@Urgau"]
+
 [mentions."compiler/rustc_lint/src/context/diagnostics/check_cfg.rs"]
+message = "Some changes occurred in check-cfg diagnostics"
 cc = ["@Urgau"]
 
 [mentions."library/core/src/intrinsics/simd.rs"]
@@ -789,6 +803,7 @@ compiler-team-contributors = [
     "@fmease",
     "@fee1-dead",
     "@BoxyUwU",
+    "@jieyouxu",
 ]
 compiler = [
     "compiler-team",
@@ -969,10 +984,12 @@ project-exploit-mitigations = [
 "/src/llvm-project" =                                    ["@cuviper"]
 "/src/rustdoc-json-types" =                              ["rustdoc"]
 "/src/stage0.json" =                                     ["bootstrap"]
+"/tests/run-make" =                                      ["@jieyouxu"]
 "/tests/ui" =                                            ["compiler"]
 "/src/tools/cargo" =                                     ["@ehuss"]
-"/src/tools/compiletest" =                               ["bootstrap", "@wesleywiser", "@oli-obk", "@compiler-errors"]
+"/src/tools/compiletest" =                               ["bootstrap", "@wesleywiser", "@oli-obk", "@compiler-errors", "@jieyouxu"]
 "/src/tools/linkchecker" =                               ["@ehuss"]
+"/src/tools/run-make-support" =                          ["@jieyouxu"]
 "/src/tools/rust-installer" =                            ["bootstrap"]
 "/src/tools/rustbook" =                                  ["@ehuss"]
 "/src/tools/rustdoc" =                                   ["rustdoc"]