about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.mailmap22
-rw-r--r--Cargo.lock15
-rw-r--r--compiler/rustc_abi/Cargo.toml4
-rw-r--r--compiler/rustc_abi/src/extern_abi/mod.rs (renamed from compiler/rustc_target/src/spec/abi/mod.rs)4
-rw-r--r--compiler/rustc_abi/src/extern_abi/tests.rs (renamed from compiler/rustc_target/src/spec/abi/tests.rs)0
-rw-r--r--compiler/rustc_abi/src/lib.rs8
-rw-r--r--compiler/rustc_ast/src/ast.rs2
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs2
-rw-r--r--compiler/rustc_ast/src/visit.rs2
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs13
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs1
-rw-r--r--compiler/rustc_codegen_cranelift/src/lib.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs5
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/context.rs9
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs7
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs26
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/mod.rs3
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs1
-rw-r--r--compiler/rustc_codegen_ssa/messages.ftl6
-rw-r--r--compiler/rustc_codegen_ssa/src/back/apple.rs171
-rw-r--r--compiler/rustc_codegen_ssa/src/back/apple/tests.rs21
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs13
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs16
-rw-r--r--compiler/rustc_codegen_ssa/src/back/mod.rs21
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs25
-rw-r--r--compiler/rustc_codegen_ssa/src/errors.rs9
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs1
-rw-r--r--compiler/rustc_const_eval/src/check_consts/check.rs105
-rw-r--r--compiler/rustc_const_eval/src/check_consts/mod.rs7
-rw-r--r--compiler/rustc_const_eval/src/check_consts/ops.rs13
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs21
-rw-r--r--compiler/rustc_const_eval/src/interpret/operand.rs5
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs10
-rw-r--r--compiler/rustc_const_eval/src/interpret/stack.rs13
-rw-r--r--compiler/rustc_const_eval/src/util/compare_types.rs21
-rw-r--r--compiler/rustc_const_eval/src/util/mod.rs2
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs10
-rw-r--r--compiler/rustc_hir_analysis/src/collect/item_bounds.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs121
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs23
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs15
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs54
-rw-r--r--compiler/rustc_hir_pretty/Cargo.toml2
-rw-r--r--compiler/rustc_hir_pretty/src/lib.rs6
-rw-r--r--compiler/rustc_hir_typeck/src/autoderef.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/callee.rs4
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs17
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs83
-rw-r--r--compiler/rustc_hir_typeck/src/expr_use_visitor.rs13
-rw-r--r--compiler/rustc_hir_typeck/src/fallback.rs207
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/method/confirm.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/op.rs8
-rw-r--r--compiler/rustc_hir_typeck/src/place_op.rs18
-rw-r--r--compiler/rustc_infer/src/infer/opaque_types/mod.rs1
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lint/messages.ftl2
-rw-r--r--compiler/rustc_lint/src/lints.rs4
-rw-r--r--compiler/rustc_lint/src/non_local_def.rs10
-rw-r--r--compiler/rustc_lint/src/types.rs5
-rw-r--r--compiler/rustc_lint/src/unused.rs2
-rw-r--r--compiler/rustc_lint_defs/Cargo.toml2
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs4
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp13
-rw-r--r--compiler/rustc_metadata/Cargo.toml1
-rw-r--r--compiler/rustc_metadata/src/creader.rs4
-rw-r--r--compiler/rustc_metadata/src/locator.rs29
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs11
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs46
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs11
-rw-r--r--compiler/rustc_middle/src/ty/adjustment.rs21
-rw-r--r--compiler/rustc_mir_build/Cargo.toml3
-rw-r--r--compiler/rustc_mir_build/src/build/custom/parse/instruction.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_place.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_rvalue.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs30
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs11
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs2
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs2
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs4
-rw-r--r--compiler/rustc_mir_transform/src/inline.rs27
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs27
-rw-r--r--compiler/rustc_parse/src/parser/item.rs2
-rw-r--r--compiler/rustc_session/src/config.rs14
-rw-r--r--compiler/rustc_session/src/options.rs5
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs142
-rw-r--r--compiler/rustc_target/src/spec/base/apple/tests.rs9
-rw-r--r--compiler/rustc_target/src/spec/mod.rs19
-rw-r--r--compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs7
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs2
-rw-r--r--compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs2
-rw-r--r--compiler/rustc_target/src/spec/tests/tests_impl.rs3
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs5
-rw-r--r--compiler/rustc_trait_selection/src/traits/mod.rs2
-rw-r--r--compiler/rustc_trait_selection/src/traits/normalize.rs33
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs29
-rw-r--r--compiler/rustc_trait_selection/src/traits/query/normalize.rs20
-rw-r--r--compiler/rustc_type_ir/src/infer_ctxt.rs7
-rw-r--r--config.example.toml2
-rw-r--r--library/Cargo.lock4
-rw-r--r--library/alloc/Cargo.toml2
-rw-r--r--library/core/src/alloc/layout.rs11
-rw-r--r--library/core/src/array/mod.rs5
-rw-r--r--library/core/src/char/mod.rs2
-rw-r--r--library/core/src/mem/maybe_uninit.rs3
-rw-r--r--library/core/src/mem/mod.rs8
-rw-r--r--library/core/src/num/int_macros.rs16
-rw-r--r--library/core/src/num/nonzero.rs1
-rw-r--r--library/core/src/num/uint_macros.rs14
-rw-r--r--library/core/src/ptr/const_ptr.rs27
-rw-r--r--library/core/src/ptr/mod.rs1
-rw-r--r--library/core/src/ptr/mut_ptr.rs27
-rw-r--r--library/core/src/ptr/non_null.rs27
-rw-r--r--library/core/src/slice/mod.rs2
-rw-r--r--library/core/src/str/mod.rs15
-rw-r--r--library/std/Cargo.toml2
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/sys/pal/windows/mod.rs2
-rw-r--r--library/std/src/sys/thread_local/guard/windows.rs2
-rw-r--r--src/bootstrap/defaults/config.library.toml3
-rw-r--r--src/bootstrap/defaults/config.tools.toml2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs8
-rw-r--r--src/bootstrap/src/core/build_steps/setup.rs1
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs5
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rwxr-xr-xsrc/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh2
-rw-r--r--src/ci/github-actions/jobs.yml12
-rw-r--r--src/doc/rustc/src/instrument-coverage.md8
-rw-r--r--src/doc/rustc/src/platform-support/apple-darwin.md5
-rw-r--r--src/doc/style-guide/src/editions.md5
-rw-r--r--src/doc/style-guide/src/expressions.md12
-rw-r--r--src/doc/unstable-book/src/compiler-flags/profile.md27
-rw-r--r--src/etc/rust_analyzer_helix.toml7
-rw-r--r--src/etc/rust_analyzer_settings.json2
-rw-r--r--src/librustdoc/clean/types.rs7
-rw-r--r--src/librustdoc/html/format.rs6
-rw-r--r--src/librustdoc/html/render/print_item.rs2
-rw-r--r--src/librustdoc/html/render/type_layout.rs2
-rw-r--r--src/librustdoc/json/conversions.rs22
-rw-r--r--src/librustdoc/passes/propagate_stability.rs74
m---------src/llvm-project0
m---------src/tools/cargo0
-rw-r--r--src/tools/clippy/clippy_lints/src/dereference.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_slicing.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/qualify_min_const_fn.rs4
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs2
-rw-r--r--src/tools/compiletest/src/common.rs5
-rw-r--r--src/tools/compiletest/src/directive-list.rs1
-rw-r--r--src/tools/compiletest/src/header.rs28
-rw-r--r--src/tools/compiletest/src/header/tests.rs1
-rw-r--r--src/tools/compiletest/src/lib.rs13
-rw-r--r--src/tools/compiletest/src/runtest.rs78
-rw-r--r--src/tools/compiletest/src/runtest/assembly.rs32
-rw-r--r--src/tools/miri/clippy.toml2
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/alloc_addresses/mod.rs2
-rw-r--r--src/tools/miri/src/alloc_addresses/reuse_pool.rs2
-rw-r--r--src/tools/miri/src/alloc_bytes.rs2
-rw-r--r--src/tools/miri/src/bin/miri.rs6
-rw-r--r--src/tools/miri/src/borrow_tracker/mod.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs2
-rw-r--r--src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs2
-rw-r--r--src/tools/miri/src/concurrency/cpu_affinity.rs2
-rw-r--r--src/tools/miri/src/concurrency/data_race.rs2
-rw-r--r--src/tools/miri/src/concurrency/range_object_map.rs2
-rw-r--r--src/tools/miri/src/concurrency/sync.rs2
-rw-r--r--src/tools/miri/src/concurrency/thread.rs4
-rw-r--r--src/tools/miri/src/concurrency/weak_memory.rs1
-rw-r--r--src/tools/miri/src/diagnostics.rs2
-rw-r--r--src/tools/miri/src/eval.rs8
-rw-r--r--src/tools/miri/src/helpers.rs17
-rw-r--r--src/tools/miri/src/intrinsics/mod.rs4
-rw-r--r--src/tools/miri/src/intrinsics/simd.rs6
-rw-r--r--src/tools/miri/src/machine.rs9
-rw-r--r--src/tools/miri/src/operator.rs2
-rw-r--r--src/tools/miri/src/range_map.rs2
-rw-r--r--src/tools/miri/src/shims/alloc.rs2
-rw-r--r--src/tools/miri/src/shims/backtrace.rs21
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs104
-rw-r--r--src/tools/miri/src/shims/io_error.rs2
-rw-r--r--src/tools/miri/src/shims/panic.rs16
-rw-r--r--src/tools/miri/src/shims/tls.rs11
-rw-r--r--src/tools/miri/src/shims/unix/android/foreign_items.rs6
-rw-r--r--src/tools/miri/src/shims/unix/android/thread.rs7
-rw-r--r--src/tools/miri/src/shims/unix/env.rs2
-rw-r--r--src/tools/miri/src/shims/unix/fd.rs2
-rw-r--r--src/tools/miri/src/shims/unix/foreign_items.rs203
-rw-r--r--src/tools/miri/src/shims/unix/freebsd/foreign_items.rs21
-rw-r--r--src/tools/miri/src/shims/unix/fs.rs4
-rw-r--r--src/tools/miri/src/shims/unix/linux/foreign_items.rs38
-rw-r--r--src/tools/miri/src/shims/unix/linux/mem.rs4
-rw-r--r--src/tools/miri/src/shims/unix/linux/sync.rs2
-rw-r--r--src/tools/miri/src/shims/unix/linux/syscall.rs6
-rw-r--r--src/tools/miri/src/shims/unix/macos/foreign_items.rs66
-rw-r--r--src/tools/miri/src/shims/unix/macos/sync.rs2
-rw-r--r--src/tools/miri/src/shims/unix/mem.rs4
-rw-r--r--src/tools/miri/src/shims/unix/solarish/foreign_items.rs15
-rw-r--r--src/tools/miri/src/shims/unix/sync.rs3
-rw-r--r--src/tools/miri/src/shims/unix/thread.rs4
-rw-r--r--src/tools/miri/src/shims/unix/unnamed_socket.rs2
-rw-r--r--src/tools/miri/src/shims/wasi/foreign_items.rs8
-rw-r--r--src/tools/miri/src/shims/windows/foreign_items.rs128
-rw-r--r--src/tools/miri/src/shims/windows/handle.rs14
-rw-r--r--src/tools/miri/src/shims/windows/sync.rs2
-rw-r--r--src/tools/miri/src/shims/windows/thread.rs4
-rw-r--r--src/tools/miri/src/shims/x86/aesni.rs14
-rw-r--r--src/tools/miri/src/shims/x86/avx.rs45
-rw-r--r--src/tools/miri/src/shims/x86/avx2.rs44
-rw-r--r--src/tools/miri/src/shims/x86/bmi.rs7
-rw-r--r--src/tools/miri/src/shims/x86/gfni.rs14
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs21
-rw-r--r--src/tools/miri/src/shims/x86/sha.rs13
-rw-r--r--src/tools/miri/src/shims/x86/sse.rs22
-rw-r--r--src/tools/miri/src/shims/x86/sse2.rs32
-rw-r--r--src/tools/miri/src/shims/x86/sse3.rs9
-rw-r--r--src/tools/miri/src/shims/x86/sse41.rs25
-rw-r--r--src/tools/miri/src/shims/x86/sse42.rs22
-rw-r--r--src/tools/miri/src/shims/x86/ssse3.rs16
-rw-r--r--src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs2
-rw-r--r--src/tools/rust-analyzer/Cargo.lock7
-rw-r--r--src/tools/rust-analyzer/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs17
-rw-r--r--src/tools/tidy/src/deps.rs4
-rw-r--r--tests/assembly/asm/comments.rs (renamed from tests/assembly/asm-comments.rs)0
-rw-r--r--tests/assembly/asm/loongarch-type.rs2
-rw-r--r--tests/assembly/compiletest-self-test/use-minicore-no-run.rs5
-rw-r--r--tests/auxiliary/minicore.rs72
-rw-r--r--tests/codegen/asm/arm64ec-clobbers.rs (renamed from tests/codegen/asm-arm64ec-clobbers.rs)0
-rw-r--r--tests/codegen/asm/foo.s (renamed from tests/codegen/foo.s)0
-rw-r--r--tests/codegen/asm/global_asm.rs (renamed from tests/codegen/global_asm.rs)0
-rw-r--r--tests/codegen/asm/global_asm_include.rs (renamed from tests/codegen/global_asm_include.rs)0
-rw-r--r--tests/codegen/asm/global_asm_x2.rs (renamed from tests/codegen/global_asm_x2.rs)0
-rw-r--r--tests/codegen/asm/goto.rs (renamed from tests/codegen/asm-goto.rs)0
-rw-r--r--tests/codegen/asm/may_unwind.rs (renamed from tests/codegen/asm-may_unwind.rs)0
-rw-r--r--tests/codegen/asm/maybe-uninit.rs (renamed from tests/codegen/asm-maybe-uninit.rs)0
-rw-r--r--tests/codegen/asm/msp430-clobbers.rs (renamed from tests/codegen/asm-msp430-clobbers.rs)0
-rw-r--r--tests/codegen/asm/multiple-options.rs (renamed from tests/codegen/asm-multiple-options.rs)0
-rw-r--r--tests/codegen/asm/options.rs (renamed from tests/codegen/asm-options.rs)0
-rw-r--r--tests/codegen/asm/powerpc-clobbers.rs (renamed from tests/codegen/asm-powerpc-clobbers.rs)0
-rw-r--r--tests/codegen/asm/s390x-clobbers.rs (renamed from tests/codegen/asm-s390x-clobbers.rs)0
-rw-r--r--tests/codegen/asm/sanitize-llvm.rs (renamed from tests/codegen/asm-sanitize-llvm.rs)0
-rw-r--r--tests/codegen/asm/x86-clobber_abi.rs (renamed from tests/codegen/asm-clobber_abi.rs)0
-rw-r--r--tests/codegen/asm/x86-clobbers.rs (renamed from tests/codegen/asm-clobbers.rs)0
-rw-r--r--tests/codegen/asm/x86-target-clobbers.rs (renamed from tests/codegen/asm-target-clobbers.rs)0
-rw-r--r--tests/codegen/clone_as_copy.rs2
-rw-r--r--tests/codegen/compiletest-self-test/minicore-smoke-test.rs20
-rw-r--r--tests/codegen/issues/issue-64219-fn-ptr-call-returning-never-is-noreturn.rs19
-rw-r--r--tests/codegen/issues/issue-86109-eliminate-div-by-zero-check.rs26
-rw-r--r--tests/codegen/try_question_mark_nop.rs14
-rw-r--r--tests/crashes/126268.rs18
-rw-r--r--tests/crashes/131050.rs20
-rw-r--r--tests/crashes/132126.rs2
-rw-r--r--tests/mir-opt/gvn_clone.rs2
-rw-r--r--tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff6
-rw-r--r--tests/mir-opt/gvn_copy_aggregate.rs2
-rw-r--r--tests/mir-opt/pre-codegen/clone_as_copy.rs2
-rw-r--r--tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir6
-rw-r--r--tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir8
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir30
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir30
-rw-r--r--tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff72
-rw-r--r--tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs32
-rw-r--r--tests/run-make/profile/rmake.rs21
-rw-r--r--tests/run-make/profile/test.rs1
-rw-r--r--tests/rustdoc/stability.rs114
-rw-r--r--tests/ui/abi/compatibility.rs69
-rw-r--r--tests/ui/async-await/async-closures/mangle.rs3
-rw-r--r--tests/ui/async-await/async-closures/no-borrow-from-env.rs5
-rw-r--r--tests/ui/async-await/async-closures/not-fn.rs2
-rw-r--r--tests/ui/async-await/async-closures/precise-captures.rs4
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs4
-rw-r--r--tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr21
-rw-r--r--tests/ui/check-cfg/well-known-values.stderr6
-rw-r--r--tests/ui/compiletest-self-test/minicore-smoke-test.rs20
-rw-r--r--tests/ui/consts/promote-not.rs2
-rw-r--r--tests/ui/editions/never-type-fallback-breaking.e2021.stderr8
-rw-r--r--tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs13
-rw-r--r--tests/ui/impl-trait/precise-capturing/bound-modifiers.rs2
-rw-r--r--tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr32
-rw-r--r--tests/ui/issues/issue-37534.rs3
-rw-r--r--tests/ui/issues/issue-37534.stderr13
-rw-r--r--tests/ui/lint/cli-lint-override.forbid_warn.stderr3
-rw-r--r--tests/ui/lint/cli-lint-override.force_warn_deny.stderr3
-rw-r--r--tests/ui/lint/cli-lint-override.warn_deny.stderr3
-rw-r--r--tests/ui/lint/invalid-nan-comparison-suggestion.fixed14
-rw-r--r--tests/ui/lint/invalid-nan-comparison-suggestion.rs14
-rw-r--r--tests/ui/lint/invalid-nan-comparison-suggestion.stderr70
-rw-r--r--tests/ui/lint/invalid-nan-comparison.rs46
-rw-r--r--tests/ui/lint/invalid-nan-comparison.stderr180
-rw-r--r--tests/ui/lint/non-local-defs/convoluted-locals-132427.rs64
-rw-r--r--tests/ui/mir/clone-canonicalization-miscompile-132353.rs25
-rw-r--r--tests/ui/never_type/defaulted-never-note.nofallback.stderr4
-rw-r--r--tests/ui/never_type/dependency-on-fallback-to-unit.stderr8
-rw-r--r--tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr8
-rw-r--r--tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr4
-rw-r--r--tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr4
-rw-r--r--tests/ui/never_type/fallback-closure-ret.nofallback.stderr4
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr32
-rw-r--r--tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr32
-rw-r--r--tests/ui/target-feature/wasm-disable-simd.rs12
-rw-r--r--tests/ui/trait-bounds/maybe-bound-generics-deny.rs4
-rw-r--r--tests/ui/trait-bounds/maybe-bound-generics-deny.stderr11
-rw-r--r--tests/ui/trait-bounds/maybe-bound-has-path-args.rs7
-rw-r--r--tests/ui/trait-bounds/maybe-bound-has-path-args.stderr17
-rw-r--r--tests/ui/trait-bounds/maybe-bound-with-assoc.rs12
-rw-r--r--tests/ui/trait-bounds/maybe-bound-with-assoc.stderr21
-rw-r--r--tests/ui/traits/const-traits/const-drop-fail-2.stderr10
-rw-r--r--tests/ui/traits/const-traits/const-drop.precise.stderr8
-rw-r--r--tests/ui/traits/const-traits/const-drop.stock.stderr8
-rw-r--r--tests/ui/traits/const-traits/cross-crate.rs7
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stock.stderr17
-rw-r--r--tests/ui/traits/const-traits/cross-crate.stocknc.stderr30
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs5
-rw-r--r--tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr15
-rw-r--r--tests/ui/traits/const-traits/specializing-constness-2.stderr11
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.rs1
-rw-r--r--tests/ui/traits/const-traits/staged-api-user-crate.stderr15
331 files changed, 3284 insertions, 1672 deletions
diff --git a/.mailmap b/.mailmap
index 56490ca5059..fdb62a9d778 100644
--- a/.mailmap
+++ b/.mailmap
@@ -31,6 +31,7 @@ Alexis Beingessner <a.beingessner@gmail.com>
 Alfie John <alfie@alfie.wtf> Alfie John <alfiej@fastmail.fm>
 Alona Enraght-Moony <code@alona.page> <nixon.emoony@gmail.com>
 Alona Enraght-Moony <code@alona.page> <nixon@caminus.local>
+Alona Enraght-Moony <code@alona.page> <contact@alona.page>
 Amanda Stjerna <mail@amandastjerna.se> <albin.stjerna@gmail.com>
 Amanda Stjerna <mail@amandastjerna.se> <amanda.stjerna@it.uu.se>
 Amos Onn <amosonn@gmail.com>
@@ -75,6 +76,7 @@ Benjamin Jackman <ben@jackman.biz>
 Benoît Cortier <benoit.cortier@fried-world.eu>
 Bheesham Persaud <bheesham123@hotmail.com> Bheesham Persaud <bheesham.persaud@live.ca>
 bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3@users.noreply.github.com>
+bjorn3 <17426603+bjorn3@users.noreply.github.com> <bjorn3_gh@protonmail.com>
 Björn Steinbrink <bsteinbr@gmail.com> <B.Steinbrink@gmx.de>
 blake2-ppc <ulrik.sverdrup@gmail.com> <blake2-ppc>
 blyxyas <blyxyas@gmail.com> Alejandra González <blyxyas@gmail.com>
@@ -172,6 +174,7 @@ Dzmitry Malyshau <kvarkus@gmail.com>
 E. Dunham <edunham@mozilla.com> edunham <edunham@mozilla.com>
 Ed Barnard <eabarnard@gmail.com>
 Eduard-Mihai Burtescu <edy.burt@gmail.com>
+Eduard-Mihai Burtescu <edy.burt@gmail.com> <eddyb@lyken.rs>
 Eduardo Bautista <me@eduardobautista.com> <=>
 Eduardo Bautista <me@eduardobautista.com> <mail@eduardobautista.com>
 Eduardo Broto <ebroto@tutanota.com>
@@ -186,6 +189,7 @@ Erick Tryzelaar <erick.tryzelaar@gmail.com> <etryzelaar@iqt.org>
 Erik Desjardins <erikdesjardins@users.noreply.github.com>
 Erik Jensen <erikjensen@rkjnsn.net>
 Erin Power <xampprocky@gmail.com>
+Erin Power <xampprocky@gmail.com> <xampprocky@icloud.com>
 Erin Power <xampprocky@gmail.com> <theaaronepower@gmail.com>
 Erin Power <xampprocky@gmail.com> <Aaronepower@users.noreply.github.com>
 Esteban Küber <esteban@kuber.com.ar>
@@ -198,6 +202,7 @@ F001 <changchun.fan@qq.com>
 Fabian Kössel <fkjogu@users.noreply.github.com>
 Falco Hirschenberger <falco.hirschenberger@gmail.com> <hirschen@itwm.fhg.de>
 Felix S. Klock II <pnkfelix@pnkfx.org> Felix S Klock II <pnkfelix@pnkfx.org>
+Felix S. Klock II <pnkfelix@pnkfx.org> <pnkfelix@mozilla.com>
 Félix Saparelli <felix@passcod.name>
 Flaper Fesp <flaper87@gmail.com>
 Florian Berger <fbergr@gmail.com>
@@ -245,7 +250,7 @@ Irina Popa <irinagpopa@gmail.com>
 Ivan Ivaschenko <defuz.net@gmail.com>
 ivan tkachenko <me@ratijas.tk>
 J. J. Weber <jjweber@gmail.com>
-Jack Huey <jack.huey@umassmed.edu>
+Jack Huey <jack.huey@umassmed.edu> <jackh726@gmail.com>
 Jacob <jacob.macritchie@gmail.com>
 Jacob Greenfield <xales@naveria.com>
 Jacob Pratt <jacob@jhpratt.dev> <the.z.cuber@gmail.com>
@@ -292,6 +297,7 @@ John Clements <clements@racket-lang.org> <clements@brinckerhoff.org>
 John Hodge <acessdev@gmail.com> John Hodge <tpg@mutabah.net>
 John Hörnvall <trolledwoods@gmail.com>
 John Kåre Alsaker <john.kare.alsaker@gmail.com>
+John Kåre Alsaker <john.kare.alsaker@gmail.com> <zoxc32@gmail.com>
 John Talling <inrustwetrust@users.noreply.github.com>
 John Van Enk <vanenkj@gmail.com>
 Jonas Tepe <jonasprogrammer@gmail.com>
@@ -368,6 +374,7 @@ Lukas Lueg <lukas.lueg@gmail.com>
 Luke Metz <luke.metz@students.olin.edu>
 Luqman Aden <me@luqman.ca> <laden@csclub.uwaterloo.ca>
 Luqman Aden <me@luqman.ca> <laden@mozilla.com>
+Luqman Aden <me@luqman.ca> <rust@luqman.ca>
 Lzu Tao <taolzu@gmail.com>
 Maik Klein <maikklein@googlemail.com>
 Malo Jaffré <jaffre.malo@gmail.com>
@@ -409,6 +416,7 @@ mental <m3nta1@yahoo.com>
 mibac138 <5672750+mibac138@users.noreply.github.com>
 Michael Williams <m.t.williams@live.com>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail>
+Michael Woerister <michaelwoerister@posteo> <michaelwoerister@gmail.com>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@users.noreply.github.com>
 Michael Woerister <michaelwoerister@posteo> <michaelwoerister@posteo.net>
 Michael Zhang <hmperson1@gmail.com>
@@ -422,6 +430,7 @@ Ms2ger <ms2ger@gmail.com> <Ms2ger@gmail.com>
 msizanoen1 <qtmlabs@protonmail.com>
 Mukilan Thiagarajan <mukilanthiagarajan@gmail.com>
 Nadrieril Feneanar <Nadrieril@users.noreply.github.com>
+Nadrieril Feneanar <Nadrieril@users.noreply.github.com> <nadrieril+git@gmail.com>
 NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm@gmail.com>
 NAKASHIMA, Makoto <makoto.nksm+github@gmail.com> <makoto.nksm+github@gmail.com>
 Nathan Ringo <remexre@gmail.com>
@@ -442,6 +451,8 @@ Niclas Schwarzlose <15schnic@gmail.com>
 Nicolas Abram <abramlujan@gmail.com>
 Nicole Mazzuca <npmazzuca@gmail.com>
 Noratrieb <48135649+Noratrieb@users.noreply.github.com> <48135649+Nilstrieb@users.noreply.github.com>
+Noratrieb <48135649+Noratrieb@users.noreply.github.com> <nilstrieb@gmail.com>
+Noratrieb <48135649+Noratrieb@users.noreply.github.com> <nora@noratrieb.dev>
 Nif Ward <nif.ward@gmail.com>
 Nika Layzell <nika@thelayzells.com> <michael@thelayzells.com>
 NODA Kai <nodakai@gmail.com>
@@ -460,6 +471,7 @@ Oliver Scherer <oli-obk@users.noreply.github.com> <github6541940@oli-obk.de>
 Oliver Scherer <oli-obk@users.noreply.github.com> <public.oliver.schneider@kit.edu>
 Oliver Scherer <oli-obk@users.noreply.github.com> <oliver.schneider@kit.edu>
 Oliver Scherer <oli-obk@users.noreply.github.com> <obk8176014uqher834@olio-obk.de>
+Oliver Scherer <oli-obk@users.noreply.github.com> <rustc-contact@oli-obk.de>
 Oliver Scherer <oli-obk@users.noreply.github.com>
 Onur Özkan <onurozkan.dev@outlook.com> <work@onurozkan.dev>
 Onur Özkan <onurozkan.dev@outlook.com>
@@ -496,6 +508,7 @@ Raphaël Huchet <rap2hpoutre@users.noreply.github.com>
 rChaser53 <tayoshizawa29@gmail.com>
 Rémy Rakic <remy.rakic@gmail.com>
 Rémy Rakic <remy.rakic@gmail.com> <remy.rakic+github@gmail.com>
+Rémy Rakic <remy.rakic@gmail.com> <remy.rakic+rust@gmail.com>
 Renato Riccieri Santos Zannon <renato@rrsz.com.br>
 Richard Diamond <wichard@vitalitystudios.com> <wichard@hahbee.co>
 Ricky Hosfelt <ricky@hosfelt.io>
@@ -525,6 +538,7 @@ Samuel Tardieu <sam@rfc1149.net>
 Santiago Pastorino <spastorino@gmail.com>
 Santiago Pastorino <spastorino@gmail.com> <santiago@wyeworks.com>
 Scott McMurray <scottmcm@users.noreply.github.com>
+Scott McMurray <scottmcm@users.noreply.github.com> <smcmurray@acm.org>
 Scott Olson <scott@solson.me> Scott Olson <scott@scott-olson.org>
 Sean Gillespie <sean.william.g@gmail.com> swgillespie <sean.william.g@gmail.com>
 Seiichi Uchida <seuchida@gmail.com>
@@ -536,6 +550,7 @@ Shyam Sundar B <shyambaskaran@outlook.com>
 Simon Barber-Dueck <sbarberdueck@gmail.com> Simon BD <simon@server>
 Simon Sapin <simon@exyr.org> <simon.sapin@exyr.org>
 Simonas Kazlauskas <git@kazlauskas.me> Simonas Kazlauskas <github@kazlauskas.me>
+Simonas Kazlauskas <git@kazlauskas.me> <simonas+t-compiler@kazlauskas.me>
 Siva Prasad <sivaauturic@gmail.com>
 Smittyvb <me@smitop.com>
 Srinivas Reddy Thatiparthy <thatiparthysreenivas@gmail.com>
@@ -556,6 +571,8 @@ Tatsuyuki Ishi <ishitatsuyuki@gmail.com>
 Tau Gärtli <git@tau.garden> <ruben.schmidmeister@icloud.com>
 Tero Hänninen <lgvz@users.noreply.github.com> Tero Hänninen <tejohann@kapsi.fi>
 The8472 <git@infinite-source.de>
+The8472 <git@infinite-source.de> <the8472.rs@infinite-source.de>
+The8472 <git@infinite-source.de> <the8472@users.noreply.github.com>
 Theo Belaire <theo.belaire@gmail.com> Theo Belaire <tyr.god.of.war.42@gmail.com>
 Theodore Luo Wang <wangtheo662@gmail.com>
 Thiago Pontes <email@thiago.me> thiagopnts <thiagopnts@gmail.com>
@@ -593,7 +610,8 @@ Waffle Lapkin <waffle.lapkin@tasking.com>
 Wesley Wiser <wwiser@gmail.com> <wesleywiser@microsoft.com>
 whitequark <whitequark@whitequark.org>
 William Ting <io@williamting.com> <william.h.ting@gmail.com>
-Wim Looman <wim@nemo157.com>
+Wim Looman <wim@nemo157.com> <rust-lang@nemo157.com>
+Wim Looman <wim@nemo157.com> <git@nemo157.com>
 Without Boats <woboats@gmail.com>
 Without Boats <woboats@gmail.com> <boats@mozilla.com>
 Xinye Tao <xy.tao@outlook.com>
diff --git a/Cargo.lock b/Cargo.lock
index fc16ccf0a67..9fa1daf6546 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -3204,9 +3204,11 @@ dependencies = [
  "rand",
  "rand_xoshiro",
  "rustc_data_structures",
+ "rustc_feature",
  "rustc_index",
  "rustc_macros",
  "rustc_serialize",
+ "rustc_span",
  "tracing",
 ]
 
@@ -3749,11 +3751,11 @@ dependencies = [
 name = "rustc_hir_pretty"
 version = "0.0.0"
 dependencies = [
+ "rustc_abi",
  "rustc_ast",
  "rustc_ast_pretty",
  "rustc_hir",
  "rustc_span",
- "rustc_target",
 ]
 
 [[package]]
@@ -3938,6 +3940,7 @@ dependencies = [
 name = "rustc_lint_defs"
 version = "0.0.0"
 dependencies = [
+ "rustc_abi",
  "rustc_ast",
  "rustc_data_structures",
  "rustc_error_messages",
@@ -3945,7 +3948,6 @@ dependencies = [
  "rustc_macros",
  "rustc_serialize",
  "rustc_span",
- "rustc_target",
  "serde",
 ]
 
@@ -4004,7 +4006,6 @@ dependencies = [
  "rustc_span",
  "rustc_target",
  "rustc_type_ir",
- "snap",
  "tempfile",
  "tracing",
 ]
@@ -4054,6 +4055,7 @@ version = "0.0.0"
 dependencies = [
  "either",
  "itertools",
+ "rustc_abi",
  "rustc_apfloat",
  "rustc_arena",
  "rustc_ast",
@@ -4069,7 +4071,6 @@ dependencies = [
  "rustc_pattern_analysis",
  "rustc_session",
  "rustc_span",
- "rustc_target",
  "rustc_trait_selection",
  "tracing",
 ]
@@ -4890,12 +4891,6 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67"
 
 [[package]]
-name = "snap"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
-
-[[package]]
 name = "socket2"
 version = "0.5.7"
 source = "registry+https://github.com/rust-lang/crates.io-index"
diff --git a/compiler/rustc_abi/Cargo.toml b/compiler/rustc_abi/Cargo.toml
index 7448f066d0a..3acd25e5461 100644
--- a/compiler/rustc_abi/Cargo.toml
+++ b/compiler/rustc_abi/Cargo.toml
@@ -9,9 +9,11 @@ bitflags = "2.4.1"
 rand = { version = "0.8.4", default-features = false, optional = true }
 rand_xoshiro = { version = "0.6.0", optional = true }
 rustc_data_structures = { path = "../rustc_data_structures", optional = true  }
+rustc_feature = { path = "../rustc_feature", optional = true }
 rustc_index = { path = "../rustc_index", default-features = false }
 rustc_macros = { path = "../rustc_macros", optional = true }
 rustc_serialize = { path = "../rustc_serialize", optional = true  }
+rustc_span = { path = "../rustc_span", optional = true }
 tracing = "0.1"
 # tidy-alphabetical-end
 
@@ -22,8 +24,10 @@ default = ["nightly", "randomize"]
 # without depending on rustc_data_structures, rustc_macros and rustc_serialize
 nightly = [
     "dep:rustc_data_structures",
+    "dep:rustc_feature",
     "dep:rustc_macros",
     "dep:rustc_serialize",
+    "dep:rustc_span",
     "rustc_index/nightly",
 ]
 randomize = ["dep:rand", "dep:rand_xoshiro", "nightly"]
diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_abi/src/extern_abi/mod.rs
index c2095155afa..f7e41280131 100644
--- a/compiler/rustc_target/src/spec/abi/mod.rs
+++ b/compiler/rustc_abi/src/extern_abi/mod.rs
@@ -7,9 +7,11 @@ use rustc_span::{Span, Symbol};
 #[cfg(test)]
 mod tests;
 
+use ExternAbi as Abi;
+
 #[derive(PartialEq, Eq, PartialOrd, Ord, Hash, Clone, Copy, Debug)]
 #[derive(HashStable_Generic, Encodable, Decodable)]
-pub enum Abi {
+pub enum ExternAbi {
     // Some of the ABIs come first because every time we add a new ABI, we have to re-bless all the
     // hashing tests. These are used in many places, so giving them stable values reduces test
     // churn. The specific values are meaningless.
diff --git a/compiler/rustc_target/src/spec/abi/tests.rs b/compiler/rustc_abi/src/extern_abi/tests.rs
index 4823058dd69..4823058dd69 100644
--- a/compiler/rustc_target/src/spec/abi/tests.rs
+++ b/compiler/rustc_abi/src/extern_abi/tests.rs
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index fac1122c4df..ec758785173 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -1,6 +1,7 @@
 // tidy-alphabetical-start
 #![cfg_attr(feature = "nightly", allow(internal_features))]
 #![cfg_attr(feature = "nightly", doc(rust_logo))]
+#![cfg_attr(feature = "nightly", feature(assert_matches))]
 #![cfg_attr(feature = "nightly", feature(rustc_attrs))]
 #![cfg_attr(feature = "nightly", feature(rustdoc_internals))]
 #![cfg_attr(feature = "nightly", feature(step_trait))]
@@ -28,8 +29,15 @@ mod layout;
 #[cfg(test)]
 mod tests;
 
+#[cfg(feature = "nightly")]
+mod extern_abi;
+
 pub use callconv::{Heterogeneous, HomogeneousAggregate, Reg, RegKind};
 #[cfg(feature = "nightly")]
+pub use extern_abi::{
+    AbiDisabled, AbiUnsupported, ExternAbi, all_names, enabled_names, is_enabled, is_stable, lookup,
+};
+#[cfg(feature = "nightly")]
 pub use layout::{FIRST_VARIANT, FieldIdx, Layout, TyAbiInterface, TyAndLayout, VariantIdx};
 pub use layout::{LayoutCalculator, LayoutCalculatorError};
 
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 8e4f4c8e71a..ec6ca70ae0a 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -2810,6 +2810,8 @@ pub struct ModSpans {
 /// E.g., `extern { .. }` or `extern "C" { .. }`.
 #[derive(Clone, Encodable, Decodable, Debug)]
 pub struct ForeignMod {
+    /// Span of the `extern` keyword.
+    pub extern_span: Span,
     /// `unsafe` keyword accepted syntactically for macro DSLs, but not
     /// semantically by Rust.
     pub safety: Safety,
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 2afbd979c30..44bb44cb728 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -525,7 +525,7 @@ pub fn walk_ty<T: MutVisitor>(vis: &mut T, ty: &mut P<Ty>) {
 }
 
 fn walk_foreign_mod<T: MutVisitor>(vis: &mut T, foreign_mod: &mut ForeignMod) {
-    let ForeignMod { safety, abi: _, items } = foreign_mod;
+    let ForeignMod { extern_span: _, safety, abi: _, items } = foreign_mod;
     visit_safety(vis, safety);
     items.flat_map_in_place(|item| vis.flat_map_foreign_item(item));
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index eb71ec5f4ec..2f8115441de 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -366,7 +366,7 @@ impl WalkItemKind for ItemKind {
                 }
                 ModKind::Unloaded => {}
             },
-            ItemKind::ForeignMod(ForeignMod { safety: _, abi: _, items }) => {
+            ItemKind::ForeignMod(ForeignMod { extern_span: _, safety: _, abi: _, items }) => {
                 walk_list!(visitor, visit_foreign_item, items);
             }
             ItemKind::GlobalAsm(asm) => try_visit!(visitor.visit_inline_asm(asm)),
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index 0a4f86d4822..dee48586f34 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -677,9 +677,8 @@ impl<'a> AstValidator<'a> {
                 Self::check_decl_no_pat(&bfty.decl, |span, _, _| {
                     self.dcx().emit_err(errors::PatternFnPointer { span });
                 });
-                if let Extern::Implicit(_) = bfty.ext {
-                    let sig_span = self.sess.source_map().next_point(ty.span.shrink_to_lo());
-                    self.maybe_lint_missing_abi(sig_span, ty.id);
+                if let Extern::Implicit(extern_span) = bfty.ext {
+                    self.maybe_lint_missing_abi(extern_span, ty.id);
                 }
             }
             TyKind::TraitObject(bounds, ..) => {
@@ -953,7 +952,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 walk_list!(self, visit_attribute, &item.attrs);
                 return; // Avoid visiting again.
             }
-            ItemKind::ForeignMod(ForeignMod { abi, safety, .. }) => {
+            ItemKind::ForeignMod(ForeignMod { extern_span, abi, safety, .. }) => {
                 self.with_in_extern_mod(*safety, |this| {
                     let old_item = mem::replace(&mut this.extern_mod, Some(item.span));
                     this.visibility_not_permitted(
@@ -977,7 +976,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                     }
 
                     if abi.is_none() {
-                        this.maybe_lint_missing_abi(item.span, item.id);
+                        this.maybe_lint_missing_abi(*extern_span, item.id);
                     }
                     visit::walk_item(this, item);
                     this.extern_mod = old_item;
@@ -1350,13 +1349,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         if let FnKind::Fn(
             _,
             _,
-            FnSig { span: sig_span, header: FnHeader { ext: Extern::Implicit(_), .. }, .. },
+            FnSig { header: FnHeader { ext: Extern::Implicit(extern_span), .. }, .. },
             _,
             _,
             _,
         ) = fk
         {
-            self.maybe_lint_missing_abi(*sig_span, id);
+            self.maybe_lint_missing_abi(*extern_span, id);
         }
 
         // Functions without bodies cannot have patterns.
diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
index 1bfb54a7bb7..511313cca6f 100644
--- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs
@@ -1525,7 +1525,6 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
                 matches!(
                     adj.kind,
                     ty::adjustment::Adjust::Borrow(ty::adjustment::AutoBorrow::Ref(
-                        _,
                         ty::adjustment::AutoBorrowMutability::Not
                             | ty::adjustment::AutoBorrowMutability::Mut {
                                 allow_two_phase_borrow: ty::adjustment::AllowTwoPhase::No
diff --git a/compiler/rustc_codegen_cranelift/src/lib.rs b/compiler/rustc_codegen_cranelift/src/lib.rs
index 602b1b98200..fc3bd0abd78 100644
--- a/compiler/rustc_codegen_cranelift/src/lib.rs
+++ b/compiler/rustc_codegen_cranelift/src/lib.rs
@@ -40,6 +40,7 @@ use std::sync::Arc;
 use cranelift_codegen::isa::TargetIsa;
 use cranelift_codegen::settings::{self, Configurable};
 use rustc_codegen_ssa::CodegenResults;
+use rustc_codegen_ssa::back::versioned_llvm_target;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_data_structures::profiling::SelfProfilerRef;
 use rustc_errors::ErrorGuaranteed;
@@ -260,7 +261,9 @@ impl CodegenBackend for CraneliftCodegenBackend {
 }
 
 fn target_triple(sess: &Session) -> target_lexicon::Triple {
-    match sess.target.llvm_target.parse() {
+    // FIXME(madsmtm): Use `sess.target.llvm_target` once target-lexicon supports unversioned macOS.
+    // See <https://github.com/bytecodealliance/target-lexicon/pull/113>
+    match versioned_llvm_target(sess).parse() {
         Ok(triple) => triple,
         Err(err) => sess.dcx().fatal(format!("target not recognized: {}", err)),
     }
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 2c5ec9dad59..64bb22e8cb2 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -232,11 +232,6 @@ fn probestack_attr<'ll>(cx: &CodegenCx<'ll, '_>) -> Option<&'ll Attribute> {
         return None;
     }
 
-    // probestack doesn't play nice either with gcov profiling.
-    if cx.sess().opts.unstable_opts.profile {
-        return None;
-    }
-
     let attr_value = match cx.sess().target.stack_probes {
         StackProbeType::None => return None,
         // Request LLVM to generate the probes inline. If the given LLVM version does not support
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index bfa9e8b82a0..01e2c308ca4 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -9,6 +9,7 @@ use llvm::{
     LLVMRustLLVMHasZlibCompressionForDebugSymbols, LLVMRustLLVMHasZstdCompressionForDebugSymbols,
 };
 use rustc_codegen_ssa::back::link::ensure_removed;
+use rustc_codegen_ssa::back::versioned_llvm_target;
 use rustc_codegen_ssa::back::write::{
     BitcodeSection, CodegenContext, EmitObj, ModuleConfig, TargetMachineFactoryConfig,
     TargetMachineFactoryFn,
@@ -211,7 +212,7 @@ pub(crate) fn target_machine_factory(
         singlethread = false;
     }
 
-    let triple = SmallCStr::new(&sess.target.llvm_target);
+    let triple = SmallCStr::new(&versioned_llvm_target(sess));
     let cpu = SmallCStr::new(llvm_util::target_cpu(sess));
     let features = CString::new(target_features.join(",")).unwrap();
     let abi = SmallCStr::new(&sess.target.llvm_abiname);
@@ -591,7 +592,6 @@ pub(crate) unsafe fn llvm_optimize(
             pgo_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
             config.instrument_coverage,
             instr_profile_output_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
-            config.instrument_gcov,
             pgo_sample_use_path.as_ref().map_or(std::ptr::null(), |s| s.as_ptr()),
             config.debug_info_for_profiling,
             llvm_selfprofiler,
diff --git a/compiler/rustc_codegen_llvm/src/context.rs b/compiler/rustc_codegen_llvm/src/context.rs
index 9778ff4918c..03f4fb527a8 100644
--- a/compiler/rustc_codegen_llvm/src/context.rs
+++ b/compiler/rustc_codegen_llvm/src/context.rs
@@ -3,6 +3,7 @@ use std::cell::{Cell, RefCell};
 use std::ffi::{CStr, c_uint};
 use std::str;
 
+use rustc_codegen_ssa::back::versioned_llvm_target;
 use rustc_codegen_ssa::base::{wants_msvc_seh, wants_wasm_eh};
 use rustc_codegen_ssa::errors as ssa_errors;
 use rustc_codegen_ssa::traits::*;
@@ -148,6 +149,11 @@ pub(crate) unsafe fn create_module<'ll>(
             target_data_layout =
                 target_data_layout.replace("-p270:32:32-p271:32:32-p272:64:64", "");
         }
+        if sess.target.arch.starts_with("sparc") {
+            // LLVM 20 updates the sparc layout to correctly align 128 bit integers to 128 bit.
+            // See https://github.com/llvm/llvm-project/pull/106951
+            target_data_layout = target_data_layout.replace("-i128:128", "");
+        }
     }
 
     // Ensure the data-layout values hardcoded remain the defaults.
@@ -177,7 +183,7 @@ pub(crate) unsafe fn create_module<'ll>(
         llvm::LLVMSetDataLayout(llmod, data_layout.as_ptr());
     }
 
-    let llvm_target = SmallCStr::new(&sess.target.llvm_target);
+    let llvm_target = SmallCStr::new(&versioned_llvm_target(sess));
     unsafe {
         llvm::LLVMRustSetNormalizedTarget(llmod, llvm_target.as_ptr());
     }
@@ -554,6 +560,7 @@ impl<'ll, 'tcx> CodegenCx<'ll, 'tcx> {
 
     /// Extra state that is only available when coverage instrumentation is enabled.
     #[inline]
+    #[track_caller]
     pub(crate) fn coverage_cx(&self) -> &coverageinfo::CrateCoverageContext<'ll, 'tcx> {
         self.coverage_cx.as_ref().expect("only called when coverage instrumentation is enabled")
     }
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index 8edd788ee36..f6378199fe2 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -54,7 +54,11 @@ pub(crate) fn finalize(cx: &CodegenCx<'_, '_>) {
         add_unused_functions(cx);
     }
 
-    let function_coverage_map = cx.coverage_cx().take_function_coverage_map();
+    // FIXME(#132395): Can this be none even when coverage is enabled?
+    let function_coverage_map = match cx.coverage_cx {
+        Some(ref cx) => cx.take_function_coverage_map(),
+        None => return,
+    };
     if function_coverage_map.is_empty() {
         // This module has no functions with coverage instrumentation
         return;
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
index a298ed86276..e4ff50816b9 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mod.rs
@@ -152,7 +152,12 @@ impl<'tcx> CoverageInfoBuilderMethods<'tcx> for Builder<'_, '_, 'tcx> {
             return;
         };
 
-        let mut coverage_map = bx.coverage_cx().function_coverage_map.borrow_mut();
+        // FIXME(#132395): Unwrapping `coverage_cx` here has led to ICEs in the
+        // wild, so keep this early-return until we understand why.
+        let mut coverage_map = match bx.coverage_cx {
+            Some(ref cx) => cx.function_coverage_map.borrow_mut(),
+            None => return,
+        };
         let func_coverage = coverage_map
             .entry(instance)
             .or_insert_with(|| FunctionCoverageCollector::new(instance, function_coverage_info));
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 9064cfaeb29..0d1fd0163eb 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -7,7 +7,6 @@ use std::{iter, ptr};
 use libc::{c_char, c_longlong, c_uint};
 use rustc_codegen_ssa::debuginfo::type_names::{VTableNameKind, cpp_like_debuginfo};
 use rustc_codegen_ssa::traits::*;
-use rustc_fs_util::path_to_c_string;
 use rustc_hir::def::{CtorKind, DefKind};
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_middle::bug;
@@ -979,33 +978,8 @@ pub(crate) fn build_compile_unit_di_node<'ll, 'tcx>(
             debug_name_table_kind,
         );
 
-        if tcx.sess.opts.unstable_opts.profile {
-            let default_gcda_path = &output_filenames.with_extension("gcda");
-            let gcda_path =
-                tcx.sess.opts.unstable_opts.profile_emit.as_ref().unwrap_or(default_gcda_path);
-
-            let gcov_cu_info = [
-                path_to_mdstring(debug_context.llcontext, &output_filenames.with_extension("gcno")),
-                path_to_mdstring(debug_context.llcontext, gcda_path),
-                unit_metadata,
-            ];
-            let gcov_metadata = llvm::LLVMMDNodeInContext2(
-                debug_context.llcontext,
-                gcov_cu_info.as_ptr(),
-                gcov_cu_info.len(),
-            );
-            let val = llvm::LLVMMetadataAsValue(debug_context.llcontext, gcov_metadata);
-
-            llvm::LLVMAddNamedMetadataOperand(debug_context.llmod, c"llvm.gcov".as_ptr(), val);
-        }
-
         return unit_metadata;
     };
-
-    fn path_to_mdstring<'ll>(llcx: &'ll llvm::Context, path: &Path) -> &'ll llvm::Metadata {
-        let path_str = path_to_c_string(path);
-        unsafe { llvm::LLVMMDStringInContext2(llcx, path_str.as_ptr(), path_str.as_bytes().len()) }
-    }
 }
 
 /// Creates a `DW_TAG_member` entry inside the DIE represented by the given `type_di_node`.
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
index 72e723aa849..b6c20cdcf0c 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/mod.rs
@@ -55,7 +55,6 @@ const DW_TAG_arg_variable: c_uint = 0x101;
 
 /// A context object for maintaining all state needed by the debuginfo module.
 pub(crate) struct CodegenUnitDebugContext<'ll, 'tcx> {
-    llcontext: &'ll llvm::Context,
     llmod: &'ll llvm::Module,
     builder: &'ll mut DIBuilder<'ll>,
     created_files: RefCell<UnordMap<Option<(StableSourceFileId, SourceFileHash)>, &'ll DIFile>>,
@@ -78,9 +77,7 @@ impl<'ll, 'tcx> CodegenUnitDebugContext<'ll, 'tcx> {
         debug!("CodegenUnitDebugContext::new");
         let builder = unsafe { llvm::LLVMRustDIBuilderCreate(llmod) };
         // DIBuilder inherits context from the module, so we'd better use the same one
-        let llcontext = unsafe { llvm::LLVMGetModuleContext(llmod) };
         CodegenUnitDebugContext {
-            llcontext,
             llmod,
             builder,
             created_files: Default::default(),
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index 8fc586d2c8f..5fad7583e1a 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2269,7 +2269,6 @@ unsafe extern "C" {
         PGOUsePath: *const c_char,
         InstrumentCoverage: bool,
         InstrProfileOutput: *const c_char,
-        InstrumentGCOV: bool,
         PGOSampleUsePath: *const c_char,
         DebugInfoForProfiling: bool,
         llvm_selfprofiler: *mut c_void,
diff --git a/compiler/rustc_codegen_ssa/messages.ftl b/compiler/rustc_codegen_ssa/messages.ftl
index d07274920fe..3b34eb063ec 100644
--- a/compiler/rustc_codegen_ssa/messages.ftl
+++ b/compiler/rustc_codegen_ssa/messages.ftl
@@ -2,6 +2,12 @@ codegen_ssa_L4Bender_exporting_symbols_unimplemented = exporting symbols not imp
 
 codegen_ssa_add_native_library = failed to add native library {$library_path}: {$error}
 
+codegen_ssa_apple_deployment_target_invalid =
+    failed to parse deployment target specified in {$env_var}: {$error}
+
+codegen_ssa_apple_deployment_target_too_low =
+    deployment target in {$env_var} was set to {$version}, but the minimum supported by `rustc` is {$os_min}
+
 codegen_ssa_apple_sdk_error_sdk_path = failed to get {$sdk_name} SDK path: {$error}
 
 codegen_ssa_archive_build_failure = failed to build archive at `{$path}`: {$error}
diff --git a/compiler/rustc_codegen_ssa/src/back/apple.rs b/compiler/rustc_codegen_ssa/src/back/apple.rs
new file mode 100644
index 00000000000..93d90cd16b2
--- /dev/null
+++ b/compiler/rustc_codegen_ssa/src/back/apple.rs
@@ -0,0 +1,171 @@
+use std::env;
+use std::fmt::{Display, from_fn};
+use std::num::ParseIntError;
+
+use rustc_session::Session;
+use rustc_target::spec::Target;
+
+use crate::errors::AppleDeploymentTarget;
+
+#[cfg(test)]
+mod tests;
+
+pub(super) fn macho_platform(target: &Target) -> u32 {
+    match (&*target.os, &*target.abi) {
+        ("macos", _) => object::macho::PLATFORM_MACOS,
+        ("ios", "macabi") => object::macho::PLATFORM_MACCATALYST,
+        ("ios", "sim") => object::macho::PLATFORM_IOSSIMULATOR,
+        ("ios", _) => object::macho::PLATFORM_IOS,
+        ("watchos", "sim") => object::macho::PLATFORM_WATCHOSSIMULATOR,
+        ("watchos", _) => object::macho::PLATFORM_WATCHOS,
+        ("tvos", "sim") => object::macho::PLATFORM_TVOSSIMULATOR,
+        ("tvos", _) => object::macho::PLATFORM_TVOS,
+        ("visionos", "sim") => object::macho::PLATFORM_XROSSIMULATOR,
+        ("visionos", _) => object::macho::PLATFORM_XROS,
+        _ => unreachable!("tried to get Mach-O platform for non-Apple target"),
+    }
+}
+
+/// Deployment target or SDK version.
+///
+/// The size of the numbers in here are limited by Mach-O's `LC_BUILD_VERSION`.
+type OSVersion = (u16, u8, u8);
+
+/// Parse an OS version triple (SDK version or deployment target).
+fn parse_version(version: &str) -> Result<OSVersion, ParseIntError> {
+    if let Some((major, minor)) = version.split_once('.') {
+        let major = major.parse()?;
+        if let Some((minor, patch)) = minor.split_once('.') {
+            Ok((major, minor.parse()?, patch.parse()?))
+        } else {
+            Ok((major, minor.parse()?, 0))
+        }
+    } else {
+        Ok((version.parse()?, 0, 0))
+    }
+}
+
+pub fn pretty_version(version: OSVersion) -> impl Display {
+    let (major, minor, patch) = version;
+    from_fn(move |f| {
+        write!(f, "{major}.{minor}")?;
+        if patch != 0 {
+            write!(f, ".{patch}")?;
+        }
+        Ok(())
+    })
+}
+
+/// Minimum operating system versions currently supported by `rustc`.
+fn os_minimum_deployment_target(os: &str) -> OSVersion {
+    // When bumping a version in here, remember to update the platform-support docs too.
+    //
+    // NOTE: The defaults may change in future `rustc` versions, so if you are looking for the
+    // default deployment target, prefer:
+    // ```
+    // $ rustc --print deployment-target
+    // ```
+    match os {
+        "macos" => (10, 12, 0),
+        "ios" => (10, 0, 0),
+        "tvos" => (10, 0, 0),
+        "watchos" => (5, 0, 0),
+        "visionos" => (1, 0, 0),
+        _ => unreachable!("tried to get deployment target for non-Apple platform"),
+    }
+}
+
+/// The deployment target for the given target.
+///
+/// This is similar to `os_minimum_deployment_target`, except that on certain targets it makes sense
+/// to raise the minimum OS version.
+///
+/// This matches what LLVM does, see in part:
+/// <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
+fn minimum_deployment_target(target: &Target) -> OSVersion {
+    match (&*target.os, &*target.arch, &*target.abi) {
+        ("macos", "aarch64", _) => (11, 0, 0),
+        ("ios", "aarch64", "macabi") => (14, 0, 0),
+        ("ios", "aarch64", "sim") => (14, 0, 0),
+        ("ios", _, _) if target.llvm_target.starts_with("arm64e") => (14, 0, 0),
+        // Mac Catalyst defaults to 13.1 in Clang.
+        ("ios", _, "macabi") => (13, 1, 0),
+        ("tvos", "aarch64", "sim") => (14, 0, 0),
+        ("watchos", "aarch64", "sim") => (7, 0, 0),
+        (os, _, _) => os_minimum_deployment_target(os),
+    }
+}
+
+/// Name of the environment variable used to fetch the deployment target on the given OS.
+fn deployment_target_env_var(os: &str) -> &'static str {
+    match os {
+        "macos" => "MACOSX_DEPLOYMENT_TARGET",
+        "ios" => "IPHONEOS_DEPLOYMENT_TARGET",
+        "watchos" => "WATCHOS_DEPLOYMENT_TARGET",
+        "tvos" => "TVOS_DEPLOYMENT_TARGET",
+        "visionos" => "XROS_DEPLOYMENT_TARGET",
+        _ => unreachable!("tried to get deployment target env var for non-Apple platform"),
+    }
+}
+
+/// Get the deployment target based on the standard environment variables, or fall back to the
+/// minimum version supported by `rustc`.
+pub fn deployment_target(sess: &Session) -> OSVersion {
+    let min = minimum_deployment_target(&sess.target);
+    let env_var = deployment_target_env_var(&sess.target.os);
+
+    if let Ok(deployment_target) = env::var(env_var) {
+        match parse_version(&deployment_target) {
+            Ok(version) => {
+                let os_min = os_minimum_deployment_target(&sess.target.os);
+                // It is common that the deployment target is set a bit too low, for example on
+                // macOS Aarch64 to also target older x86_64. So we only want to warn when variable
+                // is lower than the minimum OS supported by rustc, not when the variable is lower
+                // than the minimum for a specific target.
+                if version < os_min {
+                    sess.dcx().emit_warn(AppleDeploymentTarget::TooLow {
+                        env_var,
+                        version: pretty_version(version).to_string(),
+                        os_min: pretty_version(os_min).to_string(),
+                    });
+                }
+
+                // Raise the deployment target to the minimum supported.
+                version.max(min)
+            }
+            Err(error) => {
+                sess.dcx().emit_err(AppleDeploymentTarget::Invalid { env_var, error });
+                min
+            }
+        }
+    } else {
+        // If no deployment target variable is set, default to the minimum found above.
+        min
+    }
+}
+
+pub(super) fn add_version_to_llvm_target(
+    llvm_target: &str,
+    deployment_target: OSVersion,
+) -> String {
+    let mut components = llvm_target.split("-");
+    let arch = components.next().expect("apple target should have arch");
+    let vendor = components.next().expect("apple target should have vendor");
+    let os = components.next().expect("apple target should have os");
+    let environment = components.next();
+    assert_eq!(components.next(), None, "too many LLVM triple components");
+
+    let (major, minor, patch) = deployment_target;
+
+    assert!(
+        !os.contains(|c: char| c.is_ascii_digit()),
+        "LLVM target must not already be versioned"
+    );
+
+    if let Some(env) = environment {
+        // Insert version into OS, before environment
+        format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}-{env}")
+    } else {
+        format!("{arch}-{vendor}-{os}{major}.{minor}.{patch}")
+    }
+}
diff --git a/compiler/rustc_codegen_ssa/src/back/apple/tests.rs b/compiler/rustc_codegen_ssa/src/back/apple/tests.rs
new file mode 100644
index 00000000000..7ccda5a8190
--- /dev/null
+++ b/compiler/rustc_codegen_ssa/src/back/apple/tests.rs
@@ -0,0 +1,21 @@
+use super::{add_version_to_llvm_target, parse_version};
+
+#[test]
+fn test_add_version_to_llvm_target() {
+    assert_eq!(
+        add_version_to_llvm_target("aarch64-apple-macosx", (10, 14, 1)),
+        "aarch64-apple-macosx10.14.1"
+    );
+    assert_eq!(
+        add_version_to_llvm_target("aarch64-apple-ios-simulator", (16, 1, 0)),
+        "aarch64-apple-ios16.1.0-simulator"
+    );
+}
+
+#[test]
+fn test_parse_version() {
+    assert_eq!(parse_version("10"), Ok((10, 0, 0)));
+    assert_eq!(parse_version("10.12"), Ok((10, 12, 0)));
+    assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6)));
+    assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99)));
+}
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index 34dc599e4fd..b01a62b394b 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -40,7 +40,7 @@ use rustc_target::spec::crt_objects::CrtObjects;
 use rustc_target::spec::{
     Cc, LinkOutputKind, LinkSelfContainedComponents, LinkSelfContainedDefault, LinkerFeatures,
     LinkerFlavor, LinkerFlavorCli, Lld, PanicStrategy, RelocModel, RelroLevel, SanitizerSet,
-    SplitDebuginfo, current_apple_deployment_target,
+    SplitDebuginfo,
 };
 use tempfile::Builder as TempFileBuilder;
 use tracing::{debug, info, warn};
@@ -50,6 +50,7 @@ use super::command::Command;
 use super::linker::{self, Linker};
 use super::metadata::{MetadataPosition, create_wrapper_file};
 use super::rpath::{self, RPathConfig};
+use super::{apple, versioned_llvm_target};
 use crate::{
     CodegenResults, CompiledModule, CrateInfo, NativeLib, common, errors,
     looks_like_rust_object_file,
@@ -2447,7 +2448,7 @@ fn add_order_independent_options(
     if flavor == LinkerFlavor::Llbc {
         cmd.link_args(&[
             "--target",
-            sess.target.llvm_target.as_ref(),
+            &versioned_llvm_target(sess),
             "--target-cpu",
             &codegen_results.crate_info.target_cpu,
         ]);
@@ -3039,7 +3040,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
             _ => bug!("invalid OS/ABI combination for Apple target: {target_os}, {target_abi}"),
         };
 
-        let (major, minor, patch) = current_apple_deployment_target(&sess.target);
+        let (major, minor, patch) = apple::deployment_target(sess);
         let min_version = format!("{major}.{minor}.{patch}");
 
         // The SDK version is used at runtime when compiling with a newer SDK / version of Xcode:
@@ -3109,7 +3110,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
 
             // The presence of `-mmacosx-version-min` makes CC default to
             // macOS, and it sets the deployment target.
-            let (major, minor, patch) = current_apple_deployment_target(&sess.target);
+            let (major, minor, patch) = apple::deployment_target(sess);
             // Intentionally pass this as a single argument, Clang doesn't
             // seem to like it otherwise.
             cmd.cc_arg(&format!("-mmacosx-version-min={major}.{minor}.{patch}"));
@@ -3119,7 +3120,7 @@ fn add_apple_link_args(cmd: &mut dyn Linker, sess: &Session, flavor: LinkerFlavo
             //
             // We avoid `-m32`/`-m64`, as this is already encoded by `-arch`.
         } else {
-            cmd.cc_args(&["-target", &sess.target.llvm_target]);
+            cmd.cc_args(&["-target", &versioned_llvm_target(sess)]);
         }
     }
 }
@@ -3345,7 +3346,7 @@ fn add_lld_args(
         // targeting a different linker flavor on macOS, and that's also always
         // the case when targeting WASM.
         if sess.target.linker_flavor != sess.host.linker_flavor {
-            cmd.cc_arg(format!("--target={}", sess.target.llvm_target));
+            cmd.cc_arg(format!("--target={}", versioned_llvm_target(sess)));
         }
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 8857fda1e97..a7d95d56784 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -22,6 +22,8 @@ use rustc_span::sym;
 use rustc_target::abi::Endian;
 use rustc_target::spec::{RelocModel, Target, ef_avr_arch};
 
+use super::apple;
+
 /// The default metadata loader. This is used by cg_llvm and cg_clif.
 ///
 /// # Metadata location
@@ -238,7 +240,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
             file.set_macho_cpu_subtype(object::macho::CPU_SUBTYPE_ARM64E);
         }
 
-        file.set_macho_build_version(macho_object_build_version_for_target(&sess.target))
+        file.set_macho_build_version(macho_object_build_version_for_target(sess))
     }
     if binary_format == BinaryFormat::Coff {
         // Disable the default mangler to avoid mangling the special "@feat.00" symbol name.
@@ -322,10 +324,11 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
             // Set the appropriate flag based on ABI
             // This needs to match LLVM `RISCVELFStreamer.cpp`
             match &*sess.target.llvm_abiname {
-                "" | "ilp32" | "lp64" => (),
+                "ilp32" | "lp64" => (),
                 "ilp32f" | "lp64f" => e_flags |= elf::EF_RISCV_FLOAT_ABI_SINGLE,
                 "ilp32d" | "lp64d" => e_flags |= elf::EF_RISCV_FLOAT_ABI_DOUBLE,
-                "ilp32e" => e_flags |= elf::EF_RISCV_RVE,
+                // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI.
+                "ilp32e" | "lp64e" => e_flags |= elf::EF_RISCV_RVE,
                 _ => bug!("unknown RISC-V ABI name"),
             }
 
@@ -391,7 +394,7 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
 ///
 /// Since Xcode 15, Apple's LD apparently requires object files to use this load command, so this
 /// returns the `MachOBuildVersion` for the target to do so.
-fn macho_object_build_version_for_target(target: &Target) -> object::write::MachOBuildVersion {
+fn macho_object_build_version_for_target(sess: &Session) -> object::write::MachOBuildVersion {
     /// The `object` crate demands "X.Y.Z encoded in nibbles as xxxx.yy.zz"
     /// e.g. minOS 14.0 = 0x000E0000, or SDK 16.2 = 0x00100200
     fn pack_version((major, minor, patch): (u16, u8, u8)) -> u32 {
@@ -399,9 +402,8 @@ fn macho_object_build_version_for_target(target: &Target) -> object::write::Mach
         (major << 16) | (minor << 8) | patch
     }
 
-    let platform =
-        rustc_target::spec::current_apple_platform(target).expect("unknown Apple target OS");
-    let min_os = rustc_target::spec::current_apple_deployment_target(target);
+    let platform = apple::macho_platform(&sess.target);
+    let min_os = apple::deployment_target(sess);
 
     let mut build_version = object::write::MachOBuildVersion::default();
     build_version.platform = platform;
diff --git a/compiler/rustc_codegen_ssa/src/back/mod.rs b/compiler/rustc_codegen_ssa/src/back/mod.rs
index 2b3a2e3a369..64b5d4569ec 100644
--- a/compiler/rustc_codegen_ssa/src/back/mod.rs
+++ b/compiler/rustc_codegen_ssa/src/back/mod.rs
@@ -1,3 +1,8 @@
+use std::borrow::Cow;
+
+use rustc_session::Session;
+
+pub mod apple;
 pub mod archive;
 pub(crate) mod command;
 pub mod link;
@@ -7,3 +12,19 @@ pub mod metadata;
 pub(crate) mod rpath;
 pub mod symbol_export;
 pub mod write;
+
+/// The target triple depends on the deployment target, and is required to
+/// enable features such as cross-language LTO, and for picking the right
+/// Mach-O commands.
+///
+/// Certain optimizations also depend on the deployment target.
+pub fn versioned_llvm_target(sess: &Session) -> Cow<'_, str> {
+    if sess.target.is_like_osx {
+        apple::add_version_to_llvm_target(&sess.target.llvm_target, apple::deployment_target(sess))
+            .into()
+    } else {
+        // FIXME(madsmtm): Certain other targets also include a version,
+        // we might want to move that here as well.
+        Cow::Borrowed(&sess.target.llvm_target)
+    }
+}
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index 8445d16befb..d977cca247e 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -90,7 +90,6 @@ pub struct ModuleConfig {
     pub pgo_sample_use: Option<PathBuf>,
     pub debug_info_for_profiling: bool,
     pub instrument_coverage: bool,
-    pub instrument_gcov: bool,
 
     pub sanitizer: SanitizerSet,
     pub sanitizer_recover: SanitizerSet,
@@ -123,12 +122,7 @@ pub struct ModuleConfig {
 }
 
 impl ModuleConfig {
-    fn new(
-        kind: ModuleKind,
-        tcx: TyCtxt<'_>,
-        no_builtins: bool,
-        is_compiler_builtins: bool,
-    ) -> ModuleConfig {
+    fn new(kind: ModuleKind, tcx: TyCtxt<'_>, no_builtins: bool) -> ModuleConfig {
         // If it's a regular module, use `$regular`, otherwise use `$other`.
         // `$regular` and `$other` are evaluated lazily.
         macro_rules! if_regular {
@@ -189,13 +183,6 @@ impl ModuleConfig {
             pgo_sample_use: if_regular!(sess.opts.unstable_opts.profile_sample_use.clone(), None),
             debug_info_for_profiling: sess.opts.unstable_opts.debug_info_for_profiling,
             instrument_coverage: if_regular!(sess.instrument_coverage(), false),
-            instrument_gcov: if_regular!(
-                // compiler_builtins overrides the codegen-units settings,
-                // which is incompatible with -Zprofile which requires that
-                // only a single codegen unit is used per crate.
-                sess.opts.unstable_opts.profile && !is_compiler_builtins,
-                false
-            ),
 
             sanitizer: if_regular!(sess.opts.unstable_opts.sanitizer, SanitizerSet::empty()),
             sanitizer_dataflow_abilist: if_regular!(
@@ -473,16 +460,12 @@ pub(crate) fn start_async_codegen<B: ExtraBackendMethods>(
 
     let crate_attrs = tcx.hir().attrs(rustc_hir::CRATE_HIR_ID);
     let no_builtins = attr::contains_name(crate_attrs, sym::no_builtins);
-    let is_compiler_builtins = attr::contains_name(crate_attrs, sym::compiler_builtins);
 
     let crate_info = CrateInfo::new(tcx, target_cpu);
 
-    let regular_config =
-        ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins, is_compiler_builtins);
-    let metadata_config =
-        ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins, is_compiler_builtins);
-    let allocator_config =
-        ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins, is_compiler_builtins);
+    let regular_config = ModuleConfig::new(ModuleKind::Regular, tcx, no_builtins);
+    let metadata_config = ModuleConfig::new(ModuleKind::Metadata, tcx, no_builtins);
+    let allocator_config = ModuleConfig::new(ModuleKind::Allocator, tcx, no_builtins);
 
     let (shared_emitter, shared_emitter_main) = SharedEmitter::new();
     let (codegen_worker_send, codegen_worker_receive) = channel();
diff --git a/compiler/rustc_codegen_ssa/src/errors.rs b/compiler/rustc_codegen_ssa/src/errors.rs
index d67cf0e3a6d..cf8d1cfa0d1 100644
--- a/compiler/rustc_codegen_ssa/src/errors.rs
+++ b/compiler/rustc_codegen_ssa/src/errors.rs
@@ -2,6 +2,7 @@
 
 use std::borrow::Cow;
 use std::io::Error;
+use std::num::ParseIntError;
 use std::path::{Path, PathBuf};
 use std::process::ExitStatus;
 
@@ -540,6 +541,14 @@ pub(crate) struct UnsupportedArch<'a> {
 }
 
 #[derive(Diagnostic)]
+pub(crate) enum AppleDeploymentTarget {
+    #[diag(codegen_ssa_apple_deployment_target_invalid)]
+    Invalid { env_var: &'static str, error: ParseIntError },
+    #[diag(codegen_ssa_apple_deployment_target_too_low)]
+    TooLow { env_var: &'static str, version: String, os_min: String },
+}
+
+#[derive(Diagnostic)]
 pub(crate) enum AppleSdkRootError<'a> {
     #[diag(codegen_ssa_apple_sdk_error_sdk_path)]
     SdkPath { sdk_name: &'a str, error: Error },
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 73bfa9dbd10..7dc8ab38a97 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -6,6 +6,7 @@
 #![doc(rust_logo)]
 #![feature(assert_matches)]
 #![feature(box_patterns)]
+#![feature(debug_closure_helpers)]
 #![feature(file_buffered)]
 #![feature(if_let_guard)]
 #![feature(let_chains)]
diff --git a/compiler/rustc_const_eval/src/check_consts/check.rs b/compiler/rustc_const_eval/src/check_consts/check.rs
index 5210241d5e4..303c490d827 100644
--- a/compiler/rustc_const_eval/src/check_consts/check.rs
+++ b/compiler/rustc_const_eval/src/check_consts/check.rs
@@ -11,18 +11,19 @@ use rustc_hir::def_id::DefId;
 use rustc_hir::{self as hir, LangItem};
 use rustc_index::bit_set::BitSet;
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::ObligationCause;
 use rustc_middle::mir::visit::Visitor;
 use rustc_middle::mir::*;
 use rustc_middle::span_bug;
 use rustc_middle::ty::adjustment::PointerCoercion;
-use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt, TypingMode};
+use rustc_middle::ty::{self, Instance, InstanceKind, Ty, TypeVisitableExt};
 use rustc_mir_dataflow::Analysis;
 use rustc_mir_dataflow::impls::MaybeStorageLive;
 use rustc_mir_dataflow::storage::always_storage_live_locals;
-use rustc_span::{DUMMY_SP, Span, Symbol, sym};
+use rustc_span::{Span, Symbol, sym};
 use rustc_trait_selection::error_reporting::InferCtxtErrorExt;
-use rustc_trait_selection::traits::{self, ObligationCauseCode, ObligationCtxt};
+use rustc_trait_selection::traits::{
+    Obligation, ObligationCause, ObligationCauseCode, ObligationCtxt,
+};
 use tracing::{debug, instrument, trace};
 
 use super::ops::{self, NonConstOp, Status};
@@ -360,6 +361,73 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
         // end of evaluation.
         !is_transient
     }
+
+    fn revalidate_conditional_constness(
+        &mut self,
+        callee: DefId,
+        callee_args: ty::GenericArgsRef<'tcx>,
+        call_source: CallSource,
+        call_span: Span,
+    ) {
+        let tcx = self.tcx;
+        if !tcx.is_conditionally_const(callee) {
+            return;
+        }
+
+        let const_conditions = tcx.const_conditions(callee).instantiate(tcx, callee_args);
+        // If there are any const conditions on this fn and `const_trait_impl`
+        // is not enabled, simply bail. We shouldn't be able to call conditionally
+        // const functions on stable.
+        if !const_conditions.is_empty() && !tcx.features().const_trait_impl() {
+            self.check_op(ops::FnCallNonConst {
+                callee,
+                args: callee_args,
+                span: call_span,
+                call_source,
+                feature: Some(sym::const_trait_impl),
+            });
+            return;
+        }
+
+        let infcx = tcx.infer_ctxt().build(self.body.typing_mode(tcx));
+        let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
+
+        let body_id = self.body.source.def_id().expect_local();
+        let host_polarity = match self.const_kind() {
+            hir::ConstContext::ConstFn => ty::BoundConstness::Maybe,
+            hir::ConstContext::Static(_) | hir::ConstContext::Const { .. } => {
+                ty::BoundConstness::Const
+            }
+        };
+        let const_conditions = ocx.normalize(
+            &ObligationCause::misc(call_span, body_id),
+            self.param_env,
+            const_conditions,
+        );
+        ocx.register_obligations(const_conditions.into_iter().map(|(trait_ref, span)| {
+            Obligation::new(
+                tcx,
+                ObligationCause::new(
+                    call_span,
+                    body_id,
+                    ObligationCauseCode::WhereClause(callee, span),
+                ),
+                self.param_env,
+                trait_ref.to_host_effect_clause(tcx, host_polarity),
+            )
+        }));
+
+        let errors = ocx.select_all_or_error();
+        if !errors.is_empty() {
+            // FIXME(effects): Soon this should be unconditionally delaying a bug.
+            if matches!(call_source, CallSource::Normal) && tcx.features().effects() {
+                tcx.dcx()
+                    .span_delayed_bug(call_span, "this should have reported a ~const error in HIR");
+            } else {
+                infcx.err_ctxt().report_fulfillment_errors(errors);
+            }
+        }
+    }
 }
 
 impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
@@ -566,7 +634,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 };
 
                 let ConstCx { tcx, body, param_env, .. } = *self.ccx;
-                let caller = self.def_id();
 
                 let fn_ty = func.ty(body, tcx);
 
@@ -584,31 +651,7 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                     }
                 };
 
-                // Check that all trait bounds that are marked as `~const` can be satisfied.
-                //
-                // Typeck only does a "non-const" check since it operates on HIR and cannot distinguish
-                // which path expressions are getting called on and which path expressions are only used
-                // as function pointers. This is required for correctness.
-                let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
-                let ocx = ObligationCtxt::new_with_diagnostics(&infcx);
-
-                let predicates = tcx.predicates_of(callee).instantiate(tcx, fn_args);
-                let cause = ObligationCause::new(
-                    terminator.source_info.span,
-                    self.body.source.def_id().expect_local(),
-                    ObligationCauseCode::WhereClause(callee, DUMMY_SP),
-                );
-                let normalized_predicates = ocx.normalize(&cause, param_env, predicates);
-                ocx.register_obligations(traits::predicates_for_generics(
-                    |_, _| cause.clone(),
-                    self.param_env,
-                    normalized_predicates,
-                ));
-
-                let errors = ocx.select_all_or_error();
-                if !errors.is_empty() {
-                    infcx.err_ctxt().report_fulfillment_errors(errors);
-                }
+                self.revalidate_conditional_constness(callee, fn_args, call_source, *fn_span);
 
                 let mut is_trait = false;
                 // Attempting to call a trait method?
@@ -648,7 +691,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                             None
                         };
                         self.check_op(ops::FnCallNonConst {
-                            caller,
                             callee,
                             args: fn_args,
                             span: *fn_span,
@@ -738,7 +780,6 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
                 // Trait functions are not `const fn` so we have to skip them here.
                 if !tcx.is_const_fn(callee) && !is_trait {
                     self.check_op(ops::FnCallNonConst {
-                        caller,
                         callee,
                         args: fn_args,
                         span: *fn_span,
diff --git a/compiler/rustc_const_eval/src/check_consts/mod.rs b/compiler/rustc_const_eval/src/check_consts/mod.rs
index 56da6791847..dcdaafaecc2 100644
--- a/compiler/rustc_const_eval/src/check_consts/mod.rs
+++ b/compiler/rustc_const_eval/src/check_consts/mod.rs
@@ -32,14 +32,7 @@ impl<'mir, 'tcx> ConstCx<'mir, 'tcx> {
     pub fn new(tcx: TyCtxt<'tcx>, body: &'mir mir::Body<'tcx>) -> Self {
         let def_id = body.source.def_id().expect_local();
         let param_env = tcx.param_env(def_id);
-        Self::new_with_param_env(tcx, body, param_env)
-    }
 
-    pub fn new_with_param_env(
-        tcx: TyCtxt<'tcx>,
-        body: &'mir mir::Body<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Self {
         let const_kind = tcx.hir().body_const_context(body.source.def_id().expect_local());
         ConstCx { body, tcx, param_env, const_kind }
     }
diff --git a/compiler/rustc_const_eval/src/check_consts/ops.rs b/compiler/rustc_const_eval/src/check_consts/ops.rs
index 3f977dc4b05..ce36701a942 100644
--- a/compiler/rustc_const_eval/src/check_consts/ops.rs
+++ b/compiler/rustc_const_eval/src/check_consts/ops.rs
@@ -1,6 +1,5 @@
 //! Concrete error types for all operations which may be invalid in a certain const context.
 
-use hir::def_id::LocalDefId;
 use hir::{ConstContext, LangItem};
 use rustc_errors::Diag;
 use rustc_errors::codes::*;
@@ -12,7 +11,7 @@ use rustc_middle::mir::CallSource;
 use rustc_middle::span_bug;
 use rustc_middle::ty::print::{PrintTraitRefExt as _, with_no_trimmed_paths};
 use rustc_middle::ty::{
-    self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty, TypingMode,
+    self, Closure, FnDef, FnPtr, GenericArgKind, GenericArgsRef, Param, TraitRef, Ty,
     suggest_constraining_type_param,
 };
 use rustc_middle::util::{CallDesugaringKind, CallKind, call_kind};
@@ -74,7 +73,6 @@ impl<'tcx> NonConstOp<'tcx> for FnCallIndirect {
 /// A function call where the callee is not marked as `const`.
 #[derive(Debug, Clone, Copy)]
 pub(crate) struct FnCallNonConst<'tcx> {
-    pub caller: LocalDefId,
     pub callee: DefId,
     pub args: GenericArgsRef<'tcx>,
     pub span: Span,
@@ -87,8 +85,9 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
     #[allow(rustc::diagnostic_outside_of_impl)]
     #[allow(rustc::untranslatable_diagnostic)]
     fn build_error(&self, ccx: &ConstCx<'_, 'tcx>, _: Span) -> Diag<'tcx> {
-        let FnCallNonConst { caller, callee, args, span, call_source, feature } = *self;
-        let ConstCx { tcx, param_env, body, .. } = *ccx;
+        let FnCallNonConst { callee, args, span, call_source, feature } = *self;
+        let ConstCx { tcx, param_env, .. } = *ccx;
+        let caller = ccx.def_id();
 
         let diag_trait = |err, self_ty: Ty<'_>, trait_id| {
             let trait_ref = TraitRef::from_method(tcx, trait_id, args);
@@ -116,7 +115,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
                     let obligation =
                         Obligation::new(tcx, ObligationCause::dummy(), param_env, trait_ref);
 
-                    let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(param_env));
+                    let infcx = tcx.infer_ctxt().build(ccx.body.typing_mode(tcx));
                     let mut selcx = SelectionContext::new(&infcx);
                     let implsrc = selcx.select(&obligation);
 
@@ -289,7 +288,7 @@ impl<'tcx> NonConstOp<'tcx> for FnCallNonConst<'tcx> {
         if let Some(feature) = feature {
             ccx.tcx.disabled_nightly_features(
                 &mut err,
-                body.source.def_id().as_local().map(|local| ccx.tcx.local_def_id_to_hir_id(local)),
+                Some(ccx.tcx.local_def_id_to_hir_id(caller)),
                 [(String::new(), feature)],
             );
         }
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index d81368e9fcc..9043bd3e28e 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -3,7 +3,7 @@ use rustc_errors::DiagCtxtHandle;
 use rustc_hir::def_id::DefId;
 use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::infer::at::ToTrace;
-use rustc_infer::traits::ObligationCause;
+use rustc_infer::traits::{ObligationCause, Reveal};
 use rustc_middle::mir::interpret::{ErrorHandled, InvalidMetaKind, ReportedErrorInfo};
 use rustc_middle::query::TyCtxtAt;
 use rustc_middle::ty::layout::{
@@ -116,6 +116,7 @@ impl<'tcx, M: Machine<'tcx>> FnAbiOfHelpers<'tcx> for InterpCx<'tcx, M> {
 /// This test should be symmetric, as it is primarily about layout compatibility.
 pub(super) fn mir_assign_valid_types<'tcx>(
     tcx: TyCtxt<'tcx>,
+    typing_mode: TypingMode<'tcx>,
     param_env: ParamEnv<'tcx>,
     src: TyAndLayout<'tcx>,
     dest: TyAndLayout<'tcx>,
@@ -124,7 +125,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
     // all normal lifetimes are erased, higher-ranked types with their
     // late-bound lifetimes are still around and can lead to type
     // differences.
-    if util::relate_types(tcx, param_env, Variance::Covariant, src.ty, dest.ty) {
+    if util::relate_types(tcx, typing_mode, param_env, Variance::Covariant, src.ty, dest.ty) {
         // Make sure the layout is equal, too -- just to be safe. Miri really
         // needs layout equality. For performance reason we skip this check when
         // the types are equal. Equal types *can* have different layouts when
@@ -144,6 +145,7 @@ pub(super) fn mir_assign_valid_types<'tcx>(
 #[cfg_attr(not(debug_assertions), inline(always))]
 pub(super) fn from_known_layout<'tcx>(
     tcx: TyCtxtAt<'tcx>,
+    typing_mode: TypingMode<'tcx>,
     param_env: ParamEnv<'tcx>,
     known_layout: Option<TyAndLayout<'tcx>>,
     compute: impl FnOnce() -> InterpResult<'tcx, TyAndLayout<'tcx>>,
@@ -153,7 +155,13 @@ pub(super) fn from_known_layout<'tcx>(
         Some(known_layout) => {
             if cfg!(debug_assertions) {
                 let check_layout = compute()?;
-                if !mir_assign_valid_types(tcx.tcx, param_env, check_layout, known_layout) {
+                if !mir_assign_valid_types(
+                    tcx.tcx,
+                    typing_mode,
+                    param_env,
+                    check_layout,
+                    known_layout,
+                ) {
                     span_bug!(
                         tcx.span,
                         "expected type differs from actual type.\nexpected: {}\nactual: {}",
@@ -203,6 +211,11 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
         }
     }
 
+    pub fn typing_mode(&self) -> TypingMode<'tcx> {
+        debug_assert_eq!(self.param_env.reveal(), Reveal::All);
+        TypingMode::PostAnalysis
+    }
+
     /// Returns the span of the currently executed statement/terminator.
     /// This is the span typically used for error reporting.
     #[inline(always)]
@@ -327,7 +340,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             return true;
         }
         // Slow path: spin up an inference context to check if these traits are sufficiently equal.
-        let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env));
+        let infcx = self.tcx.infer_ctxt().build(self.typing_mode());
         let ocx = ObligationCtxt::new(&infcx);
         let cause = ObligationCause::dummy_with_span(self.cur_span());
         // equate the two trait refs after normalization
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 43ae98e74b0..a130ae89bcb 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -773,6 +773,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 )?;
             if !mir_assign_valid_types(
                 *self.tcx,
+                self.typing_mode(),
                 self.param_env,
                 self.layout_of(normalized_place_ty)?,
                 op.layout,
@@ -832,7 +833,9 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             })
         };
         let layout =
-            from_known_layout(self.tcx, self.param_env, layout, || self.layout_of(ty).into())?;
+            from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
+                self.layout_of(ty).into()
+            })?;
         let imm = match val_val {
             mir::ConstValue::Indirect { alloc_id, offset } => {
                 // This is const data, no mutation allowed.
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 139a1db60e0..cc8d1db6cfb 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -540,6 +540,7 @@ where
                 )?;
             if !mir_assign_valid_types(
                 *self.tcx,
+                self.typing_mode(),
                 self.param_env,
                 self.layout_of(normalized_place_ty)?,
                 place.layout,
@@ -870,8 +871,13 @@ where
     ) -> InterpResult<'tcx> {
         // We do NOT compare the types for equality, because well-typed code can
         // actually "transmute" `&mut T` to `&T` in an assignment without a cast.
-        let layout_compat =
-            mir_assign_valid_types(*self.tcx, self.param_env, src.layout(), dest.layout());
+        let layout_compat = mir_assign_valid_types(
+            *self.tcx,
+            self.typing_mode(),
+            self.param_env,
+            src.layout(),
+            dest.layout(),
+        );
         if !allow_transmute && !layout_compat {
             span_bug!(
                 self.cur_span(),
diff --git a/compiler/rustc_const_eval/src/interpret/stack.rs b/compiler/rustc_const_eval/src/interpret/stack.rs
index 3bc9f46aea0..50c0446b3cd 100644
--- a/compiler/rustc_const_eval/src/interpret/stack.rs
+++ b/compiler/rustc_const_eval/src/interpret/stack.rs
@@ -596,12 +596,13 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
             return interp_ok(layout);
         }
 
-        let layout = from_known_layout(self.tcx, self.param_env, layout, || {
-            let local_ty = frame.body.local_decls[local].ty;
-            let local_ty =
-                self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
-            self.layout_of(local_ty).into()
-        })?;
+        let layout =
+            from_known_layout(self.tcx, self.typing_mode(), self.param_env, layout, || {
+                let local_ty = frame.body.local_decls[local].ty;
+                let local_ty =
+                    self.instantiate_from_frame_and_normalize_erasing_regions(frame, local_ty)?;
+                self.layout_of(local_ty).into()
+            })?;
 
         // Layouts of locals are requested a lot, so we cache them.
         state.layout.set(Some(layout));
diff --git a/compiler/rustc_const_eval/src/util/compare_types.rs b/compiler/rustc_const_eval/src/util/compare_types.rs
index 7af977bab4d..0cf27d30c36 100644
--- a/compiler/rustc_const_eval/src/util/compare_types.rs
+++ b/compiler/rustc_const_eval/src/util/compare_types.rs
@@ -8,24 +8,15 @@ use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::{ParamEnv, Ty, TyCtxt, TypingMode, Variance};
 use rustc_trait_selection::traits::ObligationCtxt;
 
-/// Returns whether the two types are equal up to subtyping.
-///
-/// This is used in case we don't know the expected subtyping direction
-/// and still want to check whether anything is broken.
-pub fn is_equal_up_to_subtyping<'tcx>(
+/// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
+pub fn sub_types<'tcx>(
     tcx: TyCtxt<'tcx>,
+    typing_mode: TypingMode<'tcx>,
     param_env: ParamEnv<'tcx>,
     src: Ty<'tcx>,
     dest: Ty<'tcx>,
 ) -> bool {
-    // Fast path.
-    if src == dest {
-        return true;
-    }
-
-    // Check for subtyping in either direction.
-    relate_types(tcx, param_env, Variance::Covariant, src, dest)
-        || relate_types(tcx, param_env, Variance::Covariant, dest, src)
+    relate_types(tcx, typing_mode, param_env, Variance::Covariant, src, dest)
 }
 
 /// Returns whether `src` is a subtype of `dest`, i.e. `src <: dest`.
@@ -35,6 +26,7 @@ pub fn is_equal_up_to_subtyping<'tcx>(
 /// because we want to check for type equality.
 pub fn relate_types<'tcx>(
     tcx: TyCtxt<'tcx>,
+    typing_mode: TypingMode<'tcx>,
     param_env: ParamEnv<'tcx>,
     variance: Variance,
     src: Ty<'tcx>,
@@ -45,8 +37,7 @@ pub fn relate_types<'tcx>(
     }
 
     let mut builder = tcx.infer_ctxt().ignoring_regions();
-    // FIXME(#132279): This should eventually use the already defined hidden types.
-    let infcx = builder.build(TypingMode::from_param_env(param_env));
+    let infcx = builder.build(typing_mode);
     let ocx = ObligationCtxt::new(&infcx);
     let cause = ObligationCause::dummy();
     let src = ocx.normalize(&cause, param_env, src);
diff --git a/compiler/rustc_const_eval/src/util/mod.rs b/compiler/rustc_const_eval/src/util/mod.rs
index 66a1addfb52..25a9dbb2c11 100644
--- a/compiler/rustc_const_eval/src/util/mod.rs
+++ b/compiler/rustc_const_eval/src/util/mod.rs
@@ -8,7 +8,7 @@ mod type_name;
 
 pub use self::alignment::{is_disaligned, is_within_packed};
 pub use self::check_validity_requirement::check_validity_requirement;
-pub use self::compare_types::{is_equal_up_to_subtyping, relate_types};
+pub use self::compare_types::{relate_types, sub_types};
 pub use self::type_name::type_name;
 
 /// Classify whether an operator is "left-homogeneous", i.e., the LHS has the
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index e2585c02388..92b622fccf2 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -33,6 +33,7 @@ use std::time::{Instant, SystemTime};
 use std::{env, str};
 
 use rustc_ast as ast;
+use rustc_codegen_ssa::back::apple;
 use rustc_codegen_ssa::traits::CodegenBackend;
 use rustc_codegen_ssa::{CodegenErrors, CodegenResults};
 use rustc_data_structures::profiling::{
@@ -855,12 +856,11 @@ fn print_crate_info(
                 }
             }
             DeploymentTarget => {
-                use rustc_target::spec::current_apple_deployment_target;
-
                 if sess.target.is_like_osx {
-                    let (major, minor, patch) = current_apple_deployment_target(&sess.target);
-                    let patch = if patch != 0 { format!(".{patch}") } else { String::new() };
-                    println_info!("deployment_target={major}.{minor}{patch}")
+                    println_info!(
+                        "deployment_target={}",
+                        apple::pretty_version(apple::deployment_target(sess))
+                    )
                 } else {
                     #[allow(rustc::diagnostic_outside_of_impl)]
                     sess.dcx().fatal("only Apple targets currently support deployment version info")
diff --git a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
index da779a16569..0b81f469371 100644
--- a/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
+++ b/compiler/rustc_hir_analysis/src/collect/item_bounds.rs
@@ -43,7 +43,7 @@ fn associated_type_bounds<'tcx>(
     match filter {
         PredicateFilter::All
         | PredicateFilter::SelfOnly
-        | PredicateFilter::SelfThatDefines(_)
+        | PredicateFilter::SelfTraitThatDefines(_)
         | PredicateFilter::SelfAndAssociatedTypeBounds => {
             icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
         }
@@ -122,7 +122,7 @@ fn remap_gat_vars_and_recurse_into_nested_projections<'tcx>(
                     PredicateFilter::SelfOnly => {
                         return None;
                     }
-                    PredicateFilter::SelfThatDefines(_)
+                    PredicateFilter::SelfTraitThatDefines(_)
                     | PredicateFilter::SelfConstIfConst
                     | PredicateFilter::SelfAndAssociatedTypeBounds
                     | PredicateFilter::ConstIfConst => {
@@ -329,7 +329,7 @@ fn opaque_type_bounds<'tcx>(
         match filter {
             PredicateFilter::All
             | PredicateFilter::SelfOnly
-            | PredicateFilter::SelfThatDefines(_)
+            | PredicateFilter::SelfTraitThatDefines(_)
             | PredicateFilter::SelfAndAssociatedTypeBounds => {
                 // Associated types are implicitly sized unless a `?Sized` bound is found
                 icx.lowerer().add_sized_bound(&mut bounds, item_ty, hir_bounds, None, span);
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index efe84e0006f..7ce12d48160 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -557,7 +557,11 @@ pub(super) fn explicit_supertraits_containing_assoc_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     (trait_def_id, assoc_name): (DefId, Ident),
 ) -> ty::EarlyBinder<'tcx, &'tcx [(ty::Clause<'tcx>, Span)]> {
-    implied_predicates_with_filter(tcx, trait_def_id, PredicateFilter::SelfThatDefines(assoc_name))
+    implied_predicates_with_filter(
+        tcx,
+        trait_def_id,
+        PredicateFilter::SelfTraitThatDefines(assoc_name),
+    )
 }
 
 pub(super) fn explicit_implied_predicates_of<'tcx>(
@@ -586,7 +590,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
     let Some(trait_def_id) = trait_def_id.as_local() else {
         // if `assoc_name` is None, then the query should've been redirected to an
         // external provider
-        assert_matches!(filter, PredicateFilter::SelfThatDefines(_));
+        assert_matches!(filter, PredicateFilter::SelfTraitThatDefines(_));
         return tcx.explicit_super_predicates_of(trait_def_id);
     };
 
@@ -606,12 +610,8 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
     let mut bounds = Bounds::default();
     icx.lowerer().lower_bounds(self_param_ty, superbounds, &mut bounds, ty::List::empty(), filter);
 
-    let where_bounds_that_match = icx.probe_ty_param_bounds_in_generics(
-        generics,
-        item.owner_id.def_id,
-        self_param_ty,
-        filter,
-    );
+    let where_bounds_that_match =
+        icx.probe_ty_param_bounds_in_generics(generics, item.owner_id.def_id, filter);
 
     // Combine the two lists to form the complete set of superbounds:
     let implied_bounds =
@@ -652,7 +652,7 @@ pub(super) fn implied_predicates_with_filter<'tcx>(
 }
 
 // Make sure when elaborating supertraits, probing for associated types, etc.,
-// we really truly are elaborating clauses that have `Self` as their self type.
+// we really truly are elaborating clauses that have `ty` as their self type.
 // This is very important since downstream code relies on this being correct.
 pub(super) fn assert_only_contains_predicates_from<'tcx>(
     filter: PredicateFilter,
@@ -664,7 +664,7 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
     }
 
     match filter {
-        PredicateFilter::SelfOnly | PredicateFilter::SelfThatDefines(_) => {
+        PredicateFilter::SelfOnly => {
             for (clause, _) in bounds {
                 match clause.kind().skip_binder() {
                     ty::ClauseKind::Trait(trait_predicate) => {
@@ -704,6 +704,33 @@ pub(super) fn assert_only_contains_predicates_from<'tcx>(
                 }
             }
         }
+        PredicateFilter::SelfTraitThatDefines(_) => {
+            for (clause, _) in bounds {
+                match clause.kind().skip_binder() {
+                    ty::ClauseKind::Trait(trait_predicate) => {
+                        assert_eq!(
+                            trait_predicate.self_ty(),
+                            ty,
+                            "expected `Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+
+                    ty::ClauseKind::Projection(_)
+                    | ty::ClauseKind::TypeOutlives(_)
+                    | ty::ClauseKind::RegionOutlives(_)
+                    | ty::ClauseKind::ConstArgHasType(_, _)
+                    | ty::ClauseKind::WellFormed(_)
+                    | ty::ClauseKind::ConstEvaluatable(_)
+                    | ty::ClauseKind::HostEffect(..) => {
+                        bug!(
+                            "unexpected non-`Self` predicate when computing \
+                            `{filter:?}` implied bounds: {clause:?}"
+                        );
+                    }
+                }
+            }
+        }
         PredicateFilter::ConstIfConst => {
             for (clause, _) in bounds {
                 match clause.kind().skip_binder() {
@@ -767,21 +794,16 @@ pub(super) fn type_param_predicates<'tcx>(
         None => {}
     }
 
-    use rustc_hir::*;
-    use rustc_middle::ty::Ty;
-
     // In the HIR, bounds can derive from two places. Either
     // written inline like `<T: Foo>` or in a where-clause like
     // `where T: Foo`.
 
     let param_id = tcx.local_def_id_to_hir_id(def_id);
     let param_owner = tcx.hir().ty_param_owner(def_id);
-    let generics = tcx.generics_of(param_owner);
-    let index = generics.param_def_id_to_index[&def_id.to_def_id()];
-    let ty = Ty::new_param(tcx, index, tcx.hir().ty_param_name(def_id));
 
     // Don't look for bounds where the type parameter isn't in scope.
     let parent = if item_def_id == param_owner {
+        // FIXME: Shouldn't this be unreachable?
         None
     } else {
         tcx.generics_of(item_def_id).parent.map(|def_id| def_id.expect_local())
@@ -801,8 +823,9 @@ pub(super) fn type_param_predicates<'tcx>(
     let Some(hir_generics) = hir_node.generics() else {
         return result;
     };
+
     if let Node::Item(item) = hir_node
-        && let ItemKind::Trait(..) = item.kind
+        && let hir::ItemKind::Trait(..) = item.kind
         // Implied `Self: Trait` and supertrait bounds.
         && param_id == item_hir_id
     {
@@ -811,23 +834,34 @@ pub(super) fn type_param_predicates<'tcx>(
     }
 
     let icx = ItemCtxt::new(tcx, item_def_id);
-    let extra_predicates = extend.into_iter().chain(
-        icx.probe_ty_param_bounds_in_generics(
-            hir_generics,
-            def_id,
-            ty,
-            PredicateFilter::SelfThatDefines(assoc_name),
-        )
-        .into_iter()
-        .filter(|(predicate, _)| match predicate.kind().skip_binder() {
-            ty::ClauseKind::Trait(data) => data.self_ty().is_param(index),
-            _ => false,
-        }),
+    let extra_predicates = extend.into_iter().chain(icx.probe_ty_param_bounds_in_generics(
+        hir_generics,
+        def_id,
+        PredicateFilter::SelfTraitThatDefines(assoc_name),
+    ));
+
+    let bounds =
+        &*tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates));
+
+    // Double check that the bounds *only* contain `SelfTy: Trait` preds.
+    let self_ty = match tcx.def_kind(def_id) {
+        DefKind::TyParam => Ty::new_param(
+            tcx,
+            tcx.generics_of(item_def_id)
+                .param_def_id_to_index(tcx, def_id.to_def_id())
+                .expect("expected generic param to be owned by item"),
+            tcx.item_name(def_id.to_def_id()),
+        ),
+        DefKind::Trait | DefKind::TraitAlias => tcx.types.self_param,
+        _ => unreachable!(),
+    };
+    assert_only_contains_predicates_from(
+        PredicateFilter::SelfTraitThatDefines(assoc_name),
+        bounds,
+        self_ty,
     );
 
-    ty::EarlyBinder::bind(
-        tcx.arena.alloc_from_iter(result.skip_binder().iter().copied().chain(extra_predicates)),
-    )
+    ty::EarlyBinder::bind(bounds)
 }
 
 impl<'tcx> ItemCtxt<'tcx> {
@@ -841,7 +875,6 @@ impl<'tcx> ItemCtxt<'tcx> {
         &self,
         hir_generics: &'tcx hir::Generics<'tcx>,
         param_def_id: LocalDefId,
-        ty: Ty<'tcx>,
         filter: PredicateFilter,
     ) -> Vec<(ty::Clause<'tcx>, Span)> {
         let mut bounds = Bounds::default();
@@ -851,13 +884,21 @@ impl<'tcx> ItemCtxt<'tcx> {
                 continue;
             };
 
-            let bound_ty = if predicate.is_param_bound(param_def_id.to_def_id()) {
-                ty
-            } else if matches!(filter, PredicateFilter::All) {
-                self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty)
-            } else {
-                continue;
-            };
+            match filter {
+                _ if predicate.is_param_bound(param_def_id.to_def_id()) => {
+                    // Ok
+                }
+                PredicateFilter::All => {
+                    // Ok
+                }
+                PredicateFilter::SelfOnly
+                | PredicateFilter::SelfTraitThatDefines(_)
+                | PredicateFilter::SelfConstIfConst
+                | PredicateFilter::SelfAndAssociatedTypeBounds => continue,
+                PredicateFilter::ConstIfConst => unreachable!(),
+            }
+
+            let bound_ty = self.lowerer().lower_ty_maybe_return_type_notation(predicate.bounded_ty);
 
             let bound_vars = self.tcx.late_bound_vars(predicate.hir_id);
             self.lowerer().lower_bounds(
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index 9483439ae4e..dc3ef9952f0 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -571,17 +571,29 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
             // We list scopes outwards, this causes us to see lifetime parameters in reverse
             // declaration order. In order to make it consistent with what `generics_of` might
             // give, we will reverse the IndexMap after early captures.
+            let mut late_depth = 0;
             let mut scope = self.scope;
+            let mut crossed_late_boundary = None;
             let mut opaque_capture_scopes = vec![(opaque.def_id, &captures)];
             loop {
                 match *scope {
-                    Scope::Binder { ref bound_vars, s, .. } => {
+                    Scope::Binder { ref bound_vars, scope_type, s, .. } => {
                         for (&original_lifetime, &def) in bound_vars.iter().rev() {
+                            if let ResolvedArg::LateBound(..) = def
+                                && crossed_late_boundary.is_some()
+                            {
+                                continue;
+                            }
                             if let DefKind::LifetimeParam = self.tcx.def_kind(original_lifetime) {
+                                let def = def.shifted(late_depth);
                                 let ident = lifetime_ident(original_lifetime);
                                 self.remap_opaque_captures(&opaque_capture_scopes, def, ident);
                             }
                         }
+                        match scope_type {
+                            BinderScopeType::Normal => late_depth += 1,
+                            BinderScopeType::Concatenating => {}
+                        }
                         scope = s;
                     }
 
@@ -602,6 +614,7 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
                     Scope::Opaque { captures, def_id, s } => {
                         opaque_capture_scopes.push((def_id, captures));
+                        late_depth = 0;
                         scope = s;
                     }
 
@@ -611,8 +624,12 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
 
                     Scope::ObjectLifetimeDefault { s, .. }
                     | Scope::Supertrait { s, .. }
-                    | Scope::TraitRefBoundary { s, .. }
-                    | Scope::LateBoundary { s, .. } => {
+                    | Scope::TraitRefBoundary { s, .. } => {
+                        scope = s;
+                    }
+
+                    Scope::LateBoundary { s, what, .. } => {
+                        crossed_late_boundary = Some(what);
                         scope = s;
                     }
                 }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index a5709089db6..85ba88333f9 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -152,9 +152,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         'tcx: 'hir,
     {
         for hir_bound in hir_bounds {
-            // In order to avoid cycles, when we're lowering `SelfThatDefines`,
+            // In order to avoid cycles, when we're lowering `SelfTraitThatDefines`,
             // we skip over any traits that don't define the given associated type.
-            if let PredicateFilter::SelfThatDefines(assoc_name) = predicate_filter {
+            if let PredicateFilter::SelfTraitThatDefines(assoc_name) = predicate_filter {
                 if let Some(trait_ref) = hir_bound.trait_ref()
                     && let Some(trait_did) = trait_ref.trait_def_id()
                     && self.tcx().trait_may_define_assoc_item(trait_did, assoc_name)
@@ -168,12 +168,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             match hir_bound {
                 hir::GenericBound::Trait(poly_trait_ref) => {
                     let hir::TraitBoundModifiers { constness, polarity } = poly_trait_ref.modifiers;
-                    let polarity = match polarity {
-                        rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
-                        rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
-                        rustc_ast::BoundPolarity::Maybe(_) => continue,
-                    };
-
                     let _ = self.lower_poly_trait_ref(
                         &poly_trait_ref.trait_ref,
                         poly_trait_ref.span,
@@ -395,7 +389,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 match predicate_filter {
                     PredicateFilter::All
                     | PredicateFilter::SelfOnly
-                    | PredicateFilter::SelfThatDefines(_)
                     | PredicateFilter::SelfAndAssociatedTypeBounds => {
                         bounds.push_projection_bound(
                             tcx,
@@ -406,6 +399,8 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                             constraint.span,
                         );
                     }
+                    // SelfTraitThatDefines is only interested in trait predicates.
+                    PredicateFilter::SelfTraitThatDefines(_) => {}
                     // `ConstIfConst` is only interested in `~const` bounds.
                     PredicateFilter::ConstIfConst | PredicateFilter::SelfConstIfConst => {}
                 }
@@ -432,7 +427,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                         );
                     }
                     PredicateFilter::SelfOnly
-                    | PredicateFilter::SelfThatDefines(_)
+                    | PredicateFilter::SelfTraitThatDefines(_)
                     | PredicateFilter::SelfConstIfConst => {}
                 }
             }
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index 46a5cbb0af4..5e27ace4cbe 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -51,7 +51,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 &trait_bound.trait_ref,
                 trait_bound.span,
                 hir::BoundConstness::Never,
-                ty::PredicatePolarity::Positive,
+                hir::BoundPolarity::Positive,
                 dummy_self,
                 &mut bounds,
                 PredicateFilter::SelfOnly,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
index d70e4d8345a..fb23ad1b248 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs
@@ -76,7 +76,7 @@ pub enum PredicateFilter {
     /// Only traits that reference `Self: ..` and define an associated type
     /// with the given ident are implied by the trait. This mode exists to
     /// side-step query cycles when lowering associated types.
-    SelfThatDefines(Ident),
+    SelfTraitThatDefines(Ident),
 
     /// Only traits that reference `Self: ..` and their associated type bounds.
     /// For example, given `Self: Tr<A: B>`, this would expand to `Self: Tr`
@@ -668,7 +668,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         trait_ref: &hir::TraitRef<'tcx>,
         span: Span,
         constness: hir::BoundConstness,
-        polarity: ty::PredicatePolarity,
+        polarity: hir::BoundPolarity,
         self_ty: Ty<'tcx>,
         bounds: &mut Bounds<'tcx>,
         predicate_filter: PredicateFilter,
@@ -690,15 +690,6 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             Some(self_ty),
         );
 
-        if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
-            && !self.tcx().is_const_trait(trait_def_id)
-        {
-            self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
-                span,
-                modifier: constness.as_str(),
-            });
-        }
-
         let tcx = self.tcx();
         let bound_vars = tcx.late_bound_vars(trait_ref.hir_ref_id);
         debug!(?bound_vars);
@@ -708,10 +699,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             bound_vars,
         );
 
+        let polarity = match polarity {
+            rustc_ast::BoundPolarity::Positive => ty::PredicatePolarity::Positive,
+            rustc_ast::BoundPolarity::Negative(_) => ty::PredicatePolarity::Negative,
+            rustc_ast::BoundPolarity::Maybe(_) => {
+                // Validate associated type at least. We may want to reject these
+                // outright in the future...
+                for constraint in trait_segment.args().constraints {
+                    let _ = self.lower_assoc_item_constraint(
+                        trait_ref.hir_ref_id,
+                        poly_trait_ref,
+                        constraint,
+                        &mut Default::default(),
+                        &mut Default::default(),
+                        constraint.span,
+                        predicate_filter,
+                    );
+                }
+                return arg_count;
+            }
+        };
+
+        if let hir::BoundConstness::Always(span) | hir::BoundConstness::Maybe(span) = constness
+            && !self.tcx().is_const_trait(trait_def_id)
+        {
+            self.dcx().emit_err(crate::errors::ConstBoundForNonConstTrait {
+                span,
+                modifier: constness.as_str(),
+            });
+        }
+
         match predicate_filter {
+            // This is only concerned with trait predicates.
+            PredicateFilter::SelfTraitThatDefines(..) => {
+                bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
+            }
             PredicateFilter::All
             | PredicateFilter::SelfOnly
-            | PredicateFilter::SelfThatDefines(..)
             | PredicateFilter::SelfAndAssociatedTypeBounds => {
                 debug!(?poly_trait_ref);
                 bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
@@ -763,11 +787,11 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
             // since we should have emitted an error for them earlier, and they
             // would not be well-formed!
             if polarity != ty::PredicatePolarity::Positive {
-                assert!(
-                    self.dcx().has_errors().is_some(),
+                self.dcx().span_delayed_bug(
+                    constraint.span,
                     "negative trait bounds should not have assoc item constraints",
                 );
-                continue;
+                break;
             }
 
             // Specify type to assert that error was already reported in `Err` case.
diff --git a/compiler/rustc_hir_pretty/Cargo.toml b/compiler/rustc_hir_pretty/Cargo.toml
index aacf41b6eb7..9af1fb8279e 100644
--- a/compiler/rustc_hir_pretty/Cargo.toml
+++ b/compiler/rustc_hir_pretty/Cargo.toml
@@ -5,9 +5,9 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
+rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_ast_pretty = { path = "../rustc_ast_pretty" }
 rustc_hir = { path = "../rustc_hir" }
 rustc_span = { path = "../rustc_span" }
-rustc_target = { path = "../rustc_target" }
 # tidy-alphabetical-end
diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs
index 2073f2868b4..0a3aa8fec90 100644
--- a/compiler/rustc_hir_pretty/src/lib.rs
+++ b/compiler/rustc_hir_pretty/src/lib.rs
@@ -9,6 +9,7 @@
 use std::cell::Cell;
 use std::vec;
 
+use rustc_abi::ExternAbi;
 use rustc_ast::util::parser::{self, AssocOp, Fixity};
 use rustc_ast_pretty::pp::Breaks::{Consistent, Inconsistent};
 use rustc_ast_pretty::pp::{self, Breaks};
@@ -20,7 +21,6 @@ use rustc_hir::{
 use rustc_span::FileName;
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::{Ident, Symbol, kw};
-use rustc_target::spec::abi::Abi;
 use {rustc_ast as ast, rustc_hir as hir};
 
 pub fn id_to_string(map: &dyn rustc_hir::intravisit::Map<'_>, hir_id: HirId) -> String {
@@ -2240,7 +2240,7 @@ impl<'a> State<'a> {
 
     fn print_ty_fn(
         &mut self,
-        abi: Abi,
+        abi: ExternAbi,
         safety: hir::Safety,
         decl: &hir::FnDecl<'_>,
         name: Option<Symbol>,
@@ -2276,7 +2276,7 @@ impl<'a> State<'a> {
 
         self.print_safety(header.safety);
 
-        if header.abi != Abi::Rust {
+        if header.abi != ExternAbi::Rust {
             self.word_nbsp("extern");
             self.word_nbsp(header.abi.to_string());
         }
diff --git a/compiler/rustc_hir_typeck/src/autoderef.rs b/compiler/rustc_hir_typeck/src/autoderef.rs
index c3e095b0554..7af26623ce7 100644
--- a/compiler/rustc_hir_typeck/src/autoderef.rs
+++ b/compiler/rustc_hir_typeck/src/autoderef.rs
@@ -50,8 +50,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.try_overloaded_deref(autoderef.span(), source).and_then(
                         |InferOk { value: method, obligations: o }| {
                             obligations.extend(o);
-                            if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() {
-                                Some(OverloadedDeref { region, mutbl, span: autoderef.span() })
+                            // FIXME: we should assert the sig is &T here... there's no reason for this to be fallible.
+                            if let ty::Ref(_, _, mutbl) = *method.sig.output().kind() {
+                                Some(OverloadedDeref { mutbl, span: autoderef.span() })
                             } else {
                                 None
                             }
diff --git a/compiler/rustc_hir_typeck/src/callee.rs b/compiler/rustc_hir_typeck/src/callee.rs
index 6eb6792a119..f9a21a9bef3 100644
--- a/compiler/rustc_hir_typeck/src/callee.rs
+++ b/compiler/rustc_hir_typeck/src/callee.rs
@@ -307,7 +307,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 if borrow {
                     // Check for &self vs &mut self in the method signature. Since this is either
                     // the Fn or FnMut trait, it should be one of those.
-                    let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() else {
+                    let ty::Ref(_, _, mutbl) = method.sig.inputs()[0].kind() else {
                         bug!("Expected `FnMut`/`Fn` to take receiver by-ref/by-mut")
                     };
 
@@ -317,7 +317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::No);
 
                     autoref = Some(Adjustment {
-                        kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)),
+                        kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                         target: method.sig.inputs()[0],
                     });
                 }
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 6fa958d9496..87798ca3fd9 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -113,7 +113,7 @@ fn identity(_: Ty<'_>) -> Vec<Adjustment<'_>> {
     vec![]
 }
 
-fn simple<'tcx>(kind: Adjust<'tcx>) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>> {
+fn simple<'tcx>(kind: Adjust) -> impl FnOnce(Ty<'tcx>) -> Vec<Adjustment<'tcx>> {
     move |target| vec![Adjustment { kind, target }]
 }
 
@@ -484,14 +484,11 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
 
         // Now apply the autoref. We have to extract the region out of
         // the final ref type we got.
-        let ty::Ref(r_borrow, _, _) = ty.kind() else {
+        let ty::Ref(..) = ty.kind() else {
             span_bug!(span, "expected a ref type, got {:?}", ty);
         };
         let mutbl = AutoBorrowMutability::new(mutbl_b, self.allow_two_phase);
-        adjustments.push(Adjustment {
-            kind: Adjust::Borrow(AutoBorrow::Ref(*r_borrow, mutbl)),
-            target: ty,
-        });
+        adjustments.push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target: ty });
 
         debug!("coerce_borrowed_pointer: succeeded ty={:?} adjustments={:?}", ty, adjustments);
 
@@ -547,7 +544,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
                 let mutbl = AutoBorrowMutability::new(mutbl_b, AllowTwoPhase::No);
 
                 Some((Adjustment { kind: Adjust::Deref(None), target: ty_a }, Adjustment {
-                    kind: Adjust::Borrow(AutoBorrow::Ref(r_borrow, mutbl)),
+                    kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                     target: Ty::new_ref(self.tcx, r_borrow, ty_a, mutbl_b),
                 }))
             }
@@ -827,7 +824,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         };
 
         let (pin, a_region, a_ty, mut_a) = extract_pin_mut(a)?;
-        let (_, b_region, _b_ty, mut_b) = extract_pin_mut(b)?;
+        let (_, _, _b_ty, mut_b) = extract_pin_mut(b)?;
 
         coerce_mutbls(mut_a, mut_b)?;
 
@@ -841,7 +838,7 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         // To complete the reborrow, we need to make sure we can unify the inner types, and if so we
         // add the adjustments.
         self.unify_and(a, b, |_inner_ty| {
-            vec![Adjustment { kind: Adjust::ReborrowPin(b_region, mut_b), target: b }]
+            vec![Adjustment { kind: Adjust::ReborrowPin(mut_b), target: b }]
         })
     }
 
@@ -1321,7 +1318,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let noop = match self.typeck_results.borrow().expr_adjustments(expr) {
                 &[
                     Adjustment { kind: Adjust::Deref(_), .. },
-                    Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl_adj)), .. },
+                    Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl_adj)), .. },
                 ] => {
                     match *self.node_ty(expr.hir_id).kind() {
                         ty::Ref(_, _, mt_orig) => {
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index cceaabaff65..4f579b05d83 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -169,19 +169,34 @@ pub(crate) struct MissingParenthesesInRange {
 pub(crate) enum NeverTypeFallbackFlowingIntoUnsafe {
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_call)]
-    Call,
+    Call {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_method)]
-    Method,
+    Method {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_path)]
-    Path,
+    Path {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_union_field)]
-    UnionField,
+    UnionField {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
     #[help]
     #[diag(hir_typeck_never_type_fallback_flowing_into_unsafe_deref)]
-    Deref,
+    Deref {
+        #[subdiagnostic]
+        sugg: SuggestAnnotations,
+    },
 }
 
 #[derive(LintDiagnostic)]
@@ -191,6 +206,64 @@ pub(crate) struct DependencyOnUnitNeverTypeFallback<'tcx> {
     #[note]
     pub obligation_span: Span,
     pub obligation: ty::Predicate<'tcx>,
+    #[subdiagnostic]
+    pub sugg: SuggestAnnotations,
+}
+
+#[derive(Clone)]
+pub(crate) enum SuggestAnnotation {
+    Unit(Span),
+    Path(Span),
+    Local(Span),
+    Turbo(Span, usize, usize),
+}
+
+#[derive(Clone)]
+pub(crate) struct SuggestAnnotations {
+    pub suggestions: Vec<SuggestAnnotation>,
+}
+impl Subdiagnostic for SuggestAnnotations {
+    fn add_to_diag_with<G: EmissionGuarantee, F: SubdiagMessageOp<G>>(
+        self,
+        diag: &mut Diag<'_, G>,
+        _: &F,
+    ) {
+        if self.suggestions.is_empty() {
+            return;
+        }
+
+        let mut suggestions = vec![];
+        for suggestion in self.suggestions {
+            match suggestion {
+                SuggestAnnotation::Unit(span) => {
+                    suggestions.push((span, "()".to_string()));
+                }
+                SuggestAnnotation::Path(span) => {
+                    suggestions.push((span.shrink_to_lo(), "<() as ".to_string()));
+                    suggestions.push((span.shrink_to_hi(), ">".to_string()));
+                }
+                SuggestAnnotation::Local(span) => {
+                    suggestions.push((span, ": ()".to_string()));
+                }
+                SuggestAnnotation::Turbo(span, n_args, idx) => suggestions.push((
+                    span,
+                    format!(
+                        "::<{}>",
+                        (0..n_args)
+                            .map(|i| if i == idx { "()" } else { "_" })
+                            .collect::<Vec<_>>()
+                            .join(", "),
+                    ),
+                )),
+            }
+        }
+
+        diag.multipart_suggestion_verbose(
+            "use `()` annotations to avoid fallback changes",
+            suggestions,
+            Applicability::MachineApplicable,
+        );
+    }
 }
 
 #[derive(Subdiagnostic)]
diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
index bb5f3511373..041ccfcddbb 100644
--- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
+++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs
@@ -781,7 +781,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
                     self.walk_autoref(expr, &place_with_id, autoref);
                 }
 
-                adjustment::Adjust::ReborrowPin(_, mutbl) => {
+                adjustment::Adjust::ReborrowPin(mutbl) => {
                     // Reborrowing a Pin is like a combinations of a deref and a borrow, so we do
                     // both.
                     let bk = match mutbl {
@@ -804,7 +804,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         &self,
         expr: &hir::Expr<'_>,
         base_place: &PlaceWithHirId<'tcx>,
-        autoref: &adjustment::AutoBorrow<'tcx>,
+        autoref: &adjustment::AutoBorrow,
     ) {
         debug!(
             "walk_autoref(expr.hir_id={} base_place={:?} autoref={:?})",
@@ -812,7 +812,7 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
         );
 
         match *autoref {
-            adjustment::AutoBorrow::Ref(_, m) => {
+            adjustment::AutoBorrow::Ref(m) => {
                 self.delegate.borrow_mut().borrow(
                     base_place,
                     base_place.hir_id,
@@ -1283,7 +1283,12 @@ impl<'tcx, Cx: TypeInformationCtxt<'tcx>, D: Delegate<'tcx>> ExprUseVisitor<'tcx
             adjustment::Adjust::Deref(overloaded) => {
                 // Equivalent to *expr or something similar.
                 let base = if let Some(deref) = overloaded {
-                    let ref_ty = Ty::new_ref(self.cx.tcx(), deref.region, target, deref.mutbl);
+                    let ref_ty = Ty::new_ref(
+                        self.cx.tcx(),
+                        self.cx.tcx().lifetimes.re_erased,
+                        target,
+                        deref.mutbl,
+                    );
                     self.cat_rvalue(expr.hir_id, ref_ty)
                 } else {
                     previous()?
diff --git a/compiler/rustc_hir_typeck/src/fallback.rs b/compiler/rustc_hir_typeck/src/fallback.rs
index 68776c52555..8d8573c65c5 100644
--- a/compiler/rustc_hir_typeck/src/fallback.rs
+++ b/compiler/rustc_hir_typeck/src/fallback.rs
@@ -1,11 +1,15 @@
 use std::cell::OnceCell;
+use std::ops::ControlFlow;
 
+use rustc_data_structures::fx::FxHashSet;
 use rustc_data_structures::graph::iterate::DepthFirstSearch;
 use rustc_data_structures::graph::vec_graph::VecGraph;
 use rustc_data_structures::graph::{self};
 use rustc_data_structures::unord::{UnordBag, UnordMap, UnordSet};
 use rustc_hir as hir;
 use rustc_hir::HirId;
+use rustc_hir::def::{DefKind, Res};
+use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::Visitor;
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable};
 use rustc_session::lint;
@@ -14,7 +18,7 @@ use rustc_span::{DUMMY_SP, Span};
 use rustc_trait_selection::traits::{ObligationCause, ObligationCtxt};
 use tracing::debug;
 
-use crate::{FnCtxt, TypeckRootCtxt, errors};
+use crate::{FnCtxt, errors};
 
 #[derive(Copy, Clone)]
 pub(crate) enum DivergingFallbackBehavior {
@@ -321,7 +325,11 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         let mut diverging_fallback = UnordMap::with_capacity(diverging_vids.len());
         let unsafe_infer_vars = OnceCell::new();
 
-        self.lint_obligations_broken_by_never_type_fallback_change(behavior, &diverging_vids);
+        self.lint_obligations_broken_by_never_type_fallback_change(
+            behavior,
+            &diverging_vids,
+            &coercion_graph,
+        );
 
         for &diverging_vid in &diverging_vids {
             let diverging_ty = Ty::new_var(self.tcx, diverging_vid);
@@ -419,7 +427,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         root_vid: ty::TyVid,
     ) {
         let unsafe_infer_vars = unsafe_infer_vars.get_or_init(|| {
-            let unsafe_infer_vars = compute_unsafe_infer_vars(self.root_ctxt, self.body_id);
+            let unsafe_infer_vars = compute_unsafe_infer_vars(self, self.body_id);
             debug!(?unsafe_infer_vars);
             unsafe_infer_vars
         });
@@ -429,19 +437,31 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                 .filter_map(|x| unsafe_infer_vars.get(&x).copied())
                 .collect::<Vec<_>>();
 
+        let sugg = self.try_to_suggest_annotations(&[root_vid], coercion_graph);
+
         for (hir_id, span, reason) in affected_unsafe_infer_vars {
             self.tcx.emit_node_span_lint(
                 lint::builtin::NEVER_TYPE_FALLBACK_FLOWING_INTO_UNSAFE,
                 hir_id,
                 span,
                 match reason {
-                    UnsafeUseReason::Call => errors::NeverTypeFallbackFlowingIntoUnsafe::Call,
-                    UnsafeUseReason::Method => errors::NeverTypeFallbackFlowingIntoUnsafe::Method,
-                    UnsafeUseReason::Path => errors::NeverTypeFallbackFlowingIntoUnsafe::Path,
+                    UnsafeUseReason::Call => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Call { sugg: sugg.clone() }
+                    }
+                    UnsafeUseReason::Method => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Method { sugg: sugg.clone() }
+                    }
+                    UnsafeUseReason::Path => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Path { sugg: sugg.clone() }
+                    }
                     UnsafeUseReason::UnionField => {
-                        errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::UnionField {
+                            sugg: sugg.clone(),
+                        }
+                    }
+                    UnsafeUseReason::Deref => {
+                        errors::NeverTypeFallbackFlowingIntoUnsafe::Deref { sugg: sugg.clone() }
                     }
-                    UnsafeUseReason::Deref => errors::NeverTypeFallbackFlowingIntoUnsafe::Deref,
                 },
             );
         }
@@ -451,6 +471,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         &self,
         behavior: DivergingFallbackBehavior,
         diverging_vids: &[ty::TyVid],
+        coercions: &VecGraph<ty::TyVid, true>,
     ) {
         let DivergingFallbackBehavior::ToUnit = behavior else { return };
 
@@ -478,13 +499,14 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
         };
 
         // If we have no errors with `fallback = ()`, but *do* have errors with `fallback = !`,
-        // then this code will be broken by the never type fallback change.qba
+        // then this code will be broken by the never type fallback change.
         let unit_errors = remaining_errors_if_fallback_to(self.tcx.types.unit);
         if unit_errors.is_empty()
             && let mut never_errors = remaining_errors_if_fallback_to(self.tcx.types.never)
             && let [ref mut never_error, ..] = never_errors.as_mut_slice()
         {
             self.adjust_fulfillment_error_for_expr_obligation(never_error);
+            let sugg = self.try_to_suggest_annotations(diverging_vids, coercions);
             self.tcx.emit_node_span_lint(
                 lint::builtin::DEPENDENCY_ON_UNIT_NEVER_TYPE_FALLBACK,
                 self.tcx.local_def_id_to_hir_id(self.body_id),
@@ -492,6 +514,7 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
                 errors::DependencyOnUnitNeverTypeFallback {
                     obligation_span: never_error.obligation.cause.span,
                     obligation: never_error.obligation.predicate,
+                    sugg,
                 },
             )
         }
@@ -541,6 +564,153 @@ impl<'tcx> FnCtxt<'_, 'tcx> {
     fn root_vid(&self, ty: Ty<'tcx>) -> Option<ty::TyVid> {
         Some(self.root_var(self.shallow_resolve(ty).ty_vid()?))
     }
+
+    /// Given a set of diverging vids and coercions, walk the HIR to gather a
+    /// set of suggestions which can be applied to preserve fallback to unit.
+    fn try_to_suggest_annotations(
+        &self,
+        diverging_vids: &[ty::TyVid],
+        coercions: &VecGraph<ty::TyVid, true>,
+    ) -> errors::SuggestAnnotations {
+        let body =
+            self.tcx.hir().maybe_body_owned_by(self.body_id).expect("body id must have an owner");
+        // For each diverging var, look through the HIR for a place to give it
+        // a type annotation. We do this per var because we only really need one
+        // suggestion to influence a var to be `()`.
+        let suggestions = diverging_vids
+            .iter()
+            .copied()
+            .filter_map(|vid| {
+                let reachable_vids =
+                    graph::depth_first_search_as_undirected(coercions, vid).collect();
+                AnnotateUnitFallbackVisitor { reachable_vids, fcx: self }
+                    .visit_expr(body.value)
+                    .break_value()
+            })
+            .collect();
+        errors::SuggestAnnotations { suggestions }
+    }
+}
+
+/// Try to walk the HIR to find a place to insert a useful suggestion
+/// to preserve fallback to `()` in 2024.
+struct AnnotateUnitFallbackVisitor<'a, 'tcx> {
+    reachable_vids: FxHashSet<ty::TyVid>,
+    fcx: &'a FnCtxt<'a, 'tcx>,
+}
+impl<'tcx> AnnotateUnitFallbackVisitor<'_, 'tcx> {
+    // For a given path segment, if it's missing a turbofish, try to suggest adding
+    // one so we can constrain an argument to `()`. To keep the suggestion simple,
+    // we want to simply suggest `_` for all the other args. This (for now) only
+    // works when there are only type variables (and region variables, since we can
+    // elide them)...
+    fn suggest_for_segment(
+        &self,
+        arg_segment: &'tcx hir::PathSegment<'tcx>,
+        def_id: DefId,
+        id: HirId,
+    ) -> ControlFlow<errors::SuggestAnnotation> {
+        if arg_segment.args.is_none()
+            && let Some(all_args) = self.fcx.typeck_results.borrow().node_args_opt(id)
+            && let generics = self.fcx.tcx.generics_of(def_id)
+            && let args = &all_args[generics.parent_count..]
+            // We can't turbofish consts :(
+            && args.iter().all(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_) | ty::GenericArgKind::Lifetime(_)))
+        {
+            let n_tys = args
+                .iter()
+                .filter(|arg| matches!(arg.unpack(), ty::GenericArgKind::Type(_)))
+                .count();
+            for (idx, arg) in args.iter().enumerate() {
+                if let Some(ty) = arg.as_type()
+                    && let Some(vid) = self.fcx.root_vid(ty)
+                    && self.reachable_vids.contains(&vid)
+                {
+                    return ControlFlow::Break(errors::SuggestAnnotation::Turbo(
+                        arg_segment.ident.span.shrink_to_hi(),
+                        n_tys,
+                        idx,
+                    ));
+                }
+            }
+        }
+        ControlFlow::Continue(())
+    }
+}
+impl<'tcx> Visitor<'tcx> for AnnotateUnitFallbackVisitor<'_, 'tcx> {
+    type Result = ControlFlow<errors::SuggestAnnotation>;
+
+    fn visit_ty(&mut self, hir_ty: &'tcx hir::Ty<'tcx>) -> Self::Result {
+        // Try to replace `_` with `()`.
+        if let hir::TyKind::Infer = hir_ty.kind
+            && let ty = self.fcx.typeck_results.borrow().node_type(hir_ty.hir_id)
+            && let Some(vid) = self.fcx.root_vid(ty)
+            && self.reachable_vids.contains(&vid)
+        {
+            return ControlFlow::Break(errors::SuggestAnnotation::Unit(hir_ty.span));
+        }
+        hir::intravisit::walk_ty(self, hir_ty)
+    }
+
+    fn visit_qpath(
+        &mut self,
+        qpath: &'tcx rustc_hir::QPath<'tcx>,
+        id: HirId,
+        _span: Span,
+    ) -> Self::Result {
+        let arg_segment = match qpath {
+            hir::QPath::Resolved(_, path) => {
+                path.segments.last().expect("paths should have a segment")
+            }
+            hir::QPath::TypeRelative(_, segment) => segment,
+            hir::QPath::LangItem(..) => {
+                return hir::intravisit::walk_qpath(self, qpath, id);
+            }
+        };
+        // Alternatively, try to turbofish `::<_, (), _>`.
+        if let Some(def_id) = self.fcx.typeck_results.borrow().qpath_res(qpath, id).opt_def_id() {
+            self.suggest_for_segment(arg_segment, def_id, id)?;
+        }
+        hir::intravisit::walk_qpath(self, qpath, id)
+    }
+
+    fn visit_expr(&mut self, expr: &'tcx hir::Expr<'tcx>) -> Self::Result {
+        // Try to suggest adding an explicit qself `()` to a trait method path.
+        // i.e. changing `Default::default()` to `<() as Default>::default()`.
+        if let hir::ExprKind::Path(hir::QPath::Resolved(None, path)) = expr.kind
+            && let Res::Def(DefKind::AssocFn, def_id) = path.res
+            && self.fcx.tcx.trait_of_item(def_id).is_some()
+            && let self_ty = self.fcx.typeck_results.borrow().node_args(expr.hir_id).type_at(0)
+            && let Some(vid) = self.fcx.root_vid(self_ty)
+            && self.reachable_vids.contains(&vid)
+            && let [.., trait_segment, _method_segment] = path.segments
+        {
+            let span = path.span.shrink_to_lo().to(trait_segment.ident.span);
+            return ControlFlow::Break(errors::SuggestAnnotation::Path(span));
+        }
+        // Or else, try suggesting turbofishing the method args.
+        if let hir::ExprKind::MethodCall(segment, ..) = expr.kind
+            && let Some(def_id) =
+                self.fcx.typeck_results.borrow().type_dependent_def_id(expr.hir_id)
+        {
+            self.suggest_for_segment(segment, def_id, expr.hir_id)?;
+        }
+        hir::intravisit::walk_expr(self, expr)
+    }
+
+    fn visit_local(&mut self, local: &'tcx hir::LetStmt<'tcx>) -> Self::Result {
+        // For a local, try suggest annotating the type if it's missing.
+        if let None = local.ty
+            && let ty = self.fcx.typeck_results.borrow().node_type(local.hir_id)
+            && let Some(vid) = self.fcx.root_vid(ty)
+            && self.reachable_vids.contains(&vid)
+        {
+            return ControlFlow::Break(errors::SuggestAnnotation::Local(
+                local.pat.span.shrink_to_hi(),
+            ));
+        }
+        hir::intravisit::walk_local(self, local)
+    }
 }
 
 #[derive(Debug, Copy, Clone)]
@@ -569,27 +739,26 @@ pub(crate) enum UnsafeUseReason {
 ///
 /// `compute_unsafe_infer_vars` will return `{ id(?X) -> (hir_id, span, Call) }`
 fn compute_unsafe_infer_vars<'a, 'tcx>(
-    root_ctxt: &'a TypeckRootCtxt<'tcx>,
+    fcx: &'a FnCtxt<'a, 'tcx>,
     body_id: LocalDefId,
 ) -> UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)> {
-    let body =
-        root_ctxt.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner");
+    let body = fcx.tcx.hir().maybe_body_owned_by(body_id).expect("body id must have an owner");
     let mut res = UnordMap::default();
 
     struct UnsafeInferVarsVisitor<'a, 'tcx> {
-        root_ctxt: &'a TypeckRootCtxt<'tcx>,
+        fcx: &'a FnCtxt<'a, 'tcx>,
         res: &'a mut UnordMap<ty::TyVid, (HirId, Span, UnsafeUseReason)>,
     }
 
     impl Visitor<'_> for UnsafeInferVarsVisitor<'_, '_> {
         fn visit_expr(&mut self, ex: &'_ hir::Expr<'_>) {
-            let typeck_results = self.root_ctxt.typeck_results.borrow();
+            let typeck_results = self.fcx.typeck_results.borrow();
 
             match ex.kind {
                 hir::ExprKind::MethodCall(..) => {
                     if let Some(def_id) = typeck_results.type_dependent_def_id(ex.hir_id)
-                        && let method_ty = self.root_ctxt.tcx.type_of(def_id).instantiate_identity()
-                        && let sig = method_ty.fn_sig(self.root_ctxt.tcx)
+                        && let method_ty = self.fcx.tcx.type_of(def_id).instantiate_identity()
+                        && let sig = method_ty.fn_sig(self.fcx.tcx)
                         && let hir::Safety::Unsafe = sig.safety()
                     {
                         let mut collector = InferVarCollector {
@@ -609,7 +778,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
                     let func_ty = typeck_results.expr_ty(func);
 
                     if func_ty.is_fn()
-                        && let sig = func_ty.fn_sig(self.root_ctxt.tcx)
+                        && let sig = func_ty.fn_sig(self.fcx.tcx)
                         && let hir::Safety::Unsafe = sig.safety()
                     {
                         let mut collector = InferVarCollector {
@@ -640,7 +809,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
                     // If this path refers to an unsafe function, collect inference variables which may affect it.
                     // `is_fn` excludes closures, but those can't be unsafe.
                     if ty.is_fn()
-                        && let sig = ty.fn_sig(self.root_ctxt.tcx)
+                        && let sig = ty.fn_sig(self.fcx.tcx)
                         && let hir::Safety::Unsafe = sig.safety()
                     {
                         let mut collector = InferVarCollector {
@@ -698,7 +867,7 @@ fn compute_unsafe_infer_vars<'a, 'tcx>(
         }
     }
 
-    UnsafeInferVarsVisitor { root_ctxt, res: &mut res }.visit_expr(&body.value);
+    UnsafeInferVarsVisitor { fcx, res: &mut res }.visit_expr(&body.value);
 
     debug!(?res, "collected the following unsafe vars for {body_id:?}");
 
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 0fc566c58f7..a1a78371fbd 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -264,7 +264,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let autoborrow_mut = adj.iter().any(|adj| {
             matches!(adj, &Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. })),
+                kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. })),
                 ..
             })
         });
diff --git a/compiler/rustc_hir_typeck/src/method/confirm.rs b/compiler/rustc_hir_typeck/src/method/confirm.rs
index 92b504d10bc..3754fd02428 100644
--- a/compiler/rustc_hir_typeck/src/method/confirm.rs
+++ b/compiler/rustc_hir_typeck/src/method/confirm.rs
@@ -200,10 +200,8 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                 // for two-phase borrows.
                 let mutbl = AutoBorrowMutability::new(mutbl, AllowTwoPhase::Yes);
 
-                adjustments.push(Adjustment {
-                    kind: Adjust::Borrow(AutoBorrow::Ref(region, mutbl)),
-                    target,
-                });
+                adjustments
+                    .push(Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)), target });
 
                 if unsize {
                     let unsized_ty = if let ty::Array(elem_ty, _) = base_ty.kind() {
@@ -250,7 +248,7 @@ impl<'a, 'tcx> ConfirmContext<'a, 'tcx> {
                     _ => bug!("Cannot adjust receiver type for reborrowing pin of {target:?}"),
                 };
 
-                adjustments.push(Adjustment { kind: Adjust::ReborrowPin(region, mutbl), target });
+                adjustments.push(Adjustment { kind: Adjust::ReborrowPin(mutbl), target });
             }
             None => {}
         }
diff --git a/compiler/rustc_hir_typeck/src/op.rs b/compiler/rustc_hir_typeck/src/op.rs
index 57ac7f7d2cd..9c1459ee188 100644
--- a/compiler/rustc_hir_typeck/src/op.rs
+++ b/compiler/rustc_hir_typeck/src/op.rs
@@ -256,23 +256,23 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             Ok(method) => {
                 let by_ref_binop = !op.node.is_by_value();
                 if is_assign == IsAssign::Yes || by_ref_binop {
-                    if let ty::Ref(region, _, mutbl) = method.sig.inputs()[0].kind() {
+                    if let ty::Ref(_, _, mutbl) = method.sig.inputs()[0].kind() {
                         let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes);
                         let autoref = Adjustment {
-                            kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)),
+                            kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                             target: method.sig.inputs()[0],
                         };
                         self.apply_adjustments(lhs_expr, vec![autoref]);
                     }
                 }
                 if by_ref_binop {
-                    if let ty::Ref(region, _, mutbl) = method.sig.inputs()[1].kind() {
+                    if let ty::Ref(_, _, mutbl) = method.sig.inputs()[1].kind() {
                         // Allow two-phase borrows for binops in initial deployment
                         // since they desugar to methods
                         let mutbl = AutoBorrowMutability::new(*mutbl, AllowTwoPhase::Yes);
 
                         let autoref = Adjustment {
-                            kind: Adjust::Borrow(AutoBorrow::Ref(*region, mutbl)),
+                            kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                             target: method.sig.inputs()[1],
                         };
                         // HACK(eddyb) Bypass checks due to reborrows being in
diff --git a/compiler/rustc_hir_typeck/src/place_op.rs b/compiler/rustc_hir_typeck/src/place_op.rs
index 5dd51721022..d5c7fe5fff3 100644
--- a/compiler/rustc_hir_typeck/src/place_op.rs
+++ b/compiler/rustc_hir_typeck/src/place_op.rs
@@ -29,9 +29,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         let ok = self.try_overloaded_deref(expr.span, oprnd_ty)?;
         let method = self.register_infer_ok_obligations(ok);
-        if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() {
+        if let ty::Ref(_, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() {
             self.apply_adjustments(oprnd_expr, vec![Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(*region, AutoBorrowMutability::Not)),
+                kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
                 target: method.sig.inputs()[0],
             }]);
         } else {
@@ -158,7 +158,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 let mut adjustments = self.adjust_steps(autoderef);
                 if let ty::Ref(region, _, hir::Mutability::Not) = method.sig.inputs()[0].kind() {
                     adjustments.push(Adjustment {
-                        kind: Adjust::Borrow(AutoBorrow::Ref(*region, AutoBorrowMutability::Not)),
+                        kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)),
                         target: Ty::new_imm_ref(self.tcx, *region, adjusted_ty),
                     });
                 } else {
@@ -289,9 +289,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         )
                     {
                         let method = self.register_infer_ok_obligations(ok);
-                        if let ty::Ref(region, _, mutbl) = *method.sig.output().kind() {
-                            *deref = OverloadedDeref { region, mutbl, span: deref.span };
-                        }
+                        let ty::Ref(_, _, mutbl) = *method.sig.output().kind() else {
+                            span_bug!(
+                                self.tcx.def_span(method.def_id),
+                                "expected DerefMut to return a &mut"
+                            );
+                        };
+                        *deref = OverloadedDeref { mutbl, span: deref.span };
                         // If this is a union field, also throw an error for `DerefMut` of `ManuallyDrop` (see RFC 2514).
                         // This helps avoid accidental drops.
                         if inside_union
@@ -390,7 +394,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         // not the case today.
                         allow_two_phase_borrow: AllowTwoPhase::No,
                     };
-                    adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(*region, mutbl));
+                    adjustment.kind = Adjust::Borrow(AutoBorrow::Ref(mutbl));
                     adjustment.target = Ty::new_ref(self.tcx, *region, source, mutbl.into());
                 }
                 source = adjustment.target;
diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
index 2bc006c37da..d65ed72a8e8 100644
--- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs
+++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs
@@ -432,7 +432,6 @@ where
                     upvar.visit_with(self);
                 }
 
-                // FIXME(async_closures): Is this the right signature to visit here?
                 args.as_coroutine_closure().signature_parts_ty().visit_with(self);
             }
 
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index d3762e739db..35bba149d0a 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -832,8 +832,6 @@ fn test_unstable_options_tracking_hash() {
     tracked!(polonius, Polonius::Legacy);
     tracked!(precise_enum_drop_elaboration, false);
     tracked!(print_fuel, Some("abc".to_string()));
-    tracked!(profile, true);
-    tracked!(profile_emit, Some(PathBuf::from("abc")));
     tracked!(profile_sample_use, Some(PathBuf::from("abc")));
     tracked!(profiler_runtime, "abc".to_string());
     tracked!(regparm, Some(3));
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 3fa43296dfc..9187f6caad4 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -268,7 +268,7 @@ lint_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edi
 
 lint_extern_without_abi = extern declarations without an explicit ABI are deprecated
     .label = ABI should be specified here
-    .help = the default ABI is {$default_abi}
+    .suggestion = explicitly specify the {$default_abi} ABI
 
 lint_for_loops_over_fallibles =
     for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 000f4b697bd..38e52570e53 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -2738,11 +2738,9 @@ pub(crate) struct PatternsInFnsWithoutBodySub {
 
 #[derive(LintDiagnostic)]
 #[diag(lint_extern_without_abi)]
-#[help]
 pub(crate) struct MissingAbi {
-    #[label]
+    #[suggestion(code = "extern \"{default_abi}\"", applicability = "machine-applicable")]
     pub span: Span,
-
     pub default_abi: &'static str,
 }
 
diff --git a/compiler/rustc_lint/src/non_local_def.rs b/compiler/rustc_lint/src/non_local_def.rs
index 3c31b879bd6..3c33b2dd478 100644
--- a/compiler/rustc_lint/src/non_local_def.rs
+++ b/compiler/rustc_lint/src/non_local_def.rs
@@ -151,9 +151,15 @@ impl<'tcx> LateLintPass<'tcx> for NonLocalDefinitions {
                 //     };
                 // };
                 // ```
+                //
+                // It isn't possible to mix a impl in a module with const-anon, but an item can
+                // be put inside a module and referenced by a impl so we also have to treat the
+                // item parent as transparent to module and for consistency we have to do the same
+                // for impl, otherwise the item-def and impl-def won't have the same parent.
                 let outermost_impl_parent = peel_parent_while(cx.tcx, parent, |tcx, did| {
-                    tcx.def_kind(did) == DefKind::Const
-                        && tcx.opt_item_name(did) == Some(kw::Underscore)
+                    tcx.def_kind(did) == DefKind::Mod
+                        || (tcx.def_kind(did) == DefKind::Const
+                            && tcx.opt_item_name(did) == Some(kw::Underscore))
                 });
 
                 // 2. We check if any of the paths reference a the `impl`-parent.
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index 88878a018e7..48dd8e38a03 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -204,7 +204,10 @@ fn lint_nan<'tcx>(
                     return false;
                 };
 
-                matches!(cx.tcx.get_diagnostic_name(def_id), Some(sym::f32_nan | sym::f64_nan))
+                matches!(
+                    cx.tcx.get_diagnostic_name(def_id),
+                    Some(sym::f16_nan | sym::f32_nan | sym::f64_nan | sym::f128_nan)
+                )
             }
             _ => false,
         }
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index bbb290c9459..b50a95e7d2b 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -1610,7 +1610,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedAllocation {
         }
 
         for adj in cx.typeck_results().expr_adjustments(e) {
-            if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(_, m)) = adj.kind {
+            if let adjustment::Adjust::Borrow(adjustment::AutoBorrow::Ref(m)) = adj.kind {
                 match m {
                     adjustment::AutoBorrowMutability::Not => {
                         cx.emit_span_lint(UNUSED_ALLOCATION, e.span, UnusedAllocationDiag);
diff --git a/compiler/rustc_lint_defs/Cargo.toml b/compiler/rustc_lint_defs/Cargo.toml
index eb2a184ef84..450885e7164 100644
--- a/compiler/rustc_lint_defs/Cargo.toml
+++ b/compiler/rustc_lint_defs/Cargo.toml
@@ -5,6 +5,7 @@ edition = "2021"
 
 [dependencies]
 # tidy-alphabetical-start
+rustc_abi = { path = "../rustc_abi" }
 rustc_ast = { path = "../rustc_ast" }
 rustc_data_structures = { path = "../rustc_data_structures" }
 rustc_error_messages = { path = "../rustc_error_messages" }
@@ -12,6 +13,5 @@ rustc_hir = { path = "../rustc_hir" }
 rustc_macros = { path = "../rustc_macros" }
 rustc_serialize = { path = "../rustc_serialize" }
 rustc_span = { path = "../rustc_span" }
-rustc_target = { path = "../rustc_target" }
 serde = { version = "1.0.125", features = ["derive"] }
 # tidy-alphabetical-end
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 601784f9732..0caf6ef3a6d 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -2,6 +2,7 @@
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
+use rustc_abi::ExternAbi;
 use rustc_ast::node_id::NodeId;
 use rustc_ast::{AttrId, Attribute};
 use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
@@ -15,7 +16,6 @@ use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 pub use rustc_span::edition::Edition;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
 use rustc_span::{Span, Symbol, sym};
-use rustc_target::spec::abi::Abi;
 use serde::{Deserialize, Serialize};
 
 pub use self::Level::*;
@@ -602,7 +602,7 @@ pub enum BuiltinLintDiag {
         path: String,
         since_kind: DeprecatedSinceKind,
     },
-    MissingAbi(Span, Abi),
+    MissingAbi(Span, ExternAbi),
     UnusedDocComment(Span),
     UnusedBuiltinAttribute {
         attr_name: Symbol,
diff --git a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
index 3e906f89c15..3b7dc6de825 100644
--- a/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/PassWrapper.cpp
@@ -42,7 +42,6 @@
 #if LLVM_VERSION_GE(19, 0)
 #include "llvm/Support/PGOOptions.h"
 #endif
-#include "llvm/Transforms/Instrumentation/GCOVProfiler.h"
 #include "llvm/Transforms/Instrumentation/HWAddressSanitizer.h"
 #include "llvm/Transforms/Instrumentation/InstrProfiling.h"
 #include "llvm/Transforms/Instrumentation/MemorySanitizer.h"
@@ -714,9 +713,8 @@ extern "C" LLVMRustResult LLVMRustOptimize(
     bool SLPVectorize, bool LoopVectorize, bool DisableSimplifyLibCalls,
     bool EmitLifetimeMarkers, LLVMRustSanitizerOptions *SanitizerOptions,
     const char *PGOGenPath, const char *PGOUsePath, bool InstrumentCoverage,
-    const char *InstrProfileOutput, bool InstrumentGCOV,
-    const char *PGOSampleUsePath, bool DebugInfoForProfiling,
-    void *LlvmSelfProfiler,
+    const char *InstrProfileOutput, const char *PGOSampleUsePath,
+    bool DebugInfoForProfiling, void *LlvmSelfProfiler,
     LLVMRustSelfProfileBeforePassCallback BeforePassCallback,
     LLVMRustSelfProfileAfterPassCallback AfterPassCallback,
     const char *ExtraPasses, size_t ExtraPassesLen, const char *LLVMPlugins,
@@ -847,13 +845,6 @@ extern "C" LLVMRustResult LLVMRustOptimize(
         });
   }
 
-  if (InstrumentGCOV) {
-    PipelineStartEPCallbacks.push_back(
-        [](ModulePassManager &MPM, OptimizationLevel Level) {
-          MPM.addPass(GCOVProfilerPass(GCOVOptions::getDefault()));
-        });
-  }
-
   if (InstrumentCoverage) {
     PipelineStartEPCallbacks.push_back(
         [InstrProfileOutput](ModulePassManager &MPM, OptimizationLevel Level) {
diff --git a/compiler/rustc_metadata/Cargo.toml b/compiler/rustc_metadata/Cargo.toml
index 3b0151b1f94..cece700b4dd 100644
--- a/compiler/rustc_metadata/Cargo.toml
+++ b/compiler/rustc_metadata/Cargo.toml
@@ -27,7 +27,6 @@ rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
 rustc_target = { path = "../rustc_target" }
 rustc_type_ir = { path = "../rustc_type_ir" }
-snap = "1"
 tempfile = "3.2"
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs
index 16623915c40..d2be6ae8d69 100644
--- a/compiler/rustc_metadata/src/creader.rs
+++ b/compiler/rustc_metadata/src/creader.rs
@@ -778,9 +778,7 @@ impl<'a, 'tcx> CrateLoader<'a, 'tcx> {
 
     fn inject_profiler_runtime(&mut self, krate: &ast::Crate) {
         if self.sess.opts.unstable_opts.no_profiler_runtime
-            || !(self.sess.instrument_coverage()
-                || self.sess.opts.unstable_opts.profile
-                || self.sess.opts.cg.profile_generate.enabled())
+            || !(self.sess.instrument_coverage() || self.sess.opts.cg.profile_generate.enabled())
         {
             return;
         }
diff --git a/compiler/rustc_metadata/src/locator.rs b/compiler/rustc_metadata/src/locator.rs
index a4a69ae9514..f924ed48b6f 100644
--- a/compiler/rustc_metadata/src/locator.rs
+++ b/compiler/rustc_metadata/src/locator.rs
@@ -213,7 +213,7 @@
 //! metadata::locator or metadata::creader for all the juicy details!
 
 use std::borrow::Cow;
-use std::io::{Read, Result as IoResult, Write};
+use std::io::{Result as IoResult, Write};
 use std::ops::Deref;
 use std::path::{Path, PathBuf};
 use std::{cmp, fmt};
@@ -232,7 +232,6 @@ use rustc_session::utils::CanonicalizedPath;
 use rustc_span::Span;
 use rustc_span::symbol::Symbol;
 use rustc_target::spec::{Target, TargetTriple};
-use snap::read::FrameDecoder;
 use tracing::{debug, info};
 
 use crate::creader::{Library, MetadataLoader};
@@ -792,7 +791,6 @@ fn get_metadata_section<'p>(
         CrateFlavor::Dylib => {
             let buf =
                 loader.get_dylib_metadata(target, filename).map_err(MetadataError::LoadFailure)?;
-            // The header is uncompressed
             let header_len = METADATA_HEADER.len();
             // header + u64 length of data
             let data_start = header_len + 8;
@@ -806,7 +804,7 @@ fn get_metadata_section<'p>(
                 )));
             }
 
-            // Length of the compressed stream - this allows linkers to pad the section if they want
+            // Length of the metadata - this allows linkers to pad the section if they want
             let Ok(len_bytes) =
                 <[u8; 8]>::try_from(&buf[header_len..cmp::min(data_start, buf.len())])
             else {
@@ -814,29 +812,10 @@ fn get_metadata_section<'p>(
                     "invalid metadata length found".to_string(),
                 ));
             };
-            let compressed_len = u64::from_le_bytes(len_bytes) as usize;
+            let metadata_len = u64::from_le_bytes(len_bytes) as usize;
 
             // Header is okay -> inflate the actual metadata
-            let compressed_bytes = buf.slice(|buf| &buf[data_start..(data_start + compressed_len)]);
-            if &compressed_bytes[..cmp::min(METADATA_HEADER.len(), compressed_bytes.len())]
-                == METADATA_HEADER
-            {
-                // The metadata was not actually compressed.
-                compressed_bytes
-            } else {
-                debug!("inflating {} bytes of compressed metadata", compressed_bytes.len());
-                // Assume the decompressed data will be at least the size of the compressed data, so we
-                // don't have to grow the buffer as much.
-                let mut inflated = Vec::with_capacity(compressed_bytes.len());
-                FrameDecoder::new(&*compressed_bytes).read_to_end(&mut inflated).map_err(|_| {
-                    MetadataError::LoadFailure(format!(
-                        "failed to decompress metadata: {}",
-                        filename.display()
-                    ))
-                })?;
-
-                slice_owned(inflated, Deref::deref)
-            }
+            buf.slice(|buf| &buf[data_start..(data_start + metadata_len)])
         }
         CrateFlavor::Rmeta => {
             // mmap the file, because only a small fraction of it is read.
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index cd148aef29b..978abab8b08 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -39,7 +39,7 @@ use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
 use crate::ty::print::{FmtPrinter, Printer, pretty_print_const, with_no_trimmed_paths};
 use crate::ty::visit::TypeVisitableExt;
 use crate::ty::{
-    self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt,
+    self, AdtDef, GenericArg, GenericArgsRef, Instance, InstanceKind, List, Ty, TyCtxt, TypingMode,
     UserTypeAnnotationIndex,
 };
 
@@ -452,6 +452,15 @@ impl<'tcx> Body<'tcx> {
         self.basic_blocks.as_mut()
     }
 
+    pub fn typing_mode(&self, _tcx: TyCtxt<'tcx>) -> TypingMode<'tcx> {
+        match self.phase {
+            // FIXME(#132279): the MIR is quite clearly inside of a body, so we
+            // should instead reveal opaques defined by that body here.
+            MirPhase::Built | MirPhase::Analysis(_) => TypingMode::non_body_analysis(),
+            MirPhase::Runtime(_) => TypingMode::PostAnalysis,
+        }
+    }
+
     #[inline]
     pub fn local_kind(&self, local: Local) -> LocalKind {
         let index = local.as_usize();
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index e690bf74b6b..80ae5a7146d 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -762,33 +762,35 @@ where
 
     // Terminator at the bottom.
     extra_data(PassWhere::BeforeLocation(current_location), w)?;
-    let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
-    if options.include_extra_comments {
-        writeln!(
+    if data.terminator.is_some() {
+        let indented_terminator = format!("{0}{0}{1:?};", INDENT, data.terminator().kind);
+        if options.include_extra_comments {
+            writeln!(
+                w,
+                "{:A$} // {}{}",
+                indented_terminator,
+                if tcx.sess.verbose_internals() {
+                    format!("{current_location:?}: ")
+                } else {
+                    String::new()
+                },
+                comment(tcx, data.terminator().source_info),
+                A = ALIGN,
+            )?;
+        } else {
+            writeln!(w, "{indented_terminator}")?;
+        }
+
+        write_extra(
+            tcx,
             w,
-            "{:A$} // {}{}",
-            indented_terminator,
-            if tcx.sess.verbose_internals() {
-                format!("{current_location:?}: ")
-            } else {
-                String::new()
+            |visitor| {
+                visitor.visit_terminator(data.terminator(), current_location);
             },
-            comment(tcx, data.terminator().source_info),
-            A = ALIGN,
+            options,
         )?;
-    } else {
-        writeln!(w, "{indented_terminator}")?;
     }
 
-    write_extra(
-        tcx,
-        w,
-        |visitor| {
-            visitor.visit_terminator(data.terminator(), current_location);
-        },
-        options,
-    )?;
-
     extra_data(PassWhere::AfterLocation(current_location), w)?;
     extra_data(PassWhere::AfterTerminator(block), w)?;
 
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index c610fac80f6..85beb6ef1e7 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -19,9 +19,8 @@ use smallvec::SmallVec;
 
 use super::{BasicBlock, Const, Local, UserTypeProjection};
 use crate::mir::coverage::CoverageKind;
-use crate::traits::Reveal;
 use crate::ty::adjustment::PointerCoercion;
-use crate::ty::{self, GenericArgsRef, List, Region, Ty, UserTypeAnnotationIndex};
+use crate::ty::{self, GenericArgsRef, List, Region, Ty, TyCtxt, UserTypeAnnotationIndex};
 
 /// Represents the "flavors" of MIR.
 ///
@@ -102,10 +101,10 @@ impl MirPhase {
         }
     }
 
-    pub fn reveal(&self) -> Reveal {
-        match *self {
-            MirPhase::Built | MirPhase::Analysis(_) => Reveal::UserFacing,
-            MirPhase::Runtime(_) => Reveal::All,
+    pub fn param_env<'tcx>(&self, tcx: TyCtxt<'tcx>, body_def_id: DefId) -> ty::ParamEnv<'tcx> {
+        match self {
+            MirPhase::Built | MirPhase::Analysis(_) => tcx.param_env(body_def_id),
+            MirPhase::Runtime(_) => tcx.param_env_reveal_all_normalized(body_def_id),
         }
     }
 }
diff --git a/compiler/rustc_middle/src/ty/adjustment.rs b/compiler/rustc_middle/src/ty/adjustment.rs
index 71833eea5c0..c56038d358c 100644
--- a/compiler/rustc_middle/src/ty/adjustment.rs
+++ b/compiler/rustc_middle/src/ty/adjustment.rs
@@ -82,7 +82,7 @@ pub enum PointerCoercion {
 ///    `Box<[i32]>` is an `Adjust::Unsize` with the target `Box<[i32]>`.
 #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
 pub struct Adjustment<'tcx> {
-    pub kind: Adjust<'tcx>,
+    pub kind: Adjust,
     pub target: Ty<'tcx>,
 }
 
@@ -93,20 +93,20 @@ impl<'tcx> Adjustment<'tcx> {
 }
 
 #[derive(Clone, Debug, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
-pub enum Adjust<'tcx> {
+pub enum Adjust {
     /// Go from ! to any type.
     NeverToAny,
 
     /// Dereference once, producing a place.
-    Deref(Option<OverloadedDeref<'tcx>>),
+    Deref(Option<OverloadedDeref>),
 
     /// Take the address and produce either a `&` or `*` pointer.
-    Borrow(AutoBorrow<'tcx>),
+    Borrow(AutoBorrow),
 
     Pointer(PointerCoercion),
 
     /// Take a pinned reference and reborrow as a `Pin<&mut T>` or `Pin<&T>`.
-    ReborrowPin(ty::Region<'tcx>, hir::Mutability),
+    ReborrowPin(hir::Mutability),
 }
 
 /// An overloaded autoderef step, representing a `Deref(Mut)::deref(_mut)`
@@ -115,17 +115,16 @@ pub enum Adjust<'tcx> {
 /// being those shared by both the receiver and the returned reference.
 #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
 #[derive(TypeFoldable, TypeVisitable)]
-pub struct OverloadedDeref<'tcx> {
-    pub region: ty::Region<'tcx>,
+pub struct OverloadedDeref {
     pub mutbl: hir::Mutability,
     /// The `Span` associated with the field access or method call
     /// that triggered this overloaded deref.
     pub span: Span,
 }
 
-impl<'tcx> OverloadedDeref<'tcx> {
+impl OverloadedDeref {
     /// Get the zst function item type for this method call.
-    pub fn method_call(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> {
+    pub fn method_call<'tcx>(&self, tcx: TyCtxt<'tcx>, source: Ty<'tcx>) -> Ty<'tcx> {
         let trait_def_id = match self.mutbl {
             hir::Mutability::Not => tcx.require_lang_item(LangItem::Deref, None),
             hir::Mutability::Mut => tcx.require_lang_item(LangItem::DerefMut, None),
@@ -187,9 +186,9 @@ impl From<AutoBorrowMutability> for hir::Mutability {
 
 #[derive(Copy, Clone, PartialEq, Debug, TyEncodable, TyDecodable, HashStable)]
 #[derive(TypeFoldable, TypeVisitable)]
-pub enum AutoBorrow<'tcx> {
+pub enum AutoBorrow {
     /// Converts from T to &T.
-    Ref(ty::Region<'tcx>, AutoBorrowMutability),
+    Ref(AutoBorrowMutability),
 
     /// Converts from T to *T.
     RawPtr(hir::Mutability),
diff --git a/compiler/rustc_mir_build/Cargo.toml b/compiler/rustc_mir_build/Cargo.toml
index 529e9cc2711..11904722743 100644
--- a/compiler/rustc_mir_build/Cargo.toml
+++ b/compiler/rustc_mir_build/Cargo.toml
@@ -7,6 +7,8 @@ edition = "2021"
 # tidy-alphabetical-start
 either = "1.5.0"
 itertools = "0.12"
+
+rustc_abi = { path = "../rustc_abi" }
 rustc_apfloat = "0.2.0"
 rustc_arena = { path = "../rustc_arena" }
 rustc_ast = { path = "../rustc_ast" }
@@ -22,7 +24,6 @@ rustc_middle = { path = "../rustc_middle" }
 rustc_pattern_analysis = { path = "../rustc_pattern_analysis" }
 rustc_session = { path = "../rustc_session" }
 rustc_span = { path = "../rustc_span" }
-rustc_target = { path = "../rustc_target" }
 rustc_trait_selection = { path = "../rustc_trait_selection" }
 tracing = "0.1"
 # tidy-alphabetical-end
diff --git a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
index 9e3af891052..07964e304b9 100644
--- a/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
+++ b/compiler/rustc_mir_build/src/build/custom/parse/instruction.rs
@@ -1,3 +1,4 @@
+use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_middle::mir::interpret::Scalar;
 use rustc_middle::mir::tcx::PlaceTy;
 use rustc_middle::mir::*;
@@ -6,7 +7,6 @@ use rustc_middle::ty;
 use rustc_middle::ty::cast::mir_cast_kind;
 use rustc_span::Span;
 use rustc_span::source_map::Spanned;
-use rustc_target::abi::{FieldIdx, VariantIdx};
 
 use super::{PResult, ParseCtxt, parse_by_kind};
 use crate::build::custom::ParseError;
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index ae164cf7605..3f2e3b956fc 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -1,5 +1,6 @@
 //! See docs in build/expr/mod.rs
 
+use rustc_abi::Size;
 use rustc_ast as ast;
 use rustc_hir::LangItem;
 use rustc_middle::mir::interpret::{
@@ -11,7 +12,6 @@ use rustc_middle::ty::{
     self, CanonicalUserType, CanonicalUserTypeAnnotation, Ty, TyCtxt, UserTypeAnnotationIndex,
 };
 use rustc_middle::{bug, mir, span_bug};
-use rustc_target::abi::Size;
 use tracing::{instrument, trace};
 
 use crate::build::{Builder, parse_float_into_constval};
diff --git a/compiler/rustc_mir_build/src/build/expr/as_place.rs b/compiler/rustc_mir_build/src/build/expr/as_place.rs
index c7298e3ddfa..9f6e0735b48 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_place.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_place.rs
@@ -3,6 +3,7 @@
 use std::assert_matches::assert_matches;
 use std::iter;
 
+use rustc_abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
 use rustc_hir::def_id::LocalDefId;
 use rustc_middle::hir::place::{Projection as HirProjection, ProjectionKind as HirProjectionKind};
 use rustc_middle::middle::region;
@@ -12,7 +13,6 @@ use rustc_middle::thir::*;
 use rustc_middle::ty::{self, AdtDef, CanonicalUserTypeAnnotation, Ty, Variance};
 use rustc_middle::{bug, span_bug};
 use rustc_span::Span;
-use rustc_target::abi::{FIRST_VARIANT, FieldIdx, VariantIdx};
 use tracing::{debug, instrument, trace};
 
 use crate::build::ForGuard::{OutsideGuard, RefWithinGuard};
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 2357dd73490..1985dd3fca0 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_rvalue.rs
@@ -1,5 +1,6 @@
 //! See docs in `build/expr/mod.rs`.
 
+use rustc_abi::{BackendRepr, FieldIdx, Primitive};
 use rustc_hir::lang_items::LangItem;
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::bug;
@@ -13,7 +14,6 @@ use rustc_middle::ty::util::IntTypeExt;
 use rustc_middle::ty::{self, Ty, UpvarArgs};
 use rustc_span::source_map::Spanned;
 use rustc_span::{DUMMY_SP, Span};
-use rustc_target::abi::{BackendRepr, FieldIdx, Primitive};
 use tracing::debug;
 
 use crate::build::expr::as_place::PlaceBase;
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 51ead570205..a62d4e9d873 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -5,6 +5,7 @@
 //! This also includes code for pattern bindings in `let` statements and
 //! function parameters.
 
+use rustc_abi::VariantIdx;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir::{BindingMode, ByRef};
@@ -15,7 +16,6 @@ use rustc_middle::thir::{self, *};
 use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty};
 use rustc_span::symbol::Symbol;
 use rustc_span::{BytePos, Pos, Span};
-use rustc_target::abi::VariantIdx;
 use tracing::{debug, instrument};
 
 use crate::build::ForGuard::{self, OutsideGuard, RefWithinGuard};
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index e15ea4d8d8b..46be2aee637 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -1,4 +1,5 @@
 use itertools::Itertools;
+use rustc_abi::{ExternAbi, FieldIdx};
 use rustc_apfloat::Float;
 use rustc_apfloat::ieee::{Double, Half, Quad, Single};
 use rustc_ast::attr;
@@ -20,8 +21,6 @@ use rustc_middle::ty::{self, ScalarInt, Ty, TyCtxt, TypeVisitableExt, TypingMode
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
-use rustc_target::abi::FieldIdx;
-use rustc_target::spec::abi::Abi;
 
 use super::lints;
 use crate::build::expr::as_place::PlaceBuilder;
@@ -467,7 +466,7 @@ fn construct_fn<'tcx>(
     if let DefKind::Closure = tcx.def_kind(fn_def) {
         // HACK(eddyb) Avoid having RustCall on closures,
         // as it adds unnecessary (and wrong) auto-tupling.
-        abi = Abi::Rust;
+        abi = ExternAbi::Rust;
     }
 
     let arguments = &thir.params;
@@ -540,7 +539,7 @@ fn construct_fn<'tcx>(
 
     let mut body = builder.finish();
 
-    body.spread_arg = if abi == Abi::RustCall {
+    body.spread_arg = if abi == ExternAbi::RustCall {
         // RustCall pseudo-ABI untuples the last argument.
         Some(Local::new(arguments.len()))
     } else {
@@ -792,12 +791,6 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     }
 
     fn finish(self) -> Body<'tcx> {
-        for (index, block) in self.cfg.basic_blocks.iter().enumerate() {
-            if block.terminator.is_none() {
-                span_bug!(self.fn_span, "no terminator on block {:?}", index);
-            }
-        }
-
         let mut body = Body::new(
             MirSource::item(self.def_id.to_def_id()),
             self.cfg.basic_blocks,
@@ -811,6 +804,23 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             None,
         );
         body.coverage_info_hi = self.coverage_info.map(|b| b.into_done());
+
+        for (index, block) in body.basic_blocks.iter().enumerate() {
+            if block.terminator.is_none() {
+                use rustc_middle::mir::pretty;
+                let options = pretty::PrettyPrintMirOptions::from_cli(self.tcx);
+                pretty::write_mir_fn(
+                    self.tcx,
+                    &body,
+                    &mut |_, _| Ok(()),
+                    &mut std::io::stdout(),
+                    options,
+                )
+                .unwrap();
+                span_bug!(self.fn_span, "no terminator on block {:?}", index);
+            }
+        }
+
         body
     }
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index d20e5fcf4ec..0481f715019 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -1,4 +1,5 @@
 use itertools::Itertools;
+use rustc_abi::{FIRST_VARIANT, FieldIdx};
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
 use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res};
@@ -18,7 +19,6 @@ use rustc_middle::ty::{
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::{Span, sym};
-use rustc_target::abi::{FIRST_VARIANT, FieldIdx};
 use tracing::{debug, info, instrument, trace};
 
 use crate::errors;
@@ -140,7 +140,7 @@ impl<'tcx> Cx<'tcx> {
 
                 expr = Expr {
                     temp_lifetime,
-                    ty: Ty::new_ref(self.tcx, deref.region, expr.ty, deref.mutbl),
+                    ty: Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, expr.ty, deref.mutbl),
                     span,
                     kind: ExprKind::Borrow {
                         borrow_kind: deref.mutbl.to_borrow_kind(),
@@ -152,14 +152,14 @@ impl<'tcx> Cx<'tcx> {
 
                 self.overloaded_place(hir_expr, adjustment.target, Some(call), expr, deref.span)
             }
-            Adjust::Borrow(AutoBorrow::Ref(_, m)) => ExprKind::Borrow {
+            Adjust::Borrow(AutoBorrow::Ref(m)) => ExprKind::Borrow {
                 borrow_kind: m.to_borrow_kind(),
                 arg: self.thir.exprs.push(expr),
             },
             Adjust::Borrow(AutoBorrow::RawPtr(mutability)) => {
                 ExprKind::RawBorrow { mutability, arg: self.thir.exprs.push(expr) }
             }
-            Adjust::ReborrowPin(region, mutbl) => {
+            Adjust::ReborrowPin(mutbl) => {
                 debug!("apply ReborrowPin adjustment");
                 // Rewrite `$expr` as `Pin { __pointer: &(mut)? *($expr).__pointer }`
 
@@ -197,7 +197,8 @@ impl<'tcx> Cx<'tcx> {
                     hir::Mutability::Mut => BorrowKind::Mut { kind: mir::MutBorrowKind::Default },
                     hir::Mutability::Not => BorrowKind::Shared,
                 };
-                let new_pin_target = Ty::new_ref(self.tcx, region, ptr_target_ty, mutbl);
+                let new_pin_target =
+                    Ty::new_ref(self.tcx, self.tcx.lifetimes.re_erased, ptr_target_ty, mutbl);
                 let expr = self.thir.exprs.push(Expr {
                     temp_lifetime,
                     ty: new_pin_target,
diff --git a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
index c89f526aa17..983853d2de1 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/const_to_pat.rs
@@ -1,4 +1,5 @@
 use either::Either;
+use rustc_abi::{FieldIdx, VariantIdx};
 use rustc_apfloat::Float;
 use rustc_hir as hir;
 use rustc_index::Idx;
@@ -9,7 +10,6 @@ use rustc_middle::mir::interpret::ErrorHandled;
 use rustc_middle::thir::{FieldPat, Pat, PatKind};
 use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitableExt, TypingMode, ValTree};
 use rustc_span::Span;
-use rustc_target::abi::{FieldIdx, VariantIdx};
 use rustc_trait_selection::traits::ObligationCause;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
 use tracing::{debug, instrument, trace};
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 56e5156a91f..ec852add94d 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -5,6 +5,7 @@ mod const_to_pat;
 
 use std::cmp::Ordering;
 
+use rustc_abi::{FieldIdx, Integer};
 use rustc_errors::codes::*;
 use rustc_hir::def::{CtorOf, DefKind, Res};
 use rustc_hir::pat_util::EnumerateAndAdjustIterator;
@@ -20,7 +21,6 @@ use rustc_middle::ty::{self, CanonicalUserTypeAnnotation, Ty, TyCtxt, TypeVisita
 use rustc_middle::{bug, span_bug};
 use rustc_span::def_id::LocalDefId;
 use rustc_span::{ErrorGuaranteed, Span};
-use rustc_target::abi::{FieldIdx, Integer};
 use tracing::{debug, instrument};
 
 pub(crate) use self::check_match::check_match;
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 8a646d8cbfe..274eea9563f 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -1082,7 +1082,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
         }
 
-        if let AggregateTy::Def(_, _) = ty
+        // unsound: https://github.com/rust-lang/rust/issues/132353
+        if tcx.sess.opts.unstable_opts.unsound_mir_opts
+            && let AggregateTy::Def(_, _) = ty
             && let Some(value) =
                 self.simplify_aggregate_to_copy(rvalue, location, &fields, variant_index)
         {
diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs
index 42d6bdf6cee..404470db5c5 100644
--- a/compiler/rustc_mir_transform/src/inline.rs
+++ b/compiler/rustc_mir_transform/src/inline.rs
@@ -244,8 +244,13 @@ impl<'tcx> Inliner<'tcx> {
         // Normally, this shouldn't be required, but trait normalization failure can create a
         // validation ICE.
         let output_type = callee_body.return_ty();
-        if !util::relate_types(self.tcx, self.param_env, ty::Covariant, output_type, destination_ty)
-        {
+        if !util::sub_types(
+            self.tcx,
+            caller_body.typing_mode(self.tcx),
+            self.param_env,
+            output_type,
+            destination_ty,
+        ) {
             trace!(?output_type, ?destination_ty);
             return Err("failed to normalize return type");
         }
@@ -275,8 +280,13 @@ impl<'tcx> Inliner<'tcx> {
                 self_arg_ty.into_iter().chain(arg_tuple_tys).zip(callee_body.args_iter())
             {
                 let input_type = callee_body.local_decls[input].ty;
-                if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
-                {
+                if !util::sub_types(
+                    self.tcx,
+                    caller_body.typing_mode(self.tcx),
+                    self.param_env,
+                    input_type,
+                    arg_ty,
+                ) {
                     trace!(?arg_ty, ?input_type);
                     return Err("failed to normalize tuple argument type");
                 }
@@ -285,8 +295,13 @@ impl<'tcx> Inliner<'tcx> {
             for (arg, input) in args.iter().zip(callee_body.args_iter()) {
                 let input_type = callee_body.local_decls[input].ty;
                 let arg_ty = arg.node.ty(&caller_body.local_decls, self.tcx);
-                if !util::relate_types(self.tcx, self.param_env, ty::Covariant, input_type, arg_ty)
-                {
+                if !util::sub_types(
+                    self.tcx,
+                    caller_body.typing_mode(self.tcx),
+                    self.param_env,
+                    input_type,
+                    arg_ty,
+                ) {
                     trace!(?arg_ty, ?input_type);
                     return Err("failed to normalize argument type");
                 }
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 77356723c46..8109a9b8ba0 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -5,14 +5,14 @@ use rustc_hir::LangItem;
 use rustc_index::IndexVec;
 use rustc_index::bit_set::BitSet;
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_infer::traits::{Obligation, ObligationCause, Reveal};
+use rustc_infer::traits::{Obligation, ObligationCause};
 use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::mir::visit::{NonUseContext, PlaceContext, Visitor};
 use rustc_middle::mir::*;
 use rustc_middle::ty::adjustment::PointerCoercion;
 use rustc_middle::ty::{
     self, CoroutineArgsExt, InstanceKind, ParamEnv, ScalarInt, Ty, TyCtxt, TypeVisitableExt,
-    TypingMode, Variance,
+    Variance,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_target::abi::{FIRST_VARIANT, Size};
@@ -20,7 +20,7 @@ use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::traits::ObligationCtxt;
 use rustc_type_ir::Upcast;
 
-use crate::util::{is_within_packed, relate_types};
+use crate::util::{self, is_within_packed};
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq)]
 enum EdgeKind {
@@ -50,11 +50,7 @@ impl<'tcx> crate::MirPass<'tcx> for Validator {
         }
         let def_id = body.source.def_id();
         let mir_phase = self.mir_phase;
-        let param_env = match mir_phase.reveal() {
-            Reveal::UserFacing => tcx.param_env(def_id),
-            Reveal::All => tcx.param_env_reveal_all_normalized(def_id),
-        };
-
+        let param_env = mir_phase.param_env(tcx, def_id);
         let can_unwind = if mir_phase <= MirPhase::Runtime(RuntimePhase::Initial) {
             // In this case `AbortUnwindingCalls` haven't yet been executed.
             true
@@ -587,7 +583,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             Variance::Covariant
         };
 
-        crate::util::relate_types(self.tcx, self.param_env, variance, src, dest)
+        crate::util::relate_types(
+            self.tcx,
+            self.body.typing_mode(self.tcx),
+            self.param_env,
+            variance,
+            src,
+            dest,
+        )
     }
 
     /// Check that the given predicate definitely holds in the param-env of this MIR body.
@@ -606,7 +609,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             return true;
         }
 
-        let infcx = self.tcx.infer_ctxt().build(TypingMode::from_param_env(self.param_env));
+        let infcx = self.tcx.infer_ctxt().build(self.body.typing_mode(self.tcx));
         let ocx = ObligationCtxt::new(&infcx);
         ocx.register_obligation(Obligation::new(
             self.tcx,
@@ -798,10 +801,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                 }
             }
             ProjectionElem::Subtype(ty) => {
-                if !relate_types(
+                if !util::sub_types(
                     self.tcx,
+                    self.body.typing_mode(self.tcx),
                     self.param_env,
-                    Variance::Covariant,
                     ty,
                     place_ref.ty(&self.body.local_decls, self.tcx).ty,
                 ) {
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 36733726564..6b4e2d0f4e2 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -1194,6 +1194,7 @@ impl<'a> Parser<'a> {
         attrs: &mut AttrVec,
         mut safety: Safety,
     ) -> PResult<'a, ItemInfo> {
+        let extern_span = self.prev_token.uninterpolated_span();
         let abi = self.parse_abi(); // ABI?
         // FIXME: This recovery should be tested better.
         if safety == Safety::Default
@@ -1205,6 +1206,7 @@ impl<'a> Parser<'a> {
             let _ = self.eat_keyword(kw::Unsafe);
         }
         let module = ast::ForeignMod {
+            extern_span,
             safety,
             abi,
             items: self.parse_item_list(attrs, |p| p.parse_foreign_item(ForceCollect::No))?,
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 20a1affa008..aa6e473ea6b 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -2453,7 +2453,7 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
     let output_types = parse_output_types(early_dcx, &unstable_opts, matches);
 
     let mut cg = CodegenOptions::build(early_dcx, matches);
-    let (disable_local_thinlto, mut codegen_units) = should_override_cgus_and_disable_thinlto(
+    let (disable_local_thinlto, codegen_units) = should_override_cgus_and_disable_thinlto(
         early_dcx,
         &output_types,
         matches,
@@ -2480,18 +2480,6 @@ pub fn build_session_options(early_dcx: &mut EarlyDiagCtxt, matches: &getopts::M
 
     let assert_incr_state = parse_assert_incr_state(early_dcx, &unstable_opts.assert_incr_state);
 
-    if unstable_opts.profile && incremental.is_some() {
-        early_dcx.early_fatal("can't instrument with gcov profiling when compiling incrementally");
-    }
-    if unstable_opts.profile {
-        match codegen_units {
-            Some(1) => {}
-            None => codegen_units = Some(1),
-            Some(_) => early_dcx
-                .early_fatal("can't instrument with gcov profiling with multiple codegen units"),
-        }
-    }
-
     if cg.profile_generate.enabled() && cg.profile_use.is_some() {
         early_dcx.early_fatal("options `-C profile-generate` and `-C profile-use` are exclusive");
     }
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 17eb3870049..ae7dd96e7e0 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -1990,13 +1990,8 @@ options! {
     proc_macro_execution_strategy: ProcMacroExecutionStrategy = (ProcMacroExecutionStrategy::SameThread,
         parse_proc_macro_execution_strategy, [UNTRACKED],
         "how to run proc-macro code (default: same-thread)"),
-    profile: bool = (false, parse_bool, [TRACKED],
-        "insert profiling code (default: no)"),
     profile_closures: bool = (false, parse_no_flag, [UNTRACKED],
         "profile size of closures"),
-    profile_emit: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
-        "file path to emit profiling data at runtime when using 'profile' \
-        (default based on relative source path)"),
     profile_sample_use: Option<PathBuf> = (None, parse_opt_pathbuf, [TRACKED],
         "use the given `.prof` file for sampled profile-guided optimization (also known as AutoFDO)"),
     profiler_runtime: String = (String::from("profiler_builtins"), parse_string, [TRACKED],
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index 73763cf034c..f45c8664093 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -1,10 +1,9 @@
 use std::borrow::Cow;
 use std::env;
-use std::num::ParseIntError;
 
 use crate::spec::{
     Cc, DebuginfoKind, FramePointer, LinkerFlavor, Lld, SplitDebuginfo, StackProbeType, StaticCow,
-    Target, TargetOptions, cvs,
+    TargetOptions, cvs,
 };
 
 #[cfg(test)]
@@ -97,9 +96,8 @@ impl TargetAbi {
     }
 }
 
-/// Get the base target options, LLVM target and `target_arch` from the three
-/// things that uniquely identify Rust's Apple targets: The OS, the
-/// architecture, and the ABI.
+/// Get the base target options, unversioned LLVM target and `target_arch` from the three
+/// things that uniquely identify Rust's Apple targets: The OS, the architecture, and the ABI.
 pub(crate) fn base(
     os: &'static str,
     arch: Arch,
@@ -155,117 +153,14 @@ pub(crate) fn base(
 
         ..Default::default()
     };
-    (opts, llvm_target(os, arch, abi), arch.target_arch())
+    (opts, unversioned_llvm_target(os, arch, abi), arch.target_arch())
 }
 
-pub fn platform(target: &Target) -> Option<u32> {
-    Some(match (&*target.os, &*target.abi) {
-        ("macos", _) => object::macho::PLATFORM_MACOS,
-        ("ios", "macabi") => object::macho::PLATFORM_MACCATALYST,
-        ("ios", "sim") => object::macho::PLATFORM_IOSSIMULATOR,
-        ("ios", _) => object::macho::PLATFORM_IOS,
-        ("watchos", "sim") => object::macho::PLATFORM_WATCHOSSIMULATOR,
-        ("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,
-    })
-}
-
-/// Hack for calling `deployment_target` outside of this module.
-pub fn deployment_target_for_target(target: &Target) -> (u16, u8, u8) {
-    let arch = if target.llvm_target.starts_with("arm64e") {
-        Arch::Arm64e
-    } else if target.arch == "aarch64" {
-        Arch::Arm64
-    } else {
-        // Dummy architecture, only used by `deployment_target` anyhow
-        Arch::X86_64
-    };
-    let abi = match &*target.abi {
-        "macabi" => TargetAbi::MacCatalyst,
-        "sim" => TargetAbi::Simulator,
-        "" => TargetAbi::Normal,
-        abi => unreachable!("invalid abi '{abi}' for Apple target"),
-    };
-    deployment_target(&target.os, arch, abi)
-}
-
-/// Get the deployment target based on the standard environment variables, or
-/// fall back to a sane default.
-fn deployment_target(os: &str, arch: Arch, abi: TargetAbi) -> (u16, u8, u8) {
-    // When bumping a version in here, remember to update the platform-support
-    // docs too.
-    //
-    // NOTE: If you are looking for the default deployment target, prefer
-    // `rustc --print deployment-target`, as the default here may change in
-    // future `rustc` versions.
-
-    // Minimum operating system versions currently supported by `rustc`.
-    let os_min = match os {
-        "macos" => (10, 12, 0),
-        "ios" => (10, 0, 0),
-        "tvos" => (10, 0, 0),
-        "watchos" => (5, 0, 0),
-        "visionos" => (1, 0, 0),
-        _ => unreachable!("tried to get deployment target for non-Apple platform"),
-    };
-
-    // On certain targets it makes sense to raise the minimum OS version.
-    //
-    // This matches what LLVM does, see:
-    // <https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L1900-L1932>
-    let min = match (os, arch, abi) {
-        ("macos", Arch::Arm64 | Arch::Arm64e, _) => (11, 0, 0),
-        ("ios", Arch::Arm64 | Arch::Arm64e, TargetAbi::MacCatalyst) => (14, 0, 0),
-        ("ios", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (14, 0, 0),
-        ("ios", Arch::Arm64e, TargetAbi::Normal) => (14, 0, 0),
-        // Mac Catalyst defaults to 13.1 in Clang.
-        ("ios", _, TargetAbi::MacCatalyst) => (13, 1, 0),
-        ("tvos", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (14, 0, 0),
-        ("watchos", Arch::Arm64 | Arch::Arm64e, TargetAbi::Simulator) => (7, 0, 0),
-        _ => os_min,
-    };
-
-    // The environment variable used to fetch the deployment target.
-    let env_var = match os {
-        "macos" => "MACOSX_DEPLOYMENT_TARGET",
-        "ios" => "IPHONEOS_DEPLOYMENT_TARGET",
-        "watchos" => "WATCHOS_DEPLOYMENT_TARGET",
-        "tvos" => "TVOS_DEPLOYMENT_TARGET",
-        "visionos" => "XROS_DEPLOYMENT_TARGET",
-        _ => unreachable!("tried to get deployment target env var for non-Apple platform"),
-    };
-
-    if let Ok(deployment_target) = env::var(env_var) {
-        match parse_version(&deployment_target) {
-            // It is common that the deployment target is set too low, e.g. on
-            // macOS Aarch64 to also target older x86_64, the user may set a
-            // lower deployment target than supported.
-            //
-            // To avoid such issues, we silently raise the deployment target
-            // here.
-            // FIXME: We want to show a warning when `version < os_min`.
-            Ok(version) => version.max(min),
-            // FIXME: Report erroneous environment variable to user.
-            Err(_) => min,
-        }
-    } else {
-        min
-    }
-}
-
-/// Generate the target triple that we need to pass to LLVM and/or Clang.
-fn llvm_target(os: &str, arch: Arch, abi: TargetAbi) -> StaticCow<str> {
-    // The target triple depends on the deployment target, and is required to
-    // enable features such as cross-language LTO, and for picking the right
-    // Mach-O commands.
-    //
-    // Certain optimizations also depend on the deployment target.
-    let (major, minor, patch) = deployment_target(os, arch, abi);
+/// Generate part of the LLVM target triple.
+///
+/// See `rustc_codegen_ssa::back::versioned_llvm_target` for the full triple passed to LLVM and
+/// Clang.
+fn unversioned_llvm_target(os: &str, arch: Arch, abi: TargetAbi) -> StaticCow<str> {
     let arch = arch.target_name();
     // Convert to the "canonical" OS name used by LLVM:
     // https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L236-L282
@@ -282,7 +177,7 @@ fn llvm_target(os: &str, arch: Arch, abi: TargetAbi) -> StaticCow<str> {
         TargetAbi::MacCatalyst => "-macabi",
         TargetAbi::Simulator => "-simulator",
     };
-    format!("{arch}-apple-{os}{major}.{minor}.{patch}{environment}").into()
+    format!("{arch}-apple-{os}{environment}").into()
 }
 
 fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
@@ -321,20 +216,3 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
         cvs!["MACOSX_DEPLOYMENT_TARGET"]
     }
 }
-
-/// Parse an OS version triple (SDK version or deployment target).
-///
-/// The size of the returned numbers here are limited by Mach-O's
-/// `LC_BUILD_VERSION`.
-fn parse_version(version: &str) -> Result<(u16, u8, u8), ParseIntError> {
-    if let Some((major, minor)) = version.split_once('.') {
-        let major = major.parse()?;
-        if let Some((minor, patch)) = minor.split_once('.') {
-            Ok((major, minor.parse()?, patch.parse()?))
-        } else {
-            Ok((major, minor.parse()?, 0))
-        }
-    } else {
-        Ok((version.parse()?, 0, 0))
-    }
-}
diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs
index 9435b9a5bad..a7335c9bcae 100644
--- a/compiler/rustc_target/src/spec/base/apple/tests.rs
+++ b/compiler/rustc_target/src/spec/base/apple/tests.rs
@@ -1,4 +1,3 @@
-use super::parse_version;
 use crate::spec::targets::{
     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,
@@ -40,11 +39,3 @@ fn macos_link_environment_unmodified() {
         ],);
     }
 }
-
-#[test]
-fn test_parse_version() {
-    assert_eq!(parse_version("10"), Ok((10, 0, 0)));
-    assert_eq!(parse_version("10.12"), Ok((10, 12, 0)));
-    assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6)));
-    assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99)));
-}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index f4cbe47e0f3..d518ed60469 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -55,14 +55,16 @@ use crate::json::{Json, ToJson};
 use crate::spec::abi::Abi;
 use crate::spec::crt_objects::CrtObjects;
 
-pub mod abi;
 pub mod crt_objects;
 
+pub mod abi {
+    pub use rustc_abi::{
+        AbiDisabled, AbiUnsupported, ExternAbi as Abi, all_names, enabled_names, is_enabled,
+        is_stable, lookup,
+    };
+}
+
 mod base;
-pub use base::apple::{
-    deployment_target_for_target as current_apple_deployment_target,
-    platform as current_apple_platform,
-};
 pub use base::avr_gnu::ef_avr_arch;
 
 /// Linker is called through a C/C++ compiler.
@@ -2003,7 +2005,12 @@ impl TargetWarnings {
 /// Every field here must be specified, and has no default value.
 #[derive(PartialEq, Clone, Debug)]
 pub struct Target {
-    /// Target triple to pass to LLVM.
+    /// Unversioned target triple to pass to LLVM.
+    ///
+    /// Target triples can optionally contain an OS version (notably Apple targets), which rustc
+    /// cannot know without querying the environment.
+    ///
+    /// Use `rustc_codegen_ssa::back::versioned_llvm_target` if you need the full LLVM target.
     pub llvm_target: StaticCow<str>,
     /// Metadata about a target, for example the description or tier.
     /// Used for generating target documentation.
diff --git a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs
index c60bf650311..1b8f9b71e93 100644
--- a/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs
+++ b/compiler/rustc_target/src/spec/targets/mipsel_sony_psx.rs
@@ -14,8 +14,11 @@ pub(crate) fn target() -> Target {
         arch: "mips".into(),
 
         options: TargetOptions {
-            os: "none".into(),
-            env: "psx".into(),
+            // The Playstation 1 is mostly bare-metal, but the BIOS does provide some a slight bit
+            // of functionality post load, so we still declare it as `cfg!(target_os = "psx")`.
+            //
+            // See <https://github.com/rust-lang/rust/pull/131168> for details.
+            os: "psx".into(),
             vendor: "sony".into(),
             linker_flavor: LinkerFlavor::Gnu(Cc::No, Lld::Yes),
             cpu: "mips1".into(),
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
index 7d089aeb787..ac2141f9b08 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_linux_gnu.rs
@@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
             std: Some(true),
         },
         pointer_width: 64,
-        data_layout: "E-m:e-i64:64-n32:64-S128".into(),
+        data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
         arch: "sparc64".into(),
         options: base,
     }
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
index 21f09d6428e..d16b3776cfb 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_netbsd.rs
@@ -16,7 +16,7 @@ pub(crate) fn target() -> Target {
             std: Some(true),
         },
         pointer_width: 64,
-        data_layout: "E-m:e-i64:64-n32:64-S128".into(),
+        data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
         arch: "sparc64".into(),
         options: TargetOptions { endian: Endian::Big, mcount: "__mcount".into(), ..base },
     }
diff --git a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
index 12626dce477..91e64061020 100644
--- a/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc64_unknown_openbsd.rs
@@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
             std: Some(true),
         },
         pointer_width: 64,
-        data_layout: "E-m:e-i64:64-n32:64-S128".into(),
+        data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
         arch: "sparc64".into(),
         options: base,
     }
diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
index 08f0bb302dd..2777395757f 100644
--- a/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_linux_gnu.rs
@@ -11,7 +11,7 @@ pub(crate) fn target() -> Target {
             std: Some(true),
         },
         pointer_width: 32,
-        data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
+        data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(),
         arch: "sparc".into(),
         options: TargetOptions {
             cpu: "v9".into(),
diff --git a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
index 0157d03f854..987f69429c0 100644
--- a/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
+++ b/compiler/rustc_target/src/spec/targets/sparc_unknown_none_elf.rs
@@ -17,7 +17,7 @@ pub(crate) fn target() -> Target {
         ..Default::default()
     };
     Target {
-        data_layout: "E-m:e-p:32:32-i64:64-f128:64-n32-S64".into(),
+        data_layout: "E-m:e-p:32:32-i64:64-i128:128-f128:64-n32-S64".into(),
         llvm_target: "sparc-unknown-none-elf".into(),
         metadata: crate::spec::TargetMetadata {
             description: Some("Bare 32-bit SPARC V7+".into()),
diff --git a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
index 138ce902d5e..fdc9628f78e 100644
--- a/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
+++ b/compiler/rustc_target/src/spec/targets/sparcv9_sun_solaris.rs
@@ -19,7 +19,7 @@ pub(crate) fn target() -> Target {
             std: Some(true),
         },
         pointer_width: 64,
-        data_layout: "E-m:e-i64:64-n32:64-S128".into(),
+        data_layout: "E-m:e-i64:64-i128:128-n32:64-S128".into(),
         // Use "sparc64" instead of "sparcv9" here, since the former is already
         // used widely in the source base. If we ever needed ABI
         // differentiation from the sparc64, we could, but that would probably
diff --git a/compiler/rustc_target/src/spec/tests/tests_impl.rs b/compiler/rustc_target/src/spec/tests/tests_impl.rs
index cc5931be860..bd47d12ef9f 100644
--- a/compiler/rustc_target/src/spec/tests/tests_impl.rs
+++ b/compiler/rustc_target/src/spec/tests/tests_impl.rs
@@ -165,7 +165,8 @@ impl Target {
                 assert_matches!(&*self.llvm_abiname, "ilp32" | "ilp32f" | "ilp32d" | "ilp32e")
             }
             "riscv64" => {
-                assert_matches!(&*self.llvm_abiname, "lp64" | "lp64f" | "lp64d" | "lp64q")
+                // Note that the `lp64e` is still unstable as it's not (yet) part of the ELF psABI.
+                assert_matches!(&*self.llvm_abiname, "lp64" | "lp64f" | "lp64d" | "lp64q" | "lp64e")
             }
             _ => {}
         }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index a6474f10d5b..af3b5e0d5d4 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -551,10 +551,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                         ] => "",
                         [
                             ..,
-                            Adjustment {
-                                kind: Adjust::Borrow(AutoBorrow::Ref(_, mut_)),
-                                target: _,
-                            },
+                            Adjustment { kind: Adjust::Borrow(AutoBorrow::Ref(mut_)), target: _ },
                         ] => hir::Mutability::from(*mut_).ref_prefix_str(),
                         _ => "",
                     };
diff --git a/compiler/rustc_trait_selection/src/traits/mod.rs b/compiler/rustc_trait_selection/src/traits/mod.rs
index 1c84f2171bc..436c0fabd29 100644
--- a/compiler/rustc_trait_selection/src/traits/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/mod.rs
@@ -411,7 +411,7 @@ pub fn normalize_param_env_or_error<'tcx>(
     debug!("normalize_param_env_or_error: elaborated-predicates={:?}", predicates);
 
     let elaborated_env = ty::ParamEnv::new(tcx.mk_clauses(&predicates), unnormalized_env.reveal());
-    if !normalize::needs_normalization(&elaborated_env, unnormalized_env.reveal()) {
+    if !elaborated_env.has_aliases() {
         return elaborated_env;
     }
 
diff --git a/compiler/rustc_trait_selection/src/traits/normalize.rs b/compiler/rustc_trait_selection/src/traits/normalize.rs
index 12e00ec79ac..954dfe93387 100644
--- a/compiler/rustc_trait_selection/src/traits/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/normalize.rs
@@ -1,15 +1,16 @@
 //! Deeply normalize types using the old trait solver.
 
 use rustc_data_structures::stack::ensure_sufficient_stack;
-use rustc_infer::infer::InferOk;
 use rustc_infer::infer::at::At;
+use rustc_infer::infer::{InferCtxt, InferOk};
 use rustc_infer::traits::{
     FromSolverError, Normalized, Obligation, PredicateObligations, TraitEngine,
 };
 use rustc_macros::extension;
-use rustc_middle::traits::{ObligationCause, ObligationCauseCode, Reveal};
+use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable, TypeVisitable, TypeVisitableExt,
+    TypingMode,
 };
 use tracing::{debug, instrument};
 
@@ -109,16 +110,19 @@ where
 }
 
 pub(super) fn needs_normalization<'tcx, T: TypeVisitable<TyCtxt<'tcx>>>(
+    infcx: &InferCtxt<'tcx>,
+    param_env_for_debug_assertion: ty::ParamEnv<'tcx>,
     value: &T,
-    reveal: Reveal,
 ) -> bool {
     let mut flags = ty::TypeFlags::HAS_ALIAS;
 
     // Opaques are treated as rigid with `Reveal::UserFacing`,
     // so we can ignore those.
-    match reveal {
-        Reveal::UserFacing => flags.remove(ty::TypeFlags::HAS_TY_OPAQUE),
-        Reveal::All => {}
+    match infcx.typing_mode(param_env_for_debug_assertion) {
+        TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
+            flags.remove(ty::TypeFlags::HAS_TY_OPAQUE)
+        }
+        TypingMode::PostAnalysis => {}
     }
 
     value.has_type_flags(flags)
@@ -154,7 +158,7 @@ impl<'a, 'b, 'tcx> AssocTypeNormalizer<'a, 'b, 'tcx> {
             "Normalizing {value:?} without wrapping in a `Binder`"
         );
 
-        if !needs_normalization(&value, self.param_env.reveal()) {
+        if !needs_normalization(self.selcx.infcx, self.param_env, &value) {
             value
         } else {
             value.fold_with(self)
@@ -178,7 +182,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
     }
 
     fn fold_ty(&mut self, ty: Ty<'tcx>) -> Ty<'tcx> {
-        if !needs_normalization(&ty, self.param_env.reveal()) {
+        if !needs_normalization(self.selcx.infcx, self.param_env, &ty) {
             return ty;
         }
 
@@ -213,10 +217,11 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
         match kind {
             ty::Opaque => {
                 // Only normalize `impl Trait` outside of type inference, usually in codegen.
-                match self.param_env.reveal() {
-                    Reveal::UserFacing => ty.super_fold_with(self),
-
-                    Reveal::All => {
+                match self.selcx.infcx.typing_mode(self.param_env) {
+                    TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
+                        ty.super_fold_with(self)
+                    }
+                    TypingMode::PostAnalysis => {
                         let recursion_limit = self.cx().recursion_limit();
                         if !recursion_limit.value_within_limit(self.depth) {
                             self.selcx.infcx.err_ctxt().report_overflow_error(
@@ -403,7 +408,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
     fn fold_const(&mut self, constant: ty::Const<'tcx>) -> ty::Const<'tcx> {
         let tcx = self.selcx.tcx();
         if tcx.features().generic_const_exprs()
-            || !needs_normalization(&constant, self.param_env.reveal())
+            || !needs_normalization(self.selcx.infcx, self.param_env, &constant)
         {
             constant
         } else {
@@ -420,7 +425,7 @@ impl<'a, 'b, 'tcx> TypeFolder<TyCtxt<'tcx>> for AssocTypeNormalizer<'a, 'b, 'tcx
 
     #[inline]
     fn fold_predicate(&mut self, p: ty::Predicate<'tcx>) -> ty::Predicate<'tcx> {
-        if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
+        if p.allow_normalization() && needs_normalization(self.selcx.infcx, self.param_env, &p) {
             p.super_fold_with(self)
         } else {
             p
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index a75c07c2e8c..aab854e9caf 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -16,7 +16,7 @@ use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedD
 use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
-use rustc_middle::ty::{self, Term, Ty, TyCtxt, Upcast};
+use rustc_middle::ty::{self, Term, Ty, TyCtxt, TypingMode, Upcast};
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::sym;
 use tracing::{debug, instrument};
@@ -975,18 +975,21 @@ fn assemble_candidates_from_impls<'cx, 'tcx>(
                     // and the obligation is monomorphic, otherwise passes such as
                     // transmute checking and polymorphic MIR optimizations could
                     // get a result which isn't correct for all monomorphizations.
-                    if obligation.param_env.reveal() == Reveal::All {
-                        // NOTE(eddyb) inference variables can resolve to parameters, so
-                        // assume `poly_trait_ref` isn't monomorphic, if it contains any.
-                        let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref);
-                        !poly_trait_ref.still_further_specializable()
-                    } else {
-                        debug!(
-                            assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
-                            ?obligation.predicate,
-                            "assemble_candidates_from_impls: not eligible due to default",
-                        );
-                        false
+                    match selcx.infcx.typing_mode(obligation.param_env) {
+                        TypingMode::Coherence | TypingMode::Analysis { .. } => {
+                            debug!(
+                                assoc_ty = ?selcx.tcx().def_path_str(node_item.item.def_id),
+                                ?obligation.predicate,
+                                "assemble_candidates_from_impls: not eligible due to default",
+                            );
+                            false
+                        }
+                        TypingMode::PostAnalysis => {
+                            // NOTE(eddyb) inference variables can resolve to parameters, so
+                            // assume `poly_trait_ref` isn't monomorphic, if it contains any.
+                            let poly_trait_ref = selcx.infcx.resolve_vars_if_possible(trait_ref);
+                            !poly_trait_ref.still_further_specializable()
+                        }
                     }
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/traits/query/normalize.rs b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
index 01e6516302c..a8d701a750d 100644
--- a/compiler/rustc_trait_selection/src/traits/query/normalize.rs
+++ b/compiler/rustc_trait_selection/src/traits/query/normalize.rs
@@ -9,7 +9,7 @@ use rustc_macros::extension;
 pub use rustc_middle::traits::query::NormalizationResult;
 use rustc_middle::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt};
-use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor};
+use rustc_middle::ty::{self, Ty, TyCtxt, TypeVisitor, TypingMode};
 use rustc_span::DUMMY_SP;
 use tracing::{debug, info, instrument};
 
@@ -21,7 +21,7 @@ use crate::infer::canonical::OriginalQueryValues;
 use crate::infer::{InferCtxt, InferOk};
 use crate::traits::normalize::needs_normalization;
 use crate::traits::{
-    BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, Reveal, ScrubbedTraitError,
+    BoundVarReplacer, Normalized, ObligationCause, PlaceholderReplacer, ScrubbedTraitError,
 };
 
 #[extension(pub trait QueryNormalizeExt<'tcx>)]
@@ -89,7 +89,7 @@ impl<'a, 'tcx> At<'a, 'tcx> {
             }
         }
 
-        if !needs_normalization(&value, self.param_env.reveal()) {
+        if !needs_normalization(self.infcx, self.param_env, &value) {
             return Ok(Normalized { value, obligations: PredicateObligations::new() });
         }
 
@@ -191,7 +191,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
 
     #[instrument(level = "debug", skip(self))]
     fn try_fold_ty(&mut self, ty: Ty<'tcx>) -> Result<Ty<'tcx>, Self::Error> {
-        if !needs_normalization(&ty, self.param_env.reveal()) {
+        if !needs_normalization(self.infcx, self.param_env, &ty) {
             return Ok(ty);
         }
 
@@ -215,10 +215,12 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
         let res = match kind {
             ty::Opaque => {
                 // Only normalize `impl Trait` outside of type inference, usually in codegen.
-                match self.param_env.reveal() {
-                    Reveal::UserFacing => ty.try_super_fold_with(self)?,
+                match self.infcx.typing_mode(self.param_env) {
+                    TypingMode::Coherence | TypingMode::Analysis { defining_opaque_types: _ } => {
+                        ty.try_super_fold_with(self)?
+                    }
 
-                    Reveal::All => {
+                    TypingMode::PostAnalysis => {
                         let args = data.args.try_fold_with(self)?;
                         let recursion_limit = self.cx().recursion_limit();
 
@@ -332,7 +334,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
         &mut self,
         constant: ty::Const<'tcx>,
     ) -> Result<ty::Const<'tcx>, Self::Error> {
-        if !needs_normalization(&constant, self.param_env.reveal()) {
+        if !needs_normalization(self.infcx, self.param_env, &constant) {
             return Ok(constant);
         }
 
@@ -351,7 +353,7 @@ impl<'a, 'tcx> FallibleTypeFolder<TyCtxt<'tcx>> for QueryNormalizer<'a, 'tcx> {
         &mut self,
         p: ty::Predicate<'tcx>,
     ) -> Result<ty::Predicate<'tcx>, Self::Error> {
-        if p.allow_normalization() && needs_normalization(&p, self.param_env.reveal()) {
+        if p.allow_normalization() && needs_normalization(self.infcx, self.param_env, &p) {
             p.try_super_fold_with(self)
         } else {
             Ok(p)
diff --git a/compiler/rustc_type_ir/src/infer_ctxt.rs b/compiler/rustc_type_ir/src/infer_ctxt.rs
index 22223e4a890..aadb64f45d7 100644
--- a/compiler/rustc_type_ir/src/infer_ctxt.rs
+++ b/compiler/rustc_type_ir/src/infer_ctxt.rs
@@ -12,6 +12,13 @@ use crate::{self as ty, Interner};
 /// The current typing mode of an inference context. We unfortunately have some
 /// slightly different typing rules depending on the current context. See the
 /// doc comment for each variant for how and why they are used.
+///
+/// In most cases you can get the correct typing mode automically via:
+/// - `mir::Body::typing_mode`
+/// - `rustc_lint::LateContext::typing_mode`
+///
+/// If neither of these functions are available, feel free to reach out to
+/// t-types for help.
 #[derive_where(Clone, Copy, Hash, PartialEq, Eq, Debug; I: Interner)]
 #[cfg_attr(feature = "nightly", derive(TyEncodable, TyDecodable, HashStable_NoContext))]
 pub enum TypingMode<I: Interner> {
diff --git a/config.example.toml b/config.example.toml
index 9072a83551a..cd7ec6a05bc 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -668,8 +668,6 @@
 
 # Flag indicating whether git info will be retrieved from .git automatically.
 # Having the git information can cause a lot of rebuilds during development.
-#
-# FIXME(#76720): this can causes bugs if different compilers reuse the same metadata cache.
 #omit-git-hash = if rust.channel == "dev" { true } else { false }
 
 # Whether to create a source tarball by default when running `x dist`.
diff --git a/library/Cargo.lock b/library/Cargo.lock
index db60a484081..5defd2950e8 100644
--- a/library/Cargo.lock
+++ b/library/Cargo.lock
@@ -61,9 +61,9 @@ dependencies = [
 
 [[package]]
 name = "compiler_builtins"
-version = "0.1.134"
+version = "0.1.136"
 source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "2f743e6f7410a78c261505c729f389583de40eec62332cc8cdf2c8b9bf73049a"
+checksum = "33ccee9dd499d7ada4c81533382ce87e88c52b0676c7320b2e617d29e1bb3a3f"
 dependencies = [
  "cc",
  "rustc-std-workspace-core",
diff --git a/library/alloc/Cargo.toml b/library/alloc/Cargo.toml
index 6301ade2775..a9c375b62bd 100644
--- a/library/alloc/Cargo.toml
+++ b/library/alloc/Cargo.toml
@@ -10,7 +10,7 @@ edition = "2021"
 
 [dependencies]
 core = { path = "../core" }
-compiler_builtins = { version = "0.1.134", features = ['rustc-dep-of-std'] }
+compiler_builtins = { version = "0.1.136", features = ['rustc-dep-of-std'] }
 
 [dev-dependencies]
 rand = { version = "0.8.5", default-features = false, features = ["alloc"] }
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index 95cf9427e02..f412ca17163 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -216,7 +216,7 @@ impl Layout {
     /// [trait object]: ../../book/ch17-02-trait-objects.html
     /// [extern type]: ../../unstable-book/language-features/extern-types.html
     #[unstable(feature = "layout_for_ptr", issue = "69835")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[rustc_const_unstable(feature = "layout_for_ptr", issue = "69835")]
     #[must_use]
     pub const unsafe fn for_value_raw<T: ?Sized>(t: *const T) -> Self {
         // SAFETY: we pass along the prerequisites of these functions to the caller
@@ -232,7 +232,6 @@ impl Layout {
     /// sentinel value. Types that lazily allocate must track initialization by
     /// some other means.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[rustc_const_unstable(feature = "alloc_layout_extra", issue = "55724")]
     #[must_use]
     #[inline]
     pub const fn dangling(&self) -> NonNull<u8> {
@@ -256,6 +255,7 @@ impl Layout {
     /// `align` violates the conditions listed in [`Layout::from_size_align`].
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
     #[inline]
     pub const fn align_to(&self, align: usize) -> Result<Self, LayoutError> {
         if let Some(align) = Alignment::new(align) {
@@ -282,7 +282,6 @@ impl Layout {
     /// address for the whole allocated block of memory. One way to
     /// satisfy this constraint is to ensure `align <= self.align()`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[must_use = "this returns the padding needed, \
                   without modifying the `Layout`"]
     #[inline]
@@ -332,6 +331,7 @@ impl Layout {
     /// to the layout's current size.
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
     #[must_use = "this returns a new `Layout`, \
                   without modifying the original"]
     #[inline]
@@ -374,7 +374,6 @@ impl Layout {
     /// assert_eq!(repeated, (Layout::from_size_align(24, 4).unwrap(), 8));
     /// ```
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
     pub const fn repeat(&self, n: usize) -> Result<(Self, usize), LayoutError> {
         let padded = self.pad_to_align();
@@ -432,6 +431,7 @@ impl Layout {
     /// ```
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
     #[inline]
     pub const fn extend(&self, next: Self) -> Result<(Self, usize), LayoutError> {
         let new_align = Alignment::max(self.align, next.align);
@@ -463,7 +463,6 @@ impl Layout {
     ///
     /// On arithmetic overflow, returns `LayoutError`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
     pub const fn repeat_packed(&self, n: usize) -> Result<Self, LayoutError> {
         if let Some(size) = self.size.checked_mul(n) {
@@ -481,7 +480,6 @@ impl Layout {
     ///
     /// On arithmetic overflow, returns `LayoutError`.
     #[unstable(feature = "alloc_layout_extra", issue = "55724")]
-    #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
     #[inline]
     pub const fn extend_packed(&self, next: Self) -> Result<Self, LayoutError> {
         // SAFETY: each `size` is at most `isize::MAX == usize::MAX/2`, so the
@@ -497,6 +495,7 @@ impl Layout {
     /// `isize::MAX`, returns `LayoutError`.
     #[stable(feature = "alloc_layout_manipulation", since = "1.44.0")]
     #[rustc_const_unstable(feature = "const_alloc_layout", issue = "67521")]
+    #[cfg_attr(not(bootstrap), rustc_const_stable_indirect)]
     #[inline]
     pub const fn array<T>(n: usize) -> Result<Self, LayoutError> {
         // Reduce the amount of code we need to monomorphize per `T`.
diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs
index 9b28b8b613e..4764d7f0b0f 100644
--- a/library/core/src/array/mod.rs
+++ b/library/core/src/array/mod.rs
@@ -2,7 +2,7 @@
 //!
 //! *[See also the array primitive type](array).*
 
-#![stable(feature = "core_array", since = "1.36.0")]
+#![stable(feature = "core_array", since = "1.35.0")]
 
 use crate::borrow::{Borrow, BorrowMut};
 use crate::cmp::Ordering;
@@ -154,10 +154,11 @@ pub const fn from_mut<T>(s: &mut T) -> &mut [T; 1] {
 
 /// The error type returned when a conversion from a slice to an array fails.
 #[stable(feature = "try_from", since = "1.34.0")]
+#[rustc_allowed_through_unstable_modules]
 #[derive(Debug, Copy, Clone)]
 pub struct TryFromSliceError(());
 
-#[stable(feature = "core_array", since = "1.36.0")]
+#[stable(feature = "core_array", since = "1.35.0")]
 impl fmt::Display for TryFromSliceError {
     #[inline]
     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
diff --git a/library/core/src/char/mod.rs b/library/core/src/char/mod.rs
index fa3c2075423..59fd7250e8f 100644
--- a/library/core/src/char/mod.rs
+++ b/library/core/src/char/mod.rs
@@ -18,7 +18,7 @@
 //! functions that convert various types to `char`.
 
 #![allow(non_snake_case)]
-#![stable(feature = "core_char", since = "1.2.0")]
+#![stable(feature = "rust1", since = "1.0.0")]
 
 mod convert;
 mod decode;
diff --git a/library/core/src/mem/maybe_uninit.rs b/library/core/src/mem/maybe_uninit.rs
index b4252ef0103..a57e265c7cc 100644
--- a/library/core/src/mem/maybe_uninit.rs
+++ b/library/core/src/mem/maybe_uninit.rs
@@ -390,9 +390,6 @@ impl<T> MaybeUninit<T> {
     #[must_use]
     #[rustc_diagnostic_item = "maybe_uninit_zeroed"]
     #[stable(feature = "maybe_uninit", since = "1.36.0")]
-    // These are OK to allow since we do not leak &mut to user-visible API
-    #[rustc_allow_const_fn_unstable(const_mut_refs)]
-    #[rustc_allow_const_fn_unstable(const_ptr_write)]
     #[rustc_const_stable(feature = "const_maybe_uninit_zeroed", since = "1.75.0")]
     pub const fn zeroed() -> MaybeUninit<T> {
         let mut u = MaybeUninit::<T>::uninit();
diff --git a/library/core/src/mem/mod.rs b/library/core/src/mem/mod.rs
index 74b198c4fdd..4cf52042a57 100644
--- a/library/core/src/mem/mod.rs
+++ b/library/core/src/mem/mod.rs
@@ -1254,11 +1254,9 @@ impl<T> SizedTypeProperties for T {}
 ///
 /// Nested field accesses may be used, but not array indexes.
 ///
-/// Enum variants may be traversed as if they were fields. Variants themselves do
-/// not have an offset.
-///
-/// However, on stable only a single field name is supported, which blocks the use of
-/// enum support.
+/// If the nightly-only feature `offset_of_enum` is enabled,
+/// variants may be traversed as if they were fields.
+/// Variants themselves do not have an offset.
 ///
 /// Visibility is respected - all types and fields must be visible to the call site:
 ///
diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs
index 3a9060df286..72adb1bf190 100644
--- a/library/core/src/num/int_macros.rs
+++ b/library/core/src/num/int_macros.rs
@@ -1161,7 +1161,7 @@ macro_rules! int_impl {
         )]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
-        #[rustc_const_unstable(feature = "unchecked_neg", issue = "85122")]
+        #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_neg", issue = "85122"))]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_neg(self) -> Self {
@@ -1227,8 +1227,7 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
-        // We could always go back to wrapping
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -1294,7 +1293,7 @@ macro_rules! int_impl {
         )]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
-        #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
+        #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
@@ -1353,8 +1352,7 @@ macro_rules! int_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
-        // We could always go back to wrapping
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -1420,7 +1418,7 @@ macro_rules! int_impl {
         )]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
-        #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
+        #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
@@ -2151,7 +2149,7 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         pub const fn wrapping_shl(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
@@ -2181,7 +2179,7 @@ macro_rules! int_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         pub const fn wrapping_shr(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index f6e271954fe..f04c83693ef 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -1475,7 +1475,6 @@ macro_rules! nonzero_integer_signedness_dependent_methods {
         /// ```
         #[unstable(feature = "num_midpoint", issue = "110840")]
         #[rustc_const_unstable(feature = "const_num_midpoint", issue = "110840")]
-        #[rustc_allow_const_fn_unstable(const_num_midpoint)]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
diff --git a/library/core/src/num/uint_macros.rs b/library/core/src/num/uint_macros.rs
index eb4ea4b3c40..ded8997c634 100644
--- a/library/core/src/num/uint_macros.rs
+++ b/library/core/src/num/uint_macros.rs
@@ -1416,8 +1416,7 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
-        // We could always go back to wrapping
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -1483,7 +1482,7 @@ macro_rules! uint_impl {
         )]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
-        #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
+        #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shl(self, rhs: u32) -> Self {
@@ -1542,8 +1541,7 @@ macro_rules! uint_impl {
         /// ```
         #[stable(feature = "wrapping", since = "1.7.0")]
         #[rustc_const_stable(feature = "const_checked_int_methods", since = "1.47.0")]
-        // We could always go back to wrapping
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline]
@@ -1609,7 +1607,7 @@ macro_rules! uint_impl {
         )]
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
-        #[rustc_const_unstable(feature = "unchecked_shifts", issue = "85122")]
+        #[cfg_attr(bootstrap, rustc_const_unstable(feature = "unchecked_shifts", issue = "85122"))]
         #[inline(always)]
         #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
         pub const unsafe fn unchecked_shr(self, rhs: u32) -> Self {
@@ -2132,7 +2130,7 @@ macro_rules! uint_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         pub const fn wrapping_shl(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
@@ -2165,7 +2163,7 @@ macro_rules! uint_impl {
         #[must_use = "this returns the result of the operation, \
                       without modifying the original"]
         #[inline(always)]
-        #[rustc_allow_const_fn_unstable(unchecked_shifts)]
+        #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_shifts))]
         pub const fn wrapping_shr(self, rhs: u32) -> Self {
             // SAFETY: the masking by the bitsize of the type ensures that we do not shift
             // out of bounds
diff --git a/library/core/src/ptr/const_ptr.rs b/library/core/src/ptr/const_ptr.rs
index 75d681d76df..57a7c0fc092 100644
--- a/library/core/src/ptr/const_ptr.rs
+++ b/library/core/src/ptr/const_ptr.rs
@@ -582,7 +582,7 @@ impl<T: ?Sized> *const T {
         intrinsics::ptr_mask(self.cast::<()>(), mask).with_metadata_of(self)
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
+    /// Calculates the distance between two pointers within the same allocation. The returned value is in
     /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
     ///
     /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
@@ -677,7 +677,7 @@ impl<T: ?Sized> *const T {
         unsafe { intrinsics::ptr_offset_from(self, origin) }
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
+    /// Calculates the distance between two pointers within the same allocation. The returned value is in
     /// units of **bytes**.
     ///
     /// This is purely a convenience for casting to a `u8` pointer and
@@ -695,7 +695,7 @@ impl<T: ?Sized> *const T {
         unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
     }
 
-    /// Calculates the distance between two pointers, *where it's known that
+    /// Calculates the distance between two pointers within the same allocation, *where it's known that
     /// `self` is equal to or greater than `origin`*. The returned value is in
     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
     ///
@@ -790,6 +790,25 @@ impl<T: ?Sized> *const T {
         unsafe { intrinsics::ptr_offset_from_unsigned(self, origin) }
     }
 
+    /// Calculates the distance between two pointers within the same allocation, *where it's known that
+    /// `self` is equal to or greater than `origin`*. The returned value is in
+    /// units of **bytes**.
+    ///
+    /// This is purely a convenience for casting to a `u8` pointer and
+    /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
+    /// documentation and safety requirements.
+    ///
+    /// For non-`Sized` pointees this operation considers only the data pointers,
+    /// ignoring the metadata.
+    #[unstable(feature = "ptr_sub_ptr", issue = "95892")]
+    #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
+    #[inline]
+    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *const U) -> usize {
+        // SAFETY: the caller must uphold the safety contract for `sub_ptr`.
+        unsafe { self.cast::<u8>().sub_ptr(origin.cast::<u8>()) }
+    }
+
     /// Returns whether two pointers are guaranteed to be equal.
     ///
     /// At runtime this function behaves like `Some(self == other)`.
@@ -1005,7 +1024,7 @@ impl<T: ?Sized> *const T {
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
-    #[rustc_allow_const_fn_unstable(unchecked_neg)]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn sub(self, count: usize) -> Self
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index e9f5bf4404e..7c2205fdcd1 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -844,7 +844,6 @@ pub const fn from_ref<T: ?Sized>(r: &T) -> *const T {
 #[must_use]
 #[stable(feature = "ptr_from_ref", since = "1.76.0")]
 #[rustc_const_stable(feature = "ptr_from_ref", since = "1.76.0")]
-#[rustc_allow_const_fn_unstable(const_mut_refs)]
 #[rustc_never_returns_null_ptr]
 pub const fn from_mut<T: ?Sized>(r: &mut T) -> *mut T {
     r
diff --git a/library/core/src/ptr/mut_ptr.rs b/library/core/src/ptr/mut_ptr.rs
index 408e722267a..7aa6a309a06 100644
--- a/library/core/src/ptr/mut_ptr.rs
+++ b/library/core/src/ptr/mut_ptr.rs
@@ -746,7 +746,7 @@ impl<T: ?Sized> *mut T {
         (self as *const T).guaranteed_ne(other as _)
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
+    /// Calculates the distance between two pointers within the same allocation. The returned value is in
     /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
     ///
     /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
@@ -839,7 +839,7 @@ impl<T: ?Sized> *mut T {
         unsafe { (self as *const T).offset_from(origin) }
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
+    /// Calculates the distance between two pointers within the same allocation. The returned value is in
     /// units of **bytes**.
     ///
     /// This is purely a convenience for casting to a `u8` pointer and
@@ -857,7 +857,7 @@ impl<T: ?Sized> *mut T {
         unsafe { self.cast::<u8>().offset_from(origin.cast::<u8>()) }
     }
 
-    /// Calculates the distance between two pointers, *where it's known that
+    /// Calculates the distance between two pointers within the same allocation, *where it's known that
     /// `self` is equal to or greater than `origin`*. The returned value is in
     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
     ///
@@ -930,6 +930,25 @@ impl<T: ?Sized> *mut T {
         unsafe { (self as *const T).sub_ptr(origin) }
     }
 
+    /// Calculates the distance between two pointers within the same allocation, *where it's known that
+    /// `self` is equal to or greater than `origin`*. The returned value is in
+    /// units of **bytes**.
+    ///
+    /// This is purely a convenience for casting to a `u8` pointer and
+    /// using [`sub_ptr`][pointer::sub_ptr] on it. See that method for
+    /// documentation and safety requirements.
+    ///
+    /// For non-`Sized` pointees this operation considers only the data pointers,
+    /// ignoring the metadata.
+    #[unstable(feature = "ptr_sub_ptr", issue = "95892")]
+    #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
+    #[inline]
+    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: *mut U) -> usize {
+        // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
+        unsafe { (self as *const T).byte_sub_ptr(origin) }
+    }
+
     /// Adds an unsigned offset to a pointer.
     ///
     /// This can only move the pointer forward (or not move it). If you need to move forward or
@@ -1085,7 +1104,7 @@ impl<T: ?Sized> *mut T {
     #[stable(feature = "pointer_methods", since = "1.26.0")]
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
-    #[rustc_allow_const_fn_unstable(unchecked_neg)]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
     #[inline(always)]
     #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
     pub const unsafe fn sub(self, count: usize) -> Self
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index 86ef1f3f005..afc0c0123fa 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -635,7 +635,7 @@ impl<T: ?Sized> NonNull<T> {
     #[must_use = "returns a new pointer rather than modifying its argument"]
     #[stable(feature = "non_null_convenience", since = "1.80.0")]
     #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
-    #[rustc_allow_const_fn_unstable(unchecked_neg)]
+    #[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(unchecked_neg))]
     pub const unsafe fn sub(self, count: usize) -> Self
     where
         T: Sized,
@@ -676,7 +676,7 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { NonNull { pointer: self.pointer.byte_sub(count) } }
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
+    /// Calculates the distance between two pointers within the same allocation. The returned value is in
     /// units of T: the distance in bytes divided by `mem::size_of::<T>()`.
     ///
     /// This is equivalent to `(self as isize - origin as isize) / (mem::size_of::<T>() as isize)`,
@@ -773,7 +773,7 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { self.pointer.offset_from(origin.pointer) }
     }
 
-    /// Calculates the distance between two pointers. The returned value is in
+    /// Calculates the distance between two pointers within the same allocation. The returned value is in
     /// units of **bytes**.
     ///
     /// This is purely a convenience for casting to a `u8` pointer and
@@ -793,7 +793,7 @@ impl<T: ?Sized> NonNull<T> {
 
     // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null
 
-    /// Calculates the distance between two pointers, *where it's known that
+    /// Calculates the distance between two pointers within the same allocation, *where it's known that
     /// `self` is equal to or greater than `origin`*. The returned value is in
     /// units of T: the distance in bytes is divided by `mem::size_of::<T>()`.
     ///
@@ -866,6 +866,25 @@ impl<T: ?Sized> NonNull<T> {
         unsafe { self.pointer.sub_ptr(subtracted.pointer) }
     }
 
+    /// Calculates the distance between two pointers within the same allocation, *where it's known that
+    /// `self` is equal to or greater than `origin`*. The returned value is in
+    /// units of **bytes**.
+    ///
+    /// This is purely a convenience for casting to a `u8` pointer and
+    /// using [`sub_ptr`][NonNull::sub_ptr] on it. See that method for
+    /// documentation and safety requirements.
+    ///
+    /// For non-`Sized` pointees this operation considers only the data pointers,
+    /// ignoring the metadata.
+    #[inline(always)]
+    #[cfg_attr(miri, track_caller)] // even without panics, this helps for Miri backtraces
+    #[unstable(feature = "ptr_sub_ptr", issue = "95892")]
+    #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
+    pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize {
+        // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
+        unsafe { self.pointer.byte_sub_ptr(origin.pointer) }
+    }
+
     /// Reads the value from `self` without moving it. This leaves the
     /// memory in `self` unchanged.
     ///
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 27e51afa800..52d2179b04d 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -764,7 +764,6 @@ impl<T> [T] {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_ptr_offset", since = "1.61.0")]
-    #[rustc_allow_const_fn_unstable(const_mut_refs)]
     #[rustc_never_returns_null_ptr]
     #[inline(always)]
     #[must_use]
@@ -1867,7 +1866,6 @@ impl<T> [T] {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[rustc_const_stable(feature = "const_slice_split_at_not_mut", since = "1.71.0")]
-    #[rustc_allow_const_fn_unstable(split_at_checked)]
     #[inline]
     #[track_caller]
     #[must_use]
diff --git a/library/core/src/str/mod.rs b/library/core/src/str/mod.rs
index 9ef99e9dae8..58d6e07de8d 100644
--- a/library/core/src/str/mod.rs
+++ b/library/core/src/str/mod.rs
@@ -212,7 +212,7 @@ impl str {
         }
     }
 
-    /// Finds the closest `x` not exceeding `index` where `is_char_boundary(x)` is `true`.
+    /// Finds the closest `x` not exceeding `index` where [`is_char_boundary(x)`] is `true`.
     ///
     /// This method can help you truncate a string so that it's still valid UTF-8, but doesn't
     /// exceed a given number of bytes. Note that this is done purely at the character level
@@ -220,6 +220,8 @@ impl str {
     /// split. For example, the emoji 🧑‍🔬 (scientist) could be split so that the string only
     /// includes 🧑 (person) instead.
     ///
+    /// [`is_char_boundary(x)`]: Self::is_char_boundary
+    ///
     /// # Examples
     ///
     /// ```
@@ -248,7 +250,7 @@ impl str {
         }
     }
 
-    /// Finds the closest `x` not below `index` where `is_char_boundary(x)` is `true`.
+    /// Finds the closest `x` not below `index` where [`is_char_boundary(x)`] is `true`.
     ///
     /// If `index` is greater than the length of the string, this returns the length of the string.
     ///
@@ -256,7 +258,7 @@ impl str {
     /// for more details.
     ///
     /// [`floor_char_boundary`]: str::floor_char_boundary
-    ///
+    /// [`is_char_boundary(x)`]: Self::is_char_boundary
     ///
     /// # Examples
     ///
@@ -761,7 +763,6 @@ impl str {
     #[must_use]
     #[stable(feature = "split_at_checked", since = "1.80.0")]
     #[rustc_const_unstable(feature = "const_str_split_at", issue = "131518")]
-    #[rustc_allow_const_fn_unstable(const_is_char_boundary)]
     pub const fn split_at_mut_checked(&mut self, mid: usize) -> Option<(&mut str, &mut str)> {
         // is_char_boundary checks that the index is in [0, .len()]
         if self.is_char_boundary(mid) {
@@ -2193,7 +2194,7 @@ impl str {
     /// Returns a string slice with the prefix removed.
     ///
     /// If the string starts with the pattern `prefix`, returns the substring after the prefix,
-    /// wrapped in `Some`. Unlike `trim_start_matches`, this method removes the prefix exactly once.
+    /// wrapped in `Some`. Unlike [`trim_start_matches`], this method removes the prefix exactly once.
     ///
     /// If the string does not start with `prefix`, returns `None`.
     ///
@@ -2202,6 +2203,7 @@ impl str {
     ///
     /// [`char`]: prim@char
     /// [pattern]: self::pattern
+    /// [`trim_start_matches`]: Self::trim_start_matches
     ///
     /// # Examples
     ///
@@ -2220,7 +2222,7 @@ impl str {
     /// Returns a string slice with the suffix removed.
     ///
     /// If the string ends with the pattern `suffix`, returns the substring before the suffix,
-    /// wrapped in `Some`.  Unlike `trim_end_matches`, this method removes the suffix exactly once.
+    /// wrapped in `Some`.  Unlike [`trim_end_matches`], this method removes the suffix exactly once.
     ///
     /// If the string does not end with `suffix`, returns `None`.
     ///
@@ -2229,6 +2231,7 @@ impl str {
     ///
     /// [`char`]: prim@char
     /// [pattern]: self::pattern
+    /// [`trim_end_matches`]: Self::trim_end_matches
     ///
     /// # Examples
     ///
diff --git a/library/std/Cargo.toml b/library/std/Cargo.toml
index bfb9df7d781..9b66fc8f921 100644
--- a/library/std/Cargo.toml
+++ b/library/std/Cargo.toml
@@ -17,7 +17,7 @@ cfg-if = { version = "1.0", features = ['rustc-dep-of-std'] }
 panic_unwind = { path = "../panic_unwind", optional = true }
 panic_abort = { path = "../panic_abort" }
 core = { path = "../core", public = true }
-compiler_builtins = { version = "0.1.134" }
+compiler_builtins = { version = "0.1.136" }
 unwind = { path = "../unwind" }
 hashbrown = { version = "0.15", default-features = false, features = [
     'rustc-dep-of-std',
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index 1de52eb7b21..d0dd991a933 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -481,7 +481,7 @@ pub mod prelude;
 
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use core::any;
-#[stable(feature = "core_array", since = "1.36.0")]
+#[stable(feature = "core_array", since = "1.35.0")]
 pub use core::array;
 #[unstable(feature = "async_iterator", issue = "79024")]
 pub use core::async_iter;
diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs
index a9886012e8e..aca69490d7a 100644
--- a/library/std/src/sys/pal/windows/mod.rs
+++ b/library/std/src/sys/pal/windows/mod.rs
@@ -38,7 +38,7 @@ cfg_if::cfg_if! {
     }
 }
 
-/// Map a Result<T, WinError> to io::Result<T>.
+/// Map a [`Result<T, WinError>`] to [`io::Result<T>`](crate::io::Result<T>).
 trait IoResult<T> {
     fn io_result(self) -> crate::io::Result<T>;
 }
diff --git a/library/std/src/sys/thread_local/guard/windows.rs b/library/std/src/sys/thread_local/guard/windows.rs
index 7ee8e695c75..1752b0e1208 100644
--- a/library/std/src/sys/thread_local/guard/windows.rs
+++ b/library/std/src/sys/thread_local/guard/windows.rs
@@ -26,7 +26,7 @@
 //! This apparently translates to any callbacks in the ".CRT$XLB" section
 //! being run on certain events.
 //!
-//! So after all that, we use the compiler's #[link_section] feature to place
+//! So after all that, we use the compiler's `#[link_section]` feature to place
 //! a callback pointer into the magic section so it ends up being called.
 //!
 //! # What's up with this callback?
diff --git a/src/bootstrap/defaults/config.library.toml b/src/bootstrap/defaults/config.library.toml
index 5447565a4b0..3d697be8156 100644
--- a/src/bootstrap/defaults/config.library.toml
+++ b/src/bootstrap/defaults/config.library.toml
@@ -8,6 +8,9 @@ bench-stage = 0
 [rust]
 # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
 incremental = true
+# Download rustc from CI instead of building it from source.
+# For stage > 1 builds, this cuts compile times significantly when there are no changes on "compiler" tree.
+download-rustc = "if-unchanged"
 # Make the compiler and standard library faster to build, at the expense of a ~20% runtime slowdown.
 lto = "off"
 
diff --git a/src/bootstrap/defaults/config.tools.toml b/src/bootstrap/defaults/config.tools.toml
index efb56996bcd..27c1d1cf26d 100644
--- a/src/bootstrap/defaults/config.tools.toml
+++ b/src/bootstrap/defaults/config.tools.toml
@@ -4,7 +4,7 @@
 # This greatly increases the speed of rebuilds, especially when there are only minor changes. However, it makes the initial build slightly slower.
 incremental = true
 # Download rustc from CI instead of building it from source.
-# This cuts compile times by almost 60x, but means you can't modify the compiler.
+# For stage > 1 builds, this cuts compile times significantly when there are no changes on "compiler" tree.
 # Using these defaults will download the stage2 compiler (see `download-rustc`
 # setting) and the stage2 toolchain should therefore be used for these defaults.
 download-rustc = "if-unchanged"
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index 99ddf58104c..4ab4e60773f 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -1056,6 +1056,14 @@ pub fn rustc_cargo(
         cargo.rustflag("-l").rustflag("Enzyme-19");
     }
 
+    // Building with protected visibility reduces the number of dynamic relocations needed, giving
+    // us a faster startup time. However GNU ld < 2.40 will error if we try to link a shared object
+    // with direct references to protected symbols, so for now we only use protected symbols if
+    // linking with LLD is enabled.
+    if builder.build.config.lld_mode.is_used() {
+        cargo.rustflag("-Zdefault-visibility=protected");
+    }
+
     // We currently don't support cross-crate LTO in stage0. This also isn't hugely necessary
     // and may just be a time sink.
     if compiler.stage != 0 {
diff --git a/src/bootstrap/src/core/build_steps/setup.rs b/src/bootstrap/src/core/build_steps/setup.rs
index 51964977933..704fa46ab1e 100644
--- a/src/bootstrap/src/core/build_steps/setup.rs
+++ b/src/bootstrap/src/core/build_steps/setup.rs
@@ -571,6 +571,7 @@ Select which editor you would like to set up [default: None]: ";
                 "b526bd58d0262dd4dda2bff5bc5515b705fb668a46235ace3e057f807963a11a",
                 "828666b021d837a33e78d870b56d34c88a5e2c85de58b693607ec574f0c27000",
                 "811fb3b063c739d261fd8590dd30242e117908f5a095d594fa04585daa18ec4d",
+                "4eecb58a2168b252077369da446c30ed0e658301efe69691979d1ef0443928f4",
             ],
             EditorKind::Emacs => vec![
                 "51068d4747a13732440d1a8b8f432603badb1864fa431d83d0fd4f8fa57039e0",
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index 2ad1b39a87c..0a290a697e6 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -1725,6 +1725,11 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
         cmd.arg("--run-lib-path").arg(builder.sysroot_libdir(compiler, target));
         cmd.arg("--rustc-path").arg(builder.rustc(compiler));
 
+        // Minicore auxiliary lib for `no_core` tests that need `core` stubs in cross-compilation
+        // scenarios.
+        cmd.arg("--minicore-path")
+            .arg(builder.src.join("tests").join("auxiliary").join("minicore.rs"));
+
         let is_rustdoc = suite.ends_with("rustdoc-ui") || suite.ends_with("rustdoc-js");
 
         if mode == "run-make" {
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index b9cf8f05316..0915ec15a2f 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -290,4 +290,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Info,
         summary: "New option `llvm.offload` to control whether the llvm offload runtime for GPU support is built. Implicitly enables the openmp runtime as dependency.",
     },
+    ChangeInfo {
+        change_id: 132494,
+        severity: ChangeSeverity::Info,
+        summary: "`download-rustc='if-unchanged'` is now a default option for library profile.",
+    },
 ];
diff --git a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh
index 1a0b141e984..969389f92f7 100755
--- a/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh
+++ b/src/ci/docker/host-x86_64/x86_64-fuchsia/build-fuchsia.sh
@@ -35,7 +35,7 @@ PICK_REFS=()
 # commit hash of fuchsia.git and some other repos in the "monorepo" checkout, in
 # addition to versions of prebuilts. It should be bumped regularly by the
 # Fuchsia team – we aim for every 1-2 months.
-INTEGRATION_SHA=1c5b42266fbfefb2337c6b2f0030a91bde15f9e9
+INTEGRATION_SHA=9f632bb7446d5a6af2998f1a0ebdb4b8ea2f4511
 
 checkout=fuchsia
 jiri=.jiri_root/bin/jiri
diff --git a/src/ci/github-actions/jobs.yml b/src/ci/github-actions/jobs.yml
index a401092a3a7..c0ce358486b 100644
--- a/src/ci/github-actions/jobs.yml
+++ b/src/ci/github-actions/jobs.yml
@@ -205,7 +205,7 @@ auto:
   - image: dist-x86_64-musl
     env:
       CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-linux-8c
+    <<: *job-linux-4c
 
   - image: dist-x86_64-netbsd
     <<: *job-linux-4c
@@ -232,7 +232,7 @@ auto:
   # Tests integration with Rust for Linux.
   # Builds stage 1 compiler and tries to compile a few RfL examples with it.
   - image: x86_64-rust-for-linux
-    <<: *job-linux-8c
+    <<: *job-linux-4c
 
   - image: x86_64-gnu
     <<: *job-linux-4c
@@ -280,7 +280,7 @@ auto:
   - image: x86_64-gnu-tools
     env:
       DEPLOY_TOOLSTATES_JSON: toolstates-linux.json
-    <<: *job-linux-8c
+    <<: *job-linux-4c
 
   ####################
   #  macOS Builders  #
@@ -488,7 +488,7 @@ auto:
       SCRIPT: python x.py dist bootstrap --include-default-paths
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-windows-8c
+    <<: *job-windows
 
   - image: dist-x86_64-mingw
     env:
@@ -501,10 +501,10 @@ auto:
       NO_DOWNLOAD_CI_LLVM: 1
       DIST_REQUIRE_ALL_TOOLS: 1
       CODEGEN_BACKENDS: llvm,cranelift
-    <<: *job-windows-8c
+    <<: *job-windows
 
   - image: dist-x86_64-msvc-alt
     env:
       RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --enable-extended --enable-profiler
       SCRIPT: python x.py dist bootstrap --include-default-paths
-    <<: *job-windows-8c
+    <<: *job-windows
diff --git a/src/doc/rustc/src/instrument-coverage.md b/src/doc/rustc/src/instrument-coverage.md
index ed091d8fc57..41da47e9206 100644
--- a/src/doc/rustc/src/instrument-coverage.md
+++ b/src/doc/rustc/src/instrument-coverage.md
@@ -2,12 +2,8 @@
 
 ## Introduction
 
-The Rust compiler includes two code coverage implementations:
-
--   A GCC-compatible, gcov-based coverage implementation, enabled with `-Z profile`, which derives coverage data based on DebugInfo.
--   A source-based code coverage implementation, enabled with `-C instrument-coverage`, which uses LLVM's native, efficient coverage instrumentation to generate very precise coverage data.
-
-This document describes how to enable and use the LLVM instrumentation-based coverage, via the `-C instrument-coverage` compiler flag.
+This document describes how to enable and use LLVM instrumentation-based coverage,
+via the `-C instrument-coverage` compiler flag.
 
 ## How it works
 
diff --git a/src/doc/rustc/src/platform-support/apple-darwin.md b/src/doc/rustc/src/platform-support/apple-darwin.md
index c3a7b81f411..17ea225805b 100644
--- a/src/doc/rustc/src/platform-support/apple-darwin.md
+++ b/src/doc/rustc/src/platform-support/apple-darwin.md
@@ -52,5 +52,10 @@ Cross-compilation of these targets are supported using Clang, but may require
 Xcode or the macOS SDK (`MacOSX.sdk`) to be available to compile C code and
 to link.
 
+The Clang target is suffixed with `-macosx`. Clang's `-darwin` target refers
+to Darwin platforms in general (macOS/iOS/tvOS/watchOS/visionOS), and requires
+the `-mmacosx-version-min=...`, `-miphoneos-version-min=...` or similar flags
+to disambiguate.
+
 The path to the SDK can be passed to `rustc` using the common `SDKROOT`
 environment variable.
diff --git a/src/doc/style-guide/src/editions.md b/src/doc/style-guide/src/editions.md
index 74e873e35ff..d9dba641495 100644
--- a/src/doc/style-guide/src/editions.md
+++ b/src/doc/style-guide/src/editions.md
@@ -40,8 +40,9 @@ include:
   of a delimited expression, delimited expressions are generally combinable,
   regardless of the number of members. Previously only applied with exactly
   one member (except for closures with explicit blocks).
-- When line-breaking a binary operator, if the first operand spans multiple
-  lines, use the base indentation of the last line.
+- When line-breaking an assignment operator, if the left-hand side spans
+  multiple lines, use the base indentation of the last line of the left-hand
+  side to indent the right-hand side.
 - Miscellaneous `rustfmt` bugfixes.
 - Use version-sort (sort `x8`, `x16`, `x32`, `x64`, `x128` in that order).
 - Change "ASCIIbetical" sort to Unicode-aware "non-lowercase before lowercase".
diff --git a/src/doc/style-guide/src/expressions.md b/src/doc/style-guide/src/expressions.md
index 3bb0ee6d5ff..4f63a632030 100644
--- a/src/doc/style-guide/src/expressions.md
+++ b/src/doc/style-guide/src/expressions.md
@@ -328,9 +328,9 @@ foo_bar
 Prefer line-breaking at an assignment operator (either `=` or `+=`, etc.) rather
 than at other binary operators.
 
-If line-breaking at a binary operator (including assignment operators) where the
-first operand spans multiple lines, use the base indentation of the *last*
-line of the first operand, and indent relative to that:
+If line-breaking an assignment operator where the left-hand side spans multiple
+lines, use the base indentation of the *last* line of the left-hand side, and
+indent the right-hand side relative to that:
 
 ```rust
 impl SomeType {
@@ -344,12 +344,6 @@ impl SomeType {
         self.array[array_index as usize]
             .as_mut()
             .expect("thing must exist")
-            .extra_info
-                + long_long_long_long_long_long_long_long_long_long_long_long_long_long_long;
-
-        self.array[array_index as usize]
-            .as_mut()
-            .expect("thing must exist")
             .extra_info = Some(ExtraInfo {
                 parent,
                 count: count as u16,
diff --git a/src/doc/unstable-book/src/compiler-flags/profile.md b/src/doc/unstable-book/src/compiler-flags/profile.md
deleted file mode 100644
index 71303bfaff2..00000000000
--- a/src/doc/unstable-book/src/compiler-flags/profile.md
+++ /dev/null
@@ -1,27 +0,0 @@
-# `profile`
-
-The tracking issue for this feature is: [#42524](https://github.com/rust-lang/rust/issues/42524).
-
-------------------------
-
-This feature allows the generation of code coverage reports.
-
-Set the `-Zprofile` compiler flag in order to enable gcov profiling.
-
-For example:
-```Bash
-cargo new testgcov --bin
-cd testgcov
-export RUSTFLAGS="-Zprofile -Ccodegen-units=1 -Copt-level=0 -Clink-dead-code -Coverflow-checks=off -Zpanic_abort_tests -Cpanic=abort"
-export CARGO_INCREMENTAL=0
-cargo build
-cargo run
-```
-
-Once you've built and run your program, files with the `gcno` (after build) and `gcda` (after execution) extensions will be created.
-You can parse them with [llvm-cov gcov](https://llvm.org/docs/CommandGuide/llvm-cov.html#llvm-cov-gcov) or [grcov](https://github.com/mozilla/grcov).
-
-Please note that `RUSTFLAGS` by default applies to everything that cargo builds and runs during a build!
-When the `--target` flag is explicitly passed to cargo, the `RUSTFLAGS` no longer apply to build scripts and procedural macros.
-For more fine-grained control consider passing a `RUSTC_WRAPPER` program to cargo that only adds the profiling flags to
-rustc for the specific crates you want to profile.
diff --git a/src/etc/rust_analyzer_helix.toml b/src/etc/rust_analyzer_helix.toml
index 642350cad34..9998ebcc03c 100644
--- a/src/etc/rust_analyzer_helix.toml
+++ b/src/etc/rust_analyzer_helix.toml
@@ -1,11 +1,12 @@
 [language-server.rust-analyzer.config]
 linkedProjects = [
     "Cargo.toml",
-    "src/tools/x/Cargo.toml",
+    "compiler/rustc_codegen_cranelift/Cargo.toml",
+    "compiler/rustc_codegen_gcc/Cargo.toml",
+    "library/Cargo.toml",
     "src/bootstrap/Cargo.toml",
     "src/tools/rust-analyzer/Cargo.toml",
-    "compiler/rustc_codegen_cranelift/Cargo.toml",
-    "compiler/rustc_codegen_gcc/Cargo.toml"
+    "src/tools/x/Cargo.toml",
 ]
 
 [language-server.rust-analyzer.config.check]
diff --git a/src/etc/rust_analyzer_settings.json b/src/etc/rust_analyzer_settings.json
index a20105f0ef3..d1b186fd316 100644
--- a/src/etc/rust_analyzer_settings.json
+++ b/src/etc/rust_analyzer_settings.json
@@ -1,6 +1,5 @@
 {
     "git.detectSubmodulesLimit": 20,
-    "rust-analyzer.check.invocationLocation": "root",
     "rust-analyzer.check.invocationStrategy": "once",
     "rust-analyzer.check.overrideCommand": [
         "python3",
@@ -24,7 +23,6 @@
     "rust-analyzer.procMacro.server": "${workspaceFolder}/build/host/stage0/libexec/rust-analyzer-proc-macro-srv",
     "rust-analyzer.procMacro.enable": true,
     "rust-analyzer.cargo.buildScripts.enable": true,
-    "rust-analyzer.cargo.buildScripts.invocationLocation": "root",
     "rust-analyzer.cargo.buildScripts.invocationStrategy": "once",
     "rust-analyzer.cargo.buildScripts.overrideCommand": [
         "python3",
diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs
index c62144be3da..d49b4320db6 100644
--- a/src/librustdoc/clean/types.rs
+++ b/src/librustdoc/clean/types.rs
@@ -5,6 +5,7 @@ use std::sync::{Arc, OnceLock as OnceCell};
 use std::{fmt, iter};
 
 use arrayvec::ArrayVec;
+use rustc_abi::{ExternAbi, VariantIdx};
 use rustc_ast::MetaItemInner;
 use rustc_ast_pretty::pprust;
 use rustc_attr::{ConstStability, Deprecation, Stability, StableSince};
@@ -26,8 +27,6 @@ use rustc_session::Session;
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{Ident, Symbol, kw, sym};
 use rustc_span::{DUMMY_SP, FileName, Loc};
-use rustc_target::abi::VariantIdx;
-use rustc_target::spec::abi::Abi;
 use thin_vec::ThinVec;
 use tracing::{debug, trace};
 use {rustc_ast as ast, rustc_hir as hir};
@@ -656,7 +655,7 @@ impl Item {
                 let def_id = self.def_id().unwrap();
                 let abi = tcx.fn_sig(def_id).skip_binder().abi();
                 hir::FnHeader {
-                    safety: if abi == Abi::RustIntrinsic {
+                    safety: if abi == ExternAbi::RustIntrinsic {
                         intrinsic_operation_unsafety(tcx, def_id.expect_local())
                     } else {
                         safety
@@ -2342,7 +2341,7 @@ pub(crate) struct BareFunctionDecl {
     pub(crate) safety: hir::Safety,
     pub(crate) generic_params: Vec<GenericParamDef>,
     pub(crate) decl: FnDecl,
-    pub(crate) abi: Abi,
+    pub(crate) abi: ExternAbi,
 }
 
 #[derive(Clone, Debug)]
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 47c21d89177..e9d5ba2ea57 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -13,6 +13,7 @@ use std::fmt::{self, Display, Write};
 use std::iter::{self, once};
 
 use itertools::Itertools;
+use rustc_abi::ExternAbi;
 use rustc_attr::{ConstStability, StabilityLevel, StableSince};
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
@@ -23,7 +24,6 @@ use rustc_metadata::creader::{CStore, LoadedMacro};
 use rustc_middle::ty::{self, TyCtxt, TypingMode};
 use rustc_span::symbol::kw;
 use rustc_span::{Symbol, sym};
-use rustc_target::spec::abi::Abi;
 use tracing::{debug, trace};
 
 use super::url_parts_builder::{UrlPartsBuilder, estimate_item_path_byte_length};
@@ -1787,11 +1787,11 @@ impl clean::AssocItemConstraint {
     }
 }
 
-pub(crate) fn print_abi_with_space(abi: Abi) -> impl Display {
+pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
     display_fn(move |f| {
         let quot = if f.alternate() { "\"" } else { "&quot;" };
         match abi {
-            Abi::Rust => Ok(()),
+            ExternAbi::Rust => Ok(()),
             abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()),
         }
     })
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 5e9cbef99a9..c6a2d87cbd0 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -5,6 +5,7 @@ use std::rc::Rc;
 
 use itertools::Itertools;
 use rinja::Template;
+use rustc_abi::VariantIdx;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_hir as hir;
@@ -14,7 +15,6 @@ use rustc_index::IndexVec;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::hygiene::MacroKind;
 use rustc_span::symbol::{Symbol, kw, sym};
-use rustc_target::abi::VariantIdx;
 use tracing::{debug, info};
 
 use super::type_layout::document_type_layout;
diff --git a/src/librustdoc/html/render/type_layout.rs b/src/librustdoc/html/render/type_layout.rs
index 79209cee94f..d85ba3a2b14 100644
--- a/src/librustdoc/html/render/type_layout.rs
+++ b/src/librustdoc/html/render/type_layout.rs
@@ -1,13 +1,13 @@
 use std::fmt;
 
 use rinja::Template;
+use rustc_abi::{Primitive, TagEncoding, Variants};
 use rustc_data_structures::captures::Captures;
 use rustc_hir::def_id::DefId;
 use rustc_middle::span_bug;
 use rustc_middle::ty::layout::LayoutError;
 use rustc_middle::ty::{self};
 use rustc_span::symbol::Symbol;
-use rustc_target::abi::{Primitive, TagEncoding, Variants};
 
 use crate::html::format::display_fn;
 use crate::html::render::Context;
diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs
index 7270f170780..1c8303d4c20 100644
--- a/src/librustdoc/json/conversions.rs
+++ b/src/librustdoc/json/conversions.rs
@@ -4,6 +4,7 @@
 
 #![allow(rustc::default_hash_types)]
 
+use rustc_abi::ExternAbi;
 use rustc_ast::ast;
 use rustc_attr::DeprecatedSince;
 use rustc_hir::def::{CtorKind, DefKind};
@@ -11,7 +12,6 @@ use rustc_hir::def_id::DefId;
 use rustc_metadata::rendered_const;
 use rustc_middle::{bug, ty};
 use rustc_span::{Pos, Symbol, sym};
-use rustc_target::spec::abi::Abi as RustcAbi;
 use rustdoc_json_types::*;
 
 use super::FullItemId;
@@ -421,17 +421,17 @@ pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> FunctionHeader {
     }
 }
 
-fn convert_abi(a: RustcAbi) -> Abi {
+fn convert_abi(a: ExternAbi) -> Abi {
     match a {
-        RustcAbi::Rust => Abi::Rust,
-        RustcAbi::C { unwind } => Abi::C { unwind },
-        RustcAbi::Cdecl { unwind } => Abi::Cdecl { unwind },
-        RustcAbi::Stdcall { unwind } => Abi::Stdcall { unwind },
-        RustcAbi::Fastcall { unwind } => Abi::Fastcall { unwind },
-        RustcAbi::Aapcs { unwind } => Abi::Aapcs { unwind },
-        RustcAbi::Win64 { unwind } => Abi::Win64 { unwind },
-        RustcAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
-        RustcAbi::System { unwind } => Abi::System { unwind },
+        ExternAbi::Rust => Abi::Rust,
+        ExternAbi::C { unwind } => Abi::C { unwind },
+        ExternAbi::Cdecl { unwind } => Abi::Cdecl { unwind },
+        ExternAbi::Stdcall { unwind } => Abi::Stdcall { unwind },
+        ExternAbi::Fastcall { unwind } => Abi::Fastcall { unwind },
+        ExternAbi::Aapcs { unwind } => Abi::Aapcs { unwind },
+        ExternAbi::Win64 { unwind } => Abi::Win64 { unwind },
+        ExternAbi::SysV64 { unwind } => Abi::SysV64 { unwind },
+        ExternAbi::System { unwind } => Abi::System { unwind },
         _ => Abi::Other(a.to_string()),
     }
 }
diff --git a/src/librustdoc/passes/propagate_stability.rs b/src/librustdoc/passes/propagate_stability.rs
index f55479687f8..a28487cc79e 100644
--- a/src/librustdoc/passes/propagate_stability.rs
+++ b/src/librustdoc/passes/propagate_stability.rs
@@ -9,7 +9,7 @@
 use rustc_attr::{Stability, StabilityLevel};
 use rustc_hir::def_id::CRATE_DEF_ID;
 
-use crate::clean::{Crate, Item, ItemId};
+use crate::clean::{Crate, Item, ItemId, ItemKind};
 use crate::core::DocContext;
 use crate::fold::DocFolder;
 use crate::passes::Pass;
@@ -38,22 +38,45 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> {
             ItemId::DefId(def_id) => {
                 let own_stability = self.cx.tcx.lookup_stability(def_id);
 
-                // If any of the item's parents was stabilized later or is still unstable,
-                // then use the parent's stability instead.
-                if let Some(own_stab) = own_stability
-                    && let StabilityLevel::Stable {
-                        since: own_since,
-                        allowed_through_unstable_modules: false,
-                    } = own_stab.level
-                    && let Some(parent_stab) = parent_stability
-                    && (parent_stab.is_unstable()
-                        || parent_stab
-                            .stable_since()
-                            .is_some_and(|parent_since| parent_since > own_since))
-                {
-                    parent_stability
-                } else {
-                    own_stability
+                let (ItemKind::StrippedItem(box kind) | kind) = &item.kind;
+                match kind {
+                    ItemKind::ExternCrateItem { .. }
+                    | ItemKind::ImportItem(..)
+                    | ItemKind::StructItem(..)
+                    | ItemKind::UnionItem(..)
+                    | ItemKind::EnumItem(..)
+                    | ItemKind::FunctionItem(..)
+                    | ItemKind::ModuleItem(..)
+                    | ItemKind::TypeAliasItem(..)
+                    | ItemKind::StaticItem(..)
+                    | ItemKind::TraitItem(..)
+                    | ItemKind::TraitAliasItem(..)
+                    | ItemKind::StructFieldItem(..)
+                    | ItemKind::VariantItem(..)
+                    | ItemKind::ForeignFunctionItem(..)
+                    | ItemKind::ForeignStaticItem(..)
+                    | ItemKind::ForeignTypeItem
+                    | ItemKind::MacroItem(..)
+                    | ItemKind::ProcMacroItem(..)
+                    | ItemKind::ConstantItem(..) => {
+                        // If any of the item's parents was stabilized later or is still unstable,
+                        // then use the parent's stability instead.
+                        merge_stability(own_stability, parent_stability)
+                    }
+
+                    // Don't inherit the parent's stability for these items, because they
+                    // are potentially accessible even if the parent is more unstable.
+                    ItemKind::ImplItem(..)
+                    | ItemKind::TyMethodItem(..)
+                    | ItemKind::MethodItem(..)
+                    | ItemKind::TyAssocConstItem(..)
+                    | ItemKind::AssocConstItem(..)
+                    | ItemKind::TyAssocTypeItem(..)
+                    | ItemKind::AssocTypeItem(..)
+                    | ItemKind::PrimitiveItem(..)
+                    | ItemKind::KeywordItem => own_stability,
+
+                    ItemKind::StrippedItem(..) => unreachable!(),
                 }
             }
             ItemId::Auto { .. } | ItemId::Blanket { .. } => {
@@ -70,3 +93,20 @@ impl<'a, 'tcx> DocFolder for StabilityPropagator<'a, 'tcx> {
         Some(item)
     }
 }
+
+fn merge_stability(
+    own_stability: Option<Stability>,
+    parent_stability: Option<Stability>,
+) -> Option<Stability> {
+    if let Some(own_stab) = own_stability
+        && let StabilityLevel::Stable { since: own_since, allowed_through_unstable_modules: false } =
+            own_stab.level
+        && let Some(parent_stab) = parent_stability
+        && (parent_stab.is_unstable()
+            || parent_stab.stable_since().is_some_and(|parent_since| parent_since > own_since))
+    {
+        parent_stability
+    } else {
+        own_stability
+    }
+}
diff --git a/src/llvm-project b/src/llvm-project
-Subproject 3a17f74904a74565c54cfac0d67026362d03869
+Subproject b35599be758613448201a49f4b8c7ebfba5558a
diff --git a/src/tools/cargo b/src/tools/cargo
-Subproject e75214ea4936d2f2c909a71a1237042cc0e14b0
+Subproject 0310497822a7a673a330a5dd068b7aaa579a265
diff --git a/src/tools/clippy/clippy_lints/src/dereference.rs b/src/tools/clippy/clippy_lints/src/dereference.rs
index f34f5e05606..b167d7f2208 100644
--- a/src/tools/clippy/clippy_lints/src/dereference.rs
+++ b/src/tools/clippy/clippy_lints/src/dereference.rs
@@ -418,7 +418,7 @@ impl<'tcx> LateLintPass<'tcx> for Dereferencing<'tcx> {
                         let (required_refs, msg) = if can_auto_borrow {
                             (1, if deref_count == 1 { borrow_msg } else { deref_msg })
                         } else if let Some(&Adjustment {
-                            kind: Adjust::Borrow(AutoBorrow::Ref(_, mutability)),
+                            kind: Adjust::Borrow(AutoBorrow::Ref(mutability)),
                             ..
                         }) = next_adjust
                             && matches!(mutability, AutoBorrowMutability::Mut { .. })
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs
index 93d6b808646..d5ddc33e928 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_into_iter_loop.rs
@@ -53,7 +53,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<
         [] => AdjustKind::None,
         &[
             Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
+                kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                 ..
             },
         ] => AdjustKind::borrow(mutbl),
@@ -62,7 +62,7 @@ pub(super) fn check(cx: &LateContext<'_>, self_arg: &Expr<'_>, call_expr: &Expr<
                 kind: Adjust::Deref(_), ..
             },
             Adjustment {
-                kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
+                kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                 target,
             },
         ] => {
diff --git a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
index 022c6bcc70b..119e410b91c 100644
--- a/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
+++ b/src/tools/clippy/clippy_lints/src/loops/explicit_iter_loop.rs
@@ -199,7 +199,7 @@ fn is_ref_iterable<'tcx>(
                     kind: Adjust::Deref(_), ..
                 },
                 Adjustment {
-                    kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
+                    kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                     target,
                 },
                 ..,
@@ -236,7 +236,7 @@ fn is_ref_iterable<'tcx>(
             },
             &[
                 Adjustment {
-                    kind: Adjust::Borrow(AutoBorrow::Ref(_, mutbl)),
+                    kind: Adjust::Borrow(AutoBorrow::Ref(mutbl)),
                     target,
                 },
                 ..,
diff --git a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
index 64c19c327b2..223b0630bfd 100644
--- a/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/manual_inspect.rs
@@ -137,7 +137,7 @@ pub(crate) fn check(cx: &LateContext<'_>, expr: &Expr<'_>, arg: &Expr<'_>, name:
                                 _ if matches!(
                                     typeck.expr_adjustments(prev_expr).first(),
                                     Some(Adjustment {
-                                        kind: Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not))
+                                        kind: Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not))
                                             | Adjust::Deref(_),
                                         ..
                                     })
@@ -230,7 +230,7 @@ fn check_use<'tcx>(cx: &LateContext<'tcx>, e: &'tcx Expr<'_>) -> (UseKind<'tcx>,
             if use_cx
                 .adjustments
                 .first()
-                .is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Not)))) =>
+                .is_some_and(|a| matches!(a.kind, Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Not)))) =>
         {
             UseKind::AutoBorrowed
         },
diff --git a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
index 1c10e84d3ca..030df535c35 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_slicing.rs
@@ -110,7 +110,7 @@ impl<'tcx> LateLintPass<'tcx> for RedundantSlicing {
                 ) || cx.typeck_results().expr_adjustments(expr).first().map_or(false, |a| {
                     matches!(
                         a.kind,
-                        Adjust::Borrow(AutoBorrow::Ref(_, AutoBorrowMutability::Mut { .. }))
+                        Adjust::Borrow(AutoBorrow::Ref(AutoBorrowMutability::Mut { .. }))
                     )
                 }) || (matches!(
                     cx.typeck_results().expr_ty(indexed).ref_mutability(),
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 dbadc8432f6..8f9f75d6824 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
@@ -17,7 +17,7 @@ use rustc_middle::mir::{
 };
 use rustc_middle::traits::{BuiltinImplSource, ImplSource, ObligationCause};
 use rustc_middle::ty::adjustment::PointerCoercion;
-use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt, TypingMode};
+use rustc_middle::ty::{self, GenericArgKind, TraitRef, Ty, TyCtxt};
 use rustc_span::Span;
 use rustc_span::symbol::sym;
 use rustc_trait_selection::traits::{ObligationCtxt, SelectionContext};
@@ -420,7 +420,7 @@ fn is_ty_const_destruct<'tcx>(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>, body: &Body<'tcx>
             TraitRef::new(tcx, tcx.require_lang_item(LangItem::Destruct, Some(body.span)), [ty]),
         );
 
-        let infcx = tcx.infer_ctxt().build(TypingMode::from_param_env(obligation.param_env));
+        let infcx = tcx.infer_ctxt().build(body.typing_mode(tcx));
         let mut selcx = SelectionContext::new(&infcx);
         let Some(impl_src) = selcx.select(&obligation).ok().flatten() else {
             return false;
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index c618bfe4488..41785e161d0 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -362,7 +362,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(TypingMode::from_param_env(param_env));
+    let infcx = cx.tcx.infer_ctxt().build(cx.typing_mode());
     let cause = ObligationCause::dummy();
     let result = if infcx.at(&cause, param_env).query_normalize(ty).is_ok() {
         match ty.kind() {
diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs
index e82b88eef79..e4f2f95a91b 100644
--- a/src/tools/compiletest/src/common.rs
+++ b/src/tools/compiletest/src/common.rs
@@ -392,6 +392,11 @@ pub struct Config {
 
     /// Command for visual diff display, e.g. `diff-tool --color=always`.
     pub diff_command: Option<String>,
+
+    /// Path to minicore aux library, used for `no_core` tests that need `core` stubs in
+    /// cross-compilation scenarios that do not otherwise want/need to `-Zbuild-std`. Used in e.g.
+    /// ABI tests.
+    pub minicore_path: PathBuf,
 }
 
 impl Config {
diff --git a/src/tools/compiletest/src/directive-list.rs b/src/tools/compiletest/src/directive-list.rs
index 4d57907f26f..980b3f6829a 100644
--- a/src/tools/compiletest/src/directive-list.rs
+++ b/src/tools/compiletest/src/directive-list.rs
@@ -3,6 +3,7 @@
 /// a best-effort approximation for diagnostics. Add new headers to this list when needed.
 const KNOWN_DIRECTIVE_NAMES: &[&str] = &[
     // tidy-alphabetical-start
+    "add-core-stubs",
     "assembly-output",
     "aux-bin",
     "aux-build",
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index bfcdd747eb4..300a03e5f33 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -198,6 +198,9 @@ pub struct TestProps {
     pub no_auto_check_cfg: bool,
     /// Run tests which require enzyme being build
     pub has_enzyme: bool,
+    /// Build and use `minicore` as `core` stub for `no_core` tests in cross-compilation scenarios
+    /// that don't otherwise want/need `-Z build-std`.
+    pub add_core_stubs: bool,
 }
 
 mod directives {
@@ -243,6 +246,7 @@ mod directives {
     pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags";
     pub const FILECHECK_FLAGS: &'static str = "filecheck-flags";
     pub const NO_AUTO_CHECK_CFG: &'static str = "no-auto-check-cfg";
+    pub const ADD_CORE_STUBS: &'static str = "add-core-stubs";
     // This isn't a real directive, just one that is probably mistyped often
     pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
 }
@@ -300,6 +304,7 @@ impl TestProps {
             filecheck_flags: vec![],
             no_auto_check_cfg: false,
             has_enzyme: false,
+            add_core_stubs: false,
         }
     }
 
@@ -564,6 +569,8 @@ impl TestProps {
                     }
 
                     config.set_name_directive(ln, NO_AUTO_CHECK_CFG, &mut self.no_auto_check_cfg);
+
+                    self.update_add_core_stubs(ln, config);
                 },
             );
 
@@ -677,6 +684,27 @@ impl TestProps {
     pub fn local_pass_mode(&self) -> Option<PassMode> {
         self.pass_mode
     }
+
+    pub fn update_add_core_stubs(&mut self, ln: &str, config: &Config) {
+        let add_core_stubs = config.parse_name_directive(ln, directives::ADD_CORE_STUBS);
+        if add_core_stubs {
+            if !matches!(config.mode, Mode::Ui | Mode::Codegen | Mode::Assembly) {
+                panic!(
+                    "`add-core-stubs` is currently only supported for ui, codegen and assembly test modes"
+                );
+            }
+
+            // FIXME(jieyouxu): this check is currently order-dependent, but we should probably
+            // collect all directives in one go then perform a validation pass after that.
+            if self.local_pass_mode().is_some_and(|pm| pm == PassMode::Run) {
+                // `minicore` can only be used with non-run modes, because it's `core` prelude stubs
+                // and can't run.
+                panic!("`add-core-stubs` cannot be used to run the test binary");
+            }
+
+            self.add_core_stubs = add_core_stubs;
+        }
+    }
 }
 
 /// If the given line begins with the appropriate comment prefix for a directive,
diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs
index 2e6effcab98..0e735dc77c4 100644
--- a/src/tools/compiletest/src/header/tests.rs
+++ b/src/tools/compiletest/src/header/tests.rs
@@ -152,6 +152,7 @@ impl ConfigBuilder {
             "--git-repository=",
             "--nightly-branch=",
             "--git-merge-commit-email=",
+            "--minicore-path=",
         ];
         let mut args: Vec<String> = args.iter().map(ToString::to_string).collect();
 
diff --git a/src/tools/compiletest/src/lib.rs b/src/tools/compiletest/src/lib.rs
index ccf8057bf5c..5c06a39c477 100644
--- a/src/tools/compiletest/src/lib.rs
+++ b/src/tools/compiletest/src/lib.rs
@@ -181,7 +181,8 @@ pub fn parse_config(args: Vec<String>) -> Config {
             "compiletest-diff-tool",
             "What custom diff tool to use for displaying compiletest tests.",
             "COMMAND",
-        );
+        )
+        .reqopt("", "minicore-path", "path to minicore aux library", "PATH");
 
     let (argv0, args_) = args.split_first().unwrap();
     if args.len() == 1 || args[1] == "-h" || args[1] == "--help" {
@@ -371,7 +372,10 @@ pub fn parse_config(args: Vec<String>) -> Config {
         git_merge_commit_email: matches.opt_str("git-merge-commit-email").unwrap(),
 
         profiler_runtime: matches.opt_present("profiler-runtime"),
+
         diff_command: matches.opt_str("compiletest-diff-tool"),
+
+        minicore_path: opt_path(matches, "minicore-path"),
     }
 }
 
@@ -409,6 +413,7 @@ pub fn log_config(config: &Config) {
     logv(c, format!("host-linker: {:?}", config.host_linker));
     logv(c, format!("verbose: {}", config.verbose));
     logv(c, format!("format: {:?}", config.format));
+    logv(c, format!("minicore_path: {:?}", config.minicore_path.display()));
     logv(c, "\n".to_string());
 }
 
@@ -885,6 +890,12 @@ fn files_related_to_test(
         related.push(path);
     }
 
+    // `minicore.rs` test auxiliary: we need to make sure tests get rerun if this changes.
+    //
+    // FIXME(jieyouxu): untangle these paths, we should provide both a path to root `tests/` or
+    // `tests/auxiliary/` and the test suite in question. `src_base` is also a terrible name.
+    related.push(config.src_base.parent().unwrap().join("auxiliary").join("minicore.rs"));
+
     related
 }
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index a8a71c196fc..b337458f943 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -1150,14 +1150,20 @@ impl<'test> TestCx<'test> {
         }
     }
 
-    /// `root_testpaths` refers to the path of the original test.
-    /// the auxiliary and the test with an aux-build have the same `root_testpaths`.
+    /// `root_testpaths` refers to the path of the original test. the auxiliary and the test with an
+    /// aux-build have the same `root_testpaths`.
     fn compose_and_run_compiler(
         &self,
         mut rustc: Command,
         input: Option<String>,
         root_testpaths: &TestPaths,
     ) -> ProcRes {
+        if self.props.add_core_stubs {
+            let minicore_path = self.build_minicore();
+            rustc.arg("--extern");
+            rustc.arg(&format!("minicore={}", minicore_path.to_str().unwrap()));
+        }
+
         let aux_dir = self.aux_output_dir();
         self.build_all_auxiliary(root_testpaths, &aux_dir, &mut rustc);
 
@@ -1171,6 +1177,37 @@ impl<'test> TestCx<'test> {
         )
     }
 
+    /// Builds `minicore`. Returns the path to the minicore rlib within the base test output
+    /// directory.
+    fn build_minicore(&self) -> PathBuf {
+        let output_file_path = self.output_base_dir().join("libminicore.rlib");
+        let mut rustc = self.make_compile_args(
+            &self.config.minicore_path,
+            TargetLocation::ThisFile(output_file_path.clone()),
+            Emit::None,
+            AllowUnused::Yes,
+            LinkToAux::No,
+            vec![],
+        );
+
+        rustc.args(&["--crate-type", "rlib"]);
+        rustc.arg("-Cpanic=abort");
+
+        let res =
+            self.compose_and_run(rustc, self.config.compile_lib_path.to_str().unwrap(), None, None);
+        if !res.status.success() {
+            self.fatal_proc_rec(
+                &format!(
+                    "auxiliary build of {:?} failed to compile: ",
+                    self.config.minicore_path.display()
+                ),
+                &res,
+            );
+        }
+
+        output_file_path
+    }
+
     /// Builds an aux dependency.
     fn build_auxiliary(
         &self,
@@ -1662,6 +1699,15 @@ impl<'test> TestCx<'test> {
 
         rustc.args(&self.props.compile_flags);
 
+        // FIXME(jieyouxu): we should report a fatal error or warning if user wrote `-Cpanic=` with
+        // something that's not `abort`, however, by moving this last we should override previous
+        // `-Cpanic=`s
+        //
+        // `minicore` requires `#![no_std]` and `#![no_core]`, which means no unwinding panics.
+        if self.props.add_core_stubs {
+            rustc.arg("-Cpanic=abort");
+        }
+
         rustc
     }
 
@@ -1848,34 +1894,6 @@ impl<'test> TestCx<'test> {
         (proc_res, output_path)
     }
 
-    fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) {
-        // This works with both `--emit asm` (as default output name for the assembly)
-        // and `ptx-linker` because the latter can write output at requested location.
-        let output_path = self.output_base_name().with_extension("s");
-        let input_file = &self.testpaths.file;
-
-        // Use the `//@ assembly-output:` directive to determine how to emit assembly.
-        let emit = match self.props.assembly_output.as_deref() {
-            Some("emit-asm") => Emit::Asm,
-            Some("bpf-linker") => Emit::LinkArgsAsm,
-            Some("ptx-linker") => Emit::None, // No extra flags needed.
-            Some(other) => self.fatal(&format!("unknown 'assembly-output' directive: {other}")),
-            None => self.fatal("missing 'assembly-output' directive"),
-        };
-
-        let rustc = self.make_compile_args(
-            input_file,
-            TargetLocation::ThisFile(output_path.clone()),
-            emit,
-            AllowUnused::No,
-            LinkToAux::Yes,
-            Vec::new(),
-        );
-
-        let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths);
-        (proc_res, output_path)
-    }
-
     fn verify_with_filecheck(&self, output: &Path) -> ProcRes {
         let mut filecheck = Command::new(self.config.llvm_filecheck.as_ref().unwrap());
         filecheck.arg("--input-file").arg(output).arg(&self.testpaths.file);
diff --git a/src/tools/compiletest/src/runtest/assembly.rs b/src/tools/compiletest/src/runtest/assembly.rs
index 430a5534da1..89d7de58c20 100644
--- a/src/tools/compiletest/src/runtest/assembly.rs
+++ b/src/tools/compiletest/src/runtest/assembly.rs
@@ -1,4 +1,6 @@
-use super::TestCx;
+use std::path::PathBuf;
+
+use super::{AllowUnused, Emit, LinkToAux, ProcRes, TargetLocation, TestCx};
 
 impl TestCx<'_> {
     pub(super) fn run_assembly_test(&self) {
@@ -16,4 +18,32 @@ impl TestCx<'_> {
             self.fatal_proc_rec("verification with 'FileCheck' failed", &proc_res);
         }
     }
+
+    fn compile_test_and_save_assembly(&self) -> (ProcRes, PathBuf) {
+        // This works with both `--emit asm` (as default output name for the assembly)
+        // and `ptx-linker` because the latter can write output at requested location.
+        let output_path = self.output_base_name().with_extension("s");
+        let input_file = &self.testpaths.file;
+
+        // Use the `//@ assembly-output:` directive to determine how to emit assembly.
+        let emit = match self.props.assembly_output.as_deref() {
+            Some("emit-asm") => Emit::Asm,
+            Some("bpf-linker") => Emit::LinkArgsAsm,
+            Some("ptx-linker") => Emit::None, // No extra flags needed.
+            Some(other) => self.fatal(&format!("unknown 'assembly-output' directive: {other}")),
+            None => self.fatal("missing 'assembly-output' directive"),
+        };
+
+        let rustc = self.make_compile_args(
+            input_file,
+            TargetLocation::ThisFile(output_path.clone()),
+            emit,
+            AllowUnused::No,
+            LinkToAux::Yes,
+            Vec::new(),
+        );
+
+        let proc_res = self.compose_and_run_compiler(rustc, None, self.testpaths);
+        (proc_res, output_path)
+    }
 }
diff --git a/src/tools/miri/clippy.toml b/src/tools/miri/clippy.toml
index 284e18a45a3..504be47459c 100644
--- a/src/tools/miri/clippy.toml
+++ b/src/tools/miri/clippy.toml
@@ -1 +1 @@
-arithmetic-side-effects-allowed = ["rustc_target::abi::Size"]
+arithmetic-side-effects-allowed = ["rustc_abi::Size", "rustc_apfloat::ieee::IeeeFloat"]
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index 2ec411b54b1..3ff5b22b1ca 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-75eff9a5749411ba5a0b37cc3299116c4e263075
+00ed73cdc09a6452cb58202d56a9211fb3c73031
diff --git a/src/tools/miri/src/alloc_addresses/mod.rs b/src/tools/miri/src/alloc_addresses/mod.rs
index 50e55268248..7b377a1c4cd 100644
--- a/src/tools/miri/src/alloc_addresses/mod.rs
+++ b/src/tools/miri/src/alloc_addresses/mod.rs
@@ -7,9 +7,9 @@ use std::cell::RefCell;
 use std::cmp::max;
 
 use rand::Rng;
+use rustc_abi::{Align, Size};
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_span::Span;
-use rustc_target::abi::{Align, Size};
 
 use self::reuse_pool::ReusePool;
 use crate::concurrency::VClock;
diff --git a/src/tools/miri/src/alloc_addresses/reuse_pool.rs b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
index b5366d5ce92..b0c7ee7dff5 100644
--- a/src/tools/miri/src/alloc_addresses/reuse_pool.rs
+++ b/src/tools/miri/src/alloc_addresses/reuse_pool.rs
@@ -1,7 +1,7 @@
 //! Manages a pool of addresses that can be reused.
 
 use rand::Rng;
-use rustc_target::abi::{Align, Size};
+use rustc_abi::{Align, Size};
 
 use crate::concurrency::VClock;
 use crate::{MemoryKind, MiriConfig, ThreadId};
diff --git a/src/tools/miri/src/alloc_bytes.rs b/src/tools/miri/src/alloc_bytes.rs
index 6ada8c66fde..69ede279aa9 100644
--- a/src/tools/miri/src/alloc_bytes.rs
+++ b/src/tools/miri/src/alloc_bytes.rs
@@ -2,8 +2,8 @@ use std::alloc::Layout;
 use std::borrow::Cow;
 use std::{alloc, slice};
 
+use rustc_abi::{Align, Size};
 use rustc_middle::mir::interpret::AllocBytes;
-use rustc_target::abi::{Align, Size};
 
 /// Allocation bytes that explicitly handle the layout of the data they're storing.
 /// This is necessary to interface with native code that accesses the program store in Miri.
diff --git a/src/tools/miri/src/bin/miri.rs b/src/tools/miri/src/bin/miri.rs
index 717229ba8b3..357c50889c4 100644
--- a/src/tools/miri/src/bin/miri.rs
+++ b/src/tools/miri/src/bin/miri.rs
@@ -11,6 +11,7 @@
 extern crate tracing;
 
 // The rustc crates we need
+extern crate rustc_abi;
 extern crate rustc_data_structures;
 extern crate rustc_driver;
 extern crate rustc_hir;
@@ -21,7 +22,6 @@ extern crate rustc_metadata;
 extern crate rustc_middle;
 extern crate rustc_session;
 extern crate rustc_span;
-extern crate rustc_target;
 
 use std::env::{self, VarError};
 use std::num::NonZero;
@@ -29,6 +29,7 @@ use std::path::PathBuf;
 use std::str::FromStr;
 
 use miri::{BacktraceStyle, BorrowTrackerMethod, ProvenanceMode, RetagFields, ValidationMode};
+use rustc_abi::ExternAbi;
 use rustc_data_structures::sync::Lrc;
 use rustc_driver::Compilation;
 use rustc_hir::def_id::LOCAL_CRATE;
@@ -47,7 +48,6 @@ use rustc_session::config::{CrateType, EntryFnType, ErrorOutputType, OptLevel};
 use rustc_session::search_paths::PathKind;
 use rustc_session::{CtfeBacktrace, EarlyDiagCtxt};
 use rustc_span::def_id::DefId;
-use rustc_target::spec::abi::Abi;
 use tracing::debug;
 
 struct MiriCompilerCalls {
@@ -368,7 +368,7 @@ fn entry_fn(tcx: TyCtxt<'_>) -> (DefId, EntryFnType) {
             tcx.types.isize,
             false,
             hir::Safety::Safe,
-            Abi::Rust,
+            ExternAbi::Rust,
         ));
 
         let correct_func_sig = check_function_signature(
diff --git a/src/tools/miri/src/borrow_tracker/mod.rs b/src/tools/miri/src/borrow_tracker/mod.rs
index 5204558f98c..72319decb94 100644
--- a/src/tools/miri/src/borrow_tracker/mod.rs
+++ b/src/tools/miri/src/borrow_tracker/mod.rs
@@ -2,9 +2,9 @@ use std::cell::RefCell;
 use std::fmt;
 use std::num::NonZero;
 
+use rustc_abi::Size;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_middle::mir::RetagKind;
-use rustc_target::abi::Size;
 use smallvec::SmallVec;
 
 use crate::*;
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
index 5624c4c479e..63b18028a5b 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/diagnostics.rs
@@ -1,8 +1,8 @@
 use std::fmt;
 
+use rustc_abi::Size;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_span::{Span, SpanData};
-use rustc_target::abi::Size;
 use smallvec::SmallVec;
 
 use crate::borrow_tracker::{GlobalStateInner, ProtectorKind};
diff --git a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
index f024796c0a7..dc3370f1251 100644
--- a/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
+++ b/src/tools/miri/src/borrow_tracker/stacked_borrows/stack.rs
@@ -354,7 +354,7 @@ impl<'tcx> Stack {
         self.borrows.get(idx).cloned()
     }
 
-    #[allow(clippy::len_without_is_empty)] // Stacks are never empty
+    #[expect(clippy::len_without_is_empty)] // Stacks are never empty
     pub fn len(&self) -> usize {
         self.borrows.len()
     }
diff --git a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
index a551b017dfc..61b3338e6a2 100644
--- a/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
+++ b/src/tools/miri/src/borrow_tracker/tree_borrows/tree.rs
@@ -12,9 +12,9 @@
 
 use std::{fmt, mem};
 
+use rustc_abi::Size;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_span::Span;
-use rustc_target::abi::Size;
 use smallvec::SmallVec;
 
 use crate::borrow_tracker::tree_borrows::Permission;
diff --git a/src/tools/miri/src/concurrency/cpu_affinity.rs b/src/tools/miri/src/concurrency/cpu_affinity.rs
index 8df26d718bf..4e6bca93c5a 100644
--- a/src/tools/miri/src/concurrency/cpu_affinity.rs
+++ b/src/tools/miri/src/concurrency/cpu_affinity.rs
@@ -1,5 +1,5 @@
+use rustc_abi::Endian;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_target::abi::Endian;
 
 use crate::*;
 
diff --git a/src/tools/miri/src/concurrency/data_race.rs b/src/tools/miri/src/concurrency/data_race.rs
index 797b3191d83..f86d1eb1dcb 100644
--- a/src/tools/miri/src/concurrency/data_race.rs
+++ b/src/tools/miri/src/concurrency/data_race.rs
@@ -44,13 +44,13 @@ use std::cell::{Cell, Ref, RefCell, RefMut};
 use std::fmt::Debug;
 use std::mem;
 
+use rustc_abi::{Align, HasDataLayout, Size};
 use rustc_ast::Mutability;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir;
 use rustc_middle::ty::Ty;
 use rustc_span::Span;
-use rustc_target::abi::{Align, HasDataLayout, Size};
 
 use super::vector_clock::{VClock, VTimestamp, VectorIdx};
 use super::weak_memory::EvalContextExt as _;
diff --git a/src/tools/miri/src/concurrency/range_object_map.rs b/src/tools/miri/src/concurrency/range_object_map.rs
index d36ed36ac1a..4c9cf3dc635 100644
--- a/src/tools/miri/src/concurrency/range_object_map.rs
+++ b/src/tools/miri/src/concurrency/range_object_map.rs
@@ -4,8 +4,8 @@
 
 use std::ops::{Index, IndexMut, Range};
 
+use rustc_abi::Size;
 use rustc_const_eval::interpret::AllocRange;
-use rustc_target::abi::Size;
 
 #[derive(Clone, Debug)]
 struct Elem<T> {
diff --git a/src/tools/miri/src/concurrency/sync.rs b/src/tools/miri/src/concurrency/sync.rs
index b6668ae5e4e..78e5ad5deb2 100644
--- a/src/tools/miri/src/concurrency/sync.rs
+++ b/src/tools/miri/src/concurrency/sync.rs
@@ -3,9 +3,9 @@ use std::collections::hash_map::Entry;
 use std::ops::Not;
 use std::time::Duration;
 
+use rustc_abi::Size;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_index::{Idx, IndexVec};
-use rustc_target::abi::Size;
 
 use super::init_once::InitOnce;
 use super::vector_clock::VClock;
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 3946cb5ee54..281242bf373 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -7,6 +7,7 @@ use std::task::Poll;
 use std::time::{Duration, SystemTime};
 
 use either::Either;
+use rustc_abi::ExternAbi;
 use rustc_const_eval::CTRL_C_RECEIVED;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_hir::def_id::DefId;
@@ -14,7 +15,6 @@ use rustc_index::{Idx, IndexVec};
 use rustc_middle::mir::Mutability;
 use rustc_middle::ty::layout::TyAndLayout;
 use rustc_span::Span;
-use rustc_target::spec::abi::Abi;
 
 use crate::concurrency::data_race;
 use crate::shims::tls;
@@ -911,7 +911,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         &mut self,
         thread: Option<MPlaceTy<'tcx>>,
         start_routine: Pointer,
-        start_abi: Abi,
+        start_abi: ExternAbi,
         func_arg: ImmTy<'tcx>,
         ret_layout: TyAndLayout<'tcx>,
     ) -> InterpResult<'tcx, ThreadId> {
diff --git a/src/tools/miri/src/concurrency/weak_memory.rs b/src/tools/miri/src/concurrency/weak_memory.rs
index 800c301a821..c610f1999f7 100644
--- a/src/tools/miri/src/concurrency/weak_memory.rs
+++ b/src/tools/miri/src/concurrency/weak_memory.rs
@@ -300,7 +300,6 @@ impl<'tcx> StoreBuffer {
         interp_ok(())
     }
 
-    #[allow(clippy::if_same_then_else, clippy::needless_bool)]
     /// Selects a valid store element in the buffer.
     fn fetch_store<R: rand::Rng + ?Sized>(
         &self,
diff --git a/src/tools/miri/src/diagnostics.rs b/src/tools/miri/src/diagnostics.rs
index f055662891e..63591474120 100644
--- a/src/tools/miri/src/diagnostics.rs
+++ b/src/tools/miri/src/diagnostics.rs
@@ -1,9 +1,9 @@
 use std::fmt::{self, Write};
 use std::num::NonZero;
 
+use rustc_abi::{Align, Size};
 use rustc_errors::{Diag, DiagMessage, Level};
 use rustc_span::{DUMMY_SP, SpanData, Symbol};
-use rustc_target::abi::{Align, Size};
 
 use crate::borrow_tracker::stacked_borrows::diagnostics::TagHistory;
 use crate::borrow_tracker::tree_borrows::diagnostics as tree_diagnostics;
diff --git a/src/tools/miri/src/eval.rs b/src/tools/miri/src/eval.rs
index 9f93f151668..1e56e104918 100644
--- a/src/tools/miri/src/eval.rs
+++ b/src/tools/miri/src/eval.rs
@@ -6,13 +6,13 @@ use std::path::PathBuf;
 use std::task::Poll;
 use std::{iter, thread};
 
+use rustc_abi::ExternAbi;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::layout::{LayoutCx, LayoutOf};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_session::config::EntryFnType;
-use rustc_target::spec::abi::Abi;
 
 use crate::concurrency::thread::TlsAllocAction;
 use crate::diagnostics::report_leaks;
@@ -391,7 +391,7 @@ pub fn create_ecx<'tcx>(
 
             ecx.call_function(
                 start_instance,
-                Abi::Rust,
+                ExternAbi::Rust,
                 &[
                     ImmTy::from_scalar(
                         Scalar::from_pointer(main_ptr, &ecx),
@@ -409,7 +409,7 @@ pub fn create_ecx<'tcx>(
         EntryFnType::Start => {
             ecx.call_function(
                 entry_instance,
-                Abi::Rust,
+                ExternAbi::Rust,
                 &[argc, argv],
                 Some(&ret_place),
                 StackPopCleanup::Root { cleanup: true },
@@ -423,7 +423,7 @@ pub fn create_ecx<'tcx>(
 /// Evaluates the entry function specified by `entry_id`.
 /// Returns `Some(return_code)` if program executed completed.
 /// Returns `None` if an evaluation error occurred.
-#[allow(clippy::needless_lifetimes)]
+#[expect(clippy::needless_lifetimes)]
 pub fn eval_entry<'tcx>(
     tcx: TyCtxt<'tcx>,
     entry_id: DefId,
diff --git a/src/tools/miri/src/helpers.rs b/src/tools/miri/src/helpers.rs
index 17f664da853..526030bef2e 100644
--- a/src/tools/miri/src/helpers.rs
+++ b/src/tools/miri/src/helpers.rs
@@ -5,6 +5,7 @@ use std::time::Duration;
 use std::{cmp, iter};
 
 use rand::RngCore;
+use rustc_abi::{Align, ExternAbi, FieldIdx, FieldsShape, Size, Variants};
 use rustc_apfloat::Float;
 use rustc_apfloat::ieee::{Double, Half, Quad, Single};
 use rustc_hir::Safety;
@@ -18,8 +19,6 @@ use rustc_middle::ty::layout::{FnAbiOf, LayoutOf, MaybeResult, TyAndLayout};
 use rustc_middle::ty::{self, FloatTy, IntTy, Ty, TyCtxt, UintTy};
 use rustc_session::config::CrateType;
 use rustc_span::{Span, Symbol};
-use rustc_target::abi::{Align, FieldIdx, FieldsShape, Size, Variants};
-use rustc_target::spec::abi::Abi;
 
 use crate::*;
 
@@ -157,7 +156,7 @@ pub fn iter_exported_symbols<'tcx>(
     for cnum in dependency_format.1.iter().enumerate().filter_map(|(num, &linkage)| {
         // We add 1 to the number because that's what rustc also does everywhere it
         // calls `CrateNum::new`...
-        #[allow(clippy::arithmetic_side_effects)]
+        #[expect(clippy::arithmetic_side_effects)]
         (linkage != Linkage::NotLinked).then_some(CrateNum::new(num + 1))
     }) {
         // We can ignore `_export_info` here: we are a Rust crate, and everything is exported
@@ -435,7 +434,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn call_function(
         &mut self,
         f: ty::Instance<'tcx>,
-        caller_abi: Abi,
+        caller_abi: ExternAbi,
         args: &[ImmTy<'tcx>],
         dest: Option<&MPlaceTy<'tcx>>,
         stack_pop: StackPopCleanup,
@@ -917,7 +916,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     }
 
     /// Check that the ABI is what we expect.
-    fn check_abi<'a>(&self, abi: Abi, exp_abi: Abi) -> InterpResult<'a, ()> {
+    fn check_abi<'a>(&self, abi: ExternAbi, exp_abi: ExternAbi) -> InterpResult<'a, ()> {
         if abi != exp_abi {
             throw_ub_format!(
                 "calling a function with ABI {} using caller ABI {}",
@@ -953,8 +952,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
     fn check_abi_and_shim_symbol_clash(
         &mut self,
-        abi: Abi,
-        exp_abi: Abi,
+        abi: ExternAbi,
+        exp_abi: ExternAbi,
         link_name: Symbol,
     ) -> InterpResult<'tcx, ()> {
         self.check_abi(abi, exp_abi)?;
@@ -978,8 +977,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
     fn check_shim<'a, const N: usize>(
         &mut self,
-        abi: Abi,
-        exp_abi: Abi,
+        abi: ExternAbi,
+        exp_abi: ExternAbi,
         link_name: Symbol,
         args: &'a [OpTy<'tcx>],
     ) -> InterpResult<'tcx, &'a [OpTy<'tcx>; N]>
diff --git a/src/tools/miri/src/intrinsics/mod.rs b/src/tools/miri/src/intrinsics/mod.rs
index 776d2561b43..272dca1594e 100644
--- a/src/tools/miri/src/intrinsics/mod.rs
+++ b/src/tools/miri/src/intrinsics/mod.rs
@@ -4,11 +4,11 @@ mod atomic;
 mod simd;
 
 use rand::Rng;
+use rustc_abi::Size;
 use rustc_apfloat::{Float, Round};
 use rustc_middle::mir;
 use rustc_middle::ty::{self, FloatTy};
 use rustc_span::{Symbol, sym};
-use rustc_target::abi::Size;
 
 use self::atomic::EvalContextExt as _;
 use self::helpers::{ToHost, ToSoft, check_arg_count};
@@ -292,7 +292,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let b = this.read_scalar(b)?.to_f32()?;
                 let c = this.read_scalar(c)?.to_f32()?;
                 let fuse: bool = this.machine.rng.get_mut().gen();
-                #[allow(clippy::arithmetic_side_effects)] // float ops don't overflow
                 let res = if fuse {
                     // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11
                     a.to_host().mul_add(b.to_host(), c.to_host()).to_soft()
@@ -308,7 +307,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let b = this.read_scalar(b)?.to_f64()?;
                 let c = this.read_scalar(c)?.to_f64()?;
                 let fuse: bool = this.machine.rng.get_mut().gen();
-                #[allow(clippy::arithmetic_side_effects)] // float ops don't overflow
                 let res = if fuse {
                     // FIXME: Using host floats, to work around https://github.com/rust-lang/rustc_apfloat/issues/11
                     a.to_host().mul_add(b.to_host(), c.to_host()).to_soft()
diff --git a/src/tools/miri/src/intrinsics/simd.rs b/src/tools/miri/src/intrinsics/simd.rs
index f15b83a054f..d5c417e7231 100644
--- a/src/tools/miri/src/intrinsics/simd.rs
+++ b/src/tools/miri/src/intrinsics/simd.rs
@@ -1,10 +1,10 @@
 use either::Either;
+use rustc_abi::{Endian, HasDataLayout};
 use rustc_apfloat::{Float, Round};
 use rustc_middle::ty::FloatTy;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::{mir, ty};
 use rustc_span::{Symbol, sym};
-use rustc_target::abi::{Endian, HasDataLayout};
 
 use crate::helpers::{ToHost, ToSoft, bool_to_simd_element, check_arg_count, simd_element_to_bool};
 use crate::*;
@@ -750,7 +750,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
                     let val = if simd_element_to_bool(mask)? {
                         // Size * u64 is implemented as always checked
-                        #[allow(clippy::arithmetic_side_effects)]
                         let ptr = ptr.wrapping_offset(dest.layout.size * i, this);
                         let place = this.ptr_to_mplace(ptr, dest.layout);
                         this.read_immediate(&place)?
@@ -774,7 +773,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
                     if simd_element_to_bool(mask)? {
                         // Size * u64 is implemented as always checked
-                        #[allow(clippy::arithmetic_side_effects)]
                         let ptr = ptr.wrapping_offset(val.layout.size * i, this);
                         let place = this.ptr_to_mplace(ptr, val.layout);
                         this.write_immediate(*val, &place)?
@@ -831,7 +829,7 @@ fn simd_bitmask_index(idx: u32, vec_len: u32, endianness: Endian) -> u32 {
     assert!(idx < vec_len);
     match endianness {
         Endian::Little => idx,
-        #[allow(clippy::arithmetic_side_effects)] // idx < vec_len
+        #[expect(clippy::arithmetic_side_effects)] // idx < vec_len
         Endian::Big => vec_len - 1 - idx, // reverse order of bits
     }
 }
diff --git a/src/tools/miri/src/machine.rs b/src/tools/miri/src/machine.rs
index 60d096b92f2..cc24094b17e 100644
--- a/src/tools/miri/src/machine.rs
+++ b/src/tools/miri/src/machine.rs
@@ -10,6 +10,7 @@ use std::{fmt, process};
 
 use rand::rngs::StdRng;
 use rand::{Rng, SeedableRng};
+use rustc_abi::{Align, ExternAbi, Size};
 use rustc_attr::InlineAttr;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 #[allow(unused)]
@@ -21,8 +22,6 @@ use rustc_middle::ty::{self, Instance, Ty, TyCtxt};
 use rustc_session::config::InliningThreshold;
 use rustc_span::def_id::{CrateNum, DefId};
 use rustc_span::{Span, SpanData, Symbol};
-use rustc_target::abi::{Align, Size};
-use rustc_target::spec::abi::Abi;
 
 use crate::concurrency::cpu_affinity::{self, CpuAffinityMask};
 use crate::concurrency::data_race::{self, NaReadType, NaWriteType};
@@ -1006,7 +1005,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     fn find_mir_or_eval_fn(
         ecx: &mut MiriInterpCx<'tcx>,
         instance: ty::Instance<'tcx>,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[FnArg<'tcx, Provenance>],
         dest: &MPlaceTy<'tcx>,
         ret: Option<mir::BasicBlock>,
@@ -1033,7 +1032,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
     fn call_extra_fn(
         ecx: &mut MiriInterpCx<'tcx>,
         fn_val: DynSym,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[FnArg<'tcx, Provenance>],
         dest: &MPlaceTy<'tcx>,
         ret: Option<mir::BasicBlock>,
@@ -1075,7 +1074,7 @@ impl<'tcx> Machine<'tcx> for MiriMachine<'tcx> {
         // Call the lang item.
         let panic = ecx.tcx.lang_items().get(reason.lang_item()).unwrap();
         let panic = ty::Instance::mono(ecx.tcx.tcx, panic);
-        ecx.call_function(panic, Abi::Rust, &[], None, StackPopCleanup::Goto {
+        ecx.call_function(panic, ExternAbi::Rust, &[], None, StackPopCleanup::Goto {
             ret: None,
             unwind: mir::UnwindAction::Unreachable,
         })?;
diff --git a/src/tools/miri/src/operator.rs b/src/tools/miri/src/operator.rs
index 608e23fc110..0017a3991b5 100644
--- a/src/tools/miri/src/operator.rs
+++ b/src/tools/miri/src/operator.rs
@@ -2,9 +2,9 @@ use std::iter;
 
 use rand::Rng;
 use rand::seq::IteratorRandom;
+use rustc_abi::Size;
 use rustc_apfloat::{Float, FloatConvert};
 use rustc_middle::mir;
-use rustc_target::abi::Size;
 
 use crate::*;
 
diff --git a/src/tools/miri/src/range_map.rs b/src/tools/miri/src/range_map.rs
index 4a3670b76ac..2c2484cd0bc 100644
--- a/src/tools/miri/src/range_map.rs
+++ b/src/tools/miri/src/range_map.rs
@@ -7,7 +7,7 @@
 
 use std::ops;
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 #[derive(Clone, Debug)]
 struct Elem<T> {
diff --git a/src/tools/miri/src/shims/alloc.rs b/src/tools/miri/src/shims/alloc.rs
index e73344367ec..25c0b52d061 100644
--- a/src/tools/miri/src/shims/alloc.rs
+++ b/src/tools/miri/src/shims/alloc.rs
@@ -1,7 +1,7 @@
 use std::iter;
 
+use rustc_abi::{Align, Size};
 use rustc_ast::expand::allocator::AllocatorKind;
-use rustc_target::abi::{Align, Size};
 
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/backtrace.rs b/src/tools/miri/src/shims/backtrace.rs
index ae2cdaa8d57..64bd546458d 100644
--- a/src/tools/miri/src/shims/backtrace.rs
+++ b/src/tools/miri/src/shims/backtrace.rs
@@ -1,9 +1,8 @@
+use rustc_abi::{ExternAbi, Size};
 use rustc_ast::ast::Mutability;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::ty::{self, Instance, Ty};
 use rustc_span::{BytePos, Loc, Symbol, hygiene};
-use rustc_target::abi::Size;
-use rustc_target::spec::abi::Abi;
 
 use crate::helpers::check_min_arg_count;
 use crate::*;
@@ -12,13 +11,13 @@ impl<'tcx> EvalContextExt<'tcx> for crate::MiriInterpCx<'tcx> {}
 pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn handle_miri_backtrace_size(
         &mut self,
-        abi: Abi,
+        abi: ExternAbi,
         link_name: Symbol,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
-        let [flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+        let [flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
 
         let flags = this.read_scalar(flags)?.to_u64()?;
         if flags != 0 {
@@ -32,7 +31,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
     fn handle_miri_get_backtrace(
         &mut self,
-        abi: Abi,
+        abi: ExternAbi,
         link_name: Symbol,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
@@ -73,7 +72,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // storage for pointers is allocated by miri
             // deallocating the slice is undefined behavior with a custom global allocator
             0 => {
-                let [_flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [_flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
 
                 let alloc = this.allocate(array_layout, MiriMemoryKind::Rust.into())?;
 
@@ -88,7 +87,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             // storage for pointers is allocated by the caller
             1 => {
-                let [_flags, buf] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [_flags, buf] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
 
                 let buf_place = this.deref_pointer(buf)?;
 
@@ -138,13 +137,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
     fn handle_miri_resolve_frame(
         &mut self,
-        abi: Abi,
+        abi: ExternAbi,
         link_name: Symbol,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
-        let [ptr, flags] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+        let [ptr, flags] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
 
         let flags = this.read_scalar(flags)?.to_u64()?;
 
@@ -216,14 +215,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
     fn handle_miri_resolve_frame_names(
         &mut self,
-        abi: Abi,
+        abi: ExternAbi,
         link_name: Symbol,
         args: &[OpTy<'tcx>],
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
         let [ptr, flags, name_ptr, filename_ptr] =
-            this.check_shim(abi, Abi::Rust, link_name, args)?;
+            this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
 
         let flags = this.read_scalar(flags)?.to_u64()?;
         if flags != 0 {
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 12f8facfd02..8f7c56a2907 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -3,6 +3,7 @@ use std::io::Write;
 use std::iter;
 use std::path::Path;
 
+use rustc_abi::{Align, AlignFromBytesError, ExternAbi, Size};
 use rustc_apfloat::Float;
 use rustc_ast::expand::allocator::alloc_error_handler_name;
 use rustc_hir::def::DefKind;
@@ -10,8 +11,6 @@ use rustc_hir::def_id::CrateNum;
 use rustc_middle::middle::codegen_fn_attrs::CodegenFnAttrFlags;
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
-use rustc_target::abi::{Align, AlignFromBytesError, Size};
-use rustc_target::spec::abi::Abi;
 
 use self::helpers::{ToHost, ToSoft};
 use super::alloc::EvalContextExt as _;
@@ -22,7 +21,7 @@ use crate::*;
 #[derive(Debug, Copy, Clone)]
 pub struct DynSym(Symbol);
 
-#[allow(clippy::should_implement_trait)]
+#[expect(clippy::should_implement_trait)]
 impl DynSym {
     pub fn from_str(name: &str) -> Self {
         DynSym(Symbol::intern(name))
@@ -40,7 +39,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
         ret: Option<mir::BasicBlock>,
@@ -107,7 +106,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_dyn_sym(
         &mut self,
         sym: DynSym,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
         ret: Option<mir::BasicBlock>,
@@ -219,7 +218,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -240,7 +239,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // When adding a new shim, you should follow the following pattern:
         // ```
         // "shim_name" => {
-        //     let [arg1, arg2, arg3] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+        //     let [arg1, arg2, arg3] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
         //     let result = this.shim_name(arg1, arg2, arg3)?;
         //     this.write_scalar(result, dest)?;
         // }
@@ -278,16 +277,16 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
         match link_name.as_str() {
             // Miri-specific extern functions
             "miri_start_unwind" => {
-                let [payload] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [payload] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 this.handle_miri_start_unwind(payload)?;
                 return interp_ok(EmulateItemResult::NeedsUnwind);
             }
             "miri_run_provenance_gc" => {
-                let [] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 this.run_provenance_gc();
             }
             "miri_get_alloc_id" => {
-                let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let (alloc_id, _, _) = this.ptr_get_alloc_id(ptr, 0).map_err_kind(|_e| {
                     err_machine_stop!(TerminationInfo::Abort(format!(
@@ -297,7 +296,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(Scalar::from_u64(alloc_id.0.get()), dest)?;
             }
             "miri_print_borrow_state" => {
-                let [id, show_unnamed] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [id, show_unnamed] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 let id = this.read_scalar(id)?.to_u64()?;
                 let show_unnamed = this.read_scalar(show_unnamed)?.to_bool()?;
                 if let Some(id) = std::num::NonZero::new(id).map(AllocId)
@@ -311,7 +310,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "miri_pointer_name" => {
                 // This associates a name to a tag. Very useful for debugging, and also makes
                 // tests more strict.
-                let [ptr, nth_parent, name] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [ptr, nth_parent, name] =
+                    this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let nth_parent = this.read_scalar(nth_parent)?.to_u8()?;
                 let name = this.read_immediate(name)?;
@@ -324,7 +324,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.give_pointer_debug_name(ptr, nth_parent, &name)?;
             }
             "miri_static_root" => {
-                let [ptr] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [ptr] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let (alloc_id, offset, _) = this.ptr_get_alloc_id(ptr, 0)?;
                 if offset != Size::ZERO {
@@ -335,7 +335,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.machine.static_roots.push(alloc_id);
             }
             "miri_host_to_target_path" => {
-                let [ptr, out, out_size] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [ptr, out, out_size] =
+                    this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let out = this.read_pointer(out)?;
                 let out_size = this.read_scalar(out_size)?.to_target_usize(this)?;
@@ -371,7 +372,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Writes some bytes to the interpreter's stdout/stderr. See the
             // README for details.
             "miri_write_to_stdout" | "miri_write_to_stderr" => {
-                let [msg] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [msg] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 let msg = this.read_immediate(msg)?;
                 let msg = this.read_byte_slice(&msg)?;
                 // Note: we're ignoring errors writing to host stdout/stderr.
@@ -383,9 +384,9 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             // Promises that a pointer has a given symbolic alignment.
             "miri_promise_symbolic_alignment" => {
-                use rustc_target::abi::AlignFromBytesError;
+                use rustc_abi::AlignFromBytesError;
 
-                let [ptr, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                let [ptr, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let align = this.read_target_usize(align)?;
                 if !align.is_power_of_two() {
@@ -426,12 +427,13 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Aborting the process.
             "exit" => {
-                let [code] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [code] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let code = this.read_scalar(code)?.to_i32()?;
                 throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false });
             }
             "abort" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 throw_machine_stop!(TerminationInfo::Abort(
                     "the program aborted execution".to_owned()
                 ))
@@ -439,7 +441,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Standard C allocation
             "malloc" => {
-                let [size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [size] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let size = this.read_target_usize(size)?;
                 if size <= this.max_size_of_val().bytes() {
                     let res = this.malloc(size, /*zero_init:*/ false)?;
@@ -454,7 +457,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "calloc" => {
                 let [items, elem_size] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let items = this.read_target_usize(items)?;
                 let elem_size = this.read_target_usize(elem_size)?;
                 if let Some(size) = this.compute_size_in_bytes(Size::from_bytes(elem_size), items) {
@@ -469,13 +472,14 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
             }
             "free" => {
-                let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [ptr] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 this.free(ptr)?;
             }
             "realloc" => {
                 let [old_ptr, new_size] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let old_ptr = this.read_pointer(old_ptr)?;
                 let new_size = this.read_target_usize(new_size)?;
                 if new_size <= this.max_size_of_val().bytes() {
@@ -495,7 +499,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let default = |this: &mut MiriInterpCx<'tcx>| {
                     // Only call `check_shim` when `#[global_allocator]` isn't used. When that
                     // macro is used, we act like no shim exists, so that the exported function can run.
-                    let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                    let [size, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                     let size = this.read_target_usize(size)?;
                     let align = this.read_target_usize(align)?;
 
@@ -529,7 +533,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 return this.emulate_allocator(|this| {
                     // See the comment for `__rust_alloc` why `check_shim` is only called in the
                     // default case.
-                    let [size, align] = this.check_shim(abi, Abi::Rust, link_name, args)?;
+                    let [size, align] = this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                     let size = this.read_target_usize(size)?;
                     let align = this.read_target_usize(align)?;
 
@@ -555,7 +559,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     // See the comment for `__rust_alloc` why `check_shim` is only called in the
                     // default case.
                     let [ptr, old_size, align] =
-                        this.check_shim(abi, Abi::Rust, link_name, args)?;
+                        this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                     let ptr = this.read_pointer(ptr)?;
                     let old_size = this.read_target_usize(old_size)?;
                     let align = this.read_target_usize(align)?;
@@ -590,7 +594,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     // See the comment for `__rust_alloc` why `check_shim` is only called in the
                     // default case.
                     let [ptr, old_size, align, new_size] =
-                        this.check_shim(abi, Abi::Rust, link_name, args)?;
+                        this.check_shim(abi, ExternAbi::Rust, link_name, args)?;
                     let ptr = this.read_pointer(ptr)?;
                     let old_size = this.read_target_usize(old_size)?;
                     let align = this.read_target_usize(align)?;
@@ -614,7 +618,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // C memory handling functions
             "memcmp" => {
                 let [left, right, n] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let left = this.read_pointer(left)?;
                 let right = this.read_pointer(right)?;
                 let n = Size::from_bytes(this.read_target_usize(n)?);
@@ -639,12 +643,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "memrchr" => {
                 let [ptr, val, num] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let val = this.read_scalar(val)?.to_i32()?;
                 let num = this.read_target_usize(num)?;
                 // The docs say val is "interpreted as unsigned char".
-                #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
+                #[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
                 let val = val as u8;
 
                 // C requires that this must always be a valid pointer (C18 §7.1.4).
@@ -657,7 +661,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     .position(|&c| c == val)
                 {
                     let idx = u64::try_from(idx).unwrap();
-                    #[allow(clippy::arithmetic_side_effects)] // idx < num, so this never wraps
+                    #[expect(clippy::arithmetic_side_effects)] // idx < num, so this never wraps
                     let new_ptr = ptr.wrapping_offset(Size::from_bytes(num - idx - 1), this);
                     this.write_pointer(new_ptr, dest)?;
                 } else {
@@ -666,12 +670,12 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "memchr" => {
                 let [ptr, val, num] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let val = this.read_scalar(val)?.to_i32()?;
                 let num = this.read_target_usize(num)?;
                 // The docs say val is "interpreted as unsigned char".
-                #[allow(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
+                #[expect(clippy::cast_sign_loss, clippy::cast_possible_truncation)]
                 let val = val as u8;
 
                 // C requires that this must always be a valid pointer (C18 §7.1.4).
@@ -689,7 +693,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
             }
             "strlen" => {
-                let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [ptr] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 // This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
                 let n = this.read_c_str(ptr)?.len();
@@ -699,7 +704,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 )?;
             }
             "wcslen" => {
-                let [ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [ptr] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 // This reads at least 1 byte, so we are already enforcing that this is a valid pointer.
                 let n = this.read_wchar_t_str(ptr)?.len();
@@ -710,7 +716,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "memcpy" => {
                 let [ptr_dest, ptr_src, n] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr_dest = this.read_pointer(ptr_dest)?;
                 let ptr_src = this.read_pointer(ptr_src)?;
                 let n = this.read_target_usize(n)?;
@@ -725,7 +731,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "strcpy" => {
                 let [ptr_dest, ptr_src] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr_dest = this.read_pointer(ptr_dest)?;
                 let ptr_src = this.read_pointer(ptr_src)?;
 
@@ -754,7 +760,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "expm1f"
             | "tgammaf"
             => {
-                let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let f = this.read_scalar(f)?.to_f32()?;
                 // Using host floats (but it's fine, these operations do not have guaranteed precision).
                 let f_host = f.to_host();
@@ -782,7 +788,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "atan2f"
             | "fdimf"
             => {
-                let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let f1 = this.read_scalar(f1)?.to_f32()?;
                 let f2 = this.read_scalar(f2)?.to_f32()?;
                 // underscore case for windows, here and below
@@ -811,7 +817,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "expm1"
             | "tgamma"
             => {
-                let [f] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [f] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let f = this.read_scalar(f)?.to_f64()?;
                 // Using host floats (but it's fine, these operations do not have guaranteed precision).
                 let f_host = f.to_host();
@@ -839,7 +845,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "atan2"
             | "fdim"
             => {
-                let [f1, f2] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [f1, f2] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let f1 = this.read_scalar(f1)?.to_f64()?;
                 let f2 = this.read_scalar(f2)?.to_f64()?;
                 // underscore case for windows, here and below
@@ -860,7 +866,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "ldexp"
             | "scalbn"
             => {
-                let [x, exp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [x, exp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // For radix-2 (binary) systems, `ldexp` and `scalbn` are the same.
                 let x = this.read_scalar(x)?.to_f64()?;
                 let exp = this.read_scalar(exp)?.to_i32()?;
@@ -870,7 +876,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(res, dest)?;
             }
             "lgammaf_r" => {
-                let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [x, signp] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let x = this.read_scalar(x)?.to_f32()?;
                 let signp = this.deref_pointer(signp)?;
 
@@ -881,7 +888,8 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(res, dest)?;
             }
             "lgamma_r" => {
-                let [x, signp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [x, signp] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let x = this.read_scalar(x)?.to_f64()?;
                 let signp = this.deref_pointer(signp)?;
 
@@ -895,7 +903,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // LLVM intrinsics
             "llvm.prefetch" => {
                 let [p, rw, loc, ty] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let _ = this.read_pointer(p)?;
                 let rw = this.read_scalar(rw)?.to_i32()?;
@@ -922,7 +930,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Used to implement the x86 `_mm{,256,512}_popcnt_epi{8,16,32,64}` and wasm
             // `{i,u}8x16_popcnt` functions.
             name if name.starts_with("llvm.ctpop.v") => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (op, op_len) = this.project_to_simd(op)?;
                 let (dest, dest_len) = this.project_to_simd(dest)?;
@@ -953,7 +961,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             // FIXME: Move these to an `arm` submodule.
             "llvm.aarch64.isb" if this.tcx.sess.target.arch == "aarch64" => {
-                let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
+                let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?;
                 let arg = this.read_scalar(arg)?.to_i32()?;
                 match arg {
                     // SY ("full system scope")
@@ -966,7 +974,7 @@ trait EvalContextExtPriv<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
             }
             "llvm.arm.hint" if this.tcx.sess.target.arch == "arm" => {
-                let [arg] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
+                let [arg] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?;
                 let arg = this.read_scalar(arg)?.to_i32()?;
                 // Note that different arguments might have different target feature requirements.
                 match arg {
diff --git a/src/tools/miri/src/shims/io_error.rs b/src/tools/miri/src/shims/io_error.rs
index a50bba0d2e4..0cbb4850b7f 100644
--- a/src/tools/miri/src/shims/io_error.rs
+++ b/src/tools/miri/src/shims/io_error.rs
@@ -188,7 +188,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     }
 
     /// The inverse of `io_error_to_errnum`.
-    #[allow(clippy::needless_return)]
+    #[expect(clippy::needless_return)]
     fn try_errnum_to_io_error(
         &self,
         errnum: Scalar,
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 9bb0d7d0ce6..722c3a2f0c5 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -11,10 +11,10 @@
 //!   gets popped *during unwinding*, we take the panic payload and store it according to the extra
 //!   metadata we remembered when pushing said frame.
 
+use rustc_abi::ExternAbi;
 use rustc_ast::Mutability;
 use rustc_middle::{mir, ty};
 use rustc_target::spec::PanicStrategy;
-use rustc_target::spec::abi::Abi;
 
 use self::helpers::check_arg_count;
 use crate::*;
@@ -88,7 +88,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         trace!("try_fn: {:?}", f_instance);
         this.call_function(
             f_instance,
-            Abi::Rust,
+            ExternAbi::Rust,
             &[data.clone()],
             None,
             // Directly return to caller.
@@ -139,7 +139,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             trace!("catch_fn: {:?}", f_instance);
             this.call_function(
                 f_instance,
-                Abi::Rust,
+                ExternAbi::Rust,
                 &[catch_unwind.data, payload],
                 None,
                 // Directly return to caller of `try`.
@@ -168,7 +168,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let panic = ty::Instance::mono(this.tcx.tcx, panic);
         this.call_function(
             panic,
-            Abi::Rust,
+            ExternAbi::Rust,
             &[this.mplace_to_ref(&msg)?],
             None,
             StackPopCleanup::Goto { ret: None, unwind },
@@ -187,7 +187,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let panic = ty::Instance::mono(this.tcx.tcx, panic);
         this.call_function(
             panic,
-            Abi::Rust,
+            ExternAbi::Rust,
             &[this.mplace_to_ref(&msg)?],
             None,
             StackPopCleanup::Goto { ret: None, unwind: mir::UnwindAction::Unreachable },
@@ -216,7 +216,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 let panic_bounds_check = ty::Instance::mono(this.tcx.tcx, panic_bounds_check);
                 this.call_function(
                     panic_bounds_check,
-                    Abi::Rust,
+                    ExternAbi::Rust,
                     &[index, len],
                     None,
                     StackPopCleanup::Goto { ret: None, unwind },
@@ -237,7 +237,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     ty::Instance::mono(this.tcx.tcx, panic_misaligned_pointer_dereference);
                 this.call_function(
                     panic_misaligned_pointer_dereference,
-                    Abi::Rust,
+                    ExternAbi::Rust,
                     &[required, found],
                     None,
                     StackPopCleanup::Goto { ret: None, unwind },
@@ -248,7 +248,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // Call the lang item associated with this message.
                 let fn_item = this.tcx.require_lang_item(msg.panic_function(), None);
                 let instance = ty::Instance::mono(this.tcx.tcx, fn_item);
-                this.call_function(instance, Abi::Rust, &[], None, StackPopCleanup::Goto {
+                this.call_function(instance, ExternAbi::Rust, &[], None, StackPopCleanup::Goto {
                     ret: None,
                     unwind,
                 })?;
diff --git a/src/tools/miri/src/shims/tls.rs b/src/tools/miri/src/shims/tls.rs
index 94b2d1bc782..46a417689a2 100644
--- a/src/tools/miri/src/shims/tls.rs
+++ b/src/tools/miri/src/shims/tls.rs
@@ -4,9 +4,8 @@ use std::collections::BTreeMap;
 use std::collections::btree_map::Entry as BTreeEntry;
 use std::task::Poll;
 
+use rustc_abi::{ExternAbi, HasDataLayout, Size};
 use rustc_middle::ty;
-use rustc_target::abi::{HasDataLayout, Size};
-use rustc_target::spec::abi::Abi;
 
 use crate::*;
 
@@ -54,7 +53,7 @@ impl<'tcx> Default for TlsData<'tcx> {
 impl<'tcx> TlsData<'tcx> {
     /// Generate a new TLS key with the given destructor.
     /// `max_size` determines the integer size the key has to fit in.
-    #[allow(clippy::arithmetic_side_effects)]
+    #[expect(clippy::arithmetic_side_effects)]
     pub fn create_tls_key(
         &mut self,
         dtor: Option<ty::Instance<'tcx>>,
@@ -323,7 +322,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         // but both are ignored by std.
         this.call_function(
             thread_callback,
-            Abi::System { unwind: false },
+            ExternAbi::System { unwind: false },
             &[null_ptr.clone(), ImmTy::from_scalar(reason, this.machine.layouts.u32), null_ptr],
             None,
             StackPopCleanup::Root { cleanup: true },
@@ -344,7 +343,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             this.call_function(
                 instance,
-                Abi::C { unwind: false },
+                ExternAbi::C { unwind: false },
                 &[ImmTy::from_scalar(data, this.machine.layouts.mut_raw_ptr)],
                 None,
                 StackPopCleanup::Root { cleanup: true },
@@ -381,7 +380,7 @@ trait EvalContextPrivExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             this.call_function(
                 instance,
-                Abi::C { unwind: false },
+                ExternAbi::C { unwind: false },
                 &[ImmTy::from_scalar(ptr, this.machine.layouts.mut_raw_ptr)],
                 None,
                 StackPopCleanup::Root { cleanup: true },
diff --git a/src/tools/miri/src/shims/unix/android/foreign_items.rs b/src/tools/miri/src/shims/unix/android/foreign_items.rs
index 2e10e82d936..80ad40e1624 100644
--- a/src/tools/miri/src/shims/unix/android/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/android/foreign_items.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::shims::unix::android::thread::prctl;
 use crate::shims::unix::linux::syscall::syscall;
@@ -14,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         match link_name.as_str() {
             // Miscellaneous
             "__errno" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let errno_place = this.last_error_place()?;
                 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
             }
diff --git a/src/tools/miri/src/shims/unix/android/thread.rs b/src/tools/miri/src/shims/unix/android/thread.rs
index 6f5f0f74a22..1da13d48252 100644
--- a/src/tools/miri/src/shims/unix/android/thread.rs
+++ b/src/tools/miri/src/shims/unix/android/thread.rs
@@ -1,6 +1,5 @@
+use rustc_abi::{ExternAbi, Size};
 use rustc_span::Symbol;
-use rustc_target::abi::Size;
-use rustc_target::spec::abi::Abi;
 
 use crate::helpers::check_min_arg_count;
 use crate::shims::unix::thread::EvalContextExt as _;
@@ -11,13 +10,13 @@ const TASK_COMM_LEN: usize = 16;
 pub fn prctl<'tcx>(
     this: &mut MiriInterpCx<'tcx>,
     link_name: Symbol,
-    abi: Abi,
+    abi: ExternAbi,
     args: &[OpTy<'tcx>],
     dest: &MPlaceTy<'tcx>,
 ) -> InterpResult<'tcx> {
     // We do not use `check_shim` here because `prctl` is variadic. The argument
     // count is checked bellow.
-    this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
+    this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?;
 
     // FIXME: Use constants once https://github.com/rust-lang/libc/pull/3941 backported to the 0.2 branch.
     let pr_set_name = 15;
diff --git a/src/tools/miri/src/shims/unix/env.rs b/src/tools/miri/src/shims/unix/env.rs
index 96c5a9fad9b..aebb5757aec 100644
--- a/src/tools/miri/src/shims/unix/env.rs
+++ b/src/tools/miri/src/shims/unix/env.rs
@@ -2,10 +2,10 @@ use std::ffi::{OsStr, OsString};
 use std::io::ErrorKind;
 use std::{env, mem};
 
+use rustc_abi::Size;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_target::abi::Size;
 
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/unix/fd.rs b/src/tools/miri/src/shims/unix/fd.rs
index f3db56695fc..27bdd508f77 100644
--- a/src/tools/miri/src/shims/unix/fd.rs
+++ b/src/tools/miri/src/shims/unix/fd.rs
@@ -7,7 +7,7 @@ use std::io::{self, ErrorKind, IsTerminal, Read, SeekFrom, Write};
 use std::ops::Deref;
 use std::rc::{Rc, Weak};
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 use crate::helpers::check_min_arg_count;
 use crate::shims::unix::linux::epoll::EpollReadyEvents;
diff --git a/src/tools/miri/src/shims/unix/foreign_items.rs b/src/tools/miri/src/shims/unix/foreign_items.rs
index 355c93c444c..d59d6712c4f 100644
--- a/src/tools/miri/src/shims/unix/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/foreign_items.rs
@@ -1,10 +1,9 @@
 use std::ffi::OsStr;
 use std::str;
 
+use rustc_abi::{ExternAbi, Size};
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_span::Symbol;
-use rustc_target::abi::Size;
-use rustc_target::spec::abi::Abi;
 
 use self::shims::unix::android::foreign_items as android;
 use self::shims::unix::freebsd::foreign_items as freebsd;
@@ -43,7 +42,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -54,47 +53,47 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         match link_name.as_str() {
             // Environment related shims
             "getenv" => {
-                let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.getenv(name)?;
                 this.write_pointer(result, dest)?;
             }
             "unsetenv" => {
-                let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.unsetenv(name)?;
                 this.write_scalar(result, dest)?;
             }
             "setenv" => {
-                let [name, value, overwrite] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [name, value, overwrite] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.read_scalar(overwrite)?.to_i32()?;
                 let result = this.setenv(name, value)?;
                 this.write_scalar(result, dest)?;
             }
             "getcwd" => {
-                let [buf, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [buf, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.getcwd(buf, size)?;
                 this.write_pointer(result, dest)?;
             }
             "chdir" => {
-                let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.chdir(path)?;
                 this.write_scalar(result, dest)?;
             }
             "getpid" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false}, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?;
                 let result = this.getpid()?;
                 this.write_scalar(result, dest)?;
             }
 
             // File descriptors
             "read" => {
-                let [fd, buf, count] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf, count] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(count)?;
                 this.read(fd, buf, count, None, dest)?;
             }
             "write" => {
-                let [fd, buf, n] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf, n] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(n)?;
@@ -102,7 +101,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write(fd, buf, count, None, dest)?;
             }
             "pread" => {
-                let [fd, buf, count, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(count)?;
@@ -110,7 +109,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.read(fd, buf, count, Some(offset), dest)?;
             }
             "pwrite" => {
-                let [fd, buf, n, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(n)?;
@@ -119,7 +118,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write(fd, buf, count, Some(offset), dest)?;
             }
             "pread64" => {
-                let [fd, buf, count, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf, count, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(count)?;
@@ -127,7 +126,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.read(fd, buf, count, Some(offset), dest)?;
             }
             "pwrite64" => {
-                let [fd, buf, n, offset] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf, n, offset] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let buf = this.read_pointer(buf)?;
                 let count = this.read_target_usize(n)?;
@@ -136,32 +135,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write(fd, buf, count, Some(offset), dest)?;
             }
             "close" => {
-                let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.close(fd)?;
                 this.write_scalar(result, dest)?;
             }
             "fcntl" => {
                 // `fcntl` is variadic. The argument count is checked based on the first argument
                 // in `this.fcntl()`, so we do not use `check_shim` here.
-                this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
+                this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?;
                 let result = this.fcntl(args)?;
                 this.write_scalar(result, dest)?;
             }
             "dup" => {
-                let [old_fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [old_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let old_fd = this.read_scalar(old_fd)?.to_i32()?;
                 let new_fd = this.dup(old_fd)?;
                 this.write_scalar(new_fd, dest)?;
             }
             "dup2" => {
-                let [old_fd, new_fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [old_fd, new_fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let old_fd = this.read_scalar(old_fd)?.to_i32()?;
                 let new_fd = this.read_scalar(new_fd)?.to_i32()?;
                 let result = this.dup2(old_fd, new_fd)?;
                 this.write_scalar(result, dest)?;
             }
             "flock" => {
-                let [fd, op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let op = this.read_scalar(op)?.to_i32()?;
                 let result = this.flock(fd, op)?;
@@ -171,47 +170,47 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // File and file system access
             "open" | "open64" => {
                 // `open` is variadic, the third argument is only present when the second argument has O_CREAT (or on linux O_TMPFILE, but miri doesn't support that) set
-                this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
+                this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?;
                 let result = this.open(args)?;
                 this.write_scalar(result, dest)?;
             }
             "unlink" => {
-                let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.unlink(path)?;
                 this.write_scalar(result, dest)?;
             }
             "symlink" => {
-                let [target, linkpath] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [target, linkpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.symlink(target, linkpath)?;
                 this.write_scalar(result, dest)?;
             }
             "rename" => {
-                let [oldpath, newpath] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [oldpath, newpath] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.rename(oldpath, newpath)?;
                 this.write_scalar(result, dest)?;
             }
             "mkdir" => {
-                let [path, mode] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [path, mode] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.mkdir(path, mode)?;
                 this.write_scalar(result, dest)?;
             }
             "rmdir" => {
-                let [path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.rmdir(path)?;
                 this.write_scalar(result, dest)?;
             }
             "opendir" => {
-                let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.opendir(name)?;
                 this.write_scalar(result, dest)?;
             }
             "closedir" => {
-                let [dirp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [dirp] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.closedir(dirp)?;
                 this.write_scalar(result, dest)?;
             }
             "lseek64" => {
-                let [fd, offset, whence] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let offset = this.read_scalar(offset)?.to_i64()?;
                 let whence = this.read_scalar(whence)?.to_i32()?;
@@ -219,7 +218,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(result, dest)?;
             }
             "lseek" => {
-                let [fd, offset, whence] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, offset, whence] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
                 let whence = this.read_scalar(whence)?.to_i32()?;
@@ -228,7 +227,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "ftruncate64" => {
                 let [fd, length] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let length = this.read_scalar(length)?.to_i64()?;
                 let result = this.ftruncate64(fd, length.into())?;
@@ -236,30 +235,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "ftruncate" => {
                 let [fd, length] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let fd = this.read_scalar(fd)?.to_i32()?;
                 let length = this.read_scalar(length)?.to_int(this.libc_ty_layout("off_t").size)?;
                 let result = this.ftruncate64(fd, length)?;
                 this.write_scalar(result, dest)?;
             }
             "fsync" => {
-                let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.fsync(fd)?;
                 this.write_scalar(result, dest)?;
             }
             "fdatasync" => {
-                let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.fdatasync(fd)?;
                 this.write_scalar(result, dest)?;
             }
             "readlink" => {
-                let [pathname, buf, bufsize] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [pathname, buf, bufsize] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.readlink(pathname, buf, bufsize)?;
                 this.write_scalar(Scalar::from_target_isize(result, this), dest)?;
             }
             "posix_fadvise" => {
                 let [fd, offset, len, advice] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.read_scalar(fd)?.to_i32()?;
                 this.read_target_isize(offset)?;
                 this.read_target_isize(len)?;
@@ -268,12 +267,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_null(dest)?;
             }
             "realpath" => {
-                let [path, resolved_path] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [path, resolved_path] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.realpath(path, resolved_path)?;
                 this.write_scalar(result, dest)?;
             }
             "mkstemp" => {
-                let [template] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [template] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.mkstemp(template)?;
                 this.write_scalar(result, dest)?;
             }
@@ -281,13 +280,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Unnamed sockets and pipes
             "socketpair" => {
                 let [domain, type_, protocol, sv] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.socketpair(domain, type_, protocol, sv)?;
                 this.write_scalar(result, dest)?;
             }
             "pipe" => {
                 let [pipefd] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pipe2(pipefd, /*flags*/ None)?;
                 this.write_scalar(result, dest)?;
             }
@@ -300,44 +299,44 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     );
                 }
                 let [pipefd, flags] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pipe2(pipefd, Some(flags))?;
                 this.write_scalar(result, dest)?;
             }
 
             // Time
             "gettimeofday" => {
-                let [tv, tz] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [tv, tz] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.gettimeofday(tv, tz)?;
                 this.write_scalar(result, dest)?;
             }
             "localtime_r" => {
-                let [timep, result_op] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?;
+                let [timep, result_op] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?;
                 let result = this.localtime_r(timep, result_op)?;
                 this.write_pointer(result, dest)?;
             }
             "clock_gettime" => {
                 let [clk_id, tp] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.clock_gettime(clk_id, tp)?;
                 this.write_scalar(result, dest)?;
             }
 
             // Allocation
             "posix_memalign" => {
-                let [memptr, align, size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [memptr, align, size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.posix_memalign(memptr, align, size)?;
                 this.write_scalar(result, dest)?;
             }
 
             "mmap" => {
-                let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?;
+                let [addr, length, prot, flags, fd, offset] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?;
                 let offset = this.read_scalar(offset)?.to_int(this.libc_ty_layout("off_t").size)?;
                 let ptr = this.mmap(addr, length, prot, flags, fd, offset)?;
                 this.write_scalar(ptr, dest)?;
             }
             "munmap" => {
-                let [addr, length] = this.check_shim(abi, Abi::C {unwind: false}, link_name, args)?;
+                let [addr, length] = this.check_shim(abi, ExternAbi::C {unwind: false}, link_name, args)?;
                 let result = this.munmap(addr, length)?;
                 this.write_scalar(result, dest)?;
             }
@@ -351,7 +350,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     );
                 }
                 let [ptr, nmemb, size] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let nmemb = this.read_target_usize(nmemb)?;
                 let size = this.read_target_usize(size)?;
@@ -375,14 +374,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // This is a C11 function, we assume all Unixes have it.
                 // (MSVC explicitly does not support this.)
                 let [align, size] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let res = this.aligned_alloc(align, size)?;
                 this.write_pointer(res, dest)?;
             }
 
             // Dynamic symbol loading
             "dlsym" => {
-                let [handle, symbol] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [handle, symbol] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.read_target_usize(handle)?;
                 let symbol = this.read_pointer(symbol)?;
                 let name = this.read_c_str(symbol)?;
@@ -396,7 +395,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Querying system information
             "sysconf" => {
-                let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [name] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let name = this.read_scalar(name)?.to_i32()?;
                 // FIXME: Which of these are POSIX, and which are GNU/Linux?
                 // At least the names seem to all also exist on macOS.
@@ -425,7 +424,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Thread-local storage
             "pthread_key_create" => {
-                let [key, dtor] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [key, dtor] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let key_place = this.deref_pointer_as(key, this.libc_ty_layout("pthread_key_t"))?;
                 let dtor = this.read_pointer(dtor)?;
 
@@ -453,21 +452,21 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_null(dest)?;
             }
             "pthread_key_delete" => {
-                let [key] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
                 this.machine.tls.delete_tls_key(key)?;
                 // Return success (0)
                 this.write_null(dest)?;
             }
             "pthread_getspecific" => {
-                let [key] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [key] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
                 let active_thread = this.active_thread();
                 let ptr = this.machine.tls.load_tls(key, active_thread, this)?;
                 this.write_scalar(ptr, dest)?;
             }
             "pthread_setspecific" => {
-                let [key, new_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [key, new_ptr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let key = this.read_scalar(key)?.to_bits(key.layout.size)?;
                 let active_thread = this.active_thread();
                 let new_data = this.read_scalar(new_ptr)?;
@@ -479,151 +478,151 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Synchronization primitives
             "pthread_mutexattr_init" => {
-                let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_mutexattr_init(attr)?;
                 this.write_null(dest)?;
             }
             "pthread_mutexattr_settype" => {
-                let [attr, kind] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [attr, kind] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pthread_mutexattr_settype(attr, kind)?;
                 this.write_scalar(result, dest)?;
             }
             "pthread_mutexattr_destroy" => {
-                let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_mutexattr_destroy(attr)?;
                 this.write_null(dest)?;
             }
             "pthread_mutex_init" => {
-                let [mutex, attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [mutex, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_mutex_init(mutex, attr)?;
                 this.write_null(dest)?;
             }
             "pthread_mutex_lock" => {
-                let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_mutex_lock(mutex, dest)?;
             }
             "pthread_mutex_trylock" => {
-                let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pthread_mutex_trylock(mutex)?;
                 this.write_scalar(result, dest)?;
             }
             "pthread_mutex_unlock" => {
-                let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pthread_mutex_unlock(mutex)?;
                 this.write_scalar(result, dest)?;
             }
             "pthread_mutex_destroy" => {
-                let [mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_mutex_destroy(mutex)?;
                 this.write_int(0, dest)?;
             }
             "pthread_rwlock_rdlock" => {
-                let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_rwlock_rdlock(rwlock, dest)?;
             }
             "pthread_rwlock_tryrdlock" => {
-                let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pthread_rwlock_tryrdlock(rwlock)?;
                 this.write_scalar(result, dest)?;
             }
             "pthread_rwlock_wrlock" => {
-                let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_rwlock_wrlock(rwlock, dest)?;
             }
             "pthread_rwlock_trywrlock" => {
-                let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pthread_rwlock_trywrlock(rwlock)?;
                 this.write_scalar(result, dest)?;
             }
             "pthread_rwlock_unlock" => {
-                let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_rwlock_unlock(rwlock)?;
                 this.write_null(dest)?;
             }
             "pthread_rwlock_destroy" => {
-                let [rwlock] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [rwlock] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_rwlock_destroy(rwlock)?;
                 this.write_null(dest)?;
             }
             "pthread_condattr_init" => {
-                let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_condattr_init(attr)?;
                 this.write_null(dest)?;
             }
             "pthread_condattr_setclock" => {
                 let [attr, clock_id] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.pthread_condattr_setclock(attr, clock_id)?;
                 this.write_scalar(result, dest)?;
             }
             "pthread_condattr_getclock" => {
                 let [attr, clock_id] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_condattr_getclock(attr, clock_id)?;
                 this.write_null(dest)?;
             }
             "pthread_condattr_destroy" => {
-                let [attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_condattr_destroy(attr)?;
                 this.write_null(dest)?;
             }
             "pthread_cond_init" => {
-                let [cond, attr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [cond, attr] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_cond_init(cond, attr)?;
                 this.write_null(dest)?;
             }
             "pthread_cond_signal" => {
-                let [cond] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_cond_signal(cond)?;
                 this.write_null(dest)?;
             }
             "pthread_cond_broadcast" => {
-                let [cond] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_cond_broadcast(cond)?;
                 this.write_null(dest)?;
             }
             "pthread_cond_wait" => {
-                let [cond, mutex] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [cond, mutex] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_cond_wait(cond, mutex, dest)?;
             }
             "pthread_cond_timedwait" => {
-                let [cond, mutex, abstime] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [cond, mutex, abstime] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_cond_timedwait(cond, mutex, abstime, dest)?;
             }
             "pthread_cond_destroy" => {
-                let [cond] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [cond] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_cond_destroy(cond)?;
                 this.write_null(dest)?;
             }
 
             // Threading
             "pthread_create" => {
-                let [thread, attr, start, arg] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [thread, attr, start, arg] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_create(thread, attr, start, arg)?;
                 this.write_null(dest)?;
             }
             "pthread_join" => {
-                let [thread, retval] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [thread, retval] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_join(thread, retval)?;
                 this.write_null(dest)?;
             }
             "pthread_detach" => {
-                let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [thread] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.pthread_detach(thread)?;
                 this.write_null(dest)?;
             }
             "pthread_self" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let res = this.pthread_self()?;
                 this.write_scalar(res, dest)?;
             }
             "sched_yield" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.sched_yield()?;
                 this.write_null(dest)?;
             }
             "nanosleep" => {
-                let [req, rem] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [req, rem] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.nanosleep(req, rem)?;
                 this.write_scalar(result, dest)?;
             }
@@ -637,7 +636,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
 
                 let [pid, cpusetsize, mask] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let pid = this.read_scalar(pid)?.to_u32()?;
                 let cpusetsize = this.read_target_usize(cpusetsize)?;
                 let mask = this.read_pointer(mask)?;
@@ -677,7 +676,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
 
                 let [pid, cpusetsize, mask] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let pid = this.read_scalar(pid)?.to_u32()?;
                 let cpusetsize = this.read_target_usize(cpusetsize)?;
                 let mask = this.read_pointer(mask)?;
@@ -713,12 +712,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Miscellaneous
             "isatty" => {
-                let [fd] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.isatty(fd)?;
                 this.write_scalar(result, dest)?;
             }
             "pthread_atfork" => {
-                let [prepare, parent, child] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [prepare, parent, child] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.read_pointer(prepare)?;
                 this.read_pointer(parent)?;
                 this.read_pointer(child)?;
@@ -726,7 +725,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_null(dest)?;
             }
             "strerror_r" | "__xpg_strerror_r" => {
-                let [errnum, buf, buflen] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [errnum, buf, buflen] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let errnum = this.read_scalar(errnum)?;
                 let buf = this.read_pointer(buf)?;
                 let buflen = this.read_target_usize(buflen)?;
@@ -751,7 +750,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
 
                 let [buf, bufsize] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let buf = this.read_pointer(buf)?;
                 let bufsize = this.read_target_usize(bufsize)?;
 
@@ -777,7 +776,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     );
                 }
                 let [ptr, len, flags] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let len = this.read_target_usize(len)?;
                 let _flags = this.read_scalar(flags)?.to_i32()?;
@@ -794,7 +793,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                         this.tcx.sess.target.os
                     );
                 }
-                let [ptr, len] = this.check_shim(abi, Abi::C { unwind: false}, link_name, args)?;
+                let [ptr, len] = this.check_shim(abi, ExternAbi::C { unwind: false}, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let len = this.read_target_usize(len)?;
                 this.gen_random(ptr, len)?;
@@ -820,12 +819,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     );
                 }
                 // This function looks and behaves excatly like miri_start_unwind.
-                let [payload] = this.check_shim(abi, Abi::C { unwind: true }, link_name, args)?;
+                let [payload] = this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?;
                 this.handle_miri_start_unwind(payload)?;
                 return interp_ok(EmulateItemResult::NeedsUnwind);
             }
             "getuid" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // For now, just pretend we always have this fixed UID.
                 this.write_int(UID, dest)?;
             }
@@ -834,7 +833,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // These shims are enabled only when the caller is in the standard library.
             "pthread_attr_getguardsize"
             if this.frame_in_std() => {
-                let [_attr, guard_size] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [_attr, guard_size] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let guard_size = this.deref_pointer(guard_size)?;
                 let guard_size_layout = this.libc_ty_layout("size_t");
                 this.write_scalar(Scalar::from_uint(this.machine.page_size, guard_size_layout.size), &guard_size)?;
@@ -846,12 +845,12 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "pthread_attr_init"
             | "pthread_attr_destroy"
             if this.frame_in_std() => {
-                let [_] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [_] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_null(dest)?;
             }
             | "pthread_attr_setstacksize"
             if this.frame_in_std() => {
-                let [_, _] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_null(dest)?;
             }
 
@@ -860,7 +859,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // We don't support "pthread_attr_setstack", so we just pretend all stacks have the same values here.
                 // Hence we can mostly ignore the input `attr_place`.
                 let [attr_place, addr_place, size_place] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let _attr_place = this.deref_pointer_as(attr_place, this.libc_ty_layout("pthread_attr_t"))?;
                 let addr_place = this.deref_pointer(addr_place)?;
                 let size_place = this.deref_pointer(size_place)?;
@@ -881,13 +880,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "signal"
             | "sigaltstack"
             if this.frame_in_std() => {
-                let [_, _] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [_, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_null(dest)?;
             }
             | "sigaction"
             | "mprotect"
             if this.frame_in_std() => {
-                let [_, _, _] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [_, _, _] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_null(dest)?;
             }
 
@@ -895,7 +894,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             if this.frame_in_std() => {
                 // getpwuid_r is the standard name, __posix_getpwuid_r is used on solarish
                 let [uid, pwd, buf, buflen, result] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.check_no_isolation("`getpwuid_r`")?;
 
                 let uid = this.read_scalar(uid)?.to_u32()?;
diff --git a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
index 71953aca989..1346d8de7ea 100644
--- a/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/freebsd/foreign_items.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::shims::unix::*;
 use crate::*;
@@ -13,7 +13,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Threading
             "pthread_set_name_np" => {
                 let [thread, name] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let max_len = usize::MAX; // FreeBSD does not seem to have a limit.
                 // FreeBSD's pthread_set_name_np does not return anything.
                 this.pthread_setname_np(
@@ -34,7 +34,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "pthread_get_name_np" => {
                 let [thread, name, len] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // FreeBSD's pthread_get_name_np does not return anything
                 // and uses strlcpy, which truncates the resulting value,
                 // but always adds a null terminator (except for zero-sized buffers).
@@ -52,31 +52,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // since freebsd 12 the former form can be expected.
             "stat" | "stat@FBSD_1.0" => {
                 let [path, buf] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_stat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "lstat" | "lstat@FBSD_1.0" => {
                 let [path, buf] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_lstat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "fstat" | "fstat@FBSD_1.0" => {
-                let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_fstat(fd, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "readdir_r" | "readdir_r@FBSD_1.0" => {
                 let [dirp, entry, result] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
                 this.write_scalar(result, dest)?;
             }
 
             // Miscellaneous
             "__error" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let errno_place = this.last_error_place()?;
                 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
             }
@@ -85,7 +86,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // These shims are enabled only when the caller is in the standard library.
             "pthread_attr_get_np" if this.frame_in_std() => {
                 let [_thread, _attr] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_null(dest)?;
             }
 
diff --git a/src/tools/miri/src/shims/unix/fs.rs b/src/tools/miri/src/shims/unix/fs.rs
index f7436d7f089..091def7ac65 100644
--- a/src/tools/miri/src/shims/unix/fs.rs
+++ b/src/tools/miri/src/shims/unix/fs.rs
@@ -8,8 +8,8 @@ use std::io::{self, ErrorKind, IsTerminal, Read, Seek, SeekFrom, Write};
 use std::path::{Path, PathBuf};
 use std::time::SystemTime;
 
+use rustc_abi::Size;
 use rustc_data_structures::fx::FxHashMap;
-use rustc_target::abi::Size;
 
 use self::fd::FlockOp;
 use self::shims::time::system_time_to_duration;
@@ -385,7 +385,7 @@ pub struct DirTable {
 }
 
 impl DirTable {
-    #[allow(clippy::arithmetic_side_effects)]
+    #[expect(clippy::arithmetic_side_effects)]
     fn insert_new(&mut self, read_dir: ReadDir) -> u64 {
         let id = self.next_id;
         self.next_id += 1;
diff --git a/src/tools/miri/src/shims/unix/linux/foreign_items.rs b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
index a126d5b4fab..35658ebc2f2 100644
--- a/src/tools/miri/src/shims/unix/linux/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/linux/foreign_items.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use self::shims::unix::linux::epoll::EvalContextExt as _;
 use self::shims::unix::linux::eventfd::EvalContextExt as _;
@@ -23,7 +23,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -34,43 +34,45 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         match link_name.as_str() {
             // File related shims
             "readdir64" => {
-                let [dirp] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [dirp] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.linux_readdir64(dirp)?;
                 this.write_scalar(result, dest)?;
             }
             "sync_file_range" => {
                 let [fd, offset, nbytes, flags] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.sync_file_range(fd, offset, nbytes, flags)?;
                 this.write_scalar(result, dest)?;
             }
             "statx" => {
                 let [dirfd, pathname, flags, mask, statxbuf] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.linux_statx(dirfd, pathname, flags, mask, statxbuf)?;
                 this.write_scalar(result, dest)?;
             }
 
             // epoll, eventfd
             "epoll_create1" => {
-                let [flag] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [flag] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.epoll_create1(flag)?;
                 this.write_scalar(result, dest)?;
             }
             "epoll_ctl" => {
                 let [epfd, op, fd, event] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.epoll_ctl(epfd, op, fd, event)?;
                 this.write_scalar(result, dest)?;
             }
             "epoll_wait" => {
                 let [epfd, events, maxevents, timeout] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.epoll_wait(epfd, events, maxevents, timeout, dest)?;
             }
             "eventfd" => {
                 let [val, flag] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.eventfd(val, flag)?;
                 this.write_scalar(result, dest)?;
             }
@@ -78,7 +80,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Threading
             "pthread_setname_np" => {
                 let [thread, name] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let res = this.pthread_setname_np(
                     this.read_scalar(thread)?,
                     this.read_scalar(name)?,
@@ -90,7 +92,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "pthread_getname_np" => {
                 let [thread, name, len] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // The function's behavior isn't portable between platforms.
                 // In case of glibc, the length of the output buffer must
                 // be not shorter than TASK_COMM_LEN.
@@ -109,7 +111,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_scalar(res, dest)?;
             }
             "gettid" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.linux_gettid()?;
                 this.write_scalar(result, dest)?;
             }
@@ -122,29 +124,29 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Miscellaneous
             "mmap64" => {
                 let [addr, length, prot, flags, fd, offset] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let offset = this.read_scalar(offset)?.to_i64()?;
                 let ptr = this.mmap(addr, length, prot, flags, fd, offset.into())?;
                 this.write_scalar(ptr, dest)?;
             }
             "mremap" => {
                 let [old_address, old_size, new_size, flags] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let ptr = this.mremap(old_address, old_size, new_size, flags)?;
                 this.write_scalar(ptr, dest)?;
             }
             "__errno_location" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let errno_place = this.last_error_place()?;
                 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
             }
             "__libc_current_sigrtmin" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 this.write_int(SIGRTMIN, dest)?;
             }
             "__libc_current_sigrtmax" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 this.write_int(SIGRTMAX, dest)?;
             }
@@ -153,7 +155,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // These shims are enabled only when the caller is in the standard library.
             "pthread_getattr_np" if this.frame_in_std() => {
                 let [_thread, _attr] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_null(dest)?;
             }
 
diff --git a/src/tools/miri/src/shims/unix/linux/mem.rs b/src/tools/miri/src/shims/unix/linux/mem.rs
index d5f9669b360..8e796d5dce5 100644
--- a/src/tools/miri/src/shims/unix/linux/mem.rs
+++ b/src/tools/miri/src/shims/unix/linux/mem.rs
@@ -1,7 +1,7 @@
 //! This follows the pattern in src/shims/unix/mem.rs: We only support uses of mremap that would
 //! correspond to valid uses of realloc.
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 use crate::*;
 
@@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         let flags = this.read_scalar(flags)?.to_i32()?;
 
         // old_address must be a multiple of the page size
-        #[allow(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
+        #[expect(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
         if old_address.addr().bytes() % this.machine.page_size != 0 || new_size == 0 {
             this.set_last_error(LibcError("EINVAL"))?;
             return interp_ok(this.eval_libc("MAP_FAILED"));
diff --git a/src/tools/miri/src/shims/unix/linux/sync.rs b/src/tools/miri/src/shims/unix/linux/sync.rs
index 9fbf08b0b18..6d5747d7c15 100644
--- a/src/tools/miri/src/shims/unix/linux/sync.rs
+++ b/src/tools/miri/src/shims/unix/linux/sync.rs
@@ -182,7 +182,7 @@ pub fn futex<'tcx>(
             // before doing the syscall.
             this.atomic_fence(AtomicFenceOrd::SeqCst)?;
             let mut n = 0;
-            #[allow(clippy::arithmetic_side_effects)]
+            #[expect(clippy::arithmetic_side_effects)]
             for _ in 0..val {
                 if this.futex_wake(addr_usize, bitset)? {
                     n += 1;
diff --git a/src/tools/miri/src/shims/unix/linux/syscall.rs b/src/tools/miri/src/shims/unix/linux/syscall.rs
index 72e02447d80..0d7032adab4 100644
--- a/src/tools/miri/src/shims/unix/linux/syscall.rs
+++ b/src/tools/miri/src/shims/unix/linux/syscall.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use self::shims::unix::linux::eventfd::EvalContextExt as _;
 use crate::helpers::check_min_arg_count;
@@ -9,13 +9,13 @@ use crate::*;
 pub fn syscall<'tcx>(
     this: &mut MiriInterpCx<'tcx>,
     link_name: Symbol,
-    abi: Abi,
+    abi: ExternAbi,
     args: &[OpTy<'tcx>],
     dest: &MPlaceTy<'tcx>,
 ) -> InterpResult<'tcx> {
     // We do not use `check_shim` here because `syscall` is variadic. The argument
     // count is checked bellow.
-    this.check_abi_and_shim_symbol_clash(abi, Abi::C { unwind: false }, link_name)?;
+    this.check_abi_and_shim_symbol_clash(abi, ExternAbi::C { unwind: false }, link_name)?;
     // The syscall variadic function is legal to call with more arguments than needed,
     // extra arguments are simply ignored. The important check is that when we use an
     // argument, we have to also check all arguments *before* it to ensure that they
diff --git a/src/tools/miri/src/shims/unix/macos/foreign_items.rs b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
index cd07bc9e013..b77b46e325d 100644
--- a/src/tools/miri/src/shims/unix/macos/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/macos/foreign_items.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::sync::EvalContextExt as _;
 use crate::shims::unix::*;
@@ -14,7 +14,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -25,55 +25,58 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         match link_name.as_str() {
             // errno
             "__error" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let errno_place = this.last_error_place()?;
                 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
             }
 
             // File related shims
             "close$NOCANCEL" => {
-                let [result] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [result] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.close(result)?;
                 this.write_scalar(result, dest)?;
             }
             "stat" | "stat64" | "stat$INODE64" => {
                 let [path, buf] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_stat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "lstat" | "lstat64" | "lstat$INODE64" => {
                 let [path, buf] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_lstat(path, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "fstat" | "fstat64" | "fstat$INODE64" => {
-                let [fd, buf] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [fd, buf] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_fstat(fd, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "opendir$INODE64" => {
-                let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [name] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.opendir(name)?;
                 this.write_scalar(result, dest)?;
             }
             "readdir_r" | "readdir_r$INODE64" => {
                 let [dirp, entry, result] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.macos_fbsd_readdir_r(dirp, entry, result)?;
                 this.write_scalar(result, dest)?;
             }
             "realpath$DARWIN_EXTSN" => {
                 let [path, resolved_path] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.realpath(path, resolved_path)?;
                 this.write_scalar(result, dest)?;
             }
 
             // Environment related shims
             "_NSGetEnviron" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let environ = this.machine.env_vars.unix().environ();
                 this.write_pointer(environ, dest)?;
             }
@@ -81,7 +84,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Random data generation
             "CCRandomGenerateBytes" => {
                 let [bytes, count] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let bytes = this.read_pointer(bytes)?;
                 let count = this.read_target_usize(count)?;
                 let success = this.eval_libc_i32("kCCSuccess");
@@ -91,29 +94,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Time related shims
             "mach_absolute_time" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.mach_absolute_time()?;
                 this.write_scalar(result, dest)?;
             }
 
             "mach_timebase_info" => {
-                let [info] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [info] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.mach_timebase_info(info)?;
                 this.write_scalar(result, dest)?;
             }
 
             // Access to command-line arguments
             "_NSGetArgc" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_pointer(this.machine.argc.expect("machine must be initialized"), dest)?;
             }
             "_NSGetArgv" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.write_pointer(this.machine.argv.expect("machine must be initialized"), dest)?;
             }
             "_NSGetExecutablePath" => {
                 let [buf, bufsize] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.check_no_isolation("`_NSGetExecutablePath`")?;
 
                 let buf_ptr = this.read_pointer(buf)?;
@@ -139,7 +143,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Thread-local storage
             "_tlv_atexit" => {
                 let [dtor, data] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let dtor = this.read_pointer(dtor)?;
                 let dtor = this.get_ptr_fn(dtor)?.as_instance()?;
                 let data = this.read_scalar(data)?;
@@ -149,13 +153,15 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Querying system information
             "pthread_get_stackaddr_np" => {
-                let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [thread] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.read_target_usize(thread)?;
                 let stack_addr = Scalar::from_uint(this.machine.stack_addr, this.pointer_size());
                 this.write_scalar(stack_addr, dest)?;
             }
             "pthread_get_stacksize_np" => {
-                let [thread] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [thread] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.read_target_usize(thread)?;
                 let stack_size = Scalar::from_uint(this.machine.stack_size, this.pointer_size());
                 this.write_scalar(stack_size, dest)?;
@@ -163,7 +169,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Threading
             "pthread_setname_np" => {
-                let [name] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [name] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 // The real implementation has logic in two places:
                 // * in userland at https://github.com/apple-oss-distributions/libpthread/blob/c032e0b076700a0a47db75528a282b8d3a06531a/src/pthread.c#L1178-L1200,
@@ -193,7 +200,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "pthread_getname_np" => {
                 let [thread, name, len] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 // The function's behavior isn't portable between platforms.
                 // In case of macOS, a truncated name (due to a too small buffer)
@@ -216,23 +223,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
 
             "os_unfair_lock_lock" => {
-                let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [lock_op] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.os_unfair_lock_lock(lock_op)?;
             }
             "os_unfair_lock_trylock" => {
-                let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [lock_op] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.os_unfair_lock_trylock(lock_op, dest)?;
             }
             "os_unfair_lock_unlock" => {
-                let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [lock_op] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.os_unfair_lock_unlock(lock_op)?;
             }
             "os_unfair_lock_assert_owner" => {
-                let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [lock_op] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.os_unfair_lock_assert_owner(lock_op)?;
             }
             "os_unfair_lock_assert_not_owner" => {
-                let [lock_op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [lock_op] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 this.os_unfair_lock_assert_not_owner(lock_op)?;
             }
 
diff --git a/src/tools/miri/src/shims/unix/macos/sync.rs b/src/tools/miri/src/shims/unix/macos/sync.rs
index 1df1202442a..ffc8c222738 100644
--- a/src/tools/miri/src/shims/unix/macos/sync.rs
+++ b/src/tools/miri/src/shims/unix/macos/sync.rs
@@ -10,7 +10,7 @@
 //! and we do not detect copying of the lock, but macOS doesn't guarantee anything
 //! in that case either.
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 use crate::*;
 
diff --git a/src/tools/miri/src/shims/unix/mem.rs b/src/tools/miri/src/shims/unix/mem.rs
index 9371edfc83d..5531b944e17 100644
--- a/src/tools/miri/src/shims/unix/mem.rs
+++ b/src/tools/miri/src/shims/unix/mem.rs
@@ -14,7 +14,7 @@
 //! munmap shim which would partially unmap a region of address space previously mapped by mmap will
 //! report UB.
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 use crate::*;
 
@@ -132,7 +132,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         // addr must be a multiple of the page size, but apart from that munmap is just implemented
         // as a dealloc.
-        #[allow(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
+        #[expect(clippy::arithmetic_side_effects)] // PAGE_SIZE is nonzero
         if addr.addr().bytes() % this.machine.page_size != 0 {
             return this.set_last_error_and_return_i32(LibcError("EINVAL"));
         }
diff --git a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
index c9c1b01b8b1..efdc64f45fc 100644
--- a/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
+++ b/src/tools/miri/src/shims/unix/solarish/foreign_items.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::shims::unix::*;
 use crate::*;
@@ -13,7 +13,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Threading
             "pthread_setname_np" => {
                 let [thread, name] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // THREAD_NAME_MAX allows a thread name of 31+1 length
                 // https://github.com/illumos/illumos-gate/blob/7671517e13b8123748eda4ef1ee165c6d9dba7fe/usr/src/uts/common/sys/thread.h#L613
                 let max_len = 32;
@@ -37,7 +37,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "pthread_getname_np" => {
                 let [thread, name, len] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // https://github.com/illumos/illumos-gate/blob/c56822be04b6c157c8b6f2281e47214c3b86f657/usr/src/lib/libc/port/threads/thr.c#L2449-L2480
                 let res = this.pthread_getname_np(
                     this.read_scalar(thread)?,
@@ -51,13 +51,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Miscellaneous
             "___errno" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let errno_place = this.last_error_place()?;
                 this.write_scalar(errno_place.to_ref(this).to_scalar(), dest)?;
             }
 
             "stack_getbounds" => {
-                let [stack] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [stack] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let stack = this.deref_pointer_as(stack, this.libc_ty_layout("stack_t"))?;
 
                 this.write_int_fields_named(
@@ -76,7 +77,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             "pset_info" => {
                 let [pset, tpe, cpus, list] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // We do not need to handle the current process cpu mask, available_parallelism
                 // implementation pass null anyway. We only care for the number of
                 // cpus.
diff --git a/src/tools/miri/src/shims/unix/sync.rs b/src/tools/miri/src/shims/unix/sync.rs
index a4beaa47baa..850626d89ac 100644
--- a/src/tools/miri/src/shims/unix/sync.rs
+++ b/src/tools/miri/src/shims/unix/sync.rs
@@ -1,6 +1,6 @@
 use std::sync::atomic::{AtomicBool, Ordering};
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 use crate::concurrency::sync::LAZY_INIT_COOKIE;
 use crate::*;
@@ -685,7 +685,6 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
         let id = rwlock_get_data(this, rwlock_op)?.id;
 
-        #[allow(clippy::if_same_then_else)]
         if this.rwlock_reader_unlock(id)? || this.rwlock_writer_unlock(id)? {
             interp_ok(())
         } else {
diff --git a/src/tools/miri/src/shims/unix/thread.rs b/src/tools/miri/src/shims/unix/thread.rs
index 51256d800a4..52c135f8540 100644
--- a/src/tools/miri/src/shims/unix/thread.rs
+++ b/src/tools/miri/src/shims/unix/thread.rs
@@ -1,4 +1,4 @@
-use rustc_target::spec::abi::Abi;
+use rustc_abi::ExternAbi;
 
 use crate::*;
 
@@ -22,7 +22,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         this.start_regular_thread(
             Some(thread_info_place),
             start_routine,
-            Abi::C { unwind: false },
+            ExternAbi::C { unwind: false },
             func_arg,
             this.machine.layouts.mut_raw_ptr,
         )?;
diff --git a/src/tools/miri/src/shims/unix/unnamed_socket.rs b/src/tools/miri/src/shims/unix/unnamed_socket.rs
index d0eba1eacd1..8ccce7c1986 100644
--- a/src/tools/miri/src/shims/unix/unnamed_socket.rs
+++ b/src/tools/miri/src/shims/unix/unnamed_socket.rs
@@ -7,7 +7,7 @@ use std::collections::VecDeque;
 use std::io;
 use std::io::{ErrorKind, Read};
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 use crate::concurrency::VClock;
 use crate::shims::unix::fd::{FileDescriptionRef, WeakFileDescriptionRef};
diff --git a/src/tools/miri/src/shims/wasi/foreign_items.rs b/src/tools/miri/src/shims/wasi/foreign_items.rs
index b5de950de9a..2c349203d46 100644
--- a/src/tools/miri/src/shims/wasi/foreign_items.rs
+++ b/src/tools/miri/src/shims/wasi/foreign_items.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::shims::alloc::EvalContextExt as _;
 use crate::*;
@@ -13,7 +13,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -22,13 +22,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Allocation
             "posix_memalign" => {
                 let [memptr, align, size] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let result = this.posix_memalign(memptr, align, size)?;
                 this.write_scalar(result, dest)?;
             }
             "aligned_alloc" => {
                 let [align, size] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let res = this.aligned_alloc(align, size)?;
                 this.write_pointer(res, dest)?;
             }
diff --git a/src/tools/miri/src/shims/windows/foreign_items.rs b/src/tools/miri/src/shims/windows/foreign_items.rs
index e41ff022549..fe11aa8da4a 100644
--- a/src/tools/miri/src/shims/windows/foreign_items.rs
+++ b/src/tools/miri/src/shims/windows/foreign_items.rs
@@ -2,9 +2,8 @@ use std::ffi::OsStr;
 use std::path::{self, Path, PathBuf};
 use std::{io, iter, str};
 
+use rustc_abi::{Align, ExternAbi, Size};
 use rustc_span::Symbol;
-use rustc_target::abi::{Align, Size};
-use rustc_target::spec::abi::Abi;
 
 use self::shims::windows::handle::{Handle, PseudoHandle};
 use crate::shims::os_str::bytes_to_os_str;
@@ -26,7 +25,7 @@ fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> {
 }
 
 #[cfg(unix)]
-#[allow(clippy::get_first, clippy::arithmetic_side_effects)]
+#[expect(clippy::get_first, clippy::arithmetic_side_effects)]
 fn win_absolute<'tcx>(path: &Path) -> InterpResult<'tcx, io::Result<PathBuf>> {
     // We are on Unix, so we need to implement parts of the logic ourselves.
     let bytes = path.as_os_str().as_encoded_bytes();
@@ -79,7 +78,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_foreign_item_inner(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -97,47 +96,49 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Environment related shims
             "GetEnvironmentVariableW" => {
                 let [name, buf, size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.GetEnvironmentVariableW(name, buf, size)?;
                 this.write_scalar(result, dest)?;
             }
             "SetEnvironmentVariableW" => {
                 let [name, value] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.SetEnvironmentVariableW(name, value)?;
                 this.write_scalar(result, dest)?;
             }
             "GetEnvironmentStringsW" => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.GetEnvironmentStringsW()?;
                 this.write_pointer(result, dest)?;
             }
             "FreeEnvironmentStringsW" => {
                 let [env_block] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.FreeEnvironmentStringsW(env_block)?;
                 this.write_scalar(result, dest)?;
             }
             "GetCurrentDirectoryW" => {
                 let [size, buf] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.GetCurrentDirectoryW(size, buf)?;
                 this.write_scalar(result, dest)?;
             }
             "SetCurrentDirectoryW" => {
                 let [path] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.SetCurrentDirectoryW(path)?;
                 this.write_scalar(result, dest)?;
             }
             "GetUserProfileDirectoryW" => {
                 let [token, buf, size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.GetUserProfileDirectoryW(token, buf, size)?;
                 this.write_scalar(result, dest)?;
             }
             "GetCurrentProcessId" => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.GetCurrentProcessId()?;
                 this.write_scalar(result, dest)?;
             }
@@ -160,7 +161,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     n,
                     byte_offset,
                     _key,
-                ] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                ] = this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let handle = this.read_target_isize(handle)?;
                 let buf = this.read_pointer(buf)?;
                 let n = this.read_scalar(n)?.to_u32()?;
@@ -212,7 +213,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "GetFullPathNameW" => {
                 let [filename, size, buffer, filepart] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.check_no_isolation("`GetFullPathNameW`")?;
 
                 let filename = this.read_pointer(filename)?;
@@ -244,7 +245,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Allocation
             "HeapAlloc" => {
                 let [handle, flags, size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.read_target_isize(handle)?;
                 let flags = this.read_scalar(flags)?.to_u32()?;
                 let size = this.read_target_usize(size)?;
@@ -268,7 +269,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "HeapFree" => {
                 let [handle, flags, ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.read_target_isize(handle)?;
                 this.read_scalar(flags)?.to_u32()?;
                 let ptr = this.read_pointer(ptr)?;
@@ -281,7 +282,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "HeapReAlloc" => {
                 let [handle, flags, old_ptr, size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.read_target_isize(handle)?;
                 this.read_scalar(flags)?.to_u32()?;
                 let old_ptr = this.read_pointer(old_ptr)?;
@@ -300,7 +301,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 this.write_pointer(new_ptr, dest)?;
             }
             "LocalFree" => {
-                let [ptr] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [ptr] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 // "If the hMem parameter is NULL, LocalFree ignores the parameter and returns NULL."
                 // (https://learn.microsoft.com/en-us/windows/win32/api/winbase/nf-winbase-localfree)
@@ -313,12 +315,13 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // errno
             "SetLastError" => {
                 let [error] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let error = this.read_scalar(error)?;
                 this.set_last_error(error)?;
             }
             "GetLastError" => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let last_error = this.get_last_error()?;
                 this.write_scalar(last_error, dest)?;
             }
@@ -327,7 +330,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "GetSystemInfo" => {
                 // Also called from `page_size` crate.
                 let [system_info] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let system_info =
                     this.deref_pointer_as(system_info, this.windows_ty_layout("SYSTEM_INFO"))?;
                 // Initialize with `0`.
@@ -350,12 +353,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // This just creates a key; Windows does not natively support TLS destructors.
 
                 // Create key and return it.
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let key = this.machine.tls.create_tls_key(None, dest.layout.size)?;
                 this.write_scalar(Scalar::from_uint(key, dest.layout.size), dest)?;
             }
             "TlsGetValue" => {
-                let [key] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [key] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let key = u128::from(this.read_scalar(key)?.to_u32()?);
                 let active_thread = this.active_thread();
                 let ptr = this.machine.tls.load_tls(key, active_thread, this)?;
@@ -363,7 +368,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "TlsSetValue" => {
                 let [key, new_ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let key = u128::from(this.read_scalar(key)?.to_u32()?);
                 let active_thread = this.active_thread();
                 let new_data = this.read_scalar(new_ptr)?;
@@ -375,7 +380,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
 
             // Access to command-line arguments
             "GetCommandLineW" => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.write_pointer(
                     this.machine.cmd_line.expect("machine must be initialized"),
                     dest,
@@ -386,32 +392,32 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "GetSystemTimeAsFileTime" | "GetSystemTimePreciseAsFileTime" => {
                 #[allow(non_snake_case)]
                 let [LPFILETIME] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.GetSystemTimeAsFileTime(link_name.as_str(), LPFILETIME)?;
             }
             "QueryPerformanceCounter" => {
                 #[allow(non_snake_case)]
                 let [lpPerformanceCount] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.QueryPerformanceCounter(lpPerformanceCount)?;
                 this.write_scalar(result, dest)?;
             }
             "QueryPerformanceFrequency" => {
                 #[allow(non_snake_case)]
                 let [lpFrequency] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.QueryPerformanceFrequency(lpFrequency)?;
                 this.write_scalar(result, dest)?;
             }
             "Sleep" => {
                 let [timeout] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 this.Sleep(timeout)?;
             }
             "CreateWaitableTimerExW" => {
                 let [attributes, name, flags, access] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.read_pointer(attributes)?;
                 this.read_pointer(name)?;
                 this.read_scalar(flags)?.to_u32()?;
@@ -425,30 +431,30 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Synchronization primitives
             "InitOnceBeginInitialize" => {
                 let [ptr, flags, pending, context] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.InitOnceBeginInitialize(ptr, flags, pending, context, dest)?;
             }
             "InitOnceComplete" => {
                 let [ptr, flags, context] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let result = this.InitOnceComplete(ptr, flags, context)?;
                 this.write_scalar(result, dest)?;
             }
             "WaitOnAddress" => {
                 let [ptr_op, compare_op, size_op, timeout_op] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 this.WaitOnAddress(ptr_op, compare_op, size_op, timeout_op, dest)?;
             }
             "WakeByAddressSingle" => {
                 let [ptr_op] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 this.WakeByAddressSingle(ptr_op)?;
             }
             "WakeByAddressAll" => {
                 let [ptr_op] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 this.WakeByAddressAll(ptr_op)?;
             }
@@ -457,7 +463,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "GetProcAddress" => {
                 #[allow(non_snake_case)]
                 let [hModule, lpProcName] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.read_target_isize(hModule)?;
                 let name = this.read_c_str(this.read_pointer(lpProcName)?)?;
                 if let Ok(name) = str::from_utf8(name)
@@ -473,7 +479,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Threading
             "CreateThread" => {
                 let [security, stacksize, start, arg, flags, thread] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 let thread_id =
                     this.CreateThread(security, stacksize, start, arg, flags, thread)?;
@@ -482,13 +488,14 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "WaitForSingleObject" => {
                 let [handle, timeout] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 let ret = this.WaitForSingleObject(handle, timeout)?;
                 this.write_scalar(Scalar::from_u32(ret), dest)?;
             }
             "GetCurrentThread" => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 this.write_scalar(
                     Handle::Pseudo(PseudoHandle::CurrentThread).to_scalar(this),
@@ -497,7 +504,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "SetThreadDescription" => {
                 let [handle, name] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 let handle = this.read_scalar(handle)?;
                 let name = this.read_wide_str(this.read_pointer(name)?)?;
@@ -515,7 +522,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "GetThreadDescription" => {
                 let [handle, name_ptr] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 let handle = this.read_scalar(handle)?;
                 let name_ptr = this.deref_pointer(name_ptr)?; // the pointer where we should store the ptr to the name
@@ -540,7 +547,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Miscellaneous
             "ExitProcess" => {
                 let [code] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let code = this.read_scalar(code)?.to_u32()?;
                 throw_machine_stop!(TerminationInfo::Exit { code: code.into(), leak_check: false });
             }
@@ -548,7 +555,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // used by getrandom 0.1
                 // This is really 'RtlGenRandom'.
                 let [ptr, len] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let len = this.read_scalar(len)?.to_u32()?;
                 this.gen_random(ptr, len.into())?;
@@ -557,7 +564,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "ProcessPrng" => {
                 // used by `std`
                 let [ptr, len] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let ptr = this.read_pointer(ptr)?;
                 let len = this.read_target_usize(len)?;
                 this.gen_random(ptr, len)?;
@@ -566,7 +573,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "BCryptGenRandom" => {
                 // used by getrandom 0.2
                 let [algorithm, ptr, len, flags] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let algorithm = this.read_scalar(algorithm)?;
                 let algorithm = algorithm.to_target_usize(this)?;
                 let ptr = this.read_pointer(ptr)?;
@@ -601,7 +608,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "GetConsoleScreenBufferInfo" => {
                 // `term` needs this, so we fake it.
                 let [console, buffer_info] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.read_target_isize(console)?;
                 // FIXME: this should use deref_pointer_as, but CONSOLE_SCREEN_BUFFER_INFO is not in std
                 this.deref_pointer(buffer_info)?;
@@ -611,7 +618,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "GetStdHandle" => {
                 let [which] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 let which = this.read_scalar(which)?.to_i32()?;
                 // We just make this the identity function, so we know later in `NtWriteFile` which
                 // one it is. This is very fake, but libtest needs it so we cannot make it a
@@ -621,7 +628,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "CloseHandle" => {
                 let [handle] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 this.CloseHandle(handle)?;
 
@@ -629,7 +636,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "GetModuleFileNameW" => {
                 let [handle, filename, size] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.check_no_isolation("`GetModuleFileNameW`")?;
 
                 let handle = this.read_target_usize(handle)?;
@@ -663,7 +670,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             "FormatMessageW" => {
                 let [flags, module, message_id, language_id, buffer, size, arguments] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 let flags = this.read_scalar(flags)?.to_u32()?;
                 let _module = this.read_pointer(module)?; // seems to contain a module name
@@ -698,7 +705,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Incomplete shims that we "stub out" just to get pre-main initialization code to work.
             // These shims are enabled only when the caller is in the standard library.
             "GetProcessHeap" if this.frame_in_std() => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 // Just fake a HANDLE
                 // It's fine to not use the Handle type here because its a stub
                 this.write_int(1, dest)?;
@@ -706,20 +714,20 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "GetModuleHandleA" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
                 let [_lpModuleName] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 // We need to return something non-null here to make `compat_fn!` work.
                 this.write_int(1, dest)?;
             }
             "SetConsoleTextAttribute" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
                 let [_hConsoleOutput, _wAttribute] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 // Pretend these does not exist / nothing happened, by returning zero.
                 this.write_null(dest)?;
             }
             "GetConsoleMode" if this.frame_in_std() => {
                 let [console, mode] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 this.read_target_isize(console)?;
                 this.deref_pointer(mode)?;
                 // Indicate an error.
@@ -728,27 +736,28 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "GetFileType" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
                 let [_hFile] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 // Return unknown file type.
                 this.write_null(dest)?;
             }
             "AddVectoredExceptionHandler" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
                 let [_First, _Handler] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 // Any non zero value works for the stdlib. This is just used for stack overflows anyway.
                 this.write_int(1, dest)?;
             }
             "SetThreadStackGuarantee" if this.frame_in_std() => {
                 #[allow(non_snake_case)]
                 let [_StackSizeInBytes] =
-                    this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
                 // Any non zero value works for the stdlib. This is just used for stack overflows anyway.
                 this.write_int(1, dest)?;
             }
             // this is only callable from std because we know that std ignores the return value
             "SwitchToThread" if this.frame_in_std() => {
-                let [] = this.check_shim(abi, Abi::System { unwind: false }, link_name, args)?;
+                let [] =
+                    this.check_shim(abi, ExternAbi::System { unwind: false }, link_name, args)?;
 
                 this.yield_active_thread();
 
@@ -767,7 +776,8 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     );
                 }
                 // This function looks and behaves excatly like miri_start_unwind.
-                let [payload] = this.check_shim(abi, Abi::C { unwind: true }, link_name, args)?;
+                let [payload] =
+                    this.check_shim(abi, ExternAbi::C { unwind: true }, link_name, args)?;
                 this.handle_miri_start_unwind(payload)?;
                 return interp_ok(EmulateItemResult::NeedsUnwind);
             }
diff --git a/src/tools/miri/src/shims/windows/handle.rs b/src/tools/miri/src/shims/windows/handle.rs
index 69d78f58bed..437a21534c9 100644
--- a/src/tools/miri/src/shims/windows/handle.rs
+++ b/src/tools/miri/src/shims/windows/handle.rs
@@ -1,6 +1,6 @@
 use std::mem::variant_count;
 
-use rustc_target::abi::HasDataLayout;
+use rustc_abi::HasDataLayout;
 
 use crate::*;
 
@@ -63,7 +63,7 @@ impl Handle {
         let floor_log2 = variant_count.ilog2();
 
         // we need to add one for non powers of two to compensate for the difference
-        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
+        #[expect(clippy::arithmetic_side_effects)] // cannot overflow
         if variant_count.is_power_of_two() { floor_log2 } else { floor_log2 + 1 }
     }
 
@@ -88,8 +88,7 @@ impl Handle {
 
         // packs the data into the lower `data_size` bits
         // and packs the discriminant right above the data
-        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
-        return discriminant << data_size | data;
+        discriminant << data_size | data
     }
 
     fn new(discriminant: u32, data: u32) -> Option<Self> {
@@ -107,11 +106,10 @@ impl Handle {
         let data_size = u32::BITS.strict_sub(disc_size);
 
         // the lower `data_size` bits of this mask are 1
-        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
+        #[expect(clippy::arithmetic_side_effects)] // cannot overflow
         let data_mask = 2u32.pow(data_size) - 1;
 
         // the discriminant is stored right above the lower `data_size` bits
-        #[allow(clippy::arithmetic_side_effects)] // cannot overflow
         let discriminant = handle >> data_size;
 
         // the data is stored in the lower `data_size` bits
@@ -123,7 +121,7 @@ impl Handle {
     pub fn to_scalar(self, cx: &impl HasDataLayout) -> Scalar {
         // 64-bit handles are sign extended 32-bit handles
         // see https://docs.microsoft.com/en-us/windows/win32/winprog64/interprocess-communication
-        #[allow(clippy::cast_possible_wrap)] // we want it to wrap
+        #[expect(clippy::cast_possible_wrap)] // we want it to wrap
         let signed_handle = self.to_packed() as i32;
         Scalar::from_target_isize(signed_handle.into(), cx)
     }
@@ -134,7 +132,7 @@ impl Handle {
     ) -> InterpResult<'tcx, Option<Self>> {
         let sign_extended_handle = handle.to_target_isize(cx)?;
 
-        #[allow(clippy::cast_sign_loss)] // we want to lose the sign
+        #[expect(clippy::cast_sign_loss)] // we want to lose the sign
         let handle = if let Ok(signed_handle) = i32::try_from(sign_extended_handle) {
             signed_handle as u32
         } else {
diff --git a/src/tools/miri/src/shims/windows/sync.rs b/src/tools/miri/src/shims/windows/sync.rs
index bfc83215f9b..7263958411f 100644
--- a/src/tools/miri/src/shims/windows/sync.rs
+++ b/src/tools/miri/src/shims/windows/sync.rs
@@ -1,6 +1,6 @@
 use std::time::Duration;
 
-use rustc_target::abi::Size;
+use rustc_abi::Size;
 
 use crate::concurrency::init_once::InitOnceStatus;
 use crate::*;
diff --git a/src/tools/miri/src/shims/windows/thread.rs b/src/tools/miri/src/shims/windows/thread.rs
index a920abea3a8..fd3ef1413ed 100644
--- a/src/tools/miri/src/shims/windows/thread.rs
+++ b/src/tools/miri/src/shims/windows/thread.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_middle::ty::layout::LayoutOf;
-use rustc_target::spec::abi::Abi;
 
 use self::shims::windows::handle::{EvalContextExt as _, Handle, PseudoHandle};
 use crate::*;
@@ -49,7 +49,7 @@ pub trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         this.start_regular_thread(
             thread,
             start_routine,
-            Abi::System { unwind: false },
+            ExternAbi::System { unwind: false },
             func_arg,
             this.layout_of(this.tcx.types.u32)?,
         )
diff --git a/src/tools/miri/src/shims/x86/aesni.rs b/src/tools/miri/src/shims/x86/aesni.rs
index 3a8138654fd..33b1f27713c 100644
--- a/src/tools/miri/src/shims/x86/aesni.rs
+++ b/src/tools/miri/src/shims/x86/aesni.rs
@@ -1,7 +1,7 @@
+use rustc_abi::ExternAbi;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::*;
 
@@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_aesni_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -27,7 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdec_si128
             "aesdec" | "aesdec.256" | "aesdec.512" => {
                 let [state, key] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 aes_round(this, state, key, dest, |state, key| {
                     let key = aes::Block::from(key.to_le_bytes());
@@ -45,7 +45,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesdeclast_si128
             "aesdeclast" | "aesdeclast.256" | "aesdeclast.512" => {
                 let [state, key] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 aes_round(this, state, key, dest, |state, key| {
                     let mut state = aes::Block::from(state.to_le_bytes());
@@ -70,7 +70,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenc_si128
             "aesenc" | "aesenc.256" | "aesenc.512" => {
                 let [state, key] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 aes_round(this, state, key, dest, |state, key| {
                     let key = aes::Block::from(key.to_le_bytes());
@@ -88,7 +88,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_aesenclast_si128
             "aesenclast" | "aesenclast.256" | "aesenclast.512" => {
                 let [state, key] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 aes_round(this, state, key, dest, |state, key| {
                     let mut state = aes::Block::from(state.to_le_bytes());
@@ -109,7 +109,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Used to implement the _mm_aesimc_si128 function.
             // Performs the AES InvMixColumns operation on `op`
             "aesimc" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 // Transmute to `u128`
                 let op = op.transmute(this.machine.layouts.u128, this)?;
diff --git a/src/tools/miri/src/shims/x86/avx.rs b/src/tools/miri/src/shims/x86/avx.rs
index 080e7c8ce0b..3971fa3b913 100644
--- a/src/tools/miri/src/shims/x86/avx.rs
+++ b/src/tools/miri/src/shims/x86/avx.rs
@@ -1,9 +1,9 @@
+use rustc_abi::ExternAbi;
 use rustc_apfloat::ieee::{Double, Single};
 use rustc_middle::mir;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::{
     FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, conditional_dot_product, convert_float_to_int,
@@ -17,7 +17,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_avx_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -34,7 +34,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // semantics.
             "min.ps.256" | "max.ps.256" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "min.ps.256" => FloatBinOp::Min,
@@ -47,7 +47,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Used to implement _mm256_min_pd and _mm256_max_pd functions.
             "min.pd.256" | "max.pd.256" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "min.pd.256" => FloatBinOp::Min,
@@ -61,7 +61,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Rounds the elements of `op` according to `rounding`.
             "round.ps.256" => {
                 let [op, rounding] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?;
             }
@@ -69,14 +69,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Rounds the elements of `op` according to `rounding`.
             "round.pd.256" => {
                 let [op, rounding] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?;
             }
             // Used to implement _mm256_{rcp,rsqrt}_ps functions.
             // Performs the operations on all components of `op`.
             "rcp.ps.256" | "rsqrt.ps.256" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "rcp.ps.256" => FloatUnaryOp::Rcp,
@@ -89,7 +89,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Used to implement the _mm256_dp_ps function.
             "dp.ps.256" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 conditional_dot_product(this, left, right, imm, dest)?;
             }
@@ -98,7 +98,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // in `left` and `right`.
             "hadd.ps.256" | "hadd.pd.256" | "hsub.ps.256" | "hsub.pd.256" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "hadd.ps.256" | "hadd.pd.256" => mir::BinOp::Add,
@@ -114,7 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // if true.
             "cmp.ps.256" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which =
                     FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -127,7 +127,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // if true.
             "cmp.pd.256" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which =
                     FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -138,7 +138,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // and _mm256_cvttpd_epi32 functions.
             // Converts packed f32/f64 to packed i32.
             "cvt.ps2dq.256" | "cvtt.ps2dq.256" | "cvt.pd2dq.256" | "cvtt.pd2dq.256" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let rnd = match unprefixed_name {
                     // "current SSE rounding mode", assume nearest
@@ -157,7 +157,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // `control` determines which element of the current `data` array is written.
             "vpermilvar.ps" | "vpermilvar.ps.256" => {
                 let [data, control] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (data, data_len) = this.project_to_simd(data)?;
                 let (control, control_len) = this.project_to_simd(control)?;
@@ -191,7 +191,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // written.
             "vpermilvar.pd" | "vpermilvar.pd.256" => {
                 let [data, control] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (data, data_len) = this.project_to_simd(data)?;
                 let (control, control_len) = this.project_to_simd(control)?;
@@ -224,7 +224,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // zero, according to `imm`.
             "vperm2f128.ps.256" | "vperm2f128.pd.256" | "vperm2f128.si.256" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 assert_eq!(dest.layout, left.layout);
                 assert_eq!(dest.layout, right.layout);
@@ -268,7 +268,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // loaded.
             "maskload.ps" | "maskload.pd" | "maskload.ps.256" | "maskload.pd.256" => {
                 let [ptr, mask] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 mask_load(this, ptr, mask, dest)?;
             }
@@ -279,7 +279,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores.
             "maskstore.ps" | "maskstore.pd" | "maskstore.ps.256" | "maskstore.pd.256" => {
                 let [ptr, mask, value] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 mask_store(this, ptr, mask, value)?;
             }
@@ -289,7 +289,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // the data crosses a cache line, but for Miri this is just a regular
             // unaligned read.
             "ldu.dq.256" => {
-                let [src_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [src_ptr] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let src_ptr = this.read_pointer(src_ptr)?;
                 let dest = dest.force_mplace(this)?;
 
@@ -301,7 +302,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Tests `op & mask == 0`, `op & mask == mask` or
             // `op & mask != 0 && op & mask != mask`
             "ptestz.256" | "ptestc.256" | "ptestnzc.256" => {
-                let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op, mask] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
                 let res = match unprefixed_name {
@@ -324,7 +326,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "vtestz.pd.256" | "vtestc.pd.256" | "vtestnzc.pd.256" | "vtestz.pd" | "vtestc.pd"
             | "vtestnzc.pd" | "vtestz.ps.256" | "vtestc.ps.256" | "vtestnzc.ps.256"
             | "vtestz.ps" | "vtestc.ps" | "vtestnzc.ps" => {
-                let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op, mask] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (direct, negated) = test_high_bits_masked(this, op, mask)?;
                 let res = match unprefixed_name {
@@ -346,7 +349,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 // compiler, making these functions no-ops.
 
                 // The only thing that needs to be ensured is the correct calling convention.
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
             }
             _ => return interp_ok(EmulateItemResult::NotSupported),
         }
diff --git a/src/tools/miri/src/shims/x86/avx2.rs b/src/tools/miri/src/shims/x86/avx2.rs
index 331b693a3e4..6aefb87d4d0 100644
--- a/src/tools/miri/src/shims/x86/avx2.rs
+++ b/src/tools/miri/src/shims/x86/avx2.rs
@@ -1,8 +1,8 @@
+use rustc_abi::ExternAbi;
 use rustc_middle::mir;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::{
     ShiftOp, horizontal_bin_op, int_abs, mask_load, mask_store, mpsadbw, packssdw, packsswb,
@@ -15,7 +15,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_avx2_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -28,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Used to implement the _mm256_abs_epi{8,16,32} functions.
             // Calculates the absolute value of packed 8/16/32-bit integers.
             "pabs.b" | "pabs.w" | "pabs.d" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 int_abs(this, op, dest)?;
             }
@@ -37,7 +37,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // integer values in `left` and `right`.
             "phadd.w" | "phadd.sw" | "phadd.d" | "phsub.w" | "phsub.sw" | "phsub.d" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (which, saturating) = match unprefixed_name {
                     "phadd.w" | "phadd.d" => (mir::BinOp::Add, false),
@@ -58,7 +58,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "gather.d.pd.256" | "gather.q.pd" | "gather.q.pd.256" | "gather.d.ps"
             | "gather.d.ps.256" | "gather.q.ps" | "gather.q.ps.256" => {
                 let [src, slice, offsets, mask, scale] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 assert_eq!(dest.layout, src.layout);
 
@@ -116,7 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // intermediate 32-bit integers, and pack the results in `dest`.
             "pmadd.wd" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -153,7 +153,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // produces the output at index `i`.
             "pmadd.ub.sw" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -188,7 +188,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // loaded.
             "maskload.d" | "maskload.q" | "maskload.d.256" | "maskload.q.256" => {
                 let [ptr, mask] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 mask_load(this, ptr, mask, dest)?;
             }
@@ -199,7 +199,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Unlike SSE2's _mm_maskmoveu_si128, these are not non-temporal stores.
             "maskstore.d" | "maskstore.q" | "maskstore.d.256" | "maskstore.q.256" => {
                 let [ptr, mask, value] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 mask_store(this, ptr, mask, value)?;
             }
@@ -211,7 +211,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mpsadbw_epu8
             "mpsadbw" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 mpsadbw(this, left, right, imm, dest)?;
             }
@@ -223,7 +223,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_mulhrs_epi16
             "pmul.hr.sw" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 pmulhrsw(this, left, right, dest)?;
             }
@@ -232,7 +232,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // vector with signed saturation.
             "packsswb" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packsswb(this, left, right, dest)?;
             }
@@ -241,7 +241,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // vector with signed saturation.
             "packssdw" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packssdw(this, left, right, dest)?;
             }
@@ -250,7 +250,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // unsigned integer vector with saturation.
             "packuswb" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packuswb(this, left, right, dest)?;
             }
@@ -259,7 +259,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // the result to a 16-bit unsigned integer vector with saturation.
             "packusdw" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packusdw(this, left, right, dest)?;
             }
@@ -269,7 +269,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // as indices.
             "permd" | "permps" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -290,7 +290,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Shuffles 128-bit blocks of `a` and `b` using `imm` as pattern.
             "vperm2i128" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 assert_eq!(left.layout.size.bits(), 256);
                 assert_eq!(right.layout.size.bits(), 256);
@@ -328,7 +328,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm256_sad_epu8
             "psad.bw" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -361,7 +361,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Each 128-bit block is shuffled independently.
             "pshuf.b" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -393,7 +393,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Basically, we multiply `left` with `right.signum()`.
             "psign.b" | "psign.w" | "psign.d" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 psign(this, left, right, dest)?;
             }
@@ -408,7 +408,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q"
             | "psrl.q" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left,
@@ -424,7 +424,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" | "psrlv.d" | "psrlv.d.256"
             | "psrlv.q" | "psrlv.q.256" | "psrav.d" | "psrav.d.256" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "psllv.d" | "psllv.d.256" | "psllv.q" | "psllv.q.256" => ShiftOp::Left,
diff --git a/src/tools/miri/src/shims/x86/bmi.rs b/src/tools/miri/src/shims/x86/bmi.rs
index 59e76abf179..0f9e8d6f025 100644
--- a/src/tools/miri/src/shims/x86/bmi.rs
+++ b/src/tools/miri/src/shims/x86/bmi.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::*;
 
@@ -8,7 +8,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_bmi_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -33,7 +33,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             return interp_ok(EmulateItemResult::NotSupported);
         }
 
-        let [left, right] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+        let [left, right] =
+            this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
         let left = this.read_scalar(left)?;
         let right = this.read_scalar(right)?;
 
diff --git a/src/tools/miri/src/shims/x86/gfni.rs b/src/tools/miri/src/shims/x86/gfni.rs
index c91b8c835f2..7b92d422cc5 100644
--- a/src/tools/miri/src/shims/x86/gfni.rs
+++ b/src/tools/miri/src/shims/x86/gfni.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::*;
 
@@ -8,7 +8,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_gfni_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -30,7 +30,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affine_
             "vgf2p8affineqb.128" | "vgf2p8affineqb.256" | "vgf2p8affineqb.512" => {
                 let [left, right, imm8] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 affine_transform(this, left, right, imm8, dest, /* inverse */ false)?;
             }
             // Used to implement the `_mm{, 256, 512}_gf2p8affineinv_epi64_epi8` functions.
@@ -38,7 +38,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8affineinv
             "vgf2p8affineinvqb.128" | "vgf2p8affineinvqb.256" | "vgf2p8affineinvqb.512" => {
                 let [left, right, imm8] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 affine_transform(this, left, right, imm8, dest, /* inverse */ true)?;
             }
             // Used to implement the `_mm{, 256, 512}_gf2p8mul_epi8` functions.
@@ -48,7 +48,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul
             "vgf2p8mulb.128" | "vgf2p8mulb.256" | "vgf2p8mulb.512" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -136,7 +136,7 @@ fn affine_transform<'tcx>(
 // This is a evaluated at compile time. Trait based conversion is not available.
 /// See <https://www.corsix.org/content/galois-field-instructions-2021-cpus> for the
 /// definition of `gf_inv` which was used for the creation of this table.
-#[allow(clippy::cast_possible_truncation)]
+#[expect(clippy::cast_possible_truncation)]
 static TABLE: [u8; 256] = {
     let mut array = [0; 256];
 
@@ -163,7 +163,7 @@ static TABLE: [u8; 256] = {
 /// polynomial representation with the reduction polynomial x^8 + x^4 + x^3 + x + 1.
 /// See <https://www.corsix.org/content/galois-field-instructions-2021-cpus> for details.
 // This is a const function. Trait based conversion is not available.
-#[allow(clippy::cast_possible_truncation)]
+#[expect(clippy::cast_possible_truncation)]
 const fn gf2p8_mul(left: u8, right: u8) -> u8 {
     // This implementation is based on the `gf2p8mul_byte` definition found inside the Intel intrinsics guide.
     // See https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=gf2p8mul
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index 2f63876327f..433e9e966f2 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -1,12 +1,11 @@
 use rand::Rng as _;
+use rustc_abi::{ExternAbi, Size};
 use rustc_apfloat::Float;
 use rustc_apfloat::ieee::Single;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_middle::{mir, ty};
 use rustc_span::Symbol;
-use rustc_target::abi::Size;
-use rustc_target::spec::abi::Abi;
 
 use self::helpers::bool_to_simd_element;
 use crate::*;
@@ -29,7 +28,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -47,7 +46,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     return interp_ok(EmulateItemResult::NotSupported);
                 }
 
-                let [cb_in, a, b] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
+                let [cb_in, a, b] = this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?;
 
                 let op = if unprefixed_name.starts_with("add") {
                     mir::BinOp::AddWithOverflow
@@ -71,7 +70,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                     return interp_ok(EmulateItemResult::NotSupported);
                 }
 
-                let [c_in, a, b, out] = this.check_shim(abi, Abi::Unadjusted, link_name, args)?;
+                let [c_in, a, b, out] =
+                    this.check_shim(abi, ExternAbi::Unadjusted, link_name, args)?;
                 let out = this.deref_pointer_as(
                     out,
                     if is_u64 { this.machine.layouts.u64 } else { this.machine.layouts.u32 },
@@ -88,7 +88,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // the instruction behaves like a no-op, so it is always safe to call the
             // intrinsic.
             "sse2.pause" => {
-                let [] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 // Only exhibit the spin-loop hint behavior when SSE2 is enabled.
                 if this.tcx.sess.unstable_target_features.contains(&Symbol::intern("sse2")) {
                     this.yield_active_thread();
@@ -108,7 +108,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
 
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 pclmulqdq(this, left, right, imm, dest, len)?;
             }
@@ -397,7 +397,6 @@ enum FloatUnaryOp {
 }
 
 /// Performs `which` scalar operation on `op` and returns the result.
-#[allow(clippy::arithmetic_side_effects)] // floating point operations without side effects
 fn unary_op_f32<'tcx>(
     this: &mut crate::MiriInterpCx<'tcx>,
     which: FloatUnaryOp,
@@ -426,7 +425,7 @@ fn unary_op_f32<'tcx>(
 }
 
 /// Disturbes a floating-point result by a relative error on the order of (-2^scale, 2^scale).
-#[allow(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic
+#[expect(clippy::arithmetic_side_effects)] // floating point arithmetic cannot panic
 fn apply_random_float_error<F: rustc_apfloat::Float>(
     this: &mut crate::MiriInterpCx<'_>,
     val: F,
@@ -1000,7 +999,6 @@ fn mask_load<'tcx>(
         let dest = this.project_index(&dest, i)?;
 
         if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 {
-            #[allow(clippy::arithmetic_side_effects)] // `Size` arithmetic is checked
             let ptr = ptr.wrapping_offset(dest.layout.size * i, &this.tcx);
             // Unaligned copy, which is what we want.
             this.mem_copy(ptr, dest.ptr(), dest.layout.size, /*nonoverlapping*/ true)?;
@@ -1036,7 +1034,6 @@ fn mask_store<'tcx>(
         if this.read_scalar(&mask)?.to_uint(mask_item_size)? >> high_bit_offset != 0 {
             // *Non-inbounds* pointer arithmetic to compute the destination.
             // (That's why we can't use a place projection.)
-            #[allow(clippy::arithmetic_side_effects)] // `Size` arithmetic is checked
             let ptr = ptr.wrapping_offset(value.layout.size * i, &this.tcx);
             // Deref the pointer *unaligned*, and do the copy.
             let dest = this.ptr_to_mplace_unaligned(ptr, value.layout);
@@ -1135,7 +1132,7 @@ fn pmulhrsw<'tcx>(
 
         // The result of this operation can overflow a signed 16-bit integer.
         // When `left` and `right` are -0x8000, the result is 0x8000.
-        #[allow(clippy::cast_possible_truncation)]
+        #[expect(clippy::cast_possible_truncation)]
         let res = res as i16;
 
         this.write_scalar(Scalar::from_i16(res), &dest)?;
diff --git a/src/tools/miri/src/shims/x86/sha.rs b/src/tools/miri/src/shims/x86/sha.rs
index 8553771b694..964204127d9 100644
--- a/src/tools/miri/src/shims/x86/sha.rs
+++ b/src/tools/miri/src/shims/x86/sha.rs
@@ -4,8 +4,8 @@
 //!
 //! [RustCrypto's sha256 module]: https://github.com/RustCrypto/hashes/blob/6be8466247e936c415d8aafb848697f39894a386/sha2/src/sha256/soft.rs
 
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use crate::*;
 
@@ -14,7 +14,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_sha_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -51,7 +51,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
         match unprefixed_name {
             // Used to implement the _mm_sha256rnds2_epu32 function.
             "256rnds2" => {
-                let [a, b, k] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [a, b, k] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (a_reg, a_len) = this.project_to_simd(a)?;
                 let (b_reg, b_len) = this.project_to_simd(b)?;
@@ -72,7 +73,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             // Used to implement the _mm_sha256msg1_epu32 function.
             "256msg1" => {
-                let [a, b] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [a, b] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (a_reg, a_len) = this.project_to_simd(a)?;
                 let (b_reg, b_len) = this.project_to_simd(b)?;
@@ -90,7 +92,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             }
             // Used to implement the _mm_sha256msg2_epu32 function.
             "256msg2" => {
-                let [a, b] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [a, b] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (a_reg, a_len) = this.project_to_simd(a)?;
                 let (b_reg, b_len) = this.project_to_simd(b)?;
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index 013900e95d3..9432b40a805 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -1,6 +1,6 @@
+use rustc_abi::ExternAbi;
 use rustc_apfloat::ieee::Single;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::{
     FloatBinOp, FloatUnaryOp, bin_op_simd_float_all, bin_op_simd_float_first, unary_op_ps,
@@ -13,7 +13,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_sse_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -33,7 +33,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // `right` and copies the remaining components from `left`.
             "min.ss" | "max.ss" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "min.ss" => FloatBinOp::Min,
@@ -50,7 +50,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // semantics.
             "min.ps" | "max.ps" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "min.ps" => FloatBinOp::Min,
@@ -64,7 +64,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Performs the operations on the first component of `op` and
             // copies the remaining components from `op`.
             "rcp.ss" | "rsqrt.ss" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "rcp.ss" => FloatUnaryOp::Rcp,
@@ -77,7 +77,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Used to implement _mm_{sqrt,rcp,rsqrt}_ps functions.
             // Performs the operations on all components of `op`.
             "rcp.ps" | "rsqrt.ps" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "rcp.ps" => FloatUnaryOp::Rcp,
@@ -97,7 +97,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // with hard-coded operations.
             "cmp.ss" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which =
                     FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -114,7 +114,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // with hard-coded operations.
             "cmp.ps" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which =
                     FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -128,7 +128,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "ucomieq.ss" | "ucomilt.ss" | "ucomile.ss" | "ucomigt.ss" | "ucomige.ss"
             | "ucomineq.ss" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -156,7 +156,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // _mm_cvtss_si64 and _mm_cvttss_si64 functions.
             // Converts the first component of `op` from f32 to i32/i64.
             "cvtss2si" | "cvttss2si" | "cvtss2si64" | "cvttss2si64" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let (op, _) = this.project_to_simd(op)?;
 
                 let op = this.read_immediate(&this.project_index(&op, 0)?)?;
@@ -185,7 +185,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.felixcloutier.com/x86/cvtsi2ss
             "cvtsi2ss" | "cvtsi642ss" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (dest, dest_len) = this.project_to_simd(dest)?;
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index de72e63f8af..4ff999be7cc 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -1,6 +1,6 @@
+use rustc_abi::ExternAbi;
 use rustc_apfloat::ieee::Double;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::{
     FloatBinOp, ShiftOp, bin_op_simd_float_all, bin_op_simd_float_first, convert_float_to_int,
@@ -13,7 +13,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_sse2_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -40,7 +40,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // intermediate 32-bit integers, and pack the results in `dest`.
             "pmadd.wd" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -79,7 +79,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_sad_epu8
             "psad.bw" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -118,7 +118,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "psll.w" | "psrl.w" | "psra.w" | "psll.d" | "psrl.d" | "psra.d" | "psll.q"
             | "psrl.q" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "psll.w" | "psll.d" | "psll.q" => ShiftOp::Left,
@@ -133,7 +133,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // and _mm_cvttpd_epi32 functions.
             // Converts packed f32/f64 to packed i32.
             "cvtps2dq" | "cvttps2dq" | "cvtpd2dq" | "cvttpd2dq" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (op_len, _) = op.layout.ty.simd_size_and_type(*this.tcx);
                 let (dest_len, _) = dest.layout.ty.simd_size_and_type(*this.tcx);
@@ -171,7 +171,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // vector with signed saturation.
             "packsswb.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packsswb(this, left, right, dest)?;
             }
@@ -180,7 +180,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // unsigned integer vector with saturation.
             "packuswb.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packuswb(this, left, right, dest)?;
             }
@@ -189,7 +189,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // vector with signed saturation.
             "packssdw.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packssdw(this, left, right, dest)?;
             }
@@ -200,7 +200,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // semantics.
             "min.sd" | "max.sd" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "min.sd" => FloatBinOp::Min,
@@ -217,7 +217,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // semantics.
             "min.pd" | "max.pd" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "min.pd" => FloatBinOp::Min,
@@ -237,7 +237,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // with hard-coded operations.
             "cmp.sd" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which =
                     FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -254,7 +254,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // with hard-coded operations.
             "cmp.pd" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which =
                     FloatBinOp::cmp_from_imm(this, this.read_scalar(imm)?.to_i8()?, link_name)?;
@@ -268,7 +268,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             | "ucomieq.sd" | "ucomilt.sd" | "ucomile.sd" | "ucomigt.sd" | "ucomige.sd"
             | "ucomineq.sd" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -296,7 +296,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // _mm_cvtsd_si64 and _mm_cvttsd_si64 functions.
             // Converts the first component of `op` from f64 to i32/i64.
             "cvtsd2si" | "cvttsd2si" | "cvtsd2si64" | "cvttsd2si64" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let (op, _) = this.project_to_simd(op)?;
 
                 let op = this.read_immediate(&this.project_index(&op, 0)?)?;
@@ -323,7 +323,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // the remaining elements from `left`
             "cvtsd2ss" | "cvtss2sd" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, _) = this.project_to_simd(right)?;
diff --git a/src/tools/miri/src/shims/x86/sse3.rs b/src/tools/miri/src/shims/x86/sse3.rs
index 9aa4dd59950..86153d71b28 100644
--- a/src/tools/miri/src/shims/x86/sse3.rs
+++ b/src/tools/miri/src/shims/x86/sse3.rs
@@ -1,6 +1,6 @@
+use rustc_abi::ExternAbi;
 use rustc_middle::mir;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::horizontal_bin_op;
 use crate::*;
@@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_sse3_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -25,7 +25,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // in `left` and `right`.
             "hadd.ps" | "hadd.pd" | "hsub.ps" | "hsub.pd" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let which = match unprefixed_name {
                     "hadd.ps" | "hadd.pd" => mir::BinOp::Add,
@@ -41,7 +41,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // the data crosses a cache line, but for Miri this is just a regular
             // unaligned read.
             "ldu.dq" => {
-                let [src_ptr] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [src_ptr] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let src_ptr = this.read_pointer(src_ptr)?;
                 let dest = dest.force_mplace(this)?;
 
diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs
index 7bf8ddea2fe..b81d6f24141 100644
--- a/src/tools/miri/src/shims/x86/sse41.rs
+++ b/src/tools/miri/src/shims/x86/sse41.rs
@@ -1,5 +1,5 @@
+use rustc_abi::ExternAbi;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::{conditional_dot_product, mpsadbw, packusdw, round_all, round_first, test_bits_masked};
 use crate::*;
@@ -9,7 +9,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_sse41_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -27,7 +27,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // `i` is zeroed.
             "insertps" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -63,7 +63,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // the result to a 16-bit unsigned integer vector with saturation.
             "packusdw" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 packusdw(this, left, right, dest)?;
             }
@@ -74,7 +74,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // 4 bits of `imm`.
             "dpps" | "dppd" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 conditional_dot_product(this, left, right, imm, dest)?;
             }
@@ -83,7 +83,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // and copies the remaining elements from `left`.
             "round.ss" => {
                 let [left, right, rounding] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 round_first::<rustc_apfloat::ieee::Single>(this, left, right, rounding, dest)?;
             }
@@ -91,7 +91,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // functions. Rounds the elements of `op` according to `rounding`.
             "round.ps" => {
                 let [op, rounding] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 round_all::<rustc_apfloat::ieee::Single>(this, op, rounding, dest)?;
             }
@@ -100,7 +100,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // and copies the remaining elements from `left`.
             "round.sd" => {
                 let [left, right, rounding] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 round_first::<rustc_apfloat::ieee::Double>(this, left, right, rounding, dest)?;
             }
@@ -108,7 +108,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // functions. Rounds the elements of `op` according to `rounding`.
             "round.pd" => {
                 let [op, rounding] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 round_all::<rustc_apfloat::ieee::Double>(this, op, rounding, dest)?;
             }
@@ -116,7 +116,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Find the minimum unsinged 16-bit integer in `op` and
             // returns its value and position.
             "phminposuw" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (op, op_len) = this.project_to_simd(op)?;
                 let (dest, dest_len) = this.project_to_simd(dest)?;
@@ -151,7 +151,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mpsadbw_epu8
             "mpsadbw" => {
                 let [left, right, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 mpsadbw(this, left, right, imm, dest)?;
             }
@@ -160,7 +160,8 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Tests `(op & mask) == 0`, `(op & mask) == mask` or
             // `(op & mask) != 0 && (op & mask) != mask`
             "ptestz" | "ptestc" | "ptestnzc" => {
-                let [op, mask] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op, mask] =
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (all_zero, masked_set) = test_bits_masked(this, op, mask)?;
                 let res = match unprefixed_name {
diff --git a/src/tools/miri/src/shims/x86/sse42.rs b/src/tools/miri/src/shims/x86/sse42.rs
index f31cd406349..cc7cfab5041 100644
--- a/src/tools/miri/src/shims/x86/sse42.rs
+++ b/src/tools/miri/src/shims/x86/sse42.rs
@@ -1,9 +1,8 @@
+use rustc_abi::{ExternAbi, Size};
 use rustc_middle::mir;
 use rustc_middle::ty::Ty;
 use rustc_middle::ty::layout::LayoutOf as _;
 use rustc_span::Symbol;
-use rustc_target::abi::Size;
-use rustc_target::spec::abi::Abi;
 
 use crate::*;
 
@@ -69,7 +68,7 @@ const USE_SIGNED: u8 = 2;
 /// The mask may be negated if negation flags inside the immediate byte are set.
 ///
 /// For more information, see the Intel Software Developer's Manual, Vol. 2b, Chapter 4.1.
-#[allow(clippy::arithmetic_side_effects)]
+#[expect(clippy::arithmetic_side_effects)]
 fn compare_strings<'tcx>(
     this: &mut MiriInterpCx<'tcx>,
     str1: &OpTy<'tcx>,
@@ -201,7 +200,7 @@ fn deconstruct_args<'tcx>(
     unprefixed_name: &str,
     this: &mut MiriInterpCx<'tcx>,
     link_name: Symbol,
-    abi: Abi,
+    abi: ExternAbi,
     args: &[OpTy<'tcx>],
 ) -> InterpResult<'tcx, (OpTy<'tcx>, OpTy<'tcx>, Option<(u64, u64)>, u8)> {
     let array_layout_fn = |this: &mut MiriInterpCx<'tcx>, imm: u8| {
@@ -224,7 +223,7 @@ fn deconstruct_args<'tcx>(
 
     if is_explicit {
         let [str1, len1, str2, len2, imm] =
-            this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+            this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
         let imm = this.read_scalar(imm)?.to_u8()?;
 
         let default_len = default_len::<u32>(imm);
@@ -237,7 +236,8 @@ fn deconstruct_args<'tcx>(
 
         interp_ok((str1, str2, Some((len1, len2)), imm))
     } else {
-        let [str1, str2, imm] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+        let [str1, str2, imm] =
+            this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
         let imm = this.read_scalar(imm)?.to_u8()?;
 
         let array_layout = array_layout_fn(this, imm)?;
@@ -279,7 +279,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_sse42_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -388,7 +388,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=924,925
             "pcmpistriz128" | "pcmpistris128" => {
                 let [str1, str2, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let imm = this.read_scalar(imm)?.to_u8()?;
 
                 let str = if unprefixed_name == "pcmpistris128" { str1 } else { str2 };
@@ -409,7 +409,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#ig_expand=1046,1047
             "pcmpestriz128" | "pcmpestris128" => {
                 let [_, len1, _, len2, imm] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let len = if unprefixed_name == "pcmpestris128" { len1 } else { len2 };
                 let len = this.read_scalar(len)?.to_i32()?;
                 let imm = this.read_scalar(imm)?.to_u8()?;
@@ -437,14 +437,14 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
                 }
 
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
                 let left = this.read_scalar(left)?;
                 let right = this.read_scalar(right)?;
 
                 let crc = if bit_size == 64 {
                     // The 64-bit version will only consider the lower 32 bits,
                     // while the upper 32 bits get discarded.
-                    #[allow(clippy::cast_possible_truncation)]
+                    #[expect(clippy::cast_possible_truncation)]
                     u128::from((left.to_u64()? as u32).reverse_bits())
                 } else {
                     u128::from(left.to_u32()?.reverse_bits())
diff --git a/src/tools/miri/src/shims/x86/ssse3.rs b/src/tools/miri/src/shims/x86/ssse3.rs
index 76a2451dea4..cdab78bc742 100644
--- a/src/tools/miri/src/shims/x86/ssse3.rs
+++ b/src/tools/miri/src/shims/x86/ssse3.rs
@@ -1,6 +1,6 @@
+use rustc_abi::ExternAbi;
 use rustc_middle::mir;
 use rustc_span::Symbol;
-use rustc_target::spec::abi::Abi;
 
 use super::{horizontal_bin_op, int_abs, pmulhrsw, psign};
 use crate::*;
@@ -10,7 +10,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
     fn emulate_x86_ssse3_intrinsic(
         &mut self,
         link_name: Symbol,
-        abi: Abi,
+        abi: ExternAbi,
         args: &[OpTy<'tcx>],
         dest: &MPlaceTy<'tcx>,
     ) -> InterpResult<'tcx, EmulateItemResult> {
@@ -23,7 +23,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Used to implement the _mm_abs_epi{8,16,32} functions.
             // Calculates the absolute value of packed 8/16/32-bit integers.
             "pabs.b.128" | "pabs.w.128" | "pabs.d.128" => {
-                let [op] = this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                let [op] = this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 int_abs(this, op, dest)?;
             }
@@ -32,7 +32,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_shuffle_epi8
             "pshuf.b.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -62,7 +62,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             "phadd.w.128" | "phadd.sw.128" | "phadd.d.128" | "phsub.w.128" | "phsub.sw.128"
             | "phsub.d.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (which, saturating) = match unprefixed_name {
                     "phadd.w.128" | "phadd.d.128" => (mir::BinOp::Add, false),
@@ -82,7 +82,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_maddubs_epi16
             "pmadd.ub.sw.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 let (left, left_len) = this.project_to_simd(left)?;
                 let (right, right_len) = this.project_to_simd(right)?;
@@ -118,7 +118,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // https://www.intel.com/content/www/us/en/docs/intrinsics-guide/index.html#text=_mm_mulhrs_epi16
             "pmul.hr.sw.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 pmulhrsw(this, left, right, dest)?;
             }
@@ -129,7 +129,7 @@ pub(super) trait EvalContextExt<'tcx>: crate::MiriInterpCxExt<'tcx> {
             // Basically, we multiply `left` with `right.signum()`.
             "psign.b.128" | "psign.w.128" | "psign.d.128" => {
                 let [left, right] =
-                    this.check_shim(abi, Abi::C { unwind: false }, link_name, args)?;
+                    this.check_shim(abi, ExternAbi::C { unwind: false }, link_name, args)?;
 
                 psign(this, left, right, dest)?;
             }
diff --git a/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs b/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs
index 4e892e6e3cb..ae5731bc8a6 100644
--- a/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs
+++ b/src/tools/miri/tests/pass/shims/x86/intrinsics-sha.rs
@@ -181,7 +181,7 @@ unsafe fn schedule(v0: __m128i, v1: __m128i, v2: __m128i, v3: __m128i) -> __m128
 }
 
 // we use unaligned loads with `__m128i` pointers
-#[allow(clippy::cast_ptr_alignment)]
+#[expect(clippy::cast_ptr_alignment)]
 #[target_feature(enable = "sha,sse2,ssse3,sse4.1")]
 unsafe fn digest_blocks(state: &mut [u32; 8], blocks: &[[u8; 64]]) {
     #[allow(non_snake_case)]
diff --git a/src/tools/rust-analyzer/Cargo.lock b/src/tools/rust-analyzer/Cargo.lock
index 695c37f6d7b..424357e8473 100644
--- a/src/tools/rust-analyzer/Cargo.lock
+++ b/src/tools/rust-analyzer/Cargo.lock
@@ -1364,7 +1364,6 @@ dependencies = [
  "proc-macro-api",
  "proc-macro-test",
  "ra-ap-rustc_lexer",
- "snap",
  "span",
  "stdx",
  "syntax-bridge",
@@ -1889,12 +1888,6 @@ dependencies = [
 ]
 
 [[package]]
-name = "snap"
-version = "1.1.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-checksum = "1b6b67fb9a61334225b5b790716f609cd58395f895b3fe8b328786812a40bc3b"
-
-[[package]]
 name = "span"
 version = "0.0.0"
 dependencies = [
diff --git a/src/tools/rust-analyzer/Cargo.toml b/src/tools/rust-analyzer/Cargo.toml
index 3aa93b7b7b4..1099d2cb918 100644
--- a/src/tools/rust-analyzer/Cargo.toml
+++ b/src/tools/rust-analyzer/Cargo.toml
@@ -145,7 +145,6 @@ smallvec = { version = "1.10.0", features = [
   "const_generics",
 ] }
 smol_str = "0.3.2"
-snap = "1.1.0"
 text-size = "1.1.1"
 tracing = "0.1.40"
 tracing-tree = "0.3.0"
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
index e8d9677c928..4fabcc90067 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/Cargo.toml
@@ -16,7 +16,6 @@ doctest = false
 object.workspace = true
 libloading.workspace = true
 memmap2.workspace = true
-snap.workspace = true
 
 stdx.workspace = true
 tt.workspace = true
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
index 1f7ef7914ba..7f0e95c50de 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/dylib/version.rs
@@ -8,7 +8,6 @@ use std::{
 use memmap2::Mmap;
 use object::read::{File as BinaryFile, Object, ObjectSection};
 use paths::AbsPath;
-use snap::read::FrameDecoder as SnapDecoder;
 
 #[derive(Debug)]
 #[allow(dead_code)]
@@ -123,9 +122,8 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
     let version = u32::from_be_bytes([dot_rustc[4], dot_rustc[5], dot_rustc[6], dot_rustc[7]]);
     // Last supported version is:
     // https://github.com/rust-lang/rust/commit/b94cfefc860715fb2adf72a6955423d384c69318
-    let (snappy_portion, bytes_before_version) = match version {
-        5 | 6 => (&dot_rustc[8..], 13),
-        7 | 8 => {
+    let (mut metadata_portion, bytes_before_version) = match version {
+        8 => {
             let len_bytes = &dot_rustc[8..12];
             let data_len = u32::from_be_bytes(len_bytes.try_into().unwrap()) as usize;
             (&dot_rustc[12..data_len + 12], 13)
@@ -143,13 +141,6 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
         }
     };
 
-    let mut uncompressed: Box<dyn Read> = if &snappy_portion[0..4] == b"rust" {
-        // Not compressed.
-        Box::new(snappy_portion)
-    } else {
-        Box::new(SnapDecoder::new(snappy_portion))
-    };
-
     // We're going to skip over the bytes before the version string, so basically:
     // 8 bytes for [b'r',b'u',b's',b't',0,0,0,5]
     // 4 or 8 bytes for [crate root bytes]
@@ -157,11 +148,11 @@ pub fn read_version(dylib_path: &AbsPath) -> io::Result<String> {
     // so 13 or 17 bytes in total, and we should check the last of those bytes
     // to know the length
     let mut bytes = [0u8; 17];
-    uncompressed.read_exact(&mut bytes[..bytes_before_version])?;
+    metadata_portion.read_exact(&mut bytes[..bytes_before_version])?;
     let length = bytes[bytes_before_version - 1];
 
     let mut version_string_utf8 = vec![0u8; length as usize];
-    uncompressed.read_exact(&mut version_string_utf8)?;
+    metadata_portion.read_exact(&mut version_string_utf8)?;
     let version_string = String::from_utf8(version_string_utf8);
     version_string.map_err(|e| io::Error::new(io::ErrorKind::InvalidData, e))
 }
diff --git a/src/tools/tidy/src/deps.rs b/src/tools/tidy/src/deps.rs
index 5163f039a23..f3bd72fe647 100644
--- a/src/tools/tidy/src/deps.rs
+++ b/src/tools/tidy/src/deps.rs
@@ -24,6 +24,7 @@ const LICENSES: &[&str] = &[
     "BSD-2-Clause OR Apache-2.0 OR MIT",                   // zerocopy
     "ISC",
     "MIT / Apache-2.0",
+    "MIT AND Apache-2.0 WITH LLVM-exception AND (MIT OR Apache-2.0)", // compiler-builtins
     "MIT OR Apache-2.0 OR LGPL-2.1-or-later",              // r-efi, r-efi-alloc
     "MIT OR Apache-2.0 OR Zlib",                           // tinyvec_macros
     "MIT OR Apache-2.0",
@@ -100,7 +101,6 @@ const EXCEPTIONS: ExceptionList = &[
     ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"),     // rustc (license is the same as LLVM uses)
     ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0                       // cargo/... (because of serde)
     ("self_cell", "Apache-2.0"),                             // rustc (fluent translations)
-    ("snap", "BSD-3-Clause"),                                // rustc
     ("wasi-preview1-component-adapter-provider", "Apache-2.0 WITH LLVM-exception"), // rustc
     // tidy-alphabetical-end
 ];
@@ -162,7 +162,6 @@ const EXCEPTIONS_RUST_ANALYZER: ExceptionList = &[
     ("rustc_apfloat", "Apache-2.0 WITH LLVM-exception"),
     ("ryu", "Apache-2.0 OR BSL-1.0"), // BSL is not acceptble, but we use it under Apache-2.0
     ("scip", "Apache-2.0"),
-    ("snap", "BSD-3-Clause"),
     // tidy-alphabetical-end
 ];
 
@@ -390,7 +389,6 @@ const PERMITTED_RUSTC_DEPENDENCIES: &[&str] = &[
     "sharded-slab",
     "shlex",
     "smallvec",
-    "snap",
     "stable_deref_trait",
     "stacker",
     "static_assertions",
diff --git a/tests/assembly/asm-comments.rs b/tests/assembly/asm/comments.rs
index 557009975dd..557009975dd 100644
--- a/tests/assembly/asm-comments.rs
+++ b/tests/assembly/asm/comments.rs
diff --git a/tests/assembly/asm/loongarch-type.rs b/tests/assembly/asm/loongarch-type.rs
index 1b097f41105..c51d35876d9 100644
--- a/tests/assembly/asm/loongarch-type.rs
+++ b/tests/assembly/asm/loongarch-type.rs
@@ -3,7 +3,7 @@
 //@ compile-flags: -Zmerge-functions=disabled
 //@ needs-llvm-components: loongarch
 
-#![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
+#![feature(no_core, lang_items, rustc_attrs)]
 #![crate_type = "rlib"]
 #![no_core]
 #![allow(asm_sub_register, non_camel_case_types)]
diff --git a/tests/assembly/compiletest-self-test/use-minicore-no-run.rs b/tests/assembly/compiletest-self-test/use-minicore-no-run.rs
new file mode 100644
index 00000000000..0e4f05c4b37
--- /dev/null
+++ b/tests/assembly/compiletest-self-test/use-minicore-no-run.rs
@@ -0,0 +1,5 @@
+//! `compiletest` self-test to check that `add-core-stubs` is incompatible with run pass modes.
+
+//@ add-core-stubs
+//@ run-pass
+//@ should-fail
diff --git a/tests/auxiliary/minicore.rs b/tests/auxiliary/minicore.rs
new file mode 100644
index 00000000000..49a7580eccc
--- /dev/null
+++ b/tests/auxiliary/minicore.rs
@@ -0,0 +1,72 @@
+//! Auxiliary `minicore` prelude which stubs out `core` items for `no_core` tests that need to work
+//! in cross-compilation scenarios where no `core` is available (that don't want nor need to
+//! `-Zbuild-std`).
+//!
+//! # Important notes
+//!
+//! - `minicore` is **only** intended for `core` items, and the stubs should match the actual `core`
+//!   items.
+//!
+//! # References
+//!
+//! This is partially adapted from `rustc_codegen_cranelift`:
+//! <https://github.com/rust-lang/rust/blob/c0b5cc9003f6464c11ae1c0662c6a7e06f6f5cab/compiler/rustc_codegen_cranelift/example/mini_core.rs>.
+// ignore-tidy-linelength
+
+#![feature(no_core, lang_items, rustc_attrs)]
+#![allow(unused, improper_ctypes_definitions, internal_features)]
+#![no_std]
+#![no_core]
+
+// `core` has some exotic `marker_impls!` macro for handling the with-generics cases, but for our
+// purposes, just use a simple macro_rules macro.
+macro_rules! impl_marker_trait {
+    ($Trait:ident => [$( $ty:ident ),* $(,)?] ) => {
+        $( impl $Trait for $ty {} )*
+    }
+}
+
+#[lang = "sized"]
+pub trait Sized {}
+
+#[lang = "legacy_receiver"]
+pub trait LegacyReceiver {}
+impl<T: ?Sized> LegacyReceiver for &T {}
+impl<T: ?Sized> LegacyReceiver for &mut T {}
+
+#[lang = "copy"]
+pub trait Copy: Sized {}
+
+impl_marker_trait!(Copy => [ bool, char, isize, usize, i8, i16, i32, i64, u8, u16, u32, u64 ]);
+impl<'a, T: ?Sized> Copy for &'a T {}
+impl<T: ?Sized> Copy for *const T {}
+impl<T: ?Sized> Copy for *mut T {}
+
+#[lang = "phantom_data"]
+pub struct PhantomData<T: ?Sized>;
+impl<T: ?Sized> Copy for PhantomData<T> {}
+
+pub enum Option<T> {
+    None,
+    Some(T),
+}
+impl<T: Copy> Copy for Option<T> {}
+
+pub enum Result<T, E> {
+    Ok(T),
+    Err(E),
+}
+impl<T: Copy, E: Copy> Copy for Result<T, E> {}
+
+#[lang = "manually_drop"]
+#[repr(transparent)]
+pub struct ManuallyDrop<T: ?Sized> {
+    value: T,
+}
+impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {}
+
+#[lang = "unsafe_cell"]
+#[repr(transparent)]
+pub struct UnsafeCell<T: ?Sized> {
+    value: T,
+}
diff --git a/tests/codegen/asm-arm64ec-clobbers.rs b/tests/codegen/asm/arm64ec-clobbers.rs
index 2ec61907947..2ec61907947 100644
--- a/tests/codegen/asm-arm64ec-clobbers.rs
+++ b/tests/codegen/asm/arm64ec-clobbers.rs
diff --git a/tests/codegen/foo.s b/tests/codegen/asm/foo.s
index 304d82aa0c6..304d82aa0c6 100644
--- a/tests/codegen/foo.s
+++ b/tests/codegen/asm/foo.s
diff --git a/tests/codegen/global_asm.rs b/tests/codegen/asm/global_asm.rs
index 32075daa3cf..32075daa3cf 100644
--- a/tests/codegen/global_asm.rs
+++ b/tests/codegen/asm/global_asm.rs
diff --git a/tests/codegen/global_asm_include.rs b/tests/codegen/asm/global_asm_include.rs
index 98be9c3e333..98be9c3e333 100644
--- a/tests/codegen/global_asm_include.rs
+++ b/tests/codegen/asm/global_asm_include.rs
diff --git a/tests/codegen/global_asm_x2.rs b/tests/codegen/asm/global_asm_x2.rs
index 9e3a00f0680..9e3a00f0680 100644
--- a/tests/codegen/global_asm_x2.rs
+++ b/tests/codegen/asm/global_asm_x2.rs
diff --git a/tests/codegen/asm-goto.rs b/tests/codegen/asm/goto.rs
index e522d0da5b4..e522d0da5b4 100644
--- a/tests/codegen/asm-goto.rs
+++ b/tests/codegen/asm/goto.rs
diff --git a/tests/codegen/asm-may_unwind.rs b/tests/codegen/asm/may_unwind.rs
index be66b3975ff..be66b3975ff 100644
--- a/tests/codegen/asm-may_unwind.rs
+++ b/tests/codegen/asm/may_unwind.rs
diff --git a/tests/codegen/asm-maybe-uninit.rs b/tests/codegen/asm/maybe-uninit.rs
index 55813c35a46..55813c35a46 100644
--- a/tests/codegen/asm-maybe-uninit.rs
+++ b/tests/codegen/asm/maybe-uninit.rs
diff --git a/tests/codegen/asm-msp430-clobbers.rs b/tests/codegen/asm/msp430-clobbers.rs
index c00c04f3088..c00c04f3088 100644
--- a/tests/codegen/asm-msp430-clobbers.rs
+++ b/tests/codegen/asm/msp430-clobbers.rs
diff --git a/tests/codegen/asm-multiple-options.rs b/tests/codegen/asm/multiple-options.rs
index 1ee295e32c9..1ee295e32c9 100644
--- a/tests/codegen/asm-multiple-options.rs
+++ b/tests/codegen/asm/multiple-options.rs
diff --git a/tests/codegen/asm-options.rs b/tests/codegen/asm/options.rs
index 96a72c2f5ae..96a72c2f5ae 100644
--- a/tests/codegen/asm-options.rs
+++ b/tests/codegen/asm/options.rs
diff --git a/tests/codegen/asm-powerpc-clobbers.rs b/tests/codegen/asm/powerpc-clobbers.rs
index 0be1b66bd99..0be1b66bd99 100644
--- a/tests/codegen/asm-powerpc-clobbers.rs
+++ b/tests/codegen/asm/powerpc-clobbers.rs
diff --git a/tests/codegen/asm-s390x-clobbers.rs b/tests/codegen/asm/s390x-clobbers.rs
index 45f72206bdf..45f72206bdf 100644
--- a/tests/codegen/asm-s390x-clobbers.rs
+++ b/tests/codegen/asm/s390x-clobbers.rs
diff --git a/tests/codegen/asm-sanitize-llvm.rs b/tests/codegen/asm/sanitize-llvm.rs
index fb332f9a0f3..fb332f9a0f3 100644
--- a/tests/codegen/asm-sanitize-llvm.rs
+++ b/tests/codegen/asm/sanitize-llvm.rs
diff --git a/tests/codegen/asm-clobber_abi.rs b/tests/codegen/asm/x86-clobber_abi.rs
index cc563474bf8..cc563474bf8 100644
--- a/tests/codegen/asm-clobber_abi.rs
+++ b/tests/codegen/asm/x86-clobber_abi.rs
diff --git a/tests/codegen/asm-clobbers.rs b/tests/codegen/asm/x86-clobbers.rs
index 4094db74134..4094db74134 100644
--- a/tests/codegen/asm-clobbers.rs
+++ b/tests/codegen/asm/x86-clobbers.rs
diff --git a/tests/codegen/asm-target-clobbers.rs b/tests/codegen/asm/x86-target-clobbers.rs
index 119372491ff..119372491ff 100644
--- a/tests/codegen/asm-target-clobbers.rs
+++ b/tests/codegen/asm/x86-target-clobbers.rs
diff --git a/tests/codegen/clone_as_copy.rs b/tests/codegen/clone_as_copy.rs
index 36a59ae56b7..6ba198297e2 100644
--- a/tests/codegen/clone_as_copy.rs
+++ b/tests/codegen/clone_as_copy.rs
@@ -1,4 +1,6 @@
 //@ revisions: DEBUGINFO NODEBUGINFO
+//@ compile-flags: -Zunsound-mir-opts
+// FIXME: see <https://github.com/rust-lang/rust/issues/132353>
 //@ compile-flags: -O -Cno-prepopulate-passes
 //@ [DEBUGINFO] compile-flags: -Cdebuginfo=full
 
diff --git a/tests/codegen/compiletest-self-test/minicore-smoke-test.rs b/tests/codegen/compiletest-self-test/minicore-smoke-test.rs
new file mode 100644
index 00000000000..9dd1bf29c6c
--- /dev/null
+++ b/tests/codegen/compiletest-self-test/minicore-smoke-test.rs
@@ -0,0 +1,20 @@
+//! Basic smoke test for `minicore` test auxiliary.
+
+//@ add-core-stubs
+//@ compile-flags: --target=x86_64-unknown-linux-gnu
+//@ needs-llvm-components: x86
+
+#![crate_type = "lib"]
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+struct Meow;
+impl Copy for Meow {}
+
+// CHECK-LABEL: meow
+#[no_mangle]
+fn meow() {}
diff --git a/tests/codegen/issues/issue-64219-fn-ptr-call-returning-never-is-noreturn.rs b/tests/codegen/issues/issue-64219-fn-ptr-call-returning-never-is-noreturn.rs
new file mode 100644
index 00000000000..86d020e1751
--- /dev/null
+++ b/tests/codegen/issues/issue-64219-fn-ptr-call-returning-never-is-noreturn.rs
@@ -0,0 +1,19 @@
+//! Test for https://github.com/rust-lang/rust/issues/64219
+//! Check if `noreturn` attribute is applied on calls to
+//! function pointers returning `!` (never type).
+
+#![crate_type = "lib"]
+
+extern "C" {
+    static FOO: fn() -> !;
+}
+
+// CHECK-LABEL: @foo
+#[no_mangle]
+pub unsafe fn foo() {
+    // CHECK: call
+    // CHECK-SAME: [[NUM:#[0-9]+$]]
+    FOO();
+}
+
+// CHECK: attributes [[NUM]] = {{{.*}} noreturn {{.*}}}
diff --git a/tests/codegen/issues/issue-86109-eliminate-div-by-zero-check.rs b/tests/codegen/issues/issue-86109-eliminate-div-by-zero-check.rs
new file mode 100644
index 00000000000..a8fab61b13e
--- /dev/null
+++ b/tests/codegen/issues/issue-86109-eliminate-div-by-zero-check.rs
@@ -0,0 +1,26 @@
+//@ compile-flags: -O
+//! Test for https://github.com/rust-lang/rust/issues/86109
+//! Check LLVM can eliminate the impossible division by zero check by
+//! ensuring there is no call (to panic) instruction.
+//!
+//! This has been fixed since `rustc 1.70.0`.
+
+#![crate_type = "lib"]
+
+type T = i16;
+
+// CHECK-LABEL: @foo
+#[no_mangle]
+pub fn foo(start: T) -> T {
+    // CHECK-NOT: panic
+    if start <= 0 {
+        return 0;
+    }
+    let mut count = 0;
+    for i in start..10_000 {
+        if 752 % i != 0 {
+            count += 1;
+        }
+    }
+    count
+}
diff --git a/tests/codegen/try_question_mark_nop.rs b/tests/codegen/try_question_mark_nop.rs
index 65167f5c5af..bbab0d9eb1d 100644
--- a/tests/codegen/try_question_mark_nop.rs
+++ b/tests/codegen/try_question_mark_nop.rs
@@ -1,10 +1,7 @@
 //@ compile-flags: -O -Z merge-functions=disabled --edition=2021
 //@ only-x86_64
 // FIXME: Remove the `min-llvm-version`.
-//@ revisions: NINETEEN TWENTY
-//@[NINETEEN] min-llvm-version: 19
-//@[NINETEEN] ignore-llvm-version: 20-99
-//@[TWENTY] min-llvm-version: 20
+//@ min-llvm-version: 19
 
 #![crate_type = "lib"]
 #![feature(try_blocks)]
@@ -16,12 +13,9 @@ use std::ptr::NonNull;
 #[no_mangle]
 pub fn option_nop_match_32(x: Option<u32>) -> Option<u32> {
     // CHECK: start:
-    // NINETEEN-NEXT: [[TRUNC:%.*]] = trunc nuw i32 %0 to i1
-    // NINETEEN-NEXT: [[FIRST:%.*]] = select i1 [[TRUNC]], i32 %0
-    // NINETEEN-NEXT: insertvalue { i32, i32 } poison, i32 [[FIRST]], 0
-    // TWENTY-NEXT: insertvalue { i32, i32 } poison, i32 %0, 0
-    // CHECK-NEXT: insertvalue { i32, i32 }
-    // CHECK-NEXT: ret { i32, i32 }
+    // CHECK-NEXT: [[REG1:%.*]] = insertvalue { i32, i32 } poison, i32 %0, 0
+    // CHECK-NEXT: [[REG2:%.*]] = insertvalue { i32, i32 } [[REG1]], i32 %1, 1
+    // CHECK-NEXT: ret { i32, i32 } [[REG2]]
     match x {
         Some(x) => Some(x),
         None => None,
diff --git a/tests/crashes/126268.rs b/tests/crashes/126268.rs
new file mode 100644
index 00000000000..82e52fa115d
--- /dev/null
+++ b/tests/crashes/126268.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #126268
+#![feature(min_specialization)]
+
+trait Trait {}
+
+impl<T> Trait for T {}
+
+trait Data {
+    type Elem;
+}
+
+struct DatasetIter<'a, R: Data> {
+    data: &'a R::Elem,
+}
+
+pub struct ArrayBase {}
+
+impl<'a> Trait for DatasetIter<'a, ArrayBase> {}
diff --git a/tests/crashes/131050.rs b/tests/crashes/131050.rs
index 07f8662d016..3e3a600ef3d 100644
--- a/tests/crashes/131050.rs
+++ b/tests/crashes/131050.rs
@@ -1,25 +1,21 @@
 //@ known-bug: #131050
 //@ compile-flags: --edition=2021
 
-fn query_as<D>() {}
+use std::future::Future;
 
-async fn create_user() {
-    query_as();
-}
+fn invalid_future() -> impl Future {}
 
-async fn post_user_filter() -> impl Filter {
-    AndThen(&(), || async { create_user().await })
+fn create_complex_future() -> impl Future<Output = impl ReturnsSend> {
+    async { &|| async { invalid_future().await } }
 }
 
-async fn get_app() -> impl Send {
-    post_user_filter().await
+fn coerce_impl_trait() -> impl Future<Output = impl Send> {
+    create_complex_future()
 }
 
-trait Filter {}
-
-struct AndThen<T, F>(T, F);
+trait ReturnsSend {}
 
-impl<T, F, R> Filter for AndThen<T, F>
+impl<F, R> ReturnsSend for F
 where
     F: Fn() -> R,
     R: Send,
diff --git a/tests/crashes/132126.rs b/tests/crashes/132126.rs
new file mode 100644
index 00000000000..6a42853d469
--- /dev/null
+++ b/tests/crashes/132126.rs
@@ -0,0 +1,2 @@
+//@ known-bug: #132126
+trait UnsafeCopy where Self: use<Self> {}
diff --git a/tests/mir-opt/gvn_clone.rs b/tests/mir-opt/gvn_clone.rs
index 08938c0e1b4..c16b665fbd3 100644
--- a/tests/mir-opt/gvn_clone.rs
+++ b/tests/mir-opt/gvn_clone.rs
@@ -1,3 +1,5 @@
+//@ compile-flags: -Zunsound-mir-opts
+// FIXME: see <https://github.com/rust-lang/rust/issues/132353>
 //@ test-mir-pass: GVN
 //@ compile-flags: -Zmir-enable-passes=+InstSimplify-before-inline
 
diff --git a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
index 57b0980a0bd..8d5991872e1 100644
--- a/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
+++ b/tests/mir-opt/gvn_clone.{impl#0}-clone.GVN.diff
@@ -1,7 +1,7 @@
-- // MIR for `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` before GVN
-+ // MIR for `<impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone` after GVN
+- // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` before GVN
++ // MIR for `<impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone` after GVN
   
-  fn <impl at $DIR/gvn_clone.rs:12:10: 12:15>::clone(_1: &AllCopy) -> AllCopy {
+  fn <impl at $DIR/gvn_clone.rs:14:10: 14:15>::clone(_1: &AllCopy) -> AllCopy {
       debug self => _1;
       let mut _0: AllCopy;
       let mut _2: i32;
diff --git a/tests/mir-opt/gvn_copy_aggregate.rs b/tests/mir-opt/gvn_copy_aggregate.rs
index c9473025a15..7c181d1ad37 100644
--- a/tests/mir-opt/gvn_copy_aggregate.rs
+++ b/tests/mir-opt/gvn_copy_aggregate.rs
@@ -1,3 +1,5 @@
+//@ compile-flags: -Zunsound-mir-opts
+// FIXME: see <https://github.com/rust-lang/rust/issues/132353.
 //@ test-mir-pass: GVN
 //@ compile-flags: -Cpanic=abort
 
diff --git a/tests/mir-opt/pre-codegen/clone_as_copy.rs b/tests/mir-opt/pre-codegen/clone_as_copy.rs
index f5ff1854d38..ae4661e93fd 100644
--- a/tests/mir-opt/pre-codegen/clone_as_copy.rs
+++ b/tests/mir-opt/pre-codegen/clone_as_copy.rs
@@ -1,3 +1,5 @@
+//@ compile-flags: -Zunsound-mir-opts
+// FIXME: see <https://github.com/rust-lang/rust/issues/132353>
 //@ compile-flags: -Cdebuginfo=full
 
 // Check if we have transformed the nested clone to the copy in the complete pipeline.
diff --git a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir
index 9020cf1ef37..62a9cd9131f 100644
--- a/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/no_inlined_clone.{impl#0}-clone.PreCodegen.after.mir
@@ -3,9 +3,13 @@
 fn <impl at $DIR/no_inlined_clone.rs:9:10: 9:15>::clone(_1: &Foo) -> Foo {
     debug self => _1;
     let mut _0: Foo;
+    let mut _2: i32;
 
     bb0: {
-        _0 = copy (*_1);
+        StorageLive(_2);
+        _2 = copy ((*_1).0: i32);
+        _0 = Foo { a: move _2 };
+        StorageDead(_2);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir
index 889e80d26e1..ac485f485b1 100644
--- a/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir
+++ b/tests/mir-opt/pre-codegen/try_identity.old.PreCodegen.after.mir
@@ -19,14 +19,14 @@ fn old(_1: Result<T, E>) -> Result<T, E> {
     }
 
     bb1: {
-        _3 = copy ((_1 as Ok).0: T);
-        _0 = copy _1;
+        _3 = move ((_1 as Ok).0: T);
+        _0 = Result::<T, E>::Ok(copy _3);
         goto -> bb3;
     }
 
     bb2: {
-        _4 = copy ((_1 as Err).0: E);
-        _0 = copy _1;
+        _4 = move ((_1 as Err).0: E);
+        _0 = Result::<T, E>::Err(copy _4);
         goto -> bb3;
     }
 
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
index 4d964b0afb7..c3091bd4395 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
@@ -7,7 +7,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _6: usize;
+            let mut _7: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
                 let mut _2: &alloc::raw_vec::RawVec<u8>;
@@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                     let mut _3: &alloc::raw_vec::RawVecInner;
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
+                        let mut _6: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             debug self => _3;
                             let mut _4: std::ptr::NonNull<u8>;
@@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
                                 debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::as_ptr) {
-                            debug self => _4;
+                            debug self => _6;
                         }
                     }
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
                 debug data => _5;
-                debug len => _6;
-                let _7: *const [u8];
+                debug len => _7;
+                let _8: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -55,10 +56,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
                     debug data => _5;
-                    debug len => _6;
+                    debug len => _7;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
                         debug data_pointer => _5;
-                        debug metadata => _6;
+                        debug metadata => _7;
                     }
                 }
             }
@@ -70,17 +71,22 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
         StorageLive(_3);
         _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
+        StorageLive(_6);
+        StorageLive(_4);
         _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         _5 = copy (_4.0: *const u8);
+        _6 = NonNull::<u8> { pointer: copy _5 };
+        StorageDead(_4);
+        StorageDead(_6);
         StorageDead(_3);
         StorageDead(_2);
-        StorageLive(_6);
-        _6 = copy ((*_1).1: usize);
         StorageLive(_7);
-        _7 = *const [u8] from (copy _5, copy _6);
-        _0 = &(*_7);
+        _7 = copy ((*_1).1: usize);
+        StorageLive(_8);
+        _8 = *const [u8] from (copy _5, copy _7);
+        _0 = &(*_8);
+        StorageDead(_8);
         StorageDead(_7);
-        StorageDead(_6);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
index 4d964b0afb7..c3091bd4395 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
@@ -7,7 +7,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _6: usize;
+            let mut _7: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
                 let mut _2: &alloc::raw_vec::RawVec<u8>;
@@ -16,6 +16,7 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                     let mut _3: &alloc::raw_vec::RawVecInner;
                     scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
+                        let mut _6: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             debug self => _3;
                             let mut _4: std::ptr::NonNull<u8>;
@@ -31,20 +32,20 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
                                 debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::as_ptr) {
-                            debug self => _4;
+                            debug self => _6;
                         }
                     }
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
                 debug data => _5;
-                debug len => _6;
-                let _7: *const [u8];
+                debug len => _7;
+                let _8: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -55,10 +56,10 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
                     debug data => _5;
-                    debug len => _6;
+                    debug len => _7;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
                         debug data_pointer => _5;
-                        debug metadata => _6;
+                        debug metadata => _7;
                     }
                 }
             }
@@ -70,17 +71,22 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
         StorageLive(_3);
         _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
+        StorageLive(_6);
+        StorageLive(_4);
         _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
         _5 = copy (_4.0: *const u8);
+        _6 = NonNull::<u8> { pointer: copy _5 };
+        StorageDead(_4);
+        StorageDead(_6);
         StorageDead(_3);
         StorageDead(_2);
-        StorageLive(_6);
-        _6 = copy ((*_1).1: usize);
         StorageLive(_7);
-        _7 = *const [u8] from (copy _5, copy _6);
-        _0 = &(*_7);
+        _7 = copy ((*_1).1: usize);
+        StorageLive(_8);
+        _8 = *const [u8] from (copy _5, copy _7);
+        _0 = &(*_8);
+        StorageDead(_8);
         StorageDead(_7);
-        StorageDead(_6);
         return;
     }
 }
diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff
new file mode 100644
index 00000000000..22d4277ee45
--- /dev/null
+++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.foo.GVN.diff
@@ -0,0 +1,72 @@
+- // MIR for `foo` before GVN
++ // MIR for `foo` after GVN
+  
+  fn foo(_1: &mut Option<i32>) -> Option<i32> {
+      debug v => _1;
+      let mut _0: std::option::Option<i32>;
+      let mut _2: &std::option::Option<i32>;
+      let mut _3: &std::option::Option<i32>;
+      let _4: &&mut std::option::Option<i32>;
+      let mut _5: isize;
+      let mut _7: !;
+      let mut _8: std::option::Option<i32>;
+      let mut _9: i32;
+      let mut _10: !;
+      let mut _11: &mut std::option::Option<i32>;
+      scope 1 {
+          debug col => _6;
+          let _6: i32;
+      }
+  
+      bb0: {
+-         StorageLive(_2);
++         nop;
+          StorageLive(_3);
+          StorageLive(_4);
+          _4 = &_1;
+-         _11 = deref_copy (*_4);
+-         _3 = &(*_11);
++         _11 = copy _1;
++         _3 = &(*_1);
+          _2 = get(move _3) -> [return: bb1, unwind unreachable];
+      }
+  
+      bb1: {
+          StorageDead(_3);
+          _5 = discriminant((*_2));
+          switchInt(move _5) -> [1: bb2, otherwise: bb3];
+      }
+  
+      bb2: {
+-         StorageLive(_6);
++         nop;
+          _6 = copy (((*_2) as Some).0: i32);
+          StorageLive(_8);
+-         _8 = Option::<i32>::None;
+-         (*_1) = move _8;
++         _8 = const Option::<i32>::None;
++         (*_1) = const Option::<i32>::None;
+          StorageDead(_8);
+          StorageLive(_9);
+          _9 = copy _6;
+-         _0 = Option::<i32>::Some(move _9);
++         _0 = copy (*_2);
+          StorageDead(_9);
+-         StorageDead(_6);
++         nop;
+          StorageDead(_4);
+-         StorageDead(_2);
++         nop;
+          return;
+      }
+  
+      bb3: {
+          StorageLive(_10);
+          unreachable;
+      }
++ }
++ 
++ ALLOC0 (size: 8, align: 4) {
++     00 00 00 00 __ __ __ __                         │ ....░░░░
+  }
+  
diff --git a/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs
new file mode 100644
index 00000000000..47721b768be
--- /dev/null
+++ b/tests/mir-opt/simplify_aggregate_to_copy_miscompile.rs
@@ -0,0 +1,32 @@
+//! The `simplify_aggregate_to_copy` mir-opt introduced in
+//! <https://github.com/rust-lang/rust/pull/128299> caused a miscompile because the initial
+//! implementation
+//!
+//! > introduce[d] new dereferences without checking for aliasing
+//!
+//! This test demonstrates the behavior, and should be adjusted or removed when fixing and relanding
+//! the mir-opt.
+#![crate_type = "lib"]
+// skip-filecheck
+//@ compile-flags: -O -Zunsound-mir-opts
+//@ test-mir-pass: GVN
+#![allow(internal_features)]
+#![feature(rustc_attrs, core_intrinsics)]
+
+// EMIT_MIR simplify_aggregate_to_copy_miscompile.foo.GVN.diff
+#[no_mangle]
+fn foo(v: &mut Option<i32>) -> Option<i32> {
+    if let &Some(col) = get(&v) {
+        *v = None;
+        return Some(col);
+    } else {
+        unsafe { std::intrinsics::unreachable() }
+    }
+}
+
+#[no_mangle]
+#[inline(never)]
+#[rustc_nounwind]
+fn get(v: &Option<i32>) -> &Option<i32> {
+    v
+}
diff --git a/tests/run-make/profile/rmake.rs b/tests/run-make/profile/rmake.rs
deleted file mode 100644
index 58a1b53c040..00000000000
--- a/tests/run-make/profile/rmake.rs
+++ /dev/null
@@ -1,21 +0,0 @@
-// This test revolves around the rustc flag -Z profile, which should
-// generate a .gcno file (initial profiling information) as well
-// as a .gcda file (branch counters). The path where these are emitted
-// should also be configurable with -Z profile-emit. This test checks
-// that the files are produced, and then that the latter flag is respected.
-// See https://github.com/rust-lang/rust/pull/42433
-
-//@ ignore-cross-compile
-//@ needs-profiler-runtime
-
-use run_make_support::{path, run, rustc};
-
-fn main() {
-    rustc().arg("-g").arg("-Zprofile").input("test.rs").run();
-    run("test");
-    assert!(path("test.gcno").exists(), "no .gcno file");
-    assert!(path("test.gcda").exists(), "no .gcda file");
-    rustc().arg("-g").arg("-Zprofile").arg("-Zprofile-emit=abc/abc.gcda").input("test.rs").run();
-    run("test");
-    assert!(path("abc/abc.gcda").exists(), "gcda file not emitted to defined path");
-}
diff --git a/tests/run-make/profile/test.rs b/tests/run-make/profile/test.rs
deleted file mode 100644
index f328e4d9d04..00000000000
--- a/tests/run-make/profile/test.rs
+++ /dev/null
@@ -1 +0,0 @@
-fn main() {}
diff --git a/tests/rustdoc/stability.rs b/tests/rustdoc/stability.rs
index fc72154cad8..550eb0bc137 100644
--- a/tests/rustdoc/stability.rs
+++ b/tests/rustdoc/stability.rs
@@ -1,6 +1,8 @@
 #![feature(staged_api)]
+#![feature(rustc_attrs)]
+#![feature(rustdoc_internals)]
 
-#![stable(feature = "rust1", since = "1.0.0")]
+#![stable(feature = "core", since = "1.6.0")]
 
 //@ has stability/index.html
 //@ has - '//ul[@class="item-table"]/li[1]//a' AaStable
@@ -26,7 +28,7 @@ pub struct ZzStable;
 #[unstable(feature = "unstable", issue = "none")]
 pub mod unstable {
     //@ !hasraw stability/unstable/struct.StableInUnstable.html \
-    //      '//span[@class="since"]'
+    //      '//div[@class="main-heading"]//span[@class="since"]'
     //@ has - '//div[@class="stab unstable"]' 'experimental'
     #[stable(feature = "rust1", since = "1.0.0")]
     pub struct StableInUnstable;
@@ -34,52 +36,136 @@ pub mod unstable {
     #[stable(feature = "rust1", since = "1.0.0")]
     pub mod stable_in_unstable {
         //@ !hasraw stability/unstable/stable_in_unstable/struct.Inner.html \
-        //      '//span[@class="since"]'
+        //      '//div[@class="main-heading"]//span[@class="since"]'
         //@ has - '//div[@class="stab unstable"]' 'experimental'
         #[stable(feature = "rust1", since = "1.0.0")]
         pub struct Inner;
     }
+
+    //@ has stability/struct.AaStable.html \
+    //      '//*[@id="method.foo"]//span[@class="since"]' '2.2.2'
+    impl super::AaStable {
+        #[stable(feature = "rust2", since = "2.2.2")]
+        pub fn foo() {}
+    }
+
+    //@ has stability/unstable/struct.StableInUnstable.html \
+    //      '//*[@id="method.foo"]//span[@class="since"]' '1.0.0'
+    impl StableInUnstable {
+        #[stable(feature = "rust1", since = "1.0.0")]
+        pub fn foo() {}
+    }
+}
+
+#[unstable(feature = "unstable", issue = "none")]
+#[doc(hidden)]
+pub mod unstable_stripped {
+    //@ has stability/struct.AaStable.html \
+    //      '//*[@id="method.foo"]//span[@class="since"]' '2.2.2'
+    impl super::AaStable {
+        #[stable(feature = "rust2", since = "2.2.2")]
+        pub fn foo() {}
+    }
 }
 
 #[stable(feature = "rust2", since = "2.2.2")]
 pub mod stable_later {
     //@ has stability/stable_later/struct.StableInLater.html \
-    //      '//span[@class="since"]' '2.2.2'
+    //      '//div[@class="main-heading"]//span[@class="since"]' '2.2.2'
     #[stable(feature = "rust1", since = "1.0.0")]
     pub struct StableInLater;
 
     #[stable(feature = "rust1", since = "1.0.0")]
     pub mod stable_in_later {
         //@ has stability/stable_later/stable_in_later/struct.Inner.html \
-        //      '//span[@class="since"]' '2.2.2'
+        //      '//div[@class="main-heading"]//span[@class="since"]' '2.2.2'
         #[stable(feature = "rust1", since = "1.0.0")]
         pub struct Inner;
     }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
-pub mod stable_earlier {
-    //@ has stability/stable_earlier/struct.StableInUnstable.html \
-    //      '//span[@class="since"]' '1.0.0'
+#[rustc_allowed_through_unstable_modules]
+pub mod stable_earlier1 {
+    //@ has stability/stable_earlier1/struct.StableInUnstable.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
+    //@ has - '//*[@id="method.foo"]//span[@class="since"]' '1.0.0'
+    #[doc(inline)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub use crate::unstable::StableInUnstable;
+
+    //@ has stability/stable_earlier1/stable_in_unstable/struct.Inner.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
+    #[doc(inline)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub use crate::unstable::stable_in_unstable;
+
+    //@ has stability/stable_earlier1/struct.StableInLater.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
+    #[doc(inline)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub use crate::stable_later::StableInLater;
+
+    //@ has stability/stable_earlier1/stable_in_later/struct.Inner.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
+    #[doc(inline)]
+    #[stable(feature = "rust1", since = "1.0.0")]
+    pub use crate::stable_later::stable_in_later;
+}
+
+/// These will inherit the crate stability.
+#[stable(feature = "rust1", since = "1.0.0")]
+pub mod stable_earlier2 {
+    //@ has stability/stable_earlier2/struct.StableInUnstable.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.6.0'
+    //@ has - '//*[@id="method.foo"]//span[@class="since"]' '1.0.0'
     #[doc(inline)]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use crate::unstable::StableInUnstable;
 
-    //@ has stability/stable_earlier/stable_in_unstable/struct.Inner.html \
-    //      '//span[@class="since"]' '1.0.0'
+    //@ has stability/stable_earlier2/stable_in_unstable/struct.Inner.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.6.0'
     #[doc(inline)]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use crate::unstable::stable_in_unstable;
 
-    //@ has stability/stable_earlier/struct.StableInLater.html \
-    //      '//span[@class="since"]' '1.0.0'
+    //@ has stability/stable_earlier2/struct.StableInLater.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.6.0'
     #[doc(inline)]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use crate::stable_later::StableInLater;
 
-    //@ has stability/stable_earlier/stable_in_later/struct.Inner.html \
-    //      '//span[@class="since"]' '1.0.0'
+    //@ has stability/stable_earlier2/stable_in_later/struct.Inner.html \
+    //      '//div[@class="main-heading"]//span[@class="since"]' '1.6.0'
     #[doc(inline)]
     #[stable(feature = "rust1", since = "1.0.0")]
     pub use crate::stable_later::stable_in_later;
 }
+
+//@ !hasraw stability/trait.UnstableTraitWithStableMethod.html \
+//      '//div[@class="main-heading"]//span[@class="since"]'
+//@ has - '//*[@id="tymethod.foo"]//span[@class="since"]' '1.0.0'
+//@ has - '//*[@id="method.bar"]//span[@class="since"]' '1.0.0'
+#[unstable(feature = "unstable", issue = "none")]
+pub trait UnstableTraitWithStableMethod {
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn foo();
+    #[stable(feature = "rust1", since = "1.0.0")]
+    fn bar() {}
+}
+
+//@ has stability/primitive.i32.html \
+//      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
+#[rustc_doc_primitive = "i32"]
+//
+/// `i32` is always stable in 1.0, even if you look at it from core.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod prim_i32 {}
+
+//@ has stability/keyword.if.html \
+//      '//div[@class="main-heading"]//span[@class="since"]' '1.0.0'
+#[doc(keyword = "if")]
+//
+/// We currently don't document stability for keywords, but let's test it anyway.
+#[stable(feature = "rust1", since = "1.0.0")]
+mod if_keyword {}
diff --git a/tests/ui/abi/compatibility.rs b/tests/ui/abi/compatibility.rs
index 408dbea4ae8..01d90717107 100644
--- a/tests/ui/abi/compatibility.rs
+++ b/tests/ui/abi/compatibility.rs
@@ -1,4 +1,5 @@
 //@ check-pass
+//@ add-core-stubs
 //@ revisions: host
 //@ revisions: i686
 //@[i686] compile-flags: --target i686-unknown-linux-gnu
@@ -58,8 +59,10 @@
 //@ revisions: nvptx64
 //@[nvptx64] compile-flags: --target nvptx64-nvidia-cuda
 //@[nvptx64] needs-llvm-components: nvptx
-#![feature(rustc_attrs, unsized_fn_params, transparent_unions)]
-#![cfg_attr(not(host), feature(no_core, lang_items), no_std, no_core)]
+#![feature(no_core, rustc_attrs, lang_items)]
+#![feature(unsized_fn_params, transparent_unions)]
+#![no_std]
+#![no_core]
 #![allow(unused, improper_ctypes_definitions, internal_features)]
 
 // FIXME: some targets are broken in various ways.
@@ -67,67 +70,24 @@
 // sparc64: https://github.com/rust-lang/rust/issues/115336
 // mips64: https://github.com/rust-lang/rust/issues/115404
 
-#[cfg(host)]
-use std::{
-    any::Any, marker::PhantomData, mem::ManuallyDrop, num::NonZero, ptr::NonNull, rc::Rc, sync::Arc,
-};
+extern crate minicore;
+use minicore::*;
 
-/// To work cross-target this test must be no_core.
-/// This little prelude supplies what we need.
-#[cfg(not(host))]
+/// To work cross-target this test must be no_core. This little prelude supplies what we need.
+///
+/// Note that `minicore` provides a very minimal subset of `core` items (not yet complete). This
+/// prelude contains `alloc` and non-`core` (but in `std`) items that minicore does not stub out.
 mod prelude {
-    #[lang = "sized"]
-    pub trait Sized {}
+    use minicore::*;
 
-    #[lang = "legacy_receiver"]
-    pub trait LegacyReceiver {}
-    impl<T: ?Sized> LegacyReceiver for &T {}
-    impl<T: ?Sized> LegacyReceiver for &mut T {}
-
-    #[lang = "copy"]
-    pub trait Copy: Sized {}
-    impl Copy for i32 {}
-    impl Copy for f32 {}
-    impl<T: ?Sized> Copy for &T {}
-    impl<T: ?Sized> Copy for *const T {}
-    impl<T: ?Sized> Copy for *mut T {}
+    // Trait stub, no `type_id` method.
+    pub trait Any: 'static {}
 
     #[lang = "clone"]
     pub trait Clone: Sized {
         fn clone(&self) -> Self;
     }
 
-    #[lang = "phantom_data"]
-    pub struct PhantomData<T: ?Sized>;
-    impl<T: ?Sized> Copy for PhantomData<T> {}
-
-    #[lang = "unsafe_cell"]
-    #[repr(transparent)]
-    pub struct UnsafeCell<T: ?Sized> {
-        value: T,
-    }
-
-    pub trait Any: 'static {}
-
-    pub enum Option<T> {
-        None,
-        Some(T),
-    }
-    impl<T: Copy> Copy for Option<T> {}
-
-    pub enum Result<T, E> {
-        Ok(T),
-        Err(E),
-    }
-    impl<T: Copy, E: Copy> Copy for Result<T, E> {}
-
-    #[lang = "manually_drop"]
-    #[repr(transparent)]
-    pub struct ManuallyDrop<T: ?Sized> {
-        value: T,
-    }
-    impl<T: Copy + ?Sized> Copy for ManuallyDrop<T> {}
-
     #[repr(transparent)]
     #[rustc_layout_scalar_valid_range_start(1)]
     #[rustc_nonnull_optimization_guaranteed]
@@ -185,7 +145,6 @@ mod prelude {
         alloc: A,
     }
 }
-#[cfg(not(host))]
 use prelude::*;
 
 macro_rules! test_abi_compatible {
diff --git a/tests/ui/async-await/async-closures/mangle.rs b/tests/ui/async-await/async-closures/mangle.rs
index 632f1657436..a428905e40b 100644
--- a/tests/ui/async-await/async-closures/mangle.rs
+++ b/tests/ui/async-await/async-closures/mangle.rs
@@ -5,9 +5,6 @@
 //@[v0] compile-flags: -Csymbol-mangling-version=v0
 //@[legacy] compile-flags: -Csymbol-mangling-version=legacy -Zunstable-options
 
-// FIXME(async_closures): When `fn_sig_for_fn_abi` is fixed, remove this.
-//@ ignore-pass (test emits codegen-time warnings)
-
 #![feature(async_closure, noop_waker)]
 
 extern crate block_on;
diff --git a/tests/ui/async-await/async-closures/no-borrow-from-env.rs b/tests/ui/async-await/async-closures/no-borrow-from-env.rs
index fe84aeeb32f..3f9d26b9713 100644
--- a/tests/ui/async-await/async-closures/no-borrow-from-env.rs
+++ b/tests/ui/async-await/async-closures/no-borrow-from-env.rs
@@ -38,7 +38,10 @@ fn through_field_and_ref<'a>(x: &S<'a>) {
 
     let c = async move || { println!("{}", *x.0); };
     outlives::<'a>(c());
-    // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails
+
+    // outlives::<'a>(call_once(c));
+    // The above fails b/c the by-move coroutine of `c` captures `x` in its entirety.
+    // Since we have not asserted that the borrow for `&S<'a>` outlives `'a`, it'll fail.
 }
 
 fn main() {}
diff --git a/tests/ui/async-await/async-closures/not-fn.rs b/tests/ui/async-await/async-closures/not-fn.rs
index 5322a6d5d7a..5f2d047c3e9 100644
--- a/tests/ui/async-await/async-closures/not-fn.rs
+++ b/tests/ui/async-await/async-closures/not-fn.rs
@@ -9,7 +9,7 @@ fn main() {
 
     let mut x = 1;
     needs_fn(async || {
-        //~^ ERROR  async closure does not implement `FnMut` because it captures state from its environment
+        //~^ ERROR async closure does not implement `FnMut` because it captures state from its environment
         x += 1;
     });
 }
diff --git a/tests/ui/async-await/async-closures/precise-captures.rs b/tests/ui/async-await/async-closures/precise-captures.rs
index e82dd1dbaf0..c4c67df544f 100644
--- a/tests/ui/async-await/async-closures/precise-captures.rs
+++ b/tests/ui/async-await/async-closures/precise-captures.rs
@@ -126,7 +126,7 @@ async fn async_main() {
     {
         let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") };
         let c = guidance!(async move || {
-            // s.a = 2; // FIXME(async_closures): Figure out why this fails
+            s.a = 2;
             drop(s.b);
         });
         s.c.0 = "uncaptured";
@@ -141,7 +141,7 @@ async fn async_main() {
     {
         let mut s = S { a: 1, b: Drop("drop first"), c: Drop("untouched") };
         let c = guidance!(async move || {
-            // s.a = 2; // FIXME(async_closures): Figure out why this fails
+            s.a = 2;
             drop(s.b);
         });
         s.c.0 = "uncaptured";
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
index 18f16ca4b2d..be3f032b8ff 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.rs
@@ -38,10 +38,12 @@ fn through_field_and_ref<'a>(x: &S<'a>) {
     let c = async || { println!("{}", *x.0); }; //~ ERROR `x` does not live long enough
     outlives::<'a>(c());
     outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x`
+}
 
+fn through_field_and_ref_move<'a>(x: &S<'a>) {
     let c = async move || { println!("{}", *x.0); };
     outlives::<'a>(c()); //~ ERROR `c` does not live long enough
-    // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails
+    outlives::<'a>(call_once(c)); //~ ERROR explicit lifetime required in the type of `x`
 }
 
 fn main() {}
diff --git a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
index 1df5abdbb18..a70aece2dea 100644
--- a/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
+++ b/tests/ui/async-await/async-closures/without-precise-captures-we-are-powerless.stderr
@@ -100,7 +100,6 @@ LL |     let c = async || { println!("{}", *x.0); };
 LL |     outlives::<'a>(c());
 LL |     outlives::<'a>(call_once(c));
    |                    ------------ argument requires that `x` is borrowed for `'a`
-...
 LL | }
    |  - `x` dropped here while still borrowed
 
@@ -114,11 +113,10 @@ LL |     outlives::<'a>(call_once(c));
    |                    ^^^^^^^^^^^^ lifetime `'a` required
 
 error[E0597]: `c` does not live long enough
-  --> $DIR/without-precise-captures-we-are-powerless.rs:43:20
+  --> $DIR/without-precise-captures-we-are-powerless.rs:45:20
    |
-LL | fn through_field_and_ref<'a>(x: &S<'a>) {
-   |                          -- lifetime `'a` defined here
-...
+LL | fn through_field_and_ref_move<'a>(x: &S<'a>) {
+   |                               -- lifetime `'a` defined here
 LL |     let c = async move || { println!("{}", *x.0); };
    |         - binding `c` declared here
 LL |     outlives::<'a>(c());
@@ -126,11 +124,20 @@ LL |     outlives::<'a>(c());
    |                    |
    |                    borrowed value does not live long enough
    |                    argument requires that `c` is borrowed for `'a`
-LL |     // outlives::<'a>(call_once(c)); // FIXME(async_closures): Figure out why this fails
+LL |     outlives::<'a>(call_once(c));
 LL | }
    | - `c` dropped here while still borrowed
 
-error: aborting due to 9 previous errors
+error[E0621]: explicit lifetime required in the type of `x`
+  --> $DIR/without-precise-captures-we-are-powerless.rs:46:20
+   |
+LL | fn through_field_and_ref_move<'a>(x: &S<'a>) {
+   |                                      ------ help: add explicit lifetime `'a` to the type of `x`: `&'a S<'a>`
+...
+LL |     outlives::<'a>(call_once(c));
+   |                    ^^^^^^^^^^^^ lifetime `'a` required
+
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0505, E0597, E0621.
 For more information about an error, try `rustc --explain E0505`.
diff --git a/tests/ui/check-cfg/well-known-values.stderr b/tests/ui/check-cfg/well-known-values.stderr
index b0ca09a59ed..37d2b0343c9 100644
--- a/tests/ui/check-cfg/well-known-values.stderr
+++ b/tests/ui/check-cfg/well-known-values.stderr
@@ -156,7 +156,7 @@ warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
 LL |     target_env = "_UNEXPECTED_VALUE",
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `psx`, `relibc`, `sgx`, and `uclibc`
+   = note: expected values for `target_env` are: ``, `gnu`, `msvc`, `musl`, `newlib`, `nto70`, `nto71`, `ohos`, `p1`, `p2`, `relibc`, `sgx`, and `uclibc`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -210,7 +210,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`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `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`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: unexpected `cfg` condition value: `_UNEXPECTED_VALUE`
@@ -294,7 +294,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`, `nuttx`, `openbsd`, `psp`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `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`, `nuttx`, `openbsd`, `psp`, `psx`, `redox`, `rtems`, `solaris`, `solid_asp3`, `teeos`, `trusty`, `tvos`, `uefi`, `unknown`, `visionos`, `vita`, `vxworks`, `wasi`, `watchos`, `windows`, `xous`, and `zkvm`
    = note: see <https://doc.rust-lang.org/nightly/rustc/check-cfg.html> for more information about checking conditional configuration
 
 warning: 30 warnings emitted
diff --git a/tests/ui/compiletest-self-test/minicore-smoke-test.rs b/tests/ui/compiletest-self-test/minicore-smoke-test.rs
new file mode 100644
index 00000000000..ec879f2852e
--- /dev/null
+++ b/tests/ui/compiletest-self-test/minicore-smoke-test.rs
@@ -0,0 +1,20 @@
+//! Basic smoke test for `minicore` test auxiliary.
+//!
+//! This test is duplicated between ui/codegen/assembly because they have different runtest
+//! codepaths.
+
+//@ add-core-stubs
+//@ check-pass
+//@ compile-flags: --target=x86_64-unknown-linux-gnu
+//@ needs-llvm-components: x86
+
+#![crate_type = "lib"]
+#![feature(no_core)]
+#![no_std]
+#![no_core]
+
+extern crate minicore;
+use minicore::*;
+
+struct Meow;
+impl Copy for Meow {}
diff --git a/tests/ui/consts/promote-not.rs b/tests/ui/consts/promote-not.rs
index 80912937f31..207baccd6ab 100644
--- a/tests/ui/consts/promote-not.rs
+++ b/tests/ui/consts/promote-not.rs
@@ -23,7 +23,7 @@ pub const fn promote_cal(b: bool) -> i32 {
     13
 }
 
-// We do not promote union field accesses in `fn.
+// We do not promote union field accesses in `fn`.
 union U { x: i32, y: i32 }
 pub const fn promote_union() {
     let _x: &'static i32 = &unsafe { U { x: 0 }.x }; //~ ERROR temporary value dropped while borrowed
diff --git a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
index 134fd098b7e..79eee2a3def 100644
--- a/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
+++ b/tests/ui/editions/never-type-fallback-breaking.e2021.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail
 LL |         true => Default::default(),
    |                 ^^^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let x: () = match true {
+   |          ++++
 
 warning: this function depends on never type fallback being `()`
   --> $DIR/never-type-fallback-breaking.rs:27:1
@@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     deserialize::<()>()?;
+   |                ++++++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs
new file mode 100644
index 00000000000..83466535e13
--- /dev/null
+++ b/tests/ui/impl-trait/in-trait/late-bound-in-object-assocty.rs
@@ -0,0 +1,13 @@
+// Test for issue #132429
+//@compile-flags: -Zunstable-options --edition=2024
+//@check-pass
+
+use std::future::Future;
+
+trait Test {
+    fn foo<'a>(&'a self) -> Box<dyn Future<Output = impl IntoIterator<Item = u32>>> {
+        Box::new(async { [] })
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs
index 47695814668..46121308fa0 100644
--- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs
+++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.rs
@@ -3,8 +3,6 @@
 fn polarity() -> impl Sized + ?use<> {}
 //~^ ERROR expected identifier, found keyword `use`
 //~| ERROR cannot find trait `r#use` in this scope
-//~| WARN relaxing a default bound only does something for `?Sized`
-//~| WARN relaxing a default bound only does something for `?Sized`
 
 fn asyncness() -> impl Sized + async use<> {}
 //~^ ERROR expected identifier, found keyword `use`
diff --git a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr
index aaebfe2a86e..16e7470debf 100644
--- a/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr
+++ b/tests/ui/impl-trait/precise-capturing/bound-modifiers.stderr
@@ -5,19 +5,19 @@ LL | fn polarity() -> impl Sized + ?use<> {}
    |                                ^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `use`
-  --> $DIR/bound-modifiers.rs:9:38
+  --> $DIR/bound-modifiers.rs:7:38
    |
 LL | fn asyncness() -> impl Sized + async use<> {}
    |                                      ^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `use`
-  --> $DIR/bound-modifiers.rs:14:38
+  --> $DIR/bound-modifiers.rs:12:38
    |
 LL | fn constness() -> impl Sized + const use<> {}
    |                                      ^^^ expected identifier, found keyword
 
 error: expected identifier, found keyword `use`
-  --> $DIR/bound-modifiers.rs:19:37
+  --> $DIR/bound-modifiers.rs:17:37
    |
 LL | fn binder() -> impl Sized + for<'a> use<> {}
    |                                     ^^^ expected identifier, found keyword
@@ -29,25 +29,25 @@ LL | fn polarity() -> impl Sized + ?use<> {}
    |                                ^^^ not found in this scope
 
 error[E0405]: cannot find trait `r#use` in this scope
-  --> $DIR/bound-modifiers.rs:9:38
+  --> $DIR/bound-modifiers.rs:7:38
    |
 LL | fn asyncness() -> impl Sized + async use<> {}
    |                                      ^^^ not found in this scope
 
 error[E0405]: cannot find trait `r#use` in this scope
-  --> $DIR/bound-modifiers.rs:14:38
+  --> $DIR/bound-modifiers.rs:12:38
    |
 LL | fn constness() -> impl Sized + const use<> {}
    |                                      ^^^ not found in this scope
 
 error[E0405]: cannot find trait `r#use` in this scope
-  --> $DIR/bound-modifiers.rs:19:37
+  --> $DIR/bound-modifiers.rs:17:37
    |
 LL | fn binder() -> impl Sized + for<'a> use<> {}
    |                                     ^^^ not found in this scope
 
 error[E0658]: async closures are unstable
-  --> $DIR/bound-modifiers.rs:9:32
+  --> $DIR/bound-modifiers.rs:7:32
    |
 LL | fn asyncness() -> impl Sized + async use<> {}
    |                                ^^^^^
@@ -58,7 +58,7 @@ LL | fn asyncness() -> impl Sized + async use<> {}
    = help: to use an async block, remove the `||`: `async {`
 
 error[E0658]: const trait impls are experimental
-  --> $DIR/bound-modifiers.rs:14:32
+  --> $DIR/bound-modifiers.rs:12:32
    |
 LL | fn constness() -> impl Sized + const use<> {}
    |                                ^^^^^
@@ -67,21 +67,7 @@ LL | fn constness() -> impl Sized + const use<> {}
    = help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
-  --> $DIR/bound-modifiers.rs:3:31
-   |
-LL | fn polarity() -> impl Sized + ?use<> {}
-   |                               ^^^^^^
-
-warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
-  --> $DIR/bound-modifiers.rs:3:31
-   |
-LL | fn polarity() -> impl Sized + ?use<> {}
-   |                               ^^^^^^
-   |
-   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
-
-error: aborting due to 10 previous errors; 2 warnings emitted
+error: aborting due to 10 previous errors
 
 Some errors have detailed explanations: E0405, E0658.
 For more information about an error, try `rustc --explain E0405`.
diff --git a/tests/ui/issues/issue-37534.rs b/tests/ui/issues/issue-37534.rs
index 40f7186db09..dff89d3888d 100644
--- a/tests/ui/issues/issue-37534.rs
+++ b/tests/ui/issues/issue-37534.rs
@@ -1,6 +1,5 @@
 struct Foo<T: ?Hash> {}
 //~^ ERROR expected trait, found derive macro `Hash`
-//~^^ ERROR parameter `T` is never used
-//~^^^ WARN relaxing a default bound only does something for `?Sized`
+//~| WARN relaxing a default bound only does something for `?Sized`
 
 fn main() {}
diff --git a/tests/ui/issues/issue-37534.stderr b/tests/ui/issues/issue-37534.stderr
index a687e733d3d..8747bd5ac6f 100644
--- a/tests/ui/issues/issue-37534.stderr
+++ b/tests/ui/issues/issue-37534.stderr
@@ -15,15 +15,6 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
 LL | struct Foo<T: ?Hash> {}
    |               ^^^^^
 
-error[E0392]: type parameter `T` is never used
-  --> $DIR/issue-37534.rs:1:12
-   |
-LL | struct Foo<T: ?Hash> {}
-   |            ^ unused type parameter
-   |
-   = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
-
-error: aborting due to 2 previous errors; 1 warning emitted
+error: aborting due to 1 previous error; 1 warning emitted
 
-Some errors have detailed explanations: E0392, E0404.
-For more information about an error, try `rustc --explain E0392`.
+For more information about this error, try `rustc --explain E0404`.
diff --git a/tests/ui/lint/cli-lint-override.forbid_warn.stderr b/tests/ui/lint/cli-lint-override.forbid_warn.stderr
index d8c75c33b0c..169be997b48 100644
--- a/tests/ui/lint/cli-lint-override.forbid_warn.stderr
+++ b/tests/ui/lint/cli-lint-override.forbid_warn.stderr
@@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated
   --> $DIR/cli-lint-override.rs:12:1
    |
 LL | extern fn foo() {}
-   | ^^^^^^^^^^^^^^^ ABI should be specified here
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
    |
-   = help: the default ABI is C
    = note: requested on the command line with `-F missing-abi`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
index 779c24c93f2..574f2ca66a4 100644
--- a/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
+++ b/tests/ui/lint/cli-lint-override.force_warn_deny.stderr
@@ -2,9 +2,8 @@ warning: extern declarations without an explicit ABI are deprecated
   --> $DIR/cli-lint-override.rs:12:1
    |
 LL | extern fn foo() {}
-   | ^^^^^^^^^^^^^^^ ABI should be specified here
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
    |
-   = help: the default ABI is C
    = note: requested on the command line with `--force-warn missing-abi`
 
 warning: 1 warning emitted
diff --git a/tests/ui/lint/cli-lint-override.warn_deny.stderr b/tests/ui/lint/cli-lint-override.warn_deny.stderr
index 1ba42e9ce32..bfec37ada95 100644
--- a/tests/ui/lint/cli-lint-override.warn_deny.stderr
+++ b/tests/ui/lint/cli-lint-override.warn_deny.stderr
@@ -2,9 +2,8 @@ error: extern declarations without an explicit ABI are deprecated
   --> $DIR/cli-lint-override.rs:12:1
    |
 LL | extern fn foo() {}
-   | ^^^^^^^^^^^^^^^ ABI should be specified here
+   | ^^^^^^ help: explicitly specify the C ABI: `extern "C"`
    |
-   = help: the default ABI is C
    = note: requested on the command line with `-D missing-abi`
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed
index 46b2d4e9c3f..2d88c274080 100644
--- a/tests/ui/lint/invalid-nan-comparison-suggestion.fixed
+++ b/tests/ui/lint/invalid-nan-comparison-suggestion.fixed
@@ -1,7 +1,15 @@
 //@ check-pass
 //@ run-rustfix
 
+#![feature(f16, f128)]
+
 fn main() {
+    let x = 5f16;
+    let _ = x.is_nan();
+    //~^ WARN incorrect NaN comparison
+    let _ = !x.is_nan();
+    //~^ WARN incorrect NaN comparison
+
     let x = 5f32;
     let _ = x.is_nan();
     //~^ WARN incorrect NaN comparison
@@ -14,6 +22,12 @@ fn main() {
     let _ = !x.is_nan();
     //~^ WARN incorrect NaN comparison
 
+    let x = 5f128;
+    let _ = x.is_nan();
+    //~^ WARN incorrect NaN comparison
+    let _ = !x.is_nan();
+    //~^ WARN incorrect NaN comparison
+
     let b = &2.3f32;
     if !b.is_nan() {}
     //~^ WARN incorrect NaN comparison
diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.rs b/tests/ui/lint/invalid-nan-comparison-suggestion.rs
index 558b433d794..91753447869 100644
--- a/tests/ui/lint/invalid-nan-comparison-suggestion.rs
+++ b/tests/ui/lint/invalid-nan-comparison-suggestion.rs
@@ -1,7 +1,15 @@
 //@ check-pass
 //@ run-rustfix
 
+#![feature(f16, f128)]
+
 fn main() {
+    let x = 5f16;
+    let _ = x == f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    let _ = x != f16::NAN;
+    //~^ WARN incorrect NaN comparison
+
     let x = 5f32;
     let _ = x == f32::NAN;
     //~^ WARN incorrect NaN comparison
@@ -14,6 +22,12 @@ fn main() {
     let _ = x != f64::NAN;
     //~^ WARN incorrect NaN comparison
 
+    let x = 5f128;
+    let _ = x == f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    let _ = x != f128::NAN;
+    //~^ WARN incorrect NaN comparison
+
     let b = &2.3f32;
     if b != &f32::NAN {}
     //~^ WARN incorrect NaN comparison
diff --git a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr
index c310341de07..9d07d3f9240 100644
--- a/tests/ui/lint/invalid-nan-comparison-suggestion.stderr
+++ b/tests/ui/lint/invalid-nan-comparison-suggestion.stderr
@@ -1,18 +1,42 @@
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:6:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:8:13
    |
-LL |     let _ = x == f32::NAN;
+LL |     let _ = x == f16::NAN;
    |             ^^^^^^^^^^^^^
    |
    = note: `#[warn(invalid_nan_comparisons)]` on by default
 help: use `f32::is_nan()` or `f64::is_nan()` instead
    |
+LL -     let _ = x == f16::NAN;
+LL +     let _ = x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:10:13
+   |
+LL |     let _ = x != f16::NAN;
+   |             ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     let _ = x != f16::NAN;
+LL +     let _ = !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:14:13
+   |
+LL |     let _ = x == f32::NAN;
+   |             ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
 LL -     let _ = x == f32::NAN;
 LL +     let _ = x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:8:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:16:13
    |
 LL |     let _ = x != f32::NAN;
    |             ^^^^^^^^^^^^^
@@ -24,7 +48,7 @@ LL +     let _ = !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:12:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:20:13
    |
 LL |     let _ = x == f64::NAN;
    |             ^^^^^^^^^^^^^
@@ -36,7 +60,7 @@ LL +     let _ = x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:14:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:22:13
    |
 LL |     let _ = x != f64::NAN;
    |             ^^^^^^^^^^^^^
@@ -48,7 +72,31 @@ LL +     let _ = !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:18:8
+  --> $DIR/invalid-nan-comparison-suggestion.rs:26:13
+   |
+LL |     let _ = x == f128::NAN;
+   |             ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     let _ = x == f128::NAN;
+LL +     let _ = x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:28:13
+   |
+LL |     let _ = x != f128::NAN;
+   |             ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     let _ = x != f128::NAN;
+LL +     let _ = !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison-suggestion.rs:32:8
    |
 LL |     if b != &f32::NAN {}
    |        ^^^^^^^^^^^^^^
@@ -60,7 +108,7 @@ LL +     if !b.is_nan() {}
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:22:8
+  --> $DIR/invalid-nan-comparison-suggestion.rs:36:8
    |
 LL |     if b != { &f32::NAN } {}
    |        ^^^^^^^^^^^^^^^^^^
@@ -72,7 +120,7 @@ LL +     if !b.is_nan() {}
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:26:9
+  --> $DIR/invalid-nan-comparison-suggestion.rs:40:9
    |
 LL | /         b != {
 LL | |
@@ -87,7 +135,7 @@ LL +         !b.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:35:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:49:13
    |
 LL |     let _ = nan!() == number!();
    |             ^^^^^^^^^^^^^^^^^^^
@@ -99,7 +147,7 @@ LL +     let _ = number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison-suggestion.rs:37:13
+  --> $DIR/invalid-nan-comparison-suggestion.rs:51:13
    |
 LL |     let _ = number!() != nan!();
    |             ^^^^^^^^^^^^^^^^^^^
@@ -110,5 +158,5 @@ LL -     let _ = number!() != nan!();
 LL +     let _ = !number!().is_nan();
    |
 
-warning: 9 warnings emitted
+warning: 13 warnings emitted
 
diff --git a/tests/ui/lint/invalid-nan-comparison.rs b/tests/ui/lint/invalid-nan-comparison.rs
index 202a5e27e8e..1a2c8a7c5a0 100644
--- a/tests/ui/lint/invalid-nan-comparison.rs
+++ b/tests/ui/lint/invalid-nan-comparison.rs
@@ -1,13 +1,38 @@
 //@ check-pass
 
+#![feature(f16, f128)]
+
 fn main() {
+    f16();
     f32();
     f64();
+    f128();
 }
 
 const TEST: bool = 5f32 == f32::NAN;
 //~^ WARN incorrect NaN comparison
 
+fn f16() {
+    macro_rules! number { () => { 5f16 }; }
+    let x = number!();
+    x == f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x != f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x < f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x > f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x <= f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    x >= f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    number!() == f16::NAN;
+    //~^ WARN incorrect NaN comparison
+    f16::NAN != number!();
+    //~^ WARN incorrect NaN comparison
+}
+
 fn f32() {
     macro_rules! number { () => { 5f32 }; }
     let x = number!();
@@ -49,3 +74,24 @@ fn f64() {
     f64::NAN != number!();
     //~^ WARN incorrect NaN comparison
 }
+
+fn f128() {
+    macro_rules! number { () => { 5f128 }; }
+    let x = number!();
+    x == f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x != f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x < f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x > f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x <= f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    x >= f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    number!() == f128::NAN;
+    //~^ WARN incorrect NaN comparison
+    f128::NAN != number!();
+    //~^ WARN incorrect NaN comparison
+}
diff --git a/tests/ui/lint/invalid-nan-comparison.stderr b/tests/ui/lint/invalid-nan-comparison.stderr
index 054c06d38b3..486d2a9636c 100644
--- a/tests/ui/lint/invalid-nan-comparison.stderr
+++ b/tests/ui/lint/invalid-nan-comparison.stderr
@@ -1,5 +1,5 @@
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:8:20
+  --> $DIR/invalid-nan-comparison.rs:12:20
    |
 LL | const TEST: bool = 5f32 == f32::NAN;
    |                    ^^^^^^^^^^^^^^^^
@@ -12,7 +12,79 @@ LL + const TEST: bool = 5f32.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:14:5
+  --> $DIR/invalid-nan-comparison.rs:18:5
+   |
+LL |     x == f16::NAN;
+   |     ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x == f16::NAN;
+LL +     x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:20:5
+   |
+LL |     x != f16::NAN;
+   |     ^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x != f16::NAN;
+LL +     !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:22:5
+   |
+LL |     x < f16::NAN;
+   |     ^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:24:5
+   |
+LL |     x > f16::NAN;
+   |     ^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:26:5
+   |
+LL |     x <= f16::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:28:5
+   |
+LL |     x >= f16::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:30:5
+   |
+LL |     number!() == f16::NAN;
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     number!() == f16::NAN;
+LL +     number!().is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:32:5
+   |
+LL |     f16::NAN != number!();
+   |     ^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     f16::NAN != number!();
+LL +     !number!().is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:39:5
    |
 LL |     x == f32::NAN;
    |     ^^^^^^^^^^^^^
@@ -24,7 +96,7 @@ LL +     x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:16:5
+  --> $DIR/invalid-nan-comparison.rs:41:5
    |
 LL |     x != f32::NAN;
    |     ^^^^^^^^^^^^^
@@ -36,31 +108,31 @@ LL +     !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:18:5
+  --> $DIR/invalid-nan-comparison.rs:43:5
    |
 LL |     x < f32::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:20:5
+  --> $DIR/invalid-nan-comparison.rs:45:5
    |
 LL |     x > f32::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:22:5
+  --> $DIR/invalid-nan-comparison.rs:47:5
    |
 LL |     x <= f32::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:24:5
+  --> $DIR/invalid-nan-comparison.rs:49:5
    |
 LL |     x >= f32::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:26:5
+  --> $DIR/invalid-nan-comparison.rs:51:5
    |
 LL |     number!() == f32::NAN;
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -72,7 +144,7 @@ LL +     number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:28:5
+  --> $DIR/invalid-nan-comparison.rs:53:5
    |
 LL |     f32::NAN != number!();
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -84,7 +156,7 @@ LL +     !number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:35:5
+  --> $DIR/invalid-nan-comparison.rs:60:5
    |
 LL |     x == f64::NAN;
    |     ^^^^^^^^^^^^^
@@ -96,7 +168,7 @@ LL +     x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:37:5
+  --> $DIR/invalid-nan-comparison.rs:62:5
    |
 LL |     x != f64::NAN;
    |     ^^^^^^^^^^^^^
@@ -108,31 +180,31 @@ LL +     !x.is_nan();
    |
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:39:5
+  --> $DIR/invalid-nan-comparison.rs:64:5
    |
 LL |     x < f64::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:41:5
+  --> $DIR/invalid-nan-comparison.rs:66:5
    |
 LL |     x > f64::NAN;
    |     ^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:43:5
+  --> $DIR/invalid-nan-comparison.rs:68:5
    |
 LL |     x <= f64::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN is not orderable
-  --> $DIR/invalid-nan-comparison.rs:45:5
+  --> $DIR/invalid-nan-comparison.rs:70:5
    |
 LL |     x >= f64::NAN;
    |     ^^^^^^^^^^^^^
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:47:5
+  --> $DIR/invalid-nan-comparison.rs:72:5
    |
 LL |     number!() == f64::NAN;
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -144,7 +216,7 @@ LL +     number!().is_nan();
    |
 
 warning: incorrect NaN comparison, NaN cannot be directly compared to itself
-  --> $DIR/invalid-nan-comparison.rs:49:5
+  --> $DIR/invalid-nan-comparison.rs:74:5
    |
 LL |     f64::NAN != number!();
    |     ^^^^^^^^^^^^^^^^^^^^^
@@ -155,5 +227,77 @@ LL -     f64::NAN != number!();
 LL +     !number!().is_nan();
    |
 
-warning: 17 warnings emitted
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:81:5
+   |
+LL |     x == f128::NAN;
+   |     ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x == f128::NAN;
+LL +     x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:83:5
+   |
+LL |     x != f128::NAN;
+   |     ^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     x != f128::NAN;
+LL +     !x.is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:85:5
+   |
+LL |     x < f128::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:87:5
+   |
+LL |     x > f128::NAN;
+   |     ^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:89:5
+   |
+LL |     x <= f128::NAN;
+   |     ^^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN is not orderable
+  --> $DIR/invalid-nan-comparison.rs:91:5
+   |
+LL |     x >= f128::NAN;
+   |     ^^^^^^^^^^^^^^
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:93:5
+   |
+LL |     number!() == f128::NAN;
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     number!() == f128::NAN;
+LL +     number!().is_nan();
+   |
+
+warning: incorrect NaN comparison, NaN cannot be directly compared to itself
+  --> $DIR/invalid-nan-comparison.rs:95:5
+   |
+LL |     f128::NAN != number!();
+   |     ^^^^^^^^^^^^^^^^^^^^^^
+   |
+help: use `f32::is_nan()` or `f64::is_nan()` instead
+   |
+LL -     f128::NAN != number!();
+LL +     !number!().is_nan();
+   |
+
+warning: 33 warnings emitted
 
diff --git a/tests/ui/lint/non-local-defs/convoluted-locals-132427.rs b/tests/ui/lint/non-local-defs/convoluted-locals-132427.rs
new file mode 100644
index 00000000000..5732e048ae3
--- /dev/null
+++ b/tests/ui/lint/non-local-defs/convoluted-locals-132427.rs
@@ -0,0 +1,64 @@
+// Regression tests for https://github.com/rust-lang/rust/issues/132427
+
+//@ check-pass
+
+// original
+mod auth {
+    const _: () = {
+        pub enum ArbitraryContext {}
+
+        const _: () = {
+            impl ArbitraryContext {}
+        };
+    };
+}
+
+mod z {
+    pub enum ArbitraryContext {}
+
+    const _: () = {
+        const _: () = {
+            impl ArbitraryContext {}
+        };
+    };
+}
+
+const _: () = {
+    mod auth {
+        const _: () = {
+            pub enum ArbitraryContext {}
+
+            const _: () = {
+                impl ArbitraryContext {}
+            };
+        };
+    }
+};
+
+mod a {
+    mod b {
+        const _: () = {
+            pub enum ArbitraryContext {}
+
+            const _: () = {
+                impl ArbitraryContext {}
+            };
+        };
+    }
+}
+
+mod foo {
+    const _: () = {
+        mod auth {
+            const _: () = {
+                pub enum ArbitraryContext {}
+
+                const _: () = {
+                    impl ArbitraryContext {}
+                };
+            };
+        }
+    };
+}
+
+fn main() {}
diff --git a/tests/ui/mir/clone-canonicalization-miscompile-132353.rs b/tests/ui/mir/clone-canonicalization-miscompile-132353.rs
new file mode 100644
index 00000000000..ba740c10f90
--- /dev/null
+++ b/tests/ui/mir/clone-canonicalization-miscompile-132353.rs
@@ -0,0 +1,25 @@
+//! The mir-opt added in <https://github.com/rust-lang/rust/pull/128299> unfortunately seems to lead
+//! to a miscompile (reported in <https://github.com/rust-lang/rust/issues/132353>, minimization
+//! reproduced in this test file).
+//@ revisions: release debug
+// Note: it's not strictly cargo's release profile, but any non-zero opt-level was sufficient to
+// reproduce the miscompile.
+//@[release] compile-flags: -C opt-level=1
+//@[debug] compile-flags: -C opt-level=0
+//@ run-pass
+
+fn pop_min(mut score2head: Vec<Option<usize>>) -> Option<usize> {
+    loop {
+        if let Some(col) = score2head[0] {
+            score2head[0] = None;
+            return Some(col);
+        }
+    }
+}
+
+fn main() {
+    let min = pop_min(vec![Some(1)]);
+    println!("min: {:?}", min);
+    // panic happened on 1.83.0 beta in release mode but not debug mode.
+    let _ = min.unwrap();
+}
diff --git a/tests/ui/never_type/defaulted-never-note.nofallback.stderr b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
index d88615186dd..6bc4501b6a3 100644
--- a/tests/ui/never_type/defaulted-never-note.nofallback.stderr
+++ b/tests/ui/never_type/defaulted-never-note.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: ImplementedForUnitButNotNever` will f
 LL |     foo(_x);
    |         ^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let _x: () = return;
+   |           ++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
index ec49137ba79..79f47bb5fbc 100644
--- a/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
+++ b/tests/ui/never_type/dependency-on-fallback-to-unit.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Default` will fail
 LL |         false => <_>::default(),
    |                   ^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         false => <()>::default(),
+   |                   ~~
 
 warning: this function depends on never type fallback being `()`
   --> $DIR/dependency-on-fallback-to-unit.rs:19:1
@@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: Default` will fail
    |
 LL |     deserialize()?;
    |     ^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     deserialize::<()>()?;
+   |                ++++++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
index 2a3c5edc218..d40d1da76f9 100644
--- a/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-control-flow.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail
 LL |         x = UnitDefault::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let x: ();
+   |          ++++
 
 warning: this function depends on never type fallback being `()`
   --> $DIR/diverging-fallback-control-flow.rs:42:1
@@ -28,6 +32,10 @@ note: in edition 2024, the requirement `!: UnitDefault` will fail
    |
 LL |         x = UnitDefault::default();
    |             ^^^^^^^^^^^^^^^^^^^^^^
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let x: ();
+   |          ++++
 
 warning: 2 warnings emitted
 
diff --git a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
index 11245cc7aab..d11c21d9573 100644
--- a/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-no-leak.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Test` will fail
 LL |     unconstrained_arg(return);
    |                       ^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     unconstrained_arg::<()>(return);
+   |                      ++++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
index b485c94df4d..30a5e60a758 100644
--- a/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
+++ b/tests/ui/never_type/diverging-fallback-unconstrained-return.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: UnitReturn` will fail
 LL |     let _ = if true { unconstrained_return() } else { panic!() };
    |                       ^^^^^^^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     let _: () = if true { unconstrained_return() } else { panic!() };
+   |          ++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
index 3fb5536dee7..fb0166dd9e0 100644
--- a/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
+++ b/tests/ui/never_type/fallback-closure-ret.nofallback.stderr
@@ -13,6 +13,10 @@ note: in edition 2024, the requirement `!: Bar` will fail
 LL |     foo(|| panic!());
    |     ^^^^^^^^^^^^^^^^
    = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |     foo::<(), _>(|| panic!());
+   |        +++++++++
 
 warning: 1 warning emitted
 
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
index a75039b8237..6a48a7b9b47 100644
--- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2015.stderr
@@ -8,6 +8,10 @@ LL |         unsafe { mem::zeroed() }
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: `#[warn(never_type_fallback_flowing_into_unsafe)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { mem::zeroed::<()>() }
+   |                             ++++++
 
 warning: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13
@@ -18,6 +22,10 @@ LL |             core::mem::transmute(Zst)
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             core::mem::transmute::<_, ()>(Zst)
+   |                                 +++++++++
 
 warning: never type fallback affects this union access
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18
@@ -38,6 +46,10 @@ LL |         unsafe { *ptr::from_ref(&()).cast() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { *ptr::from_ref(&()).cast::<()>() }
+   |                                          ++++++
 
 warning: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18
@@ -48,6 +60,10 @@ LL |         unsafe { internally_create(x) }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { internally_create::<()>(x) }
+   |                                   ++++++
 
 warning: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18
@@ -58,6 +74,10 @@ LL |         unsafe { zeroed() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 warning: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22
@@ -68,6 +88,10 @@ LL |         let zeroed = mem::zeroed;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 warning: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17
@@ -78,6 +102,10 @@ LL |         let f = internally_create;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let f = internally_create::<()>;
+   |                                  ++++++
 
 warning: never type fallback affects this call to an `unsafe` method
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13
@@ -102,6 +130,10 @@ LL |         msg_send!();
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: this warning originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             match send_message::<() /* ?0 */>() {
+   |                                  ~~
 
 warning: 10 warnings emitted
 
diff --git a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
index 4138e9f8c86..844cd62c267 100644
--- a/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
+++ b/tests/ui/never_type/lint-never-type-fallback-flowing-into-unsafe.e2024.stderr
@@ -8,6 +8,10 @@ LL |         unsafe { mem::zeroed() }
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: `#[deny(never_type_fallback_flowing_into_unsafe)]` on by default
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { mem::zeroed::<()>() }
+   |                             ++++++
 
 error: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:30:13
@@ -18,6 +22,10 @@ LL |             core::mem::transmute(Zst)
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             core::mem::transmute::<_, ()>(Zst)
+   |                                 +++++++++
 
 error: never type fallback affects this union access
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:47:18
@@ -38,6 +46,10 @@ LL |         unsafe { *ptr::from_ref(&()).cast() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { *ptr::from_ref(&()).cast::<()>() }
+   |                                          ++++++
 
 error: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:79:18
@@ -48,6 +60,10 @@ LL |         unsafe { internally_create(x) }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         unsafe { internally_create::<()>(x) }
+   |                                   ++++++
 
 error: never type fallback affects this call to an `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:97:18
@@ -58,6 +74,10 @@ LL |         unsafe { zeroed() }
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 error: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:92:22
@@ -68,6 +88,10 @@ LL |         let zeroed = mem::zeroed;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let zeroed = mem::zeroed::<()>;
+   |                                 ++++++
 
 error: never type fallback affects this `unsafe` function
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:115:17
@@ -78,6 +102,10 @@ LL |         let f = internally_create;
    = warning: this will change its meaning in a future release!
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
+help: use `()` annotations to avoid fallback changes
+   |
+LL |         let f = internally_create::<()>;
+   |                                  ++++++
 
 error: never type fallback affects this call to an `unsafe` method
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:140:13
@@ -102,6 +130,10 @@ LL |         msg_send!();
    = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
    = help: specify the type explicitly
    = note: this error originates in the macro `msg_send` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: use `()` annotations to avoid fallback changes
+   |
+LL |             match send_message::<() /* ?0 */>() {
+   |                                  ~~
 
 warning: the type `!` does not permit zero-initialization
   --> $DIR/lint-never-type-fallback-flowing-into-unsafe.rs:13:18
diff --git a/tests/ui/target-feature/wasm-disable-simd.rs b/tests/ui/target-feature/wasm-disable-simd.rs
new file mode 100644
index 00000000000..998c8674823
--- /dev/null
+++ b/tests/ui/target-feature/wasm-disable-simd.rs
@@ -0,0 +1,12 @@
+//@ only-wasm32-wasip1
+//@ compile-flags: -Ctarget-feature=-simd128 --crate-type=lib
+//@ build-pass
+
+// This is a regression test of #131031.
+
+use std::arch::wasm32::*;
+
+#[target_feature(enable = "simd128")]
+pub unsafe fn some_simd128_fn(chunk: v128) -> bool {
+    u8x16_all_true(chunk)
+}
diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.rs b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs
new file mode 100644
index 00000000000..dfa8e9886b6
--- /dev/null
+++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.rs
@@ -0,0 +1,4 @@
+fn uwu<T: ?Sized<i32>>() {}
+//~^ ERROR trait takes 0 generic arguments but 1 generic argument was supplied
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr
new file mode 100644
index 00000000000..3297eb6279f
--- /dev/null
+++ b/tests/ui/trait-bounds/maybe-bound-generics-deny.stderr
@@ -0,0 +1,11 @@
+error[E0107]: trait takes 0 generic arguments but 1 generic argument was supplied
+  --> $DIR/maybe-bound-generics-deny.rs:1:12
+   |
+LL | fn uwu<T: ?Sized<i32>>() {}
+   |            ^^^^^----- help: remove the unnecessary generics
+   |            |
+   |            expected 0 generic arguments
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0107`.
diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.rs b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs
new file mode 100644
index 00000000000..2cb63f25d06
--- /dev/null
+++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.rs
@@ -0,0 +1,7 @@
+trait Trait {}
+
+fn test<T: ?self::<i32>::Trait>() {}
+//~^ ERROR type arguments are not allowed on this type
+//~| WARN relaxing a default bound only does something for `?Sized`
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr
new file mode 100644
index 00000000000..701e493f5a5
--- /dev/null
+++ b/tests/ui/trait-bounds/maybe-bound-has-path-args.stderr
@@ -0,0 +1,17 @@
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-bound-has-path-args.rs:3:12
+   |
+LL | fn test<T: ?self::<i32>::Trait>() {}
+   |            ^^^^^^^^^^^^^^^^^^^
+
+error[E0109]: type arguments are not allowed on this type
+  --> $DIR/maybe-bound-has-path-args.rs:3:20
+   |
+LL | fn test<T: ?self::<i32>::Trait>() {}
+   |             ----   ^^^ type argument not allowed
+   |             |
+   |             not allowed on this type
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0109`.
diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.rs b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs
new file mode 100644
index 00000000000..b6b2551e463
--- /dev/null
+++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.rs
@@ -0,0 +1,12 @@
+trait HasAssoc {
+    type Assoc;
+}
+fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
+//~^ WARN relaxing a default bound
+
+trait NoAssoc {}
+fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
+//~^ WARN relaxing a default bound
+//~| ERROR associated type `Missing` not found for `NoAssoc`
+
+fn main() {}
diff --git a/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr
new file mode 100644
index 00000000000..91d78e59cd5
--- /dev/null
+++ b/tests/ui/trait-bounds/maybe-bound-with-assoc.stderr
@@ -0,0 +1,21 @@
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-bound-with-assoc.rs:4:16
+   |
+LL | fn hasassoc<T: ?HasAssoc<Assoc = ()>>() {}
+   |                ^^^^^^^^^^^^^^^^^^^^^
+
+warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
+  --> $DIR/maybe-bound-with-assoc.rs:8:15
+   |
+LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
+   |               ^^^^^^^^^^^^^^^^^^^^^^
+
+error[E0220]: associated type `Missing` not found for `NoAssoc`
+  --> $DIR/maybe-bound-with-assoc.rs:8:24
+   |
+LL | fn noassoc<T: ?NoAssoc<Missing = ()>>() {}
+   |                        ^^^^^^^ associated type `Missing` not found
+
+error: aborting due to 1 previous error; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0220`.
diff --git a/tests/ui/traits/const-traits/const-drop-fail-2.stderr b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
index 82d6412ded0..102dbb1a599 100644
--- a/tests/ui/traits/const-traits/const-drop-fail-2.stderr
+++ b/tests/ui/traits/const-traits/const-drop-fail-2.stderr
@@ -29,6 +29,12 @@ LL | const fn check<T: ~const Destruct>(_: T) {}
    |                                    |
    |                                    the destructor for this type cannot be evaluated in constant functions
 
+error[E0277]: the trait bound `T: ~const A` is not satisfied
+  --> $DIR/const-drop-fail-2.rs:41:9
+   |
+LL |         T::a();
+   |         ^^^^^^
+
 error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
   --> $DIR/const-drop-fail-2.rs:41:9
    |
@@ -41,7 +47,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 5 previous errors
+error: aborting due to 6 previous errors
 
-Some errors have detailed explanations: E0015, E0493.
+Some errors have detailed explanations: E0015, E0277, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-drop.precise.stderr b/tests/ui/traits/const-traits/const-drop.precise.stderr
index 381e4d78c28..7471b200c33 100644
--- a/tests/ui/traits/const-traits/const-drop.precise.stderr
+++ b/tests/ui/traits/const-traits/const-drop.precise.stderr
@@ -78,6 +78,12 @@ error[E0493]: destructor of `T` cannot be evaluated at compile-time
 LL | const fn a<T: ~const Destruct>(_: T) {}
    |                                ^ the destructor for this type cannot be evaluated in constant functions
 
+error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied
+  --> $DIR/const-drop.rs:69:13
+   |
+LL |             T::foo();
+   |             ^^^^^^^^
+
 error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
   --> $DIR/const-drop.rs:69:13
    |
@@ -90,7 +96,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 10 previous errors
+error: aborting due to 11 previous errors
 
 Some errors have detailed explanations: E0015, E0277, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/const-drop.stock.stderr b/tests/ui/traits/const-traits/const-drop.stock.stderr
index 399e7849673..71378349161 100644
--- a/tests/ui/traits/const-traits/const-drop.stock.stderr
+++ b/tests/ui/traits/const-traits/const-drop.stock.stderr
@@ -80,6 +80,12 @@ LL | const fn a<T: ~const Destruct>(_: T) {}
    |                                |
    |                                the destructor for this type cannot be evaluated in constant functions
 
+error[E0277]: the trait bound `T: ~const SomeTrait` is not satisfied
+  --> $DIR/const-drop.rs:69:13
+   |
+LL |             T::foo();
+   |             ^^^^^^^^
+
 error[E0015]: cannot call non-const fn `<T as SomeTrait>::foo` in constant functions
   --> $DIR/const-drop.rs:69:13
    |
@@ -92,7 +98,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 10 previous errors
+error: aborting due to 11 previous errors
 
 Some errors have detailed explanations: E0015, E0277, E0493.
 For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/cross-crate.rs b/tests/ui/traits/const-traits/cross-crate.rs
index cfcada9c828..30d2260a744 100644
--- a/tests/ui/traits/const-traits/cross-crate.rs
+++ b/tests/ui/traits/const-traits/cross-crate.rs
@@ -18,10 +18,11 @@ const fn const_context() {
     #[cfg(any(stocknc, gatednc))]
     NonConst.func();
     //[stocknc]~^ ERROR: cannot call
-    //[gatednc]~^^ ERROR: the trait bound
+    //[stocknc]~| ERROR: cannot call
+    //[gatednc]~^^^ ERROR: the trait bound
     Const.func();
-    //[stock]~^ ERROR: cannot call
-    //[stocknc]~^^ ERROR: cannot call
+    //[stock,stocknc]~^ ERROR: cannot call
+    //[stock,stocknc]~| ERROR: cannot call
 }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/cross-crate.stock.stderr b/tests/ui/traits/const-traits/cross-crate.stock.stderr
index b481bdc470c..b35891071b0 100644
--- a/tests/ui/traits/const-traits/cross-crate.stock.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.stock.stderr
@@ -1,5 +1,5 @@
 error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:22:11
+  --> $DIR/cross-crate.rs:23:11
    |
 LL |     Const.func();
    |           ^^^^^^
@@ -10,6 +10,19 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
 LL + #![feature(const_trait_impl)]
    |
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:23:11
+   |
+LL |     Const.func();
+   |           ^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
index 5c3e3b6ff40..89de89159db 100644
--- a/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
+++ b/tests/ui/traits/const-traits/cross-crate.stocknc.stderr
@@ -10,18 +10,44 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
 LL + #![feature(const_trait_impl)]
    |
 
+error[E0015]: cannot call non-const fn `<cross_crate::NonConst as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:19:14
+   |
+LL |     NonConst.func();
+   |              ^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
+  --> $DIR/cross-crate.rs:23:11
+   |
+LL |     Const.func();
+   |           ^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
 error[E0015]: cannot call non-const fn `<cross_crate::Const as cross_crate::MyTrait>::func` in constant functions
-  --> $DIR/cross-crate.rs:22:11
+  --> $DIR/cross-crate.rs:23:11
    |
 LL |     Const.func();
    |           ^^^^^^
    |
    = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
    |
 LL + #![feature(const_trait_impl)]
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs
index b534d23b107..96acdc300e0 100644
--- a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.rs
@@ -1,6 +1,3 @@
-//@ known-bug: #110395
-//@ check-pass
-
 #![feature(const_trait_impl)]
 
 #[const_trait]
@@ -13,7 +10,7 @@ const fn foo<T>() where T: ~const Tr {}
 pub trait Foo {
     fn foo() {
         foo::<()>();
-        //FIXME ~^ ERROR the trait bound `(): Tr` is not satisfied
+        //~^ ERROR the trait bound `(): ~const Tr` is not satisfied
     }
 }
 
diff --git a/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
new file mode 100644
index 00000000000..308a60c08d3
--- /dev/null
+++ b/tests/ui/traits/const-traits/default-method-body-is-const-body-checking.stderr
@@ -0,0 +1,15 @@
+error[E0277]: the trait bound `(): ~const Tr` is not satisfied
+  --> $DIR/default-method-body-is-const-body-checking.rs:12:9
+   |
+LL |         foo::<()>();
+   |         ^^^^^^^^^^^
+   |
+note: required by a bound in `foo`
+  --> $DIR/default-method-body-is-const-body-checking.rs:7:28
+   |
+LL | const fn foo<T>() where T: ~const Tr {}
+   |                            ^^^^^^ required by this bound in `foo`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/ui/traits/const-traits/specializing-constness-2.stderr b/tests/ui/traits/const-traits/specializing-constness-2.stderr
index 8e6f6945a1b..98a9de2324a 100644
--- a/tests/ui/traits/const-traits/specializing-constness-2.stderr
+++ b/tests/ui/traits/const-traits/specializing-constness-2.stderr
@@ -1,3 +1,9 @@
+error[E0277]: the trait bound `T: ~const A` is not satisfied
+  --> $DIR/specializing-constness-2.rs:27:5
+   |
+LL |     <T as A>::a();
+   |     ^^^^^^^^^^^^^
+
 error[E0015]: cannot call non-const fn `<T as A>::a` in constant functions
   --> $DIR/specializing-constness-2.rs:27:5
    |
@@ -10,6 +16,7 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0015`.
+Some errors have detailed explanations: E0015, E0277.
+For more information about an error, try `rustc --explain E0015`.
diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.rs b/tests/ui/traits/const-traits/staged-api-user-crate.rs
index c4ecb8f67a1..c820d1ff47c 100644
--- a/tests/ui/traits/const-traits/staged-api-user-crate.rs
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.rs
@@ -11,6 +11,7 @@ fn non_const_context() {
 const fn stable_const_context() {
     Unstable::func();
     //~^ ERROR cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
+    //~| ERROR cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
 }
 
 fn main() {}
diff --git a/tests/ui/traits/const-traits/staged-api-user-crate.stderr b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
index 781191ec97c..24cdb1d3d5a 100644
--- a/tests/ui/traits/const-traits/staged-api-user-crate.stderr
+++ b/tests/ui/traits/const-traits/staged-api-user-crate.stderr
@@ -10,6 +10,19 @@ help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
 LL + #![feature(const_trait_impl)]
    |
 
-error: aborting due to 1 previous error
+error[E0015]: cannot call non-const fn `<staged_api::Unstable as staged_api::MyTrait>::func` in constant functions
+  --> $DIR/staged-api-user-crate.rs:12:5
+   |
+LL |     Unstable::func();
+   |     ^^^^^^^^^^^^^^^^
+   |
+   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+help: add `#![feature(const_trait_impl)]` to the crate attributes to enable
+   |
+LL + #![feature(const_trait_impl)]
+   |
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0015`.