about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_abi/src/layout.rs2
-rw-r--r--compiler/rustc_abi/src/lib.rs2
-rw-r--r--compiler/rustc_ast/src/ast.rs20
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs4
-rw-r--r--compiler/rustc_ast/src/util/classify.rs3
-rw-r--r--compiler/rustc_ast/src/visit.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs8
-rw-r--r--compiler/rustc_ast_lowering/src/pat.rs3
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state/expr.rs7
-rw-r--r--compiler/rustc_borrowck/src/type_check/relate_tys.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/asm.rs71
-rw-r--r--compiler/rustc_builtin_macros/src/assert.rs4
-rw-r--r--compiler/rustc_builtin_macros/src/assert/context.rs3
-rw-r--r--compiler/rustc_builtin_macros/src/cfg.rs8
-rw-r--r--compiler/rustc_builtin_macros/src/compile_error.rs18
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs72
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs191
-rw-r--r--compiler/rustc_builtin_macros/src/concat_idents.rs38
-rw-r--r--compiler/rustc_builtin_macros/src/deriving/default.rs53
-rw-r--r--compiler/rustc_builtin_macros/src/env.rs56
-rw-r--r--compiler/rustc_builtin_macros/src/format.rs90
-rw-r--r--compiler/rustc_builtin_macros/src/lib.rs1
-rw-r--r--compiler/rustc_builtin_macros/src/source_util.rs88
-rw-r--r--compiler/rustc_builtin_macros/src/type_ascribe.rs4
-rw-r--r--compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs7
-rw-r--r--compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs4
-rw-r--r--compiler/rustc_codegen_gcc/src/intrinsic/mod.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/back/write.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs8
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs4
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm/ffi.rs2
-rw-r--r--compiler/rustc_error_codes/src/error_codes/E0511.md8
-rw-r--r--compiler/rustc_expand/src/base.rs102
-rw-r--r--compiler/rustc_expand/src/expand.rs82
-rw-r--r--compiler/rustc_expand/src/mbe/diagnostics.rs18
-rw-r--r--compiler/rustc_expand/src/mbe/macro_check.rs62
-rw-r--r--compiler/rustc_expand/src/mbe/macro_rules.rs132
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs62
-rw-r--r--compiler/rustc_feature/src/removed.rs3
-rw-r--r--compiler/rustc_feature/src/unstable.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs174
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_hir_typeck/src/coercion.rs32
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs1
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs3
-rw-r--r--compiler/rustc_infer/src/infer/at.rs18
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs1
-rw-r--r--compiler/rustc_infer/src/infer/relate/combine.rs58
-rw-r--r--compiler/rustc_infer/src/infer/relate/equate.rs13
-rw-r--r--compiler/rustc_infer/src/infer/relate/generalize.rs53
-rw-r--r--compiler/rustc_infer/src/infer/relate/glb.rs9
-rw-r--r--compiler/rustc_infer/src/infer/relate/lub.rs9
-rw-r--r--compiler/rustc_infer/src/infer/relate/mod.rs12
-rw-r--r--compiler/rustc_infer/src/infer/relate/sub.rs9
-rw-r--r--compiler/rustc_lint/messages.ftl23
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lints.rs2
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs47
-rw-r--r--compiler/rustc_lint/src/types.rs5
-rw-r--r--compiler/rustc_lint/src/unused.rs2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp2
-rw-r--r--compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp2
-rw-r--r--compiler/rustc_metadata/src/native_libs.rs2
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect.rs2
-rw-r--r--compiler/rustc_middle/src/traits/solve/inspect/format.rs15
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs1
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_mir_transform/src/ffi_unwind_calls.rs1
-rw-r--r--compiler/rustc_next_trait_solver/src/canonicalizer.rs38
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs92
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs166
-rw-r--r--compiler/rustc_parse/src/parser/item.rs4
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs20
-rw-r--r--compiler/rustc_parse/src/parser/stmt.rs64
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs2
-rw-r--r--compiler/rustc_passes/src/check_attr.rs4
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs2
-rw-r--r--compiler/rustc_passes/src/stability.rs5
-rw-r--r--compiler/rustc_smir/src/rustc_internal/internal.rs1
-rw-r--r--compiler/rustc_smir/src/rustc_smir/convert/ty.rs1
-rw-r--r--compiler/rustc_span/src/symbol.rs1
-rw-r--r--compiler/rustc_target/src/spec/abi/mod.rs15
-rw-r--r--compiler/rustc_target/src/spec/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/alias_relate.rs67
-rw-r--r--compiler/rustc_trait_selection/src/solve/assembly/mod.rs7
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs74
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs179
-rw-r--r--compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs59
-rw-r--r--compiler/rustc_trait_selection/src/solve/fulfill.rs25
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/analyse.rs13
-rw-r--r--compiler/rustc_trait_selection/src/solve/inspect/build.rs14
-rw-r--r--compiler/rustc_trait_selection/src/solve/mod.rs1
-rw-r--r--compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs54
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/confirmation.rs5
-rw-r--r--compiler/rustc_ty_utils/src/abi.rs15
-rw-r--r--compiler/stable_mir/src/ty.rs1
-rw-r--r--library/alloc/src/string.rs4
-rw-r--r--library/alloc/src/vec/mod.rs8
-rw-r--r--library/core/src/intrinsics.rs25
-rw-r--r--library/core/src/intrinsics/simd.rs80
-rw-r--r--library/core/src/lib.rs2
-rw-r--r--library/panic_unwind/src/miri.rs6
-rw-r--r--library/std/src/lib.rs2
-rw-r--r--library/std/src/panicking.rs8
-rw-r--r--library/std/src/sync/mpmc/list.rs4
-rw-r--r--library/std/src/sys/pal/windows/c.rs28
-rw-r--r--library/std/src/sys/pal/windows/compat.rs11
-rw-r--r--library/std/src/sys/pal/windows/thread_parking.rs221
m---------src/doc/book0
m---------src/doc/edition-guide0
m---------src/doc/reference0
m---------src/doc/rust-by-example0
m---------src/doc/rustc-dev-guide0
-rw-r--r--src/librustdoc/html/static/js/main.js14
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs3
-rw-r--r--src/tools/clippy/clippy_utils/src/sugg.rs3
-rw-r--r--src/tools/compiletest/src/header.rs8
-rw-r--r--src/tools/compiletest/src/runtest.rs39
-rw-r--r--src/tools/miri/rust-version2
-rw-r--r--src/tools/miri/src/concurrency/thread.rs2
-rw-r--r--src/tools/miri/src/shims/foreign_items.rs6
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs2
-rw-r--r--src/tools/miri/src/shims/panic.rs16
-rw-r--r--src/tools/miri/tests/fail/function_calls/check_callback_abi.rs2
-rw-r--r--src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr2
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs6
-rw-r--r--src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs6
-rw-r--r--src/tools/miri/tests/fail/panic/bad_miri_start_unwind.rs (renamed from src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs)4
-rw-r--r--src/tools/miri/tests/fail/panic/bad_miri_start_unwind.stderr (renamed from src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr)8
-rw-r--r--src/tools/miri/tests/fail/panic/unwind_panic_abort.rs4
-rw-r--r--src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr4
-rw-r--r--src/tools/miri/tests/pass/float_nan.rs8
-rw-r--r--src/tools/miri/tests/pass/function_calls/disable_abi_check.rs2
-rw-r--r--src/tools/miri/tests/pass/portable-simd-ptrs.rs2
-rw-r--r--src/tools/miri/tests/pass/portable-simd.rs10
-rw-r--r--src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs2
-rw-r--r--src/tools/miri/tests/utils/miri_extern.rs2
-rw-r--r--src/tools/rustfmt/src/expr.rs2
-rw-r--r--src/tools/rustfmt/src/formatting.rs22
-rw-r--r--src/tools/rustfmt/src/parse/parser.rs16
-rw-r--r--src/tools/rustfmt/src/parse/session.rs6
-rw-r--r--src/tools/rustfmt/src/test/parser.rs7
-rw-r--r--src/tools/rustfmt/src/utils.rs3
-rw-r--r--src/tools/rustfmt/tests/parser/stashed-diag2.rs3
-rw-r--r--tests/assembly/wasm_exceptions.rs2
-rw-r--r--tests/codegen/instrument-coverage/instrument-coverage-off.rs (renamed from tests/codegen/instrument-coverage-off.rs)0
-rw-r--r--tests/codegen/instrument-coverage/instrument-coverage.rs (renamed from tests/codegen/instrument-coverage.rs)0
-rw-r--r--tests/codegen/instrument-coverage/testprog.rs120
-rw-r--r--tests/codegen/issues/issue-84268.rs4
-rw-r--r--tests/codegen/meta-filecheck/check-prefix.rs4
-rw-r--r--tests/codegen/meta-filecheck/filecheck-flags.rs8
-rw-r--r--tests/codegen/meta-filecheck/msvc-prefix-bad.rs7
-rw-r--r--tests/codegen/meta-filecheck/msvc-prefix-good.rs7
-rw-r--r--tests/codegen/meta-filecheck/no-directives.rs5
-rw-r--r--tests/codegen/meta-filecheck/revision-prefix.rs8
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs4
-rw-r--r--tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs2
-rw-r--r--tests/codegen/simd/simd_arith_offset.rs4
-rw-r--r--tests/codegen/wasm_exceptions.rs2
-rw-r--r--tests/incremental/issue-61530.rs4
-rw-r--r--tests/run-make/coverage-llvmir/Makefile64
-rw-r--r--tests/run-make/coverage-llvmir/filecheck.testprog.txt50
-rw-r--r--tests/run-make/coverage-llvmir/testprog.rs38
-rw-r--r--tests/run-make/tools.mk4
-rw-r--r--tests/run-make/wasm-exceptions-nostd/src/lib.rs2
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.rs8
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.stderr27
-rw-r--r--tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs12
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.next.stderr4
-rw-r--r--tests/ui/coherence/occurs-check/opaques.next.stderr6
-rw-r--r--tests/ui/consts/const-eval/simd/insert_extract.rs4
-rw-r--r--tests/ui/error-codes/E0511.rs4
-rw-r--r--tests/ui/feature-gates/feature-gate-abi.rs13
-rw-r--r--tests/ui/feature-gates/feature-gate-abi.stderr132
-rw-r--r--tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.rs20
-rw-r--r--tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr49
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.next.stderr4
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.rs3
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr2
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr8
-rw-r--r--tests/ui/impl-trait/two_tait_defining_each_other2.rs2
-rw-r--r--tests/ui/inline-const/instance-doesnt-depend-on-type.rs2
-rw-r--r--tests/ui/interior-mutability/interior-mutability.stderr2
-rw-r--r--tests/ui/intrinsics/bad-intrinsic-monomorphization.rs4
-rw-r--r--tests/ui/lexer/lex-emoji-identifiers.rs2
-rw-r--r--tests/ui/lexer/lex-emoji-identifiers.stderr3
-rw-r--r--tests/ui/lifetimes/could-not-resolve-issue-121503.rs13
-rw-r--r--tests/ui/lifetimes/could-not-resolve-issue-121503.stderr28
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs7
-rw-r--r--tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr13
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.rs (renamed from tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs)0
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.stderr (renamed from tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr)4
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs15
-rw-r--r--tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr26
-rw-r--r--tests/ui/simd/array-trait.rs4
-rw-r--r--tests/ui/simd/array-type.rs4
-rw-r--r--tests/ui/simd/generics.rs4
-rw-r--r--tests/ui/simd/intrinsic/float-math-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/float-minmax-pass.rs7
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-2.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-as.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-bitmask-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-bitmask.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-bswap-byte.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-cast-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-cast-pointer-width.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-cast.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-comparison.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-elements-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-elements.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-gather-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-reduction-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-reduction.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-select-pass.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-select.rs4
-rw-r--r--tests/ui/simd/intrinsic/generic-shuffle.rs4
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557-ice.rs4
-rw-r--r--tests/ui/simd/intrinsic/inlining-issue67557.rs4
-rw-r--r--tests/ui/simd/intrinsic/issue-85855.rs4
-rw-r--r--tests/ui/simd/intrinsic/ptr-cast.rs4
-rw-r--r--tests/ui/simd/issue-105439.rs4
-rw-r--r--tests/ui/simd/issue-39720.rs4
-rw-r--r--tests/ui/simd/issue-85915-simd-ptrs.rs4
-rw-r--r--tests/ui/simd/issue-89193.rs4
-rw-r--r--tests/ui/simd/masked-load-store-build-fail.rs4
-rw-r--r--tests/ui/simd/masked-load-store-check-fail.rs4
-rw-r--r--tests/ui/simd/masked-load-store.rs4
-rw-r--r--tests/ui/simd/monomorphize-shuffle-index.rs4
-rw-r--r--tests/ui/simd/repr_packed.rs4
-rw-r--r--tests/ui/simd/shuffle.rs4
-rw-r--r--tests/ui/simd/simd-bitmask.rs4
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-empty.rs2
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-oversized.rs2
-rw-r--r--tests/ui/simd/type-generic-monomorphisation-power-of-two.rs2
-rw-r--r--tests/ui/simd/type-generic-monomorphisation.rs2
-rw-r--r--tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-1.rs26
-rw-r--r--tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-2.rs26
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs2
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr4
-rw-r--r--tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs2
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs4
-rw-r--r--tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr19
-rw-r--r--tests/ui/traits/next-solver/generalize/instantiate-canonical-occurs-check-failure.rs29
-rw-r--r--tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr9
-rw-r--r--tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs34
-rw-r--r--tests/ui/traits/next-solver/issue-118950-root-region.stderr4
280 files changed, 2580 insertions, 1955 deletions
diff --git a/compiler/rustc_abi/src/layout.rs b/compiler/rustc_abi/src/layout.rs
index ec3ab828b71..28e148bddb2 100644
--- a/compiler/rustc_abi/src/layout.rs
+++ b/compiler/rustc_abi/src/layout.rs
@@ -958,7 +958,7 @@ fn univariant<
             #[cfg(feature = "randomize")]
             {
                 use rand::{seq::SliceRandom, SeedableRng};
-                // `ReprOptions.layout_seed` is a deterministic seed we can use to randomize field
+                // `ReprOptions.field_shuffle_seed` is a deterministic seed we can use to randomize field
                 // ordering.
                 let mut rng =
                     rand_xoshiro::Xoshiro128StarStar::seed_from_u64(repr.field_shuffle_seed);
diff --git a/compiler/rustc_abi/src/lib.rs b/compiler/rustc_abi/src/lib.rs
index c45a4a410f9..297dbf89029 100644
--- a/compiler/rustc_abi/src/lib.rs
+++ b/compiler/rustc_abi/src/lib.rs
@@ -41,7 +41,7 @@ bitflags! {
         // Internal only for now. If true, don't reorder fields.
         const IS_LINEAR          = 1 << 3;
         // If true, the type's layout can be randomized using
-        // the seed stored in `ReprOptions.layout_seed`
+        // the seed stored in `ReprOptions.field_shuffle_seed`
         const RANDOMIZE_LAYOUT   = 1 << 4;
         // Any of these flags being set prevent field reordering optimisation.
         const IS_UNOPTIMISABLE   = ReprFlags::IS_C.bits()
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 3fdb2a2225a..8ba2f222fcf 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1296,23 +1296,10 @@ impl Expr {
             ExprKind::Yeet(..) => ExprPrecedence::Yeet,
             ExprKind::FormatArgs(..) => ExprPrecedence::FormatArgs,
             ExprKind::Become(..) => ExprPrecedence::Become,
-            ExprKind::Err => ExprPrecedence::Err,
+            ExprKind::Err(_) | ExprKind::Dummy => ExprPrecedence::Err,
         }
     }
 
-    pub fn take(&mut self) -> Self {
-        mem::replace(
-            self,
-            Expr {
-                id: DUMMY_NODE_ID,
-                kind: ExprKind::Err,
-                span: DUMMY_SP,
-                attrs: AttrVec::new(),
-                tokens: None,
-            },
-        )
-    }
-
     /// To a first-order approximation, is this a pattern?
     pub fn is_approximately_pattern(&self) -> bool {
         matches!(
@@ -1531,7 +1518,10 @@ pub enum ExprKind {
     FormatArgs(P<FormatArgs>),
 
     /// Placeholder for an expression that wasn't syntactically well formed in some way.
-    Err,
+    Err(ErrorGuaranteed),
+
+    /// Acts as a null expression. Lowering it will always emit a bug.
+    Dummy,
 }
 
 /// Used to differentiate between `for` loops and `for await` loops.
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index c42c4199973..60bc21c6441 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -1526,7 +1526,7 @@ pub fn noop_visit_expr<T: MutVisitor>(
         }
         ExprKind::Try(expr) => vis.visit_expr(expr),
         ExprKind::TryBlock(body) => vis.visit_block(body),
-        ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
+        ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err(_) | ExprKind::Dummy => {}
     }
     vis.visit_id(id);
     vis.visit_span(span);
@@ -1642,7 +1642,7 @@ impl DummyAstNode for Expr {
     fn dummy() -> Self {
         Expr {
             id: DUMMY_NODE_ID,
-            kind: ExprKind::Err,
+            kind: ExprKind::Dummy,
             span: Default::default(),
             attrs: Default::default(),
             tokens: Default::default(),
diff --git a/compiler/rustc_ast/src/util/classify.rs b/compiler/rustc_ast/src/util/classify.rs
index 098b8f2d6d0..f21a9cabb81 100644
--- a/compiler/rustc_ast/src/util/classify.rs
+++ b/compiler/rustc_ast/src/util/classify.rs
@@ -89,7 +89,8 @@ pub fn expr_trailing_brace(mut expr: &ast::Expr) -> Option<&ast::Expr> {
             | Paren(_)
             | Try(_)
             | Yeet(None)
-            | Err => break None,
+            | Err(_)
+            | Dummy => break None,
         }
     }
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index ecf379cc240..f29022386a9 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -1063,7 +1063,7 @@ pub fn walk_expr<'a, V: Visitor<'a>>(visitor: &mut V, expression: &'a Expr) -> V
         }
         ExprKind::Try(subexpression) => try_visit!(visitor.visit_expr(subexpression)),
         ExprKind::TryBlock(body) => try_visit!(visitor.visit_block(body)),
-        ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err => {}
+        ExprKind::Lit(_) | ExprKind::IncludedBytes(..) | ExprKind::Err(_) | ExprKind::Dummy => {}
     }
 
     visitor.visit_expr_post(expression)
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index aafa99b3aa6..9950db4784b 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -14,6 +14,7 @@ use rustc_ast::*;
 use rustc_data_structures::stack::ensure_sufficient_stack;
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
+use rustc_middle::span_bug;
 use rustc_session::errors::report_lit_error;
 use rustc_span::source_map::{respan, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
@@ -328,9 +329,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     )
                 }
                 ExprKind::Yield(opt_expr) => self.lower_expr_yield(e.span, opt_expr.as_deref()),
-                ExprKind::Err => {
-                    hir::ExprKind::Err(self.dcx().span_delayed_bug(e.span, "lowered ExprKind::Err"))
+                ExprKind::Err(guar) => hir::ExprKind::Err(*guar),
+
+                ExprKind::Dummy => {
+                    span_bug!(e.span, "lowered ExprKind::Dummy")
                 }
+
                 ExprKind::Try(sub_expr) => self.lower_expr_try(e.span, sub_expr),
 
                 ExprKind::Paren(_) | ExprKind::ForLoop { .. } => {
diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs
index c097feb6b34..469cdac11e4 100644
--- a/compiler/rustc_ast_lowering/src/pat.rs
+++ b/compiler/rustc_ast_lowering/src/pat.rs
@@ -331,7 +331,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
             ExprKind::Lit(..)
             | ExprKind::ConstBlock(..)
             | ExprKind::IncludedBytes(..)
-            | ExprKind::Err => {}
+            | ExprKind::Err(_)
+            | ExprKind::Dummy => {}
             ExprKind::Path(..) if allow_paths => {}
             ExprKind::Unary(UnOp::Neg, inner) if matches!(inner.kind, ExprKind::Lit(_)) => {}
             _ => {
diff --git a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
index ff154a009ed..433ef03b6e5 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state/expr.rs
@@ -893,11 +893,16 @@ impl<'a> State<'a> {
                 self.word_nbsp("try");
                 self.print_block_with_attrs(blk, attrs)
             }
-            ast::ExprKind::Err => {
+            ast::ExprKind::Err(_) => {
                 self.popen();
                 self.word("/*ERROR*/");
                 self.pclose()
             }
+            ast::ExprKind::Dummy => {
+                self.popen();
+                self.word("/*DUMMY*/");
+                self.pclose();
+            }
         }
 
         self.ann.post(self, AnnNode::Expr(expr));
diff --git a/compiler/rustc_borrowck/src/type_check/relate_tys.rs b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
index 61b803ea38d..00296aa38da 100644
--- a/compiler/rustc_borrowck/src/type_check/relate_tys.rs
+++ b/compiler/rustc_borrowck/src/type_check/relate_tys.rs
@@ -1,7 +1,8 @@
 use rustc_data_structures::fx::FxHashMap;
 use rustc_errors::ErrorGuaranteed;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
-use rustc_infer::infer::{NllRegionVariableOrigin, ObligationEmittingRelation};
+use rustc_infer::infer::NllRegionVariableOrigin;
+use rustc_infer::infer::{ObligationEmittingRelation, StructurallyRelateAliases};
 use rustc_infer::traits::{Obligation, PredicateObligations};
 use rustc_middle::mir::ConstraintCategory;
 use rustc_middle::traits::query::NoSolution;
@@ -548,6 +549,10 @@ impl<'bccx, 'tcx> ObligationEmittingRelation<'tcx> for NllTypeRelating<'_, 'bccx
         self.locations.span(self.type_checker.body)
     }
 
+    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
+        StructurallyRelateAliases::No
+    }
+
     fn param_env(&self) -> ty::ParamEnv<'tcx> {
         self.type_checker.param_env
     }
diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs
index 263081ea19e..29bf5e9f304 100644
--- a/compiler/rustc_builtin_macros/src/asm.rs
+++ b/compiler/rustc_builtin_macros/src/asm.rs
@@ -13,7 +13,7 @@ use rustc_session::lint;
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::Ident;
 use rustc_span::symbol::{kw, sym, Symbol};
-use rustc_span::{InnerSpan, Span};
+use rustc_span::{ErrorGuaranteed, InnerSpan, Span};
 use rustc_target::asm::InlineAsmArch;
 use smallvec::smallvec;
 
@@ -433,7 +433,10 @@ fn parse_reg<'a>(
     Ok(result)
 }
 
-fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::InlineAsm> {
+fn expand_preparsed_asm(
+    ecx: &mut ExtCtxt<'_>,
+    args: AsmArgs,
+) -> Result<ast::InlineAsm, ErrorGuaranteed> {
     let mut template = vec![];
     // Register operands are implicitly used since they are not allowed to be
     // referenced in the template string.
@@ -459,10 +462,10 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
             match expr_to_spanned_string(ecx, template_expr, msg) {
                 Ok(template_part) => template_part,
                 Err(err) => {
-                    if let Some((err, _)) = err {
-                        err.emit();
-                    }
-                    return None;
+                    return Err(match err {
+                        Ok((err, _)) => err.emit(),
+                        Err(guar) => guar,
+                    });
                 }
             };
 
@@ -551,8 +554,8 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
                 let err_sp = template_span.from_inner(InnerSpan::new(span.start, span.end));
                 e.span_label(err_sp, label);
             }
-            e.emit();
-            return None;
+            let guar = e.emit();
+            return Err(guar);
         }
 
         curarg = parser.curarg;
@@ -719,7 +722,7 @@ fn expand_preparsed_asm(ecx: &mut ExtCtxt<'_>, args: AsmArgs) -> Option<ast::Inl
         }
     }
 
-    Some(ast::InlineAsm {
+    Ok(ast::InlineAsm {
         template,
         template_strs: template_strs.into_boxed_slice(),
         operands: args.operands,
@@ -736,22 +739,21 @@ pub(super) fn expand_asm<'cx>(
 ) -> Box<dyn base::MacResult + 'cx> {
     match parse_args(ecx, sp, tts, false) {
         Ok(args) => {
-            let expr = if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
-                P(ast::Expr {
+            let expr = match expand_preparsed_asm(ecx, args) {
+                Ok(inline_asm) => P(ast::Expr {
                     id: ast::DUMMY_NODE_ID,
                     kind: ast::ExprKind::InlineAsm(P(inline_asm)),
                     span: sp,
                     attrs: ast::AttrVec::new(),
                     tokens: None,
-                })
-            } else {
-                DummyResult::raw_expr(sp, true)
+                }),
+                Err(guar) => DummyResult::raw_expr(sp, Some(guar)),
             };
             MacEager::expr(expr)
         }
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
@@ -762,28 +764,25 @@ pub(super) fn expand_global_asm<'cx>(
     tts: TokenStream,
 ) -> Box<dyn base::MacResult + 'cx> {
     match parse_args(ecx, sp, tts, true) {
-        Ok(args) => {
-            if let Some(inline_asm) = expand_preparsed_asm(ecx, args) {
-                MacEager::items(smallvec![P(ast::Item {
-                    ident: Ident::empty(),
-                    attrs: ast::AttrVec::new(),
-                    id: ast::DUMMY_NODE_ID,
-                    kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
-                    vis: ast::Visibility {
-                        span: sp.shrink_to_lo(),
-                        kind: ast::VisibilityKind::Inherited,
-                        tokens: None,
-                    },
-                    span: sp,
+        Ok(args) => match expand_preparsed_asm(ecx, args) {
+            Ok(inline_asm) => MacEager::items(smallvec![P(ast::Item {
+                ident: Ident::empty(),
+                attrs: ast::AttrVec::new(),
+                id: ast::DUMMY_NODE_ID,
+                kind: ast::ItemKind::GlobalAsm(Box::new(inline_asm)),
+                vis: ast::Visibility {
+                    span: sp.shrink_to_lo(),
+                    kind: ast::VisibilityKind::Inherited,
                     tokens: None,
-                })])
-            } else {
-                DummyResult::any(sp)
-            }
-        }
+                },
+                span: sp,
+                tokens: None,
+            })]),
+            Err(guar) => DummyResult::any(sp, guar),
+        },
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/assert.rs b/compiler/rustc_builtin_macros/src/assert.rs
index 501d557f3ab..613ce43dec2 100644
--- a/compiler/rustc_builtin_macros/src/assert.rs
+++ b/compiler/rustc_builtin_macros/src/assert.rs
@@ -23,8 +23,8 @@ pub fn expand_assert<'cx>(
     let Assert { cond_expr, custom_message } = match parse_assert(cx, span, tts) {
         Ok(assert) => assert,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(span);
+            let guar = err.emit();
+            return DummyResult::any(span, guar);
         }
     };
 
diff --git a/compiler/rustc_builtin_macros/src/assert/context.rs b/compiler/rustc_builtin_macros/src/assert/context.rs
index 01821ee833f..56c56b2704b 100644
--- a/compiler/rustc_builtin_macros/src/assert/context.rs
+++ b/compiler/rustc_builtin_macros/src/assert/context.rs
@@ -303,7 +303,8 @@ impl<'cx, 'a> Context<'cx, 'a> {
             | ExprKind::Closure(_)
             | ExprKind::ConstBlock(_)
             | ExprKind::Continue(_)
-            | ExprKind::Err
+            | ExprKind::Dummy
+            | ExprKind::Err(_)
             | ExprKind::Field(_, _)
             | ExprKind::ForLoop { .. }
             | ExprKind::FormatArgs(_)
diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs
index 581d390992a..04bf7dceeff 100644
--- a/compiler/rustc_builtin_macros/src/cfg.rs
+++ b/compiler/rustc_builtin_macros/src/cfg.rs
@@ -8,14 +8,14 @@ use rustc_ast::token;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_attr as attr;
 use rustc_errors::PResult;
-use rustc_expand::base::{self, *};
+use rustc_expand::base::{DummyResult, ExtCtxt, MacEager, MacResult};
 use rustc_span::Span;
 
 pub fn expand_cfg(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
 
     match parse_cfg(cx, sp, tts) {
@@ -29,8 +29,8 @@ pub fn expand_cfg(
             MacEager::expr(cx.expr_bool(sp, matches_cfg))
         }
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/compile_error.rs b/compiler/rustc_builtin_macros/src/compile_error.rs
index f157575da79..b4455d7823f 100644
--- a/compiler/rustc_builtin_macros/src/compile_error.rs
+++ b/compiler/rustc_builtin_macros/src/compile_error.rs
@@ -1,24 +1,22 @@
 // The compiler code necessary to support the compile_error! extension.
 
 use rustc_ast::tokenstream::TokenStream;
-use rustc_expand::base::{self, *};
+use rustc_expand::base::{get_single_str_from_tts, DummyResult, ExtCtxt, MacResult};
 use rustc_span::Span;
 
 pub fn expand_compile_error<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
-    let Some(var) = get_single_str_from_tts(cx, sp, tts, "compile_error!") else {
-        return DummyResult::any(sp);
+) -> Box<dyn MacResult + 'cx> {
+    let var = match get_single_str_from_tts(cx, sp, tts, "compile_error!") {
+        Ok(var) => var,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
 
-    #[expect(
-        rustc::diagnostic_outside_of_impl,
-        reason = "diagnostic message is specified by user"
-    )]
+    #[expect(rustc::diagnostic_outside_of_impl, reason = "diagnostic message is specified by user")]
     #[expect(rustc::untranslatable_diagnostic, reason = "diagnostic message is specified by user")]
-    cx.dcx().span_err(sp, var.to_string());
+    let guar = cx.dcx().span_err(sp, var.to_string());
 
-    DummyResult::any(sp)
+    DummyResult::any(sp, guar)
 }
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index 795161e65d8..abfaa9b006e 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -1,73 +1,69 @@
-use rustc_ast as ast;
 use rustc_ast::tokenstream::TokenStream;
-use rustc_expand::base::{self, DummyResult};
+use rustc_ast::{ExprKind, LitKind, UnOp};
+use rustc_expand::base::{get_exprs_from_tts, DummyResult, ExtCtxt, MacEager, MacResult};
 use rustc_session::errors::report_lit_error;
 use rustc_span::symbol::Symbol;
 
 use crate::errors;
 
 pub fn expand_concat(
-    cx: &mut base::ExtCtxt<'_>,
+    cx: &mut ExtCtxt<'_>,
     sp: rustc_span::Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
-    let Some(es) = base::get_exprs_from_tts(cx, tts) else {
-        return DummyResult::any(sp);
+) -> Box<dyn MacResult + 'static> {
+    let es = match get_exprs_from_tts(cx, tts) {
+        Ok(es) => es,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let mut accumulator = String::new();
     let mut missing_literal = vec![];
-    let mut has_errors = false;
+    let mut guar = None;
     for e in es {
         match e.kind {
-            ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
-                Ok(ast::LitKind::Str(s, _) | ast::LitKind::Float(s, _)) => {
+            ExprKind::Lit(token_lit) => match LitKind::from_token_lit(token_lit) {
+                Ok(LitKind::Str(s, _) | LitKind::Float(s, _)) => {
                     accumulator.push_str(s.as_str());
                 }
-                Ok(ast::LitKind::Char(c)) => {
+                Ok(LitKind::Char(c)) => {
                     accumulator.push(c);
                 }
-                Ok(ast::LitKind::Int(i, _)) => {
+                Ok(LitKind::Int(i, _)) => {
                     accumulator.push_str(&i.to_string());
                 }
-                Ok(ast::LitKind::Bool(b)) => {
+                Ok(LitKind::Bool(b)) => {
                     accumulator.push_str(&b.to_string());
                 }
-                Ok(ast::LitKind::CStr(..)) => {
-                    cx.dcx().emit_err(errors::ConcatCStrLit { span: e.span });
-                    has_errors = true;
+                Ok(LitKind::CStr(..)) => {
+                    guar = Some(cx.dcx().emit_err(errors::ConcatCStrLit { span: e.span }));
                 }
-                Ok(ast::LitKind::Byte(..) | ast::LitKind::ByteStr(..)) => {
-                    cx.dcx().emit_err(errors::ConcatBytestr { span: e.span });
-                    has_errors = true;
+                Ok(LitKind::Byte(..) | LitKind::ByteStr(..)) => {
+                    guar = Some(cx.dcx().emit_err(errors::ConcatBytestr { span: e.span }));
                 }
-                Ok(ast::LitKind::Err(_)) => {
-                    has_errors = true;
+                Ok(LitKind::Err(guarantee)) => {
+                    guar = Some(guarantee);
                 }
                 Err(err) => {
-                    report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span);
-                    has_errors = true;
+                    guar = Some(report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span));
                 }
             },
             // We also want to allow negative numeric literals.
-            ast::ExprKind::Unary(ast::UnOp::Neg, ref expr)
-                if let ast::ExprKind::Lit(token_lit) = expr.kind =>
-            {
-                match ast::LitKind::from_token_lit(token_lit) {
-                    Ok(ast::LitKind::Int(i, _)) => accumulator.push_str(&format!("-{i}")),
-                    Ok(ast::LitKind::Float(f, _)) => accumulator.push_str(&format!("-{f}")),
+            ExprKind::Unary(UnOp::Neg, ref expr) if let ExprKind::Lit(token_lit) = expr.kind => {
+                match LitKind::from_token_lit(token_lit) {
+                    Ok(LitKind::Int(i, _)) => accumulator.push_str(&format!("-{i}")),
+                    Ok(LitKind::Float(f, _)) => accumulator.push_str(&format!("-{f}")),
                     Err(err) => {
-                        report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span);
-                        has_errors = true;
+                        guar = Some(report_lit_error(&cx.sess.parse_sess, err, token_lit, e.span));
                     }
                     _ => missing_literal.push(e.span),
                 }
             }
-            ast::ExprKind::IncludedBytes(..) => {
+            ExprKind::IncludedBytes(..) => {
                 cx.dcx().emit_err(errors::ConcatBytestr { span: e.span });
             }
-            ast::ExprKind::Err => {
-                has_errors = true;
+            ExprKind::Err(guarantee) => {
+                guar = Some(guarantee);
             }
+            ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"),
             _ => {
                 missing_literal.push(e.span);
             }
@@ -75,11 +71,11 @@ pub fn expand_concat(
     }
 
     if !missing_literal.is_empty() {
-        cx.dcx().emit_err(errors::ConcatMissingLiteral { spans: missing_literal });
-        return DummyResult::any(sp);
-    } else if has_errors {
-        return DummyResult::any(sp);
+        let guar = cx.dcx().emit_err(errors::ConcatMissingLiteral { spans: missing_literal });
+        return DummyResult::any(sp, guar);
+    } else if let Some(guar) = guar {
+        return DummyResult::any(sp, guar);
     }
     let sp = cx.with_def_site_ctxt(sp);
-    base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
+    MacEager::expr(cx.expr_str(sp, Symbol::intern(&accumulator)))
 }
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index 3ef8cb7bffe..3fb0b50f417 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -1,192 +1,181 @@
-use rustc_ast as ast;
-use rustc_ast::{ptr::P, tokenstream::TokenStream};
-use rustc_expand::base::{self, DummyResult};
+use rustc_ast::{ptr::P, token, tokenstream::TokenStream, ExprKind, LitIntType, LitKind, UintTy};
+use rustc_expand::base::{get_exprs_from_tts, DummyResult, ExtCtxt, MacEager, MacResult};
 use rustc_session::errors::report_lit_error;
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 
 use crate::errors;
 
 /// Emits errors for literal expressions that are invalid inside and outside of an array.
 fn invalid_type_err(
-    cx: &mut base::ExtCtxt<'_>,
-    token_lit: ast::token::Lit,
+    cx: &mut ExtCtxt<'_>,
+    token_lit: token::Lit,
     span: Span,
     is_nested: bool,
-) {
+) -> ErrorGuaranteed {
     use errors::{
         ConcatBytesInvalid, ConcatBytesInvalidSuggestion, ConcatBytesNonU8, ConcatBytesOob,
     };
     let snippet = cx.sess.source_map().span_to_snippet(span).ok();
     let dcx = cx.dcx();
-    match ast::LitKind::from_token_lit(token_lit) {
-        Ok(ast::LitKind::CStr(_, _)) => {
+    match LitKind::from_token_lit(token_lit) {
+        Ok(LitKind::CStr(_, _)) => {
             // Avoid ambiguity in handling of terminal `NUL` by refusing to
             // concatenate C string literals as bytes.
-            dcx.emit_err(errors::ConcatCStrLit { span: span });
+            dcx.emit_err(errors::ConcatCStrLit { span })
         }
-        Ok(ast::LitKind::Char(_)) => {
+        Ok(LitKind::Char(_)) => {
             let sugg =
                 snippet.map(|snippet| ConcatBytesInvalidSuggestion::CharLit { span, snippet });
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "character", sugg })
         }
-        Ok(ast::LitKind::Str(_, _)) => {
+        Ok(LitKind::Str(_, _)) => {
             // suggestion would be invalid if we are nested
             let sugg = if !is_nested {
                 snippet.map(|snippet| ConcatBytesInvalidSuggestion::StrLit { span, snippet })
             } else {
                 None
             };
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "string", sugg })
         }
-        Ok(ast::LitKind::Float(_, _)) => {
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None });
+        Ok(LitKind::Float(_, _)) => {
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "float", sugg: None })
         }
-        Ok(ast::LitKind::Bool(_)) => {
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None });
+        Ok(LitKind::Bool(_)) => {
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None })
         }
-        Ok(ast::LitKind::Err(_)) => {}
-        Ok(ast::LitKind::Int(_, _)) if !is_nested => {
+        Ok(LitKind::Int(_, _)) if !is_nested => {
             let sugg =
-                snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span: span, snippet });
-            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg });
+                snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span, snippet });
+            dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "numeric", sugg })
         }
-        Ok(ast::LitKind::Int(
-            val,
-            ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
-        )) => {
+        Ok(LitKind::Int(val, LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::U8))) => {
             assert!(val.get() > u8::MAX.into()); // must be an error
-            dcx.emit_err(ConcatBytesOob { span });
-        }
-        Ok(ast::LitKind::Int(_, _)) => {
-            dcx.emit_err(ConcatBytesNonU8 { span });
-        }
-        Ok(ast::LitKind::ByteStr(..) | ast::LitKind::Byte(_)) => unreachable!(),
-        Err(err) => {
-            report_lit_error(&cx.sess.parse_sess, err, token_lit, span);
+            dcx.emit_err(ConcatBytesOob { span })
         }
+        Ok(LitKind::Int(_, _)) => dcx.emit_err(ConcatBytesNonU8 { span }),
+        Ok(LitKind::ByteStr(..) | LitKind::Byte(_)) => unreachable!(),
+        Ok(LitKind::Err(guar)) => guar,
+        Err(err) => report_lit_error(&cx.sess.parse_sess, err, token_lit, span),
     }
 }
 
+/// Returns `expr` as a *single* byte literal if applicable.
+///
+/// Otherwise, returns `None`, and either pushes the `expr`'s span to `missing_literals` or
+/// updates `guar` accordingly.
 fn handle_array_element(
-    cx: &mut base::ExtCtxt<'_>,
-    has_errors: &mut bool,
+    cx: &mut ExtCtxt<'_>,
+    guar: &mut Option<ErrorGuaranteed>,
     missing_literals: &mut Vec<rustc_span::Span>,
     expr: &P<rustc_ast::Expr>,
 ) -> Option<u8> {
     let dcx = cx.dcx();
-    match expr.kind {
-        ast::ExprKind::Array(_) | ast::ExprKind::Repeat(_, _) => {
-            if !*has_errors {
-                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false });
-            }
-            *has_errors = true;
-            None
-        }
-        ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
-            Ok(ast::LitKind::Int(
-                val,
-                ast::LitIntType::Unsuffixed | ast::LitIntType::Unsigned(ast::UintTy::U8),
-            )) if val.get() <= u8::MAX.into() => Some(val.get() as u8),
 
-            Ok(ast::LitKind::Byte(val)) => Some(val),
-            Ok(ast::LitKind::ByteStr(..)) => {
-                if !*has_errors {
-                    dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: true });
+    match expr.kind {
+        ExprKind::Lit(token_lit) => {
+            match LitKind::from_token_lit(token_lit) {
+                Ok(LitKind::Int(
+                    val,
+                    LitIntType::Unsuffixed | LitIntType::Unsigned(UintTy::U8),
+                )) if let Ok(val) = u8::try_from(val.get()) => {
+                    return Some(val);
                 }
-                *has_errors = true;
-                None
-            }
-            _ => {
-                if !*has_errors {
-                    invalid_type_err(cx, token_lit, expr.span, true);
+                Ok(LitKind::Byte(val)) => return Some(val),
+                Ok(LitKind::ByteStr(..)) => {
+                    guar.get_or_insert_with(|| {
+                        dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: true })
+                    });
                 }
-                *has_errors = true;
-                None
-            }
-        },
-        ast::ExprKind::IncludedBytes(..) => {
-            if !*has_errors {
-                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false });
-            }
-            *has_errors = true;
-            None
+                _ => {
+                    guar.get_or_insert_with(|| invalid_type_err(cx, token_lit, expr.span, true));
+                }
+            };
+        }
+        ExprKind::Array(_) | ExprKind::Repeat(_, _) => {
+            guar.get_or_insert_with(|| {
+                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false })
+            });
         }
-        _ => {
-            missing_literals.push(expr.span);
-            None
+        ExprKind::IncludedBytes(..) => {
+            guar.get_or_insert_with(|| {
+                dcx.emit_err(errors::ConcatBytesArray { span: expr.span, bytestr: false })
+            });
         }
+        _ => missing_literals.push(expr.span),
     }
+
+    None
 }
 
 pub fn expand_concat_bytes(
-    cx: &mut base::ExtCtxt<'_>,
-    sp: rustc_span::Span,
+    cx: &mut ExtCtxt<'_>,
+    sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
-    let Some(es) = base::get_exprs_from_tts(cx, tts) else {
-        return DummyResult::any(sp);
+) -> Box<dyn MacResult + 'static> {
+    let es = match get_exprs_from_tts(cx, tts) {
+        Ok(es) => es,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let mut accumulator = Vec::new();
     let mut missing_literals = vec![];
-    let mut has_errors = false;
+    let mut guar = None;
     for e in es {
         match &e.kind {
-            ast::ExprKind::Array(exprs) => {
+            ExprKind::Array(exprs) => {
                 for expr in exprs {
                     if let Some(elem) =
-                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                        handle_array_element(cx, &mut guar, &mut missing_literals, expr)
                     {
                         accumulator.push(elem);
                     }
                 }
             }
-            ast::ExprKind::Repeat(expr, count) => {
-                if let ast::ExprKind::Lit(token_lit) = count.value.kind
-                    && let Ok(ast::LitKind::Int(count_val, _)) =
-                        ast::LitKind::from_token_lit(token_lit)
+            ExprKind::Repeat(expr, count) => {
+                if let ExprKind::Lit(token_lit) = count.value.kind
+                    && let Ok(LitKind::Int(count_val, _)) = LitKind::from_token_lit(token_lit)
                 {
                     if let Some(elem) =
-                        handle_array_element(cx, &mut has_errors, &mut missing_literals, expr)
+                        handle_array_element(cx, &mut guar, &mut missing_literals, expr)
                     {
                         for _ in 0..count_val.get() {
                             accumulator.push(elem);
                         }
                     }
                 } else {
-                    cx.dcx().emit_err(errors::ConcatBytesBadRepeat { span: count.value.span });
+                    guar = Some(
+                        cx.dcx().emit_err(errors::ConcatBytesBadRepeat { span: count.value.span }),
+                    );
                 }
             }
-            &ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
-                Ok(ast::LitKind::Byte(val)) => {
+            &ExprKind::Lit(token_lit) => match LitKind::from_token_lit(token_lit) {
+                Ok(LitKind::Byte(val)) => {
                     accumulator.push(val);
                 }
-                Ok(ast::LitKind::ByteStr(ref bytes, _)) => {
+                Ok(LitKind::ByteStr(ref bytes, _)) => {
                     accumulator.extend_from_slice(bytes);
                 }
                 _ => {
-                    if !has_errors {
-                        invalid_type_err(cx, token_lit, e.span, false);
-                    }
-                    has_errors = true;
+                    guar.get_or_insert_with(|| invalid_type_err(cx, token_lit, e.span, false));
                 }
             },
-            ast::ExprKind::IncludedBytes(bytes) => {
+            ExprKind::IncludedBytes(bytes) => {
                 accumulator.extend_from_slice(bytes);
             }
-            ast::ExprKind::Err => {
-                has_errors = true;
+            ExprKind::Err(guarantee) => {
+                guar = Some(*guarantee);
             }
+            ExprKind::Dummy => cx.dcx().span_bug(e.span, "concatenating `ExprKind::Dummy`"),
             _ => {
                 missing_literals.push(e.span);
             }
         }
     }
     if !missing_literals.is_empty() {
-        cx.dcx().emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals });
-        return base::MacEager::expr(DummyResult::raw_expr(sp, true));
-    } else if has_errors {
-        return base::MacEager::expr(DummyResult::raw_expr(sp, true));
+        let guar = cx.dcx().emit_err(errors::ConcatBytesMissingLiteral { spans: missing_literals });
+        return MacEager::expr(DummyResult::raw_expr(sp, Some(guar)));
+    } else if let Some(guar) = guar {
+        return MacEager::expr(DummyResult::raw_expr(sp, Some(guar)));
     }
     let sp = cx.with_def_site_ctxt(sp);
-    base::MacEager::expr(cx.expr_byte_str(sp, accumulator))
+    MacEager::expr(cx.expr_byte_str(sp, accumulator))
 }
diff --git a/compiler/rustc_builtin_macros/src/concat_idents.rs b/compiler/rustc_builtin_macros/src/concat_idents.rs
index 17fd3901cc6..fffcddc5325 100644
--- a/compiler/rustc_builtin_macros/src/concat_idents.rs
+++ b/compiler/rustc_builtin_macros/src/concat_idents.rs
@@ -1,8 +1,8 @@
-use rustc_ast as ast;
 use rustc_ast::ptr::P;
 use rustc_ast::token::{self, Token};
 use rustc_ast::tokenstream::{TokenStream, TokenTree};
-use rustc_expand::base::{self, *};
+use rustc_ast::{AttrVec, Expr, ExprKind, Path, Ty, TyKind, DUMMY_NODE_ID};
+use rustc_expand::base::{DummyResult, ExtCtxt, MacResult};
 use rustc_span::symbol::{Ident, Symbol};
 use rustc_span::Span;
 
@@ -12,10 +12,10 @@ pub fn expand_concat_idents<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
+) -> Box<dyn MacResult + 'cx> {
     if tts.is_empty() {
-        cx.dcx().emit_err(errors::ConcatIdentsMissingArgs { span: sp });
-        return DummyResult::any(sp);
+        let guar = cx.dcx().emit_err(errors::ConcatIdentsMissingArgs { span: sp });
+        return DummyResult::any(sp, guar);
     }
 
     let mut res_str = String::new();
@@ -24,8 +24,8 @@ pub fn expand_concat_idents<'cx>(
             match e {
                 TokenTree::Token(Token { kind: token::Comma, .. }, _) => {}
                 _ => {
-                    cx.dcx().emit_err(errors::ConcatIdentsMissingComma { span: sp });
-                    return DummyResult::any(sp);
+                    let guar = cx.dcx().emit_err(errors::ConcatIdentsMissingComma { span: sp });
+                    return DummyResult::any(sp, guar);
                 }
             }
         } else {
@@ -36,8 +36,8 @@ pub fn expand_concat_idents<'cx>(
                 }
             }
 
-            cx.dcx().emit_err(errors::ConcatIdentsIdentArgs { span: sp });
-            return DummyResult::any(sp);
+            let guar = cx.dcx().emit_err(errors::ConcatIdentsIdentArgs { span: sp });
+            return DummyResult::any(sp, guar);
         }
     }
 
@@ -47,21 +47,21 @@ pub fn expand_concat_idents<'cx>(
         ident: Ident,
     }
 
-    impl base::MacResult for ConcatIdentsResult {
-        fn make_expr(self: Box<Self>) -> Option<P<ast::Expr>> {
-            Some(P(ast::Expr {
-                id: ast::DUMMY_NODE_ID,
-                kind: ast::ExprKind::Path(None, ast::Path::from_ident(self.ident)),
+    impl MacResult for ConcatIdentsResult {
+        fn make_expr(self: Box<Self>) -> Option<P<Expr>> {
+            Some(P(Expr {
+                id: DUMMY_NODE_ID,
+                kind: ExprKind::Path(None, Path::from_ident(self.ident)),
                 span: self.ident.span,
-                attrs: ast::AttrVec::new(),
+                attrs: AttrVec::new(),
                 tokens: None,
             }))
         }
 
-        fn make_ty(self: Box<Self>) -> Option<P<ast::Ty>> {
-            Some(P(ast::Ty {
-                id: ast::DUMMY_NODE_ID,
-                kind: ast::TyKind::Path(None, ast::Path::from_ident(self.ident)),
+        fn make_ty(self: Box<Self>) -> Option<P<Ty>> {
+            Some(P(Ty {
+                id: DUMMY_NODE_ID,
+                kind: TyKind::Path(None, Path::from_ident(self.ident)),
                 span: self.ident.span,
                 tokens: None,
             }))
diff --git a/compiler/rustc_builtin_macros/src/deriving/default.rs b/compiler/rustc_builtin_macros/src/deriving/default.rs
index 0bd2d423a29..386d4a54b65 100644
--- a/compiler/rustc_builtin_macros/src/deriving/default.rs
+++ b/compiler/rustc_builtin_macros/src/deriving/default.rs
@@ -6,7 +6,7 @@ use rustc_ast::{attr, walk_list, EnumDef, VariantData};
 use rustc_expand::base::{Annotatable, DummyResult, ExtCtxt};
 use rustc_span::symbol::Ident;
 use rustc_span::symbol::{kw, sym};
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use smallvec::SmallVec;
 use thin_vec::{thin_vec, ThinVec};
 
@@ -83,16 +83,19 @@ fn default_enum_substructure(
     trait_span: Span,
     enum_def: &EnumDef,
 ) -> BlockOrExpr {
-    let expr = if let Ok(default_variant) = extract_default_variant(cx, enum_def, trait_span)
-        && let Ok(_) = validate_default_attribute(cx, default_variant)
-    {
-        // We now know there is exactly one unit variant with exactly one `#[default]` attribute.
-        cx.expr_path(cx.path(
-            default_variant.span,
-            vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident],
-        ))
-    } else {
-        DummyResult::raw_expr(trait_span, true)
+    let expr = match try {
+        let default_variant = extract_default_variant(cx, enum_def, trait_span)?;
+        validate_default_attribute(cx, default_variant)?;
+        default_variant
+    } {
+        Ok(default_variant) => {
+            // We now know there is exactly one unit variant with exactly one `#[default]` attribute.
+            cx.expr_path(cx.path(
+                default_variant.span,
+                vec![Ident::new(kw::SelfUpper, default_variant.span), default_variant.ident],
+            ))
+        }
+        Err(guar) => DummyResult::raw_expr(trait_span, Some(guar)),
     };
     BlockOrExpr::new_expr(expr)
 }
@@ -101,7 +104,7 @@ fn extract_default_variant<'a>(
     cx: &mut ExtCtxt<'_>,
     enum_def: &'a EnumDef,
     trait_span: Span,
-) -> Result<&'a rustc_ast::Variant, ()> {
+) -> Result<&'a rustc_ast::Variant, ErrorGuaranteed> {
     let default_variants: SmallVec<[_; 1]> = enum_def
         .variants
         .iter()
@@ -120,9 +123,9 @@ fn extract_default_variant<'a>(
             let suggs = possible_defaults
                 .map(|v| errors::NoDefaultVariantSugg { span: v.span, ident: v.ident })
                 .collect();
-            cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, suggs });
+            let guar = cx.dcx().emit_err(errors::NoDefaultVariant { span: trait_span, suggs });
 
-            return Err(());
+            return Err(guar);
         }
         [first, rest @ ..] => {
             let suggs = default_variants
@@ -140,28 +143,28 @@ fn extract_default_variant<'a>(
                         .then_some(errors::MultipleDefaultsSugg { spans, ident: variant.ident })
                 })
                 .collect();
-            cx.dcx().emit_err(errors::MultipleDefaults {
+            let guar = cx.dcx().emit_err(errors::MultipleDefaults {
                 span: trait_span,
                 first: first.span,
                 additional: rest.iter().map(|v| v.span).collect(),
                 suggs,
             });
-            return Err(());
+            return Err(guar);
         }
     };
 
     if !matches!(variant.data, VariantData::Unit(..)) {
-        cx.dcx().emit_err(errors::NonUnitDefault { span: variant.ident.span });
-        return Err(());
+        let guar = cx.dcx().emit_err(errors::NonUnitDefault { span: variant.ident.span });
+        return Err(guar);
     }
 
     if let Some(non_exhaustive_attr) = attr::find_by_name(&variant.attrs, sym::non_exhaustive) {
-        cx.dcx().emit_err(errors::NonExhaustiveDefault {
+        let guar = cx.dcx().emit_err(errors::NonExhaustiveDefault {
             span: variant.ident.span,
             non_exhaustive: non_exhaustive_attr.span,
         });
 
-        return Err(());
+        return Err(guar);
     }
 
     Ok(variant)
@@ -170,7 +173,7 @@ fn extract_default_variant<'a>(
 fn validate_default_attribute(
     cx: &mut ExtCtxt<'_>,
     default_variant: &rustc_ast::Variant,
-) -> Result<(), ()> {
+) -> Result<(), ErrorGuaranteed> {
     let attrs: SmallVec<[_; 1]> =
         attr::filter_by_name(&default_variant.attrs, kw::Default).collect();
 
@@ -183,7 +186,7 @@ fn validate_default_attribute(
             let sugg = errors::MultipleDefaultAttrsSugg {
                 spans: rest.iter().map(|attr| attr.span).collect(),
             };
-            cx.dcx().emit_err(errors::MultipleDefaultAttrs {
+            let guar = cx.dcx().emit_err(errors::MultipleDefaultAttrs {
                 span: default_variant.ident.span,
                 first: first.span,
                 first_rest: rest[0].span,
@@ -192,13 +195,13 @@ fn validate_default_attribute(
                 sugg,
             });
 
-            return Err(());
+            return Err(guar);
         }
     };
     if !attr.is_word() {
-        cx.dcx().emit_err(errors::DefaultHasArg { span: attr.span });
+        let guar = cx.dcx().emit_err(errors::DefaultHasArg { span: attr.span });
 
-        return Err(());
+        return Err(guar);
     }
     Ok(())
 }
diff --git a/compiler/rustc_builtin_macros/src/env.rs b/compiler/rustc_builtin_macros/src/env.rs
index a0fd0e3f9be..f057d44bf71 100644
--- a/compiler/rustc_builtin_macros/src/env.rs
+++ b/compiler/rustc_builtin_macros/src/env.rs
@@ -3,9 +3,13 @@
 // interface.
 //
 
+use rustc_ast::token::{self, LitKind};
 use rustc_ast::tokenstream::TokenStream;
-use rustc_ast::{self as ast, AstDeref, GenericArg};
-use rustc_expand::base::{self, *};
+use rustc_ast::{AstDeref, ExprKind, GenericArg, Mutability};
+use rustc_expand::base::{
+    expr_to_string, get_exprs_from_tts, get_single_str_from_tts, DummyResult, ExtCtxt, MacEager,
+    MacResult,
+};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
 use rustc_span::Span;
 use std::env;
@@ -27,9 +31,10 @@ pub fn expand_option_env<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
-    let Some(var) = get_single_str_from_tts(cx, sp, tts, "option_env!") else {
-        return DummyResult::any(sp);
+) -> Box<dyn MacResult + 'cx> {
+    let var = match get_single_str_from_tts(cx, sp, tts, "option_env!") {
+        Ok(var) => var,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
 
     let sp = cx.with_def_site_ctxt(sp);
@@ -46,7 +51,7 @@ pub fn expand_option_env<'cx>(
                     sp,
                     cx.ty_ident(sp, Ident::new(sym::str, sp)),
                     Some(lt),
-                    ast::Mutability::Not,
+                    Mutability::Not,
                 ))],
             ))
         }
@@ -63,26 +68,27 @@ pub fn expand_env<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
+) -> Box<dyn MacResult + 'cx> {
     let mut exprs = match get_exprs_from_tts(cx, tts) {
-        Some(exprs) if exprs.is_empty() || exprs.len() > 2 => {
-            cx.dcx().emit_err(errors::EnvTakesArgs { span: sp });
-            return DummyResult::any(sp);
+        Ok(exprs) if exprs.is_empty() || exprs.len() > 2 => {
+            let guar = cx.dcx().emit_err(errors::EnvTakesArgs { span: sp });
+            return DummyResult::any(sp, guar);
         }
-        None => return DummyResult::any(sp),
-        Some(exprs) => exprs.into_iter(),
+        Err(guar) => return DummyResult::any(sp, guar),
+        Ok(exprs) => exprs.into_iter(),
     };
 
     let var_expr = exprs.next().unwrap();
-    let Some((var, _)) = expr_to_string(cx, var_expr.clone(), "expected string literal") else {
-        return DummyResult::any(sp);
+    let var = match expr_to_string(cx, var_expr.clone(), "expected string literal") {
+        Ok((var, _)) => var,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
 
     let custom_msg = match exprs.next() {
         None => None,
         Some(second) => match expr_to_string(cx, second, "expected string literal") {
-            None => return DummyResult::any(sp),
-            Some((s, _)) => Some(s),
+            Ok((s, _)) => Some(s),
+            Err(guar) => return DummyResult::any(sp, guar),
         },
     };
 
@@ -91,32 +97,30 @@ pub fn expand_env<'cx>(
     cx.sess.parse_sess.env_depinfo.borrow_mut().insert((var, value));
     let e = match value {
         None => {
-            let ast::ExprKind::Lit(ast::token::Lit {
-                kind: ast::token::LitKind::Str | ast::token::LitKind::StrRaw(..),
-                symbol,
-                ..
+            let ExprKind::Lit(token::Lit {
+                kind: LitKind::Str | LitKind::StrRaw(..), symbol, ..
             }) = &var_expr.kind
             else {
                 unreachable!("`expr_to_string` ensures this is a string lit")
             };
 
-            if let Some(msg_from_user) = custom_msg {
-                cx.dcx().emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user });
+            let guar = if let Some(msg_from_user) = custom_msg {
+                cx.dcx().emit_err(errors::EnvNotDefinedWithUserMessage { span, msg_from_user })
             } else if is_cargo_env_var(var.as_str()) {
                 cx.dcx().emit_err(errors::EnvNotDefined::CargoEnvVar {
                     span,
                     var: *symbol,
                     var_expr: var_expr.ast_deref(),
-                });
+                })
             } else {
                 cx.dcx().emit_err(errors::EnvNotDefined::CustomEnvVar {
                     span,
                     var: *symbol,
                     var_expr: var_expr.ast_deref(),
-                });
-            }
+                })
+            };
 
-            return DummyResult::any(sp);
+            return DummyResult::any(sp, guar);
         }
         Some(value) => cx.expr_str(span, value),
     };
diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs
index 3366378d38d..06c2b617706 100644
--- a/compiler/rustc_builtin_macros/src/format.rs
+++ b/compiler/rustc_builtin_macros/src/format.rs
@@ -13,7 +13,7 @@ use rustc_expand::base::{self, *};
 use rustc_parse::parser::Recovered;
 use rustc_parse_format as parse;
 use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::{BytePos, InnerSpan, Span};
+use rustc_span::{BytePos, ErrorGuaranteed, InnerSpan, Span};
 
 use rustc_lint_defs::builtin::NAMED_ARGUMENTS_USED_POSITIONALLY;
 use rustc_lint_defs::{BufferedEarlyLint, BuiltinLintDiagnostics, LintId};
@@ -160,7 +160,7 @@ fn make_format_args(
     ecx: &mut ExtCtxt<'_>,
     input: MacroInput,
     append_newline: bool,
-) -> Result<FormatArgs, ()> {
+) -> Result<FormatArgs, ErrorGuaranteed> {
     let msg = "format argument must be a string literal";
     let unexpanded_fmt_span = input.fmtstr.span;
 
@@ -173,38 +173,41 @@ fn make_format_args(
         }
         Ok(fmt) => fmt,
         Err(err) => {
-            if let Some((mut err, suggested)) = err {
-                if !suggested {
-                    if let ExprKind::Block(block, None) = &efmt.kind
-                        && block.stmts.len() == 1
-                        && let StmtKind::Expr(expr) = &block.stmts[0].kind
-                        && let ExprKind::Path(None, path) = &expr.kind
-                        && path.is_potential_trivial_const_arg()
-                    {
-                        err.multipart_suggestion(
-                            "quote your inlined format argument to use as string literal",
-                            vec![
-                                (unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()),
-                                (unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()),
-                            ],
-                            Applicability::MaybeIncorrect,
-                        );
-                    } else {
-                        let sugg_fmt = match args.explicit_args().len() {
-                            0 => "{}".to_string(),
-                            _ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
-                        };
-                        err.span_suggestion(
-                            unexpanded_fmt_span.shrink_to_lo(),
-                            "you might be missing a string literal to format with",
-                            format!("\"{sugg_fmt}\", "),
-                            Applicability::MaybeIncorrect,
-                        );
+            let guar = match err {
+                Ok((mut err, suggested)) => {
+                    if !suggested {
+                        if let ExprKind::Block(block, None) = &efmt.kind
+                            && block.stmts.len() == 1
+                            && let StmtKind::Expr(expr) = &block.stmts[0].kind
+                            && let ExprKind::Path(None, path) = &expr.kind
+                            && path.is_potential_trivial_const_arg()
+                        {
+                            err.multipart_suggestion(
+                                "quote your inlined format argument to use as string literal",
+                                vec![
+                                    (unexpanded_fmt_span.shrink_to_hi(), "\"".to_string()),
+                                    (unexpanded_fmt_span.shrink_to_lo(), "\"".to_string()),
+                                ],
+                                Applicability::MaybeIncorrect,
+                            );
+                        } else {
+                            let sugg_fmt = match args.explicit_args().len() {
+                                0 => "{}".to_string(),
+                                _ => format!("{}{{}}", "{} ".repeat(args.explicit_args().len())),
+                            };
+                            err.span_suggestion(
+                                unexpanded_fmt_span.shrink_to_lo(),
+                                "you might be missing a string literal to format with",
+                                format!("\"{sugg_fmt}\", "),
+                                Applicability::MaybeIncorrect,
+                            );
+                        }
                     }
+                    err.emit()
                 }
-                err.emit();
-            }
-            return Err(());
+                Err(guar) => guar,
+            };
+            return Err(guar);
         }
     };
 
@@ -293,8 +296,8 @@ fn make_format_args(
                 }
             }
         }
-        ecx.dcx().emit_err(e);
-        return Err(());
+        let guar = ecx.dcx().emit_err(e);
+        return Err(guar);
     }
 
     let to_span = |inner_span: rustc_parse_format::InnerSpan| {
@@ -353,9 +356,9 @@ fn make_format_args(
                     } else {
                         // For the moment capturing variables from format strings expanded from macros is
                         // disabled (see RFC #2795)
-                        ecx.dcx().emit_err(errors::FormatNoArgNamed { span, name });
+                        let guar = ecx.dcx().emit_err(errors::FormatNoArgNamed { span, name });
                         unnamed_arg_after_named_arg = true;
-                        DummyResult::raw_expr(span, true)
+                        DummyResult::raw_expr(span, Some(guar))
                     };
                     Ok(args.add(FormatArgument { kind: FormatArgumentKind::Captured(ident), expr }))
                 }
@@ -972,16 +975,13 @@ fn expand_format_args_impl<'cx>(
 ) -> Box<dyn base::MacResult + 'cx> {
     sp = ecx.with_def_site_ctxt(sp);
     match parse_args(ecx, sp, tts) {
-        Ok(input) => {
-            if let Ok(format_args) = make_format_args(ecx, input, nl) {
-                MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args))))
-            } else {
-                MacEager::expr(DummyResult::raw_expr(sp, true))
-            }
-        }
+        Ok(input) => match make_format_args(ecx, input, nl) {
+            Ok(format_args) => MacEager::expr(ecx.expr(sp, ExprKind::FormatArgs(P(format_args)))),
+            Err(guar) => MacEager::expr(DummyResult::raw_expr(sp, Some(guar))),
+        },
         Err(err) => {
-            err.emit();
-            DummyResult::any(sp)
+            let guar = err.emit();
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/lib.rs b/compiler/rustc_builtin_macros/src/lib.rs
index d30ccab2394..f344dbcd10c 100644
--- a/compiler/rustc_builtin_macros/src/lib.rs
+++ b/compiler/rustc_builtin_macros/src/lib.rs
@@ -15,6 +15,7 @@
 #![feature(lint_reasons)]
 #![feature(proc_macro_internals)]
 #![feature(proc_macro_quote)]
+#![feature(try_blocks)]
 
 extern crate proc_macro;
 
diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs
index 43d13569d1e..8e0978de237 100644
--- a/compiler/rustc_builtin_macros/src/source_util.rs
+++ b/compiler/rustc_builtin_macros/src/source_util.rs
@@ -3,7 +3,10 @@ use rustc_ast::ptr::P;
 use rustc_ast::token;
 use rustc_ast::tokenstream::TokenStream;
 use rustc_ast_pretty::pprust;
-use rustc_expand::base::{self, *};
+use rustc_expand::base::{
+    check_zero_tts, get_single_str_from_tts, parse_expr, resolve_path, DummyResult, ExtCtxt,
+    MacEager, MacResult,
+};
 use rustc_expand::module::DirOwnership;
 use rustc_parse::new_parser_from_file;
 use rustc_parse::parser::{ForceCollect, Parser};
@@ -23,14 +26,14 @@ pub fn expand_line(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    base::check_zero_tts(cx, sp, tts, "line!");
+    check_zero_tts(cx, sp, tts, "line!");
 
     let topmost = cx.expansion_cause().unwrap_or(sp);
     let loc = cx.source_map().lookup_char_pos(topmost.lo());
 
-    base::MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
+    MacEager::expr(cx.expr_u32(topmost, loc.line as u32))
 }
 
 /* column!(): expands to the current column number */
@@ -38,14 +41,14 @@ pub fn expand_column(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    base::check_zero_tts(cx, sp, tts, "column!");
+    check_zero_tts(cx, sp, tts, "column!");
 
     let topmost = cx.expansion_cause().unwrap_or(sp);
     let loc = cx.source_map().lookup_char_pos(topmost.lo());
 
-    base::MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1))
+    MacEager::expr(cx.expr_u32(topmost, loc.col.to_usize() as u32 + 1))
 }
 
 /// file!(): expands to the current filename */
@@ -55,15 +58,15 @@ pub fn expand_file(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    base::check_zero_tts(cx, sp, tts, "file!");
+    check_zero_tts(cx, sp, tts, "file!");
 
     let topmost = cx.expansion_cause().unwrap_or(sp);
     let loc = cx.source_map().lookup_char_pos(topmost.lo());
 
     use rustc_session::{config::RemapPathScopeComponents, RemapFileNameExt};
-    base::MacEager::expr(cx.expr_str(
+    MacEager::expr(cx.expr_str(
         topmost,
         Symbol::intern(
             &loc.file.name.for_scope(cx.sess, RemapPathScopeComponents::MACRO).to_string_lossy(),
@@ -75,23 +78,23 @@ pub fn expand_stringify(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
     let s = pprust::tts_to_string(&tts);
-    base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
+    MacEager::expr(cx.expr_str(sp, Symbol::intern(&s)))
 }
 
 pub fn expand_mod(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    base::check_zero_tts(cx, sp, tts, "module_path!");
+    check_zero_tts(cx, sp, tts, "module_path!");
     let mod_path = &cx.current_expansion.module.mod_path;
     let string = mod_path.iter().map(|x| x.to_string()).collect::<Vec<String>>().join("::");
 
-    base::MacEager::expr(cx.expr_str(sp, Symbol::intern(&string)))
+    MacEager::expr(cx.expr_str(sp, Symbol::intern(&string)))
 }
 
 /// include! : parse the given file as an expr
@@ -101,17 +104,18 @@ pub fn expand_include<'cx>(
     cx: &'cx mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'cx> {
+) -> Box<dyn MacResult + 'cx> {
     let sp = cx.with_def_site_ctxt(sp);
-    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include!") else {
-        return DummyResult::any(sp);
+    let file = match get_single_str_from_tts(cx, sp, tts, "include!") {
+        Ok(file) => file,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     // The file will be added to the code map by the parser
     let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(sp);
+            let guar = err.emit();
+            return DummyResult::any(sp, guar);
         }
     };
     let p = new_parser_from_file(cx.parse_sess(), &file, Some(sp));
@@ -128,9 +132,9 @@ pub fn expand_include<'cx>(
         p: Parser<'a>,
         node_id: ast::NodeId,
     }
-    impl<'a> base::MacResult for ExpandResult<'a> {
+    impl<'a> MacResult for ExpandResult<'a> {
         fn make_expr(mut self: Box<ExpandResult<'a>>) -> Option<P<ast::Expr>> {
-            let r = base::parse_expr(&mut self.p)?;
+            let expr = parse_expr(&mut self.p).ok()?;
             if self.p.token != token::Eof {
                 self.p.sess.buffer_lint(
                     INCOMPLETE_INCLUDE,
@@ -139,7 +143,7 @@ pub fn expand_include<'cx>(
                     "include macro expected single expression in source",
                 );
             }
-            Some(r)
+            Some(expr)
         }
 
         fn make_items(mut self: Box<ExpandResult<'a>>) -> Option<SmallVec<[P<ast::Item>; 1]>> {
@@ -174,32 +178,33 @@ pub fn expand_include_str(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_str!") else {
-        return DummyResult::any(sp);
+    let file = match get_single_str_from_tts(cx, sp, tts, "include_str!") {
+        Ok(file) => file,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(sp);
+            let guar = err.emit();
+            return DummyResult::any(sp, guar);
         }
     };
     match cx.source_map().load_binary_file(&file) {
         Ok(bytes) => match std::str::from_utf8(&bytes) {
             Ok(src) => {
                 let interned_src = Symbol::intern(src);
-                base::MacEager::expr(cx.expr_str(sp, interned_src))
+                MacEager::expr(cx.expr_str(sp, interned_src))
             }
             Err(_) => {
-                cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display()));
-                DummyResult::any(sp)
+                let guar = cx.dcx().span_err(sp, format!("{} wasn't a utf-8 file", file.display()));
+                DummyResult::any(sp, guar)
             }
         },
         Err(e) => {
-            cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
-            DummyResult::any(sp)
+            let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
+            DummyResult::any(sp, guar)
         }
     }
 }
@@ -208,26 +213,27 @@ pub fn expand_include_bytes(
     cx: &mut ExtCtxt<'_>,
     sp: Span,
     tts: TokenStream,
-) -> Box<dyn base::MacResult + 'static> {
+) -> Box<dyn MacResult + 'static> {
     let sp = cx.with_def_site_ctxt(sp);
-    let Some(file) = get_single_str_from_tts(cx, sp, tts, "include_bytes!") else {
-        return DummyResult::any(sp);
+    let file = match get_single_str_from_tts(cx, sp, tts, "include_bytes!") {
+        Ok(file) => file,
+        Err(guar) => return DummyResult::any(sp, guar),
     };
     let file = match resolve_path(&cx.sess, file.as_str(), sp) {
         Ok(f) => f,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(sp);
+            let guar = err.emit();
+            return DummyResult::any(sp, guar);
         }
     };
     match cx.source_map().load_binary_file(&file) {
         Ok(bytes) => {
             let expr = cx.expr(sp, ast::ExprKind::IncludedBytes(bytes));
-            base::MacEager::expr(expr)
+            MacEager::expr(expr)
         }
         Err(e) => {
-            cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
-            DummyResult::any(sp)
+            let guar = cx.dcx().span_err(sp, format!("couldn't read {}: {}", file.display(), e));
+            DummyResult::any(sp, guar)
         }
     }
 }
diff --git a/compiler/rustc_builtin_macros/src/type_ascribe.rs b/compiler/rustc_builtin_macros/src/type_ascribe.rs
index 564797012ae..e8b8fe75338 100644
--- a/compiler/rustc_builtin_macros/src/type_ascribe.rs
+++ b/compiler/rustc_builtin_macros/src/type_ascribe.rs
@@ -13,8 +13,8 @@ pub fn expand_type_ascribe(
     let (expr, ty) = match parse_ascribe(cx, tts) {
         Ok(parsed) => parsed,
         Err(err) => {
-            err.emit();
-            return DummyResult::any(span);
+            let guar = err.emit();
+            return DummyResult::any(span, guar);
         }
     };
 
diff --git a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs
index 80a2776ca1e..a71217a554b 100644
--- a/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs
+++ b/compiler/rustc_codegen_cranelift/example/float-minmax-pass.rs
@@ -4,17 +4,14 @@
 
 // Test that the simd_f{min,max} intrinsics produce the correct results.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, core_intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
-    fn simd_fmin<T>(x: T, y: T) -> T;
-    fn simd_fmax<T>(x: T, y: T) -> T;
-}
+use std::intrinsics::simd::*;
 
 fn main() {
     let x = f32x4(1.0, 2.0, 3.0, 4.0);
diff --git a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
index 199d5df29e7..84269ec2942 100644
--- a/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
+++ b/compiler/rustc_codegen_cranelift/src/intrinsics/mod.rs
@@ -23,7 +23,7 @@ use rustc_middle::ty::layout::{HasParamEnv, ValidityRequirement};
 use rustc_middle::ty::print::{with_no_trimmed_paths, with_no_visible_paths};
 use rustc_middle::ty::GenericArgsRef;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym, Symbol};
+use rustc_span::symbol::{sym, Symbol};
 
 pub(crate) use self::llvm::codegen_llvm_intrinsic_call;
 use crate::prelude::*;
@@ -1132,7 +1132,7 @@ fn codegen_regular_intrinsic_call<'tcx>(
             ret.write_cvalue(fx, val);
         }
 
-        kw::Try => {
+        sym::catch_unwind => {
             intrinsic_args!(fx, args => (f, data, catch_fn); intrinsic);
             let f = f.load_scalar(fx);
             let data = data.load_scalar(fx);
diff --git a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
index f162ef831b7..d43f5d74757 100644
--- a/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
+++ b/compiler/rustc_codegen_gcc/src/intrinsic/mod.rs
@@ -21,7 +21,7 @@ use rustc_middle::ty::{self, Instance, Ty};
 use rustc_middle::ty::layout::LayoutOf;
 #[cfg(feature="master")]
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt};
-use rustc_span::{Span, Symbol, symbol::kw, sym};
+use rustc_span::{Span, Symbol, sym};
 use rustc_target::abi::HasDataLayout;
 use rustc_target::abi::call::{ArgAbi, FnAbi, PassMode};
 use rustc_target::spec::PanicStrategy;
@@ -129,7 +129,7 @@ impl<'a, 'gcc, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'a, 'gcc, 'tcx> {
                     let res = self.context.new_call(None, builtin, &[a]);
                     self.icmp(IntPredicate::IntEQ, res, self.const_i32(0))
                 }
-                kw::Try => {
+                sym::catch_unwind => {
                     try_intrinsic(
                         self,
                         args[0].immediate(),
diff --git a/compiler/rustc_codegen_llvm/src/back/write.rs b/compiler/rustc_codegen_llvm/src/back/write.rs
index 27cb0366f17..08aab849868 100644
--- a/compiler/rustc_codegen_llvm/src/back/write.rs
+++ b/compiler/rustc_codegen_llvm/src/back/write.rs
@@ -36,7 +36,7 @@ use rustc_span::InnerSpan;
 use rustc_target::spec::{CodeModel, RelocModel, SanitizerSet, SplitDebuginfo, TlsModel};
 
 use crate::llvm::diagnostic::OptimizationDiagnosticKind;
-use libc::{c_char, c_int, c_uint, c_void, size_t};
+use libc::{c_char, c_int, c_void, size_t};
 use std::ffi::CString;
 use std::fs;
 use std::io::{self, Write};
@@ -406,7 +406,7 @@ fn report_inline_asm(
     cgcx: &CodegenContext<LlvmCodegenBackend>,
     msg: String,
     level: llvm::DiagnosticLevel,
-    mut cookie: c_uint,
+    mut cookie: u64,
     source: Option<(String, Vec<InnerSpan>)>,
 ) {
     // In LTO build we may get srcloc values from other crates which are invalid
@@ -420,7 +420,7 @@ fn report_inline_asm(
         llvm::DiagnosticLevel::Warning => Level::Warning,
         llvm::DiagnosticLevel::Note | llvm::DiagnosticLevel::Remark => Level::Note,
     };
-    cgcx.diag_emitter.inline_asm_error(cookie as u32, msg, level, source);
+    cgcx.diag_emitter.inline_asm_error(cookie.try_into().unwrap(), msg, level, source);
 }
 
 unsafe extern "C" fn diagnostic_handler(info: &DiagnosticInfo, user: *mut c_void) {
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index 58c0765d814..e5de2f78376 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -17,7 +17,7 @@ use rustc_hir as hir;
 use rustc_middle::ty::layout::{FnAbiOf, HasTyCtxt, LayoutOf};
 use rustc_middle::ty::{self, GenericArgsRef, Ty};
 use rustc_middle::{bug, span_bug};
-use rustc_span::{sym, symbol::kw, Span, Symbol};
+use rustc_span::{sym, Span, Symbol};
 use rustc_target::abi::{self, Align, HasDataLayout, Primitive};
 use rustc_target::spec::{HasTargetSpec, PanicStrategy};
 
@@ -133,8 +133,8 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
             }
             sym::unlikely => self
                 .call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]),
-            kw::Try => {
-                try_intrinsic(
+            sym::catch_unwind => {
+                catch_unwind_intrinsic(
                     self,
                     args[0].immediate(),
                     args[1].immediate(),
@@ -457,7 +457,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     }
 }
 
-fn try_intrinsic<'ll>(
+fn catch_unwind_intrinsic<'ll>(
     bx: &mut Builder<'_, 'll, '_>,
     try_func: &'ll Value,
     data: &'ll Value,
diff --git a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
index 06e846a2b45..f9b28178ddb 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/diagnostic.rs
@@ -123,7 +123,7 @@ impl SrcMgrDiagnostic {
 #[derive(Clone)]
 pub struct InlineAsmDiagnostic {
     pub level: super::DiagnosticLevel,
-    pub cookie: c_uint,
+    pub cookie: u64,
     pub message: String,
     pub source: Option<(String, Vec<InnerSpan>)>,
 }
@@ -149,7 +149,7 @@ impl InlineAsmDiagnostic {
         let smdiag = SrcMgrDiagnostic::unpack(super::LLVMRustGetSMDiagnostic(di, &mut cookie));
         InlineAsmDiagnostic {
             level: smdiag.level,
-            cookie,
+            cookie: cookie.into(),
             message: smdiag.message,
             source: smdiag.source,
         }
diff --git a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
index dbf35e5f499..70fc7a66bcd 100644
--- a/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm/ffi.rs
@@ -2256,7 +2256,7 @@ extern "C" {
     pub fn LLVMRustUnpackInlineAsmDiagnostic<'a>(
         DI: &'a DiagnosticInfo,
         level_out: &mut DiagnosticLevel,
-        cookie_out: &mut c_uint,
+        cookie_out: &mut u64,
         message_out: &mut Option<&'a Twine>,
     );
 
diff --git a/compiler/rustc_error_codes/src/error_codes/E0511.md b/compiler/rustc_error_codes/src/error_codes/E0511.md
index 5351a685eb5..681f4e611c3 100644
--- a/compiler/rustc_error_codes/src/error_codes/E0511.md
+++ b/compiler/rustc_error_codes/src/error_codes/E0511.md
@@ -3,9 +3,9 @@ Invalid monomorphization of an intrinsic function was used.
 Erroneous code example:
 
 ```compile_fail,E0511
-#![feature(platform_intrinsics)]
+#![feature(intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(a: T, b: T) -> T;
 }
 
@@ -19,13 +19,13 @@ The generic type has to be a SIMD type. Example:
 
 ```
 #![feature(repr_simd)]
-#![feature(platform_intrinsics)]
+#![feature(intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
 struct i32x2(i32, i32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(a: T, b: T) -> T;
 }
 
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index 1c8d18bec65..7ece46523db 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -532,7 +532,7 @@ impl MacResult for MacEager {
 /// after hitting errors.
 #[derive(Copy, Clone)]
 pub struct DummyResult {
-    is_error: bool,
+    guar: Option<ErrorGuaranteed>,
     span: Span,
 }
 
@@ -541,20 +541,24 @@ impl DummyResult {
     ///
     /// Use this as a return value after hitting any errors and
     /// calling `span_err`.
-    pub fn any(span: Span) -> Box<dyn MacResult + 'static> {
-        Box::new(DummyResult { is_error: true, span })
+    pub fn any(span: Span, guar: ErrorGuaranteed) -> Box<dyn MacResult + 'static> {
+        Box::new(DummyResult { guar: Some(guar), span })
     }
 
     /// Same as `any`, but must be a valid fragment, not error.
     pub fn any_valid(span: Span) -> Box<dyn MacResult + 'static> {
-        Box::new(DummyResult { is_error: false, span })
+        Box::new(DummyResult { guar: None, span })
     }
 
     /// A plain dummy expression.
-    pub fn raw_expr(sp: Span, is_error: bool) -> P<ast::Expr> {
+    pub fn raw_expr(sp: Span, guar: Option<ErrorGuaranteed>) -> P<ast::Expr> {
         P(ast::Expr {
             id: ast::DUMMY_NODE_ID,
-            kind: if is_error { ast::ExprKind::Err } else { ast::ExprKind::Tup(ThinVec::new()) },
+            kind: if let Some(guar) = guar {
+                ast::ExprKind::Err(guar)
+            } else {
+                ast::ExprKind::Tup(ThinVec::new())
+            },
             span: sp,
             attrs: ast::AttrVec::new(),
             tokens: None,
@@ -582,7 +586,7 @@ impl DummyResult {
 
 impl MacResult for DummyResult {
     fn make_expr(self: Box<DummyResult>) -> Option<P<ast::Expr>> {
-        Some(DummyResult::raw_expr(self.span, self.is_error))
+        Some(DummyResult::raw_expr(self.span, self.guar))
     }
 
     fn make_pat(self: Box<DummyResult>) -> Option<P<ast::Pat>> {
@@ -608,7 +612,7 @@ impl MacResult for DummyResult {
     fn make_stmts(self: Box<DummyResult>) -> Option<SmallVec<[ast::Stmt; 1]>> {
         Some(smallvec![ast::Stmt {
             id: ast::DUMMY_NODE_ID,
-            kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.is_error)),
+            kind: ast::StmtKind::Expr(DummyResult::raw_expr(self.span, self.guar)),
             span: self.span,
         }])
     }
@@ -884,17 +888,19 @@ impl SyntaxExtension {
         }
     }
 
+    /// A dummy bang macro `foo!()`.
     pub fn dummy_bang(edition: Edition) -> SyntaxExtension {
         fn expander<'cx>(
-            _: &'cx mut ExtCtxt<'_>,
+            cx: &'cx mut ExtCtxt<'_>,
             span: Span,
             _: TokenStream,
         ) -> Box<dyn MacResult + 'cx> {
-            DummyResult::any(span)
+            DummyResult::any(span, cx.dcx().span_delayed_bug(span, "expanded a dummy bang macro"))
         }
         SyntaxExtension::default(SyntaxExtensionKind::LegacyBang(Box::new(expander)), edition)
     }
 
+    /// A dummy derive macro `#[derive(Foo)]`.
     pub fn dummy_derive(edition: Edition) -> SyntaxExtension {
         fn expander(
             _: &mut ExtCtxt<'_>,
@@ -1066,7 +1072,7 @@ pub struct ExtCtxt<'a> {
     pub sess: &'a Session,
     pub ecfg: expand::ExpansionConfig<'a>,
     pub num_standard_library_imports: usize,
-    pub reduced_recursion_limit: Option<Limit>,
+    pub reduced_recursion_limit: Option<(Limit, ErrorGuaranteed)>,
     pub root_path: PathBuf,
     pub resolver: &'a mut dyn ResolverExpand,
     pub current_expansion: ExpansionData,
@@ -1244,7 +1250,7 @@ pub fn resolve_path(
 /// Extracts a string literal from the macro expanded version of `expr`,
 /// returning a diagnostic error of `err_msg` if `expr` is not a string literal.
 /// The returned bool indicates whether an applicable suggestion has already been
-/// added to the diagnostic to avoid emitting multiple suggestions. `Err(None)`
+/// added to the diagnostic to avoid emitting multiple suggestions. `Err(Err(ErrorGuaranteed))`
 /// indicates that an ast error was encountered.
 // FIXME(Nilstrieb) Make this function setup translatable
 #[allow(rustc::untranslatable_diagnostic)]
@@ -1252,7 +1258,10 @@ pub fn expr_to_spanned_string<'a>(
     cx: &'a mut ExtCtxt<'_>,
     expr: P<ast::Expr>,
     err_msg: &'static str,
-) -> Result<(Symbol, ast::StrStyle, Span), Option<(DiagnosticBuilder<'a>, bool)>> {
+) -> Result<
+    (Symbol, ast::StrStyle, Span),
+    Result<(DiagnosticBuilder<'a>, bool /* has_suggestions */), ErrorGuaranteed>,
+> {
     // Perform eager expansion on the expression.
     // We want to be able to handle e.g., `concat!("foo", "bar")`.
     let expr = cx.expander().fully_expand_fragment(AstFragment::Expr(expr)).make_expr();
@@ -1269,35 +1278,33 @@ pub fn expr_to_spanned_string<'a>(
                     "",
                     Applicability::MaybeIncorrect,
                 );
-                Some((err, true))
+                Ok((err, true))
             }
-            Ok(ast::LitKind::Err(_)) => None,
-            Err(err) => {
-                report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span);
-                None
-            }
-            _ => Some((cx.dcx().struct_span_err(expr.span, err_msg), false)),
+            Ok(ast::LitKind::Err(guar)) => Err(guar),
+            Err(err) => Err(report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span)),
+            _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
         },
-        ast::ExprKind::Err => None,
-        _ => Some((cx.dcx().struct_span_err(expr.span, err_msg), false)),
+        ast::ExprKind::Err(guar) => Err(guar),
+        ast::ExprKind::Dummy => {
+            cx.dcx().span_bug(expr.span, "tried to get a string literal from `ExprKind::Dummy`")
+        }
+        _ => Ok((cx.dcx().struct_span_err(expr.span, err_msg), false)),
     })
 }
 
 /// Extracts a string literal from the macro expanded version of `expr`,
 /// emitting `err_msg` if `expr` is not a string literal. This does not stop
-/// compilation on error, merely emits a non-fatal error and returns `None`.
+/// compilation on error, merely emits a non-fatal error and returns `Err`.
 pub fn expr_to_string(
     cx: &mut ExtCtxt<'_>,
     expr: P<ast::Expr>,
     err_msg: &'static str,
-) -> Option<(Symbol, ast::StrStyle)> {
+) -> Result<(Symbol, ast::StrStyle), ErrorGuaranteed> {
     expr_to_spanned_string(cx, expr, err_msg)
-        .map_err(|err| {
-            err.map(|(err, _)| {
-                err.emit();
-            })
+        .map_err(|err| match err {
+            Ok((err, _)) => err.emit(),
+            Err(guar) => guar,
         })
-        .ok()
         .map(|(symbol, style, _)| (symbol, style))
 }
 
@@ -1311,32 +1318,30 @@ pub fn check_zero_tts(cx: &ExtCtxt<'_>, span: Span, tts: TokenStream, name: &str
     }
 }
 
-/// Parse an expression. On error, emit it, advancing to `Eof`, and return `None`.
-pub fn parse_expr(p: &mut parser::Parser<'_>) -> Option<P<ast::Expr>> {
-    match p.parse_expr() {
-        Ok(e) => return Some(e),
-        Err(err) => {
-            err.emit();
-        }
-    }
+/// Parse an expression. On error, emit it, advancing to `Eof`, and return `Err`.
+pub fn parse_expr(p: &mut parser::Parser<'_>) -> Result<P<ast::Expr>, ErrorGuaranteed> {
+    let guar = match p.parse_expr() {
+        Ok(expr) => return Ok(expr),
+        Err(err) => err.emit(),
+    };
     while p.token != token::Eof {
         p.bump();
     }
-    None
+    Err(guar)
 }
 
 /// Interpreting `tts` as a comma-separated sequence of expressions,
-/// expect exactly one string literal, or emit an error and return `None`.
+/// expect exactly one string literal, or emit an error and return `Err`.
 pub fn get_single_str_from_tts(
     cx: &mut ExtCtxt<'_>,
     span: Span,
     tts: TokenStream,
     name: &str,
-) -> Option<Symbol> {
+) -> Result<Symbol, ErrorGuaranteed> {
     let mut p = cx.new_parser_from_tts(tts);
     if p.token == token::Eof {
-        cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
-        return None;
+        let guar = cx.dcx().emit_err(errors::OnlyOneArgument { span, name });
+        return Err(guar);
     }
     let ret = parse_expr(&mut p)?;
     let _ = p.eat(&token::Comma);
@@ -1348,8 +1353,11 @@ pub fn get_single_str_from_tts(
 }
 
 /// Extracts comma-separated expressions from `tts`.
-/// On error, emit it, and return `None`.
-pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>, tts: TokenStream) -> Option<Vec<P<ast::Expr>>> {
+/// On error, emit it, and return `Err`.
+pub fn get_exprs_from_tts(
+    cx: &mut ExtCtxt<'_>,
+    tts: TokenStream,
+) -> Result<Vec<P<ast::Expr>>, ErrorGuaranteed> {
     let mut p = cx.new_parser_from_tts(tts);
     let mut es = Vec::new();
     while p.token != token::Eof {
@@ -1364,11 +1372,11 @@ pub fn get_exprs_from_tts(cx: &mut ExtCtxt<'_>, tts: TokenStream) -> Option<Vec<
             continue;
         }
         if p.token != token::Eof {
-            cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span });
-            return None;
+            let guar = cx.dcx().emit_err(errors::ExpectedCommaInList { span: p.token.span });
+            return Err(guar);
         }
     }
-    Some(es)
+    Ok(es)
 }
 
 pub fn parse_macro_name_and_helper_attrs(
diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs
index 2752d3ebd68..9bc7b4bdd1e 100644
--- a/compiler/rustc_expand/src/expand.rs
+++ b/compiler/rustc_expand/src/expand.rs
@@ -34,7 +34,7 @@ use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::parse::feature_err;
 use rustc_session::{Limit, Session};
 use rustc_span::symbol::{sym, Ident};
-use rustc_span::{FileName, LocalExpnId, Span};
+use rustc_span::{ErrorGuaranteed, FileName, LocalExpnId, Span};
 
 use smallvec::SmallVec;
 use std::ops::Deref;
@@ -232,8 +232,8 @@ pub enum SupportsMacroExpansion {
 }
 
 impl AstFragmentKind {
-    pub(crate) fn dummy(self, span: Span) -> AstFragment {
-        self.make_from(DummyResult::any(span)).expect("couldn't create a dummy AST fragment")
+    pub(crate) fn dummy(self, span: Span, guar: ErrorGuaranteed) -> AstFragment {
+        self.make_from(DummyResult::any(span, guar)).expect("couldn't create a dummy AST fragment")
     }
 
     pub fn supports_macro_expansion(self) -> SupportsMacroExpansion {
@@ -604,14 +604,14 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         (fragment, invocations)
     }
 
-    fn error_recursion_limit_reached(&mut self) {
+    fn error_recursion_limit_reached(&mut self) -> ErrorGuaranteed {
         let expn_data = self.cx.current_expansion.id.expn_data();
         let suggested_limit = match self.cx.ecfg.recursion_limit {
             Limit(0) => Limit(2),
             limit => limit * 2,
         };
 
-        self.cx.dcx().emit_err(RecursionLimitReached {
+        let guar = self.cx.dcx().emit_err(RecursionLimitReached {
             span: expn_data.call_site,
             descr: expn_data.kind.descr(),
             suggested_limit,
@@ -619,14 +619,21 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         });
 
         self.cx.trace_macros_diag();
+        guar
     }
 
     /// A macro's expansion does not fit in this fragment kind.
     /// For example, a non-type macro in a type position.
-    fn error_wrong_fragment_kind(&mut self, kind: AstFragmentKind, mac: &ast::MacCall, span: Span) {
-        self.cx.dcx().emit_err(WrongFragmentKind { span, kind: kind.name(), name: &mac.path });
-
+    fn error_wrong_fragment_kind(
+        &mut self,
+        kind: AstFragmentKind,
+        mac: &ast::MacCall,
+        span: Span,
+    ) -> ErrorGuaranteed {
+        let guar =
+            self.cx.dcx().emit_err(WrongFragmentKind { span, kind: kind.name(), name: &mac.path });
         self.cx.trace_macros_diag();
+        guar
     }
 
     fn expand_invoc(
@@ -634,36 +641,41 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
         invoc: Invocation,
         ext: &SyntaxExtensionKind,
     ) -> ExpandResult<AstFragment, Invocation> {
-        let recursion_limit =
-            self.cx.reduced_recursion_limit.unwrap_or(self.cx.ecfg.recursion_limit);
+        let recursion_limit = match self.cx.reduced_recursion_limit {
+            Some((limit, _)) => limit,
+            None => self.cx.ecfg.recursion_limit,
+        };
+
         if !recursion_limit.value_within_limit(self.cx.current_expansion.depth) {
-            if self.cx.reduced_recursion_limit.is_none() {
-                self.error_recursion_limit_reached();
-            }
+            let guar = match self.cx.reduced_recursion_limit {
+                Some((_, guar)) => guar,
+                None => self.error_recursion_limit_reached(),
+            };
 
             // Reduce the recursion limit by half each time it triggers.
-            self.cx.reduced_recursion_limit = Some(recursion_limit / 2);
+            self.cx.reduced_recursion_limit = Some((recursion_limit / 2, guar));
 
-            return ExpandResult::Ready(invoc.fragment_kind.dummy(invoc.span()));
+            return ExpandResult::Ready(invoc.fragment_kind.dummy(invoc.span(), guar));
         }
 
         let (fragment_kind, span) = (invoc.fragment_kind, invoc.span());
         ExpandResult::Ready(match invoc.kind {
             InvocationKind::Bang { mac, .. } => match ext {
                 SyntaxExtensionKind::Bang(expander) => {
-                    let Ok(tok_result) = expander.expand(self.cx, span, mac.args.tokens.clone())
-                    else {
-                        return ExpandResult::Ready(fragment_kind.dummy(span));
-                    };
-                    self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
+                    match expander.expand(self.cx, span, mac.args.tokens.clone()) {
+                        Ok(tok_result) => {
+                            self.parse_ast_fragment(tok_result, fragment_kind, &mac.path, span)
+                        }
+                        Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)),
+                    }
                 }
                 SyntaxExtensionKind::LegacyBang(expander) => {
                     let tok_result = expander.expand(self.cx, span, mac.args.tokens.clone());
                     let result = if let Some(result) = fragment_kind.make_from(tok_result) {
                         result
                     } else {
-                        self.error_wrong_fragment_kind(fragment_kind, &mac, span);
-                        fragment_kind.dummy(span)
+                        let guar = self.error_wrong_fragment_kind(fragment_kind, &mac, span);
+                        fragment_kind.dummy(span, guar)
                     };
                     result
                 }
@@ -705,11 +717,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                         self.cx.dcx().emit_err(UnsupportedKeyValue { span });
                     }
                     let inner_tokens = attr_item.args.inner_tokens();
-                    let Ok(tok_result) = expander.expand(self.cx, span, inner_tokens, tokens)
-                    else {
-                        return ExpandResult::Ready(fragment_kind.dummy(span));
-                    };
-                    self.parse_ast_fragment(tok_result, fragment_kind, &attr_item.path, span)
+                    match expander.expand(self.cx, span, inner_tokens, tokens) {
+                        Ok(tok_result) => self.parse_ast_fragment(
+                            tok_result,
+                            fragment_kind,
+                            &attr_item.path,
+                            span,
+                        ),
+                        Err(guar) => return ExpandResult::Ready(fragment_kind.dummy(span, guar)),
+                    }
                 }
                 SyntaxExtensionKind::LegacyAttr(expander) => {
                     match validate_attr::parse_meta(&self.cx.sess.parse_sess, &attr) {
@@ -729,15 +745,15 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                                 AstFragmentKind::Expr | AstFragmentKind::MethodReceiverExpr
                             ) && items.is_empty()
                             {
-                                self.cx.dcx().emit_err(RemoveExprNotSupported { span });
-                                fragment_kind.dummy(span)
+                                let guar = self.cx.dcx().emit_err(RemoveExprNotSupported { span });
+                                fragment_kind.dummy(span, guar)
                             } else {
                                 fragment_kind.expect_from_annotatables(items)
                             }
                         }
                         Err(err) => {
-                            err.emit();
-                            fragment_kind.dummy(span)
+                            let guar = err.emit();
+                            fragment_kind.dummy(span, guar)
                         }
                     }
                 }
@@ -857,9 +873,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
                     err.span(span);
                 }
                 annotate_err_with_kind(&mut err, kind, span);
-                err.emit();
+                let guar = err.emit();
                 self.cx.trace_macros_diag();
-                kind.dummy(span)
+                kind.dummy(span, guar)
             }
         }
     }
diff --git a/compiler/rustc_expand/src/mbe/diagnostics.rs b/compiler/rustc_expand/src/mbe/diagnostics.rs
index 25af974d326..5629c5ef5fa 100644
--- a/compiler/rustc_expand/src/mbe/diagnostics.rs
+++ b/compiler/rustc_expand/src/mbe/diagnostics.rs
@@ -11,7 +11,7 @@ use rustc_errors::{Applicability, DiagCtxt, DiagnosticBuilder, DiagnosticMessage
 use rustc_parse::parser::{Parser, Recovery};
 use rustc_span::source_map::SourceMap;
 use rustc_span::symbol::Ident;
-use rustc_span::Span;
+use rustc_span::{ErrorGuaranteed, Span};
 use std::borrow::Cow;
 
 use super::macro_rules::{parser_from_cx, NoopTracker};
@@ -47,7 +47,7 @@ pub(super) fn failed_to_match_macro<'cx>(
 
     let Some(BestFailure { token, msg: label, remaining_matcher, .. }) = tracker.best_failure
     else {
-        return DummyResult::any(sp);
+        return DummyResult::any(sp, cx.dcx().span_delayed_bug(sp, "failed to match a macro"));
     };
 
     let span = token.span.substitute_dummy(sp);
@@ -106,9 +106,9 @@ pub(super) fn failed_to_match_macro<'cx>(
             }
         }
     }
-    err.emit();
+    let guar = err.emit();
     cx.trace_macros_diag();
-    DummyResult::any(sp)
+    DummyResult::any(sp, guar)
 }
 
 /// The tracker used for the slow error path that collects useful info for diagnostics.
@@ -180,10 +180,10 @@ impl<'a, 'cx, 'matcher> Tracker<'matcher> for CollectTrackerAndEmitter<'a, 'cx,
             }
             Error(err_sp, msg) => {
                 let span = err_sp.substitute_dummy(self.root_span);
-                self.cx.dcx().span_err(span, msg.clone());
-                self.result = Some(DummyResult::any(span));
+                let guar = self.cx.dcx().span_err(span, msg.clone());
+                self.result = Some(DummyResult::any(span, guar));
             }
-            ErrorReported(_) => self.result = Some(DummyResult::any(self.root_span)),
+            ErrorReported(guar) => self.result = Some(DummyResult::any(self.root_span, *guar)),
         }
     }
 
@@ -224,7 +224,7 @@ pub(super) fn emit_frag_parse_err(
     site_span: Span,
     arm_span: Span,
     kind: AstFragmentKind,
-) {
+) -> ErrorGuaranteed {
     // FIXME(davidtwco): avoid depending on the error message text
     if parser.token == token::Eof
         && let DiagnosticMessage::Str(message) = &e.messages[0].0
@@ -282,7 +282,7 @@ pub(super) fn emit_frag_parse_err(
         },
         _ => annotate_err_with_kind(&mut e, kind, site_span),
     };
-    e.emit();
+    e.emit()
 }
 
 pub(crate) fn annotate_err_with_kind(
diff --git a/compiler/rustc_expand/src/mbe/macro_check.rs b/compiler/rustc_expand/src/mbe/macro_check.rs
index ffc8f782fd3..8174cb03d33 100644
--- a/compiler/rustc_expand/src/mbe/macro_check.rs
+++ b/compiler/rustc_expand/src/mbe/macro_check.rs
@@ -114,7 +114,7 @@ use rustc_errors::{DiagnosticMessage, MultiSpan};
 use rustc_session::lint::builtin::{META_VARIABLE_MISUSE, MISSING_FRAGMENT_SPECIFIER};
 use rustc_session::parse::ParseSess;
 use rustc_span::symbol::kw;
-use rustc_span::{symbol::MacroRulesNormalizedIdent, Span};
+use rustc_span::{symbol::MacroRulesNormalizedIdent, ErrorGuaranteed, Span};
 
 use smallvec::SmallVec;
 
@@ -203,17 +203,17 @@ pub(super) fn check_meta_variables(
     span: Span,
     lhses: &[TokenTree],
     rhses: &[TokenTree],
-) -> bool {
+) -> Result<(), ErrorGuaranteed> {
     if lhses.len() != rhses.len() {
         sess.dcx.span_bug(span, "length mismatch between LHSes and RHSes")
     }
-    let mut valid = true;
+    let mut guar = None;
     for (lhs, rhs) in iter::zip(lhses, rhses) {
         let mut binders = Binders::default();
-        check_binders(sess, node_id, lhs, &Stack::Empty, &mut binders, &Stack::Empty, &mut valid);
-        check_occurrences(sess, node_id, rhs, &Stack::Empty, &binders, &Stack::Empty, &mut valid);
+        check_binders(sess, node_id, lhs, &Stack::Empty, &mut binders, &Stack::Empty, &mut guar);
+        check_occurrences(sess, node_id, rhs, &Stack::Empty, &binders, &Stack::Empty, &mut guar);
     }
-    valid
+    guar.map_or(Ok(()), Err)
 }
 
 /// Checks `lhs` as part of the LHS of a macro definition, extends `binders` with new binders, and
@@ -226,7 +226,7 @@ pub(super) fn check_meta_variables(
 /// - `macros` is the stack of possible outer macros
 /// - `binders` contains the binders of the LHS
 /// - `ops` is the stack of Kleene operators from the LHS
-/// - `valid` is set in case of errors
+/// - `guar` is set in case of errors
 fn check_binders(
     sess: &ParseSess,
     node_id: NodeId,
@@ -234,7 +234,7 @@ fn check_binders(
     macros: &Stack<'_, MacroState<'_>>,
     binders: &mut Binders,
     ops: &Stack<'_, KleeneToken>,
-    valid: &mut bool,
+    guar: &mut Option<ErrorGuaranteed>,
 ) {
     match *lhs {
         TokenTree::Token(..) => {}
@@ -258,7 +258,7 @@ fn check_binders(
                 binders.insert(name, BinderInfo { span, ops: ops.into() });
             } else {
                 // 3. The meta-variable is bound: This is an occurrence.
-                check_occurrences(sess, node_id, lhs, macros, binders, ops, valid);
+                check_occurrences(sess, node_id, lhs, macros, binders, ops, guar);
             }
         }
         // Similarly, this can only happen when checking a toplevel macro.
@@ -281,8 +281,10 @@ fn check_binders(
             if let Some(prev_info) = get_binder_info(macros, binders, name) {
                 // Duplicate binders at the top-level macro definition are errors. The lint is only
                 // for nested macro definitions.
-                sess.dcx.emit_err(errors::DuplicateMatcherBinding { span, prev: prev_info.span });
-                *valid = false;
+                *guar = Some(
+                    sess.dcx
+                        .emit_err(errors::DuplicateMatcherBinding { span, prev: prev_info.span }),
+                );
             } else {
                 binders.insert(name, BinderInfo { span, ops: ops.into() });
             }
@@ -291,13 +293,13 @@ fn check_binders(
         TokenTree::MetaVarExpr(..) => {}
         TokenTree::Delimited(.., ref del) => {
             for tt in &del.tts {
-                check_binders(sess, node_id, tt, macros, binders, ops, valid);
+                check_binders(sess, node_id, tt, macros, binders, ops, guar);
             }
         }
         TokenTree::Sequence(_, ref seq) => {
             let ops = ops.push(seq.kleene);
             for tt in &seq.tts {
-                check_binders(sess, node_id, tt, macros, binders, &ops, valid);
+                check_binders(sess, node_id, tt, macros, binders, &ops, guar);
             }
         }
     }
@@ -327,7 +329,7 @@ fn get_binder_info<'a>(
 /// - `macros` is the stack of possible outer macros
 /// - `binders` contains the binders of the associated LHS
 /// - `ops` is the stack of Kleene operators from the RHS
-/// - `valid` is set in case of errors
+/// - `guar` is set in case of errors
 fn check_occurrences(
     sess: &ParseSess,
     node_id: NodeId,
@@ -335,7 +337,7 @@ fn check_occurrences(
     macros: &Stack<'_, MacroState<'_>>,
     binders: &Binders,
     ops: &Stack<'_, KleeneToken>,
-    valid: &mut bool,
+    guar: &mut Option<ErrorGuaranteed>,
 ) {
     match *rhs {
         TokenTree::Token(..) => {}
@@ -353,11 +355,11 @@ fn check_occurrences(
             check_ops_is_prefix(sess, node_id, macros, binders, ops, dl.entire(), name);
         }
         TokenTree::Delimited(.., ref del) => {
-            check_nested_occurrences(sess, node_id, &del.tts, macros, binders, ops, valid);
+            check_nested_occurrences(sess, node_id, &del.tts, macros, binders, ops, guar);
         }
         TokenTree::Sequence(_, ref seq) => {
             let ops = ops.push(seq.kleene);
-            check_nested_occurrences(sess, node_id, &seq.tts, macros, binders, &ops, valid);
+            check_nested_occurrences(sess, node_id, &seq.tts, macros, binders, &ops, guar);
         }
     }
 }
@@ -392,7 +394,7 @@ enum NestedMacroState {
 /// - `macros` is the stack of possible outer macros
 /// - `binders` contains the binders of the associated LHS
 /// - `ops` is the stack of Kleene operators from the RHS
-/// - `valid` is set in case of errors
+/// - `guar` is set in case of errors
 fn check_nested_occurrences(
     sess: &ParseSess,
     node_id: NodeId,
@@ -400,7 +402,7 @@ fn check_nested_occurrences(
     macros: &Stack<'_, MacroState<'_>>,
     binders: &Binders,
     ops: &Stack<'_, KleeneToken>,
-    valid: &mut bool,
+    guar: &mut Option<ErrorGuaranteed>,
 ) {
     let mut state = NestedMacroState::Empty;
     let nested_macros = macros.push(MacroState { binders, ops: ops.into() });
@@ -432,7 +434,7 @@ fn check_nested_occurrences(
             (NestedMacroState::MacroRulesNot, &TokenTree::MetaVar(..)) => {
                 state = NestedMacroState::MacroRulesNotName;
                 // We check that the meta-variable is correctly used.
-                check_occurrences(sess, node_id, tt, macros, binders, ops, valid);
+                check_occurrences(sess, node_id, tt, macros, binders, ops, guar);
             }
             (NestedMacroState::MacroRulesNotName, TokenTree::Delimited(.., del))
             | (NestedMacroState::MacroName, TokenTree::Delimited(.., del))
@@ -441,7 +443,7 @@ fn check_nested_occurrences(
                 let macro_rules = state == NestedMacroState::MacroRulesNotName;
                 state = NestedMacroState::Empty;
                 let rest =
-                    check_nested_macro(sess, node_id, macro_rules, &del.tts, &nested_macros, valid);
+                    check_nested_macro(sess, node_id, macro_rules, &del.tts, &nested_macros, guar);
                 // If we did not check the whole macro definition, then check the rest as if outside
                 // the macro definition.
                 check_nested_occurrences(
@@ -451,7 +453,7 @@ fn check_nested_occurrences(
                     macros,
                     binders,
                     ops,
-                    valid,
+                    guar,
                 );
             }
             (
@@ -463,7 +465,7 @@ fn check_nested_occurrences(
             (NestedMacroState::Macro, &TokenTree::MetaVar(..)) => {
                 state = NestedMacroState::MacroName;
                 // We check that the meta-variable is correctly used.
-                check_occurrences(sess, node_id, tt, macros, binders, ops, valid);
+                check_occurrences(sess, node_id, tt, macros, binders, ops, guar);
             }
             (NestedMacroState::MacroName, TokenTree::Delimited(.., del))
                 if del.delim == Delimiter::Parenthesis =>
@@ -477,7 +479,7 @@ fn check_nested_occurrences(
                     &nested_macros,
                     &mut nested_binders,
                     &Stack::Empty,
-                    valid,
+                    guar,
                 );
             }
             (NestedMacroState::MacroNameParen, TokenTree::Delimited(.., del))
@@ -491,12 +493,12 @@ fn check_nested_occurrences(
                     &nested_macros,
                     &nested_binders,
                     &Stack::Empty,
-                    valid,
+                    guar,
                 );
             }
             (_, tt) => {
                 state = NestedMacroState::Empty;
-                check_occurrences(sess, node_id, tt, macros, binders, ops, valid);
+                check_occurrences(sess, node_id, tt, macros, binders, ops, guar);
             }
         }
     }
@@ -515,14 +517,14 @@ fn check_nested_occurrences(
 /// - `macro_rules` specifies whether the macro is `macro_rules`
 /// - `tts` is checked as a list of (LHS) => {RHS}
 /// - `macros` is the stack of outer macros
-/// - `valid` is set in case of errors
+/// - `guar` is set in case of errors
 fn check_nested_macro(
     sess: &ParseSess,
     node_id: NodeId,
     macro_rules: bool,
     tts: &[TokenTree],
     macros: &Stack<'_, MacroState<'_>>,
-    valid: &mut bool,
+    guar: &mut Option<ErrorGuaranteed>,
 ) -> usize {
     let n = tts.len();
     let mut i = 0;
@@ -539,8 +541,8 @@ fn check_nested_macro(
         let lhs = &tts[i];
         let rhs = &tts[i + 2];
         let mut binders = Binders::default();
-        check_binders(sess, node_id, lhs, macros, &mut binders, &Stack::Empty, valid);
-        check_occurrences(sess, node_id, rhs, macros, &binders, &Stack::Empty, valid);
+        check_binders(sess, node_id, lhs, macros, &mut binders, &Stack::Empty, guar);
+        check_occurrences(sess, node_id, rhs, macros, &binders, &Stack::Empty, guar);
         // Since the last semicolon is optional for `macro_rules` macros and decl_macro are not terminated,
         // we increment our checked position by how many token trees we already checked (the 3
         // above) before checking for the separator.
diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs
index bf99e9e6d5c..c11d538048a 100644
--- a/compiler/rustc_expand/src/mbe/macro_rules.rs
+++ b/compiler/rustc_expand/src/mbe/macro_rules.rs
@@ -66,8 +66,10 @@ impl<'a> ParserAnyMacro<'a> {
         let fragment = match parse_ast_fragment(parser, kind) {
             Ok(f) => f,
             Err(err) => {
-                diagnostics::emit_frag_parse_err(err, parser, snapshot, site_span, arm_span, kind);
-                return kind.dummy(site_span);
+                let guar = diagnostics::emit_frag_parse_err(
+                    err, parser, snapshot, site_span, arm_span, kind,
+                );
+                return kind.dummy(site_span, guar);
             }
         };
 
@@ -101,7 +103,6 @@ struct MacroRulesMacroExpander {
     transparency: Transparency,
     lhses: Vec<Vec<MatcherLoc>>,
     rhses: Vec<mbe::TokenTree>,
-    valid: bool,
 }
 
 impl TTMacroExpander for MacroRulesMacroExpander {
@@ -111,9 +112,6 @@ impl TTMacroExpander for MacroRulesMacroExpander {
         sp: Span,
         input: TokenStream,
     ) -> Box<dyn MacResult + 'cx> {
-        if !self.valid {
-            return DummyResult::any(sp);
-        }
         expand_macro(
             cx,
             sp,
@@ -128,12 +126,17 @@ impl TTMacroExpander for MacroRulesMacroExpander {
     }
 }
 
-fn macro_rules_dummy_expander<'cx>(
-    _: &'cx mut ExtCtxt<'_>,
-    span: Span,
-    _: TokenStream,
-) -> Box<dyn MacResult + 'cx> {
-    DummyResult::any(span)
+struct DummyExpander(ErrorGuaranteed);
+
+impl TTMacroExpander for DummyExpander {
+    fn expand<'cx>(
+        &self,
+        _: &'cx mut ExtCtxt<'_>,
+        span: Span,
+        _: TokenStream,
+    ) -> Box<dyn MacResult + 'cx> {
+        DummyResult::any(span, self.0)
+    }
 }
 
 fn trace_macros_note(cx_expansions: &mut FxIndexMap<Span, Vec<String>>, sp: Span, message: String) {
@@ -217,8 +220,8 @@ fn expand_macro<'cx>(
             let tts = match transcribe(cx, &named_matches, rhs, rhs_span, transparency) {
                 Ok(tts) => tts,
                 Err(err) => {
-                    err.emit();
-                    return DummyResult::any(arm_span);
+                    let guar = err.emit();
+                    return DummyResult::any(arm_span, guar);
                 }
             };
 
@@ -249,9 +252,9 @@ fn expand_macro<'cx>(
                 is_local,
             })
         }
-        Err(CanRetry::No(_)) => {
+        Err(CanRetry::No(guar)) => {
             debug!("Will not retry matching as an error was emitted already");
-            DummyResult::any(sp)
+            DummyResult::any(sp, guar)
         }
         Err(CanRetry::Yes) => {
             // Retry and emit a better error.
@@ -371,7 +374,7 @@ pub fn compile_declarative_macro(
             def.id != DUMMY_NODE_ID,
         )
     };
-    let dummy_syn_ext = || (mk_syn_ext(Box::new(macro_rules_dummy_expander)), Vec::new());
+    let dummy_syn_ext = |guar| (mk_syn_ext(Box::new(DummyExpander(guar))), Vec::new());
 
     let dcx = &sess.parse_sess.dcx;
     let lhs_nm = Ident::new(sym::lhs, def.span);
@@ -456,19 +459,20 @@ pub fn compile_declarative_macro(
                 let mut err = sess.dcx().struct_span_err(sp, s);
                 err.span_label(sp, msg);
                 annotate_doc_comment(sess.dcx(), &mut err, sess.source_map(), sp);
-                err.emit();
-                return dummy_syn_ext();
+                let guar = err.emit();
+                return dummy_syn_ext(guar);
             }
             Error(sp, msg) => {
-                sess.dcx().span_err(sp.substitute_dummy(def.span), msg);
-                return dummy_syn_ext();
+                let guar = sess.dcx().span_err(sp.substitute_dummy(def.span), msg);
+                return dummy_syn_ext(guar);
             }
-            ErrorReported(_) => {
-                return dummy_syn_ext();
+            ErrorReported(guar) => {
+                return dummy_syn_ext(guar);
             }
         };
 
-    let mut valid = true;
+    let mut guar = None;
+    let mut check_emission = |ret: Result<(), ErrorGuaranteed>| guar = guar.or(ret.err());
 
     // Extract the arguments:
     let lhses = match &argument_map[&MacroRulesNormalizedIdent::new(lhs_nm)] {
@@ -488,7 +492,7 @@ pub fn compile_declarative_macro(
                     .unwrap();
                     // We don't handle errors here, the driver will abort
                     // after parsing/expansion. we can report every error in every macro this way.
-                    valid &= check_lhs_nt_follows(sess, def, &tt).is_ok();
+                    check_emission(check_lhs_nt_follows(sess, def, &tt));
                     return tt;
                 }
                 sess.dcx().span_bug(def.span, "wrong-structured lhs")
@@ -520,15 +524,21 @@ pub fn compile_declarative_macro(
     };
 
     for rhs in &rhses {
-        valid &= check_rhs(sess, rhs);
+        check_emission(check_rhs(sess, rhs));
     }
 
     // don't abort iteration early, so that errors for multiple lhses can be reported
     for lhs in &lhses {
-        valid &= check_lhs_no_empty_seq(sess, slice::from_ref(lhs));
+        check_emission(check_lhs_no_empty_seq(sess, slice::from_ref(lhs)));
     }
 
-    valid &= macro_check::check_meta_variables(&sess.parse_sess, def.id, def.span, &lhses, &rhses);
+    check_emission(macro_check::check_meta_variables(
+        &sess.parse_sess,
+        def.id,
+        def.span,
+        &lhses,
+        &rhses,
+    ));
 
     let (transparency, transparency_error) = attr::find_transparency(&def.attrs, macro_rules);
     match transparency_error {
@@ -541,11 +551,15 @@ pub fn compile_declarative_macro(
         None => {}
     }
 
+    if let Some(guar) = guar {
+        // To avoid warning noise, only consider the rules of this
+        // macro for the lint, if all rules are valid.
+        return dummy_syn_ext(guar);
+    }
+
     // Compute the spans of the macro rules for unused rule linting.
-    // To avoid warning noise, only consider the rules of this
-    // macro for the lint, if all rules are valid.
     // Also, we are only interested in non-foreign macros.
-    let rule_spans = if valid && def.id != DUMMY_NODE_ID {
+    let rule_spans = if def.id != DUMMY_NODE_ID {
         lhses
             .iter()
             .zip(rhses.iter())
@@ -562,23 +576,19 @@ pub fn compile_declarative_macro(
     };
 
     // Convert the lhses into `MatcherLoc` form, which is better for doing the
-    // actual matching. Unless the matcher is invalid.
-    let lhses = if valid {
-        lhses
-            .iter()
-            .map(|lhs| {
-                // Ignore the delimiters around the matcher.
-                match lhs {
-                    mbe::TokenTree::Delimited(.., delimited) => {
-                        mbe::macro_parser::compute_locs(&delimited.tts)
-                    }
-                    _ => sess.dcx().span_bug(def.span, "malformed macro lhs"),
+    // actual matching.
+    let lhses = lhses
+        .iter()
+        .map(|lhs| {
+            // Ignore the delimiters around the matcher.
+            match lhs {
+                mbe::TokenTree::Delimited(.., delimited) => {
+                    mbe::macro_parser::compute_locs(&delimited.tts)
                 }
-            })
-            .collect()
-    } else {
-        vec![]
-    };
+                _ => sess.dcx().span_bug(def.span, "malformed macro lhs"),
+            }
+        })
+        .collect();
 
     let expander = Box::new(MacroRulesMacroExpander {
         name: def.ident,
@@ -587,7 +597,6 @@ pub fn compile_declarative_macro(
         transparency,
         lhses,
         rhses,
-        valid,
     });
     (mk_syn_ext(expander), rule_spans)
 }
@@ -640,7 +649,7 @@ fn is_empty_token_tree(sess: &Session, seq: &mbe::SequenceRepetition) -> bool {
 
 /// Checks that the lhs contains no repetition which could match an empty token
 /// tree, because then the matcher would hang indefinitely.
-fn check_lhs_no_empty_seq(sess: &Session, tts: &[mbe::TokenTree]) -> bool {
+fn check_lhs_no_empty_seq(sess: &Session, tts: &[mbe::TokenTree]) -> Result<(), ErrorGuaranteed> {
     use mbe::TokenTree;
     for tt in tts {
         match tt {
@@ -648,35 +657,26 @@ fn check_lhs_no_empty_seq(sess: &Session, tts: &[mbe::TokenTree]) -> bool {
             | TokenTree::MetaVar(..)
             | TokenTree::MetaVarDecl(..)
             | TokenTree::MetaVarExpr(..) => (),
-            TokenTree::Delimited(.., del) => {
-                if !check_lhs_no_empty_seq(sess, &del.tts) {
-                    return false;
-                }
-            }
+            TokenTree::Delimited(.., del) => check_lhs_no_empty_seq(sess, &del.tts)?,
             TokenTree::Sequence(span, seq) => {
                 if is_empty_token_tree(sess, seq) {
                     let sp = span.entire();
-                    sess.dcx().span_err(sp, "repetition matches empty token tree");
-                    return false;
-                }
-                if !check_lhs_no_empty_seq(sess, &seq.tts) {
-                    return false;
+                    let guar = sess.dcx().span_err(sp, "repetition matches empty token tree");
+                    return Err(guar);
                 }
+                check_lhs_no_empty_seq(sess, &seq.tts)?
             }
         }
     }
 
-    true
+    Ok(())
 }
 
-fn check_rhs(sess: &Session, rhs: &mbe::TokenTree) -> bool {
+fn check_rhs(sess: &Session, rhs: &mbe::TokenTree) -> Result<(), ErrorGuaranteed> {
     match *rhs {
-        mbe::TokenTree::Delimited(..) => return true,
-        _ => {
-            sess.dcx().span_err(rhs.span(), "macro rhs must be delimited");
-        }
+        mbe::TokenTree::Delimited(..) => Ok(()),
+        _ => Err(sess.dcx().span_err(rhs.span(), "macro rhs must be delimited")),
     }
-    false
 }
 
 fn check_matcher(
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 6cb41be7c94..682363ed19d 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -277,25 +277,35 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ungated!(cfg_attr, Normal, template!(List: "predicate, attr1, attr2, ..."), DuplicatesOk),
 
     // Testing:
-    ungated!(ignore, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing),
+    ungated!(
+        ignore, Normal, template!(Word, NameValueStr: "reason"), WarnFollowing,
+        @only_local: true,
+    ),
     ungated!(
         should_panic, Normal,
         template!(Word, List: r#"expected = "reason""#, NameValueStr: "reason"), FutureWarnFollowing,
+        @only_local: true,
     ),
     // FIXME(Centril): This can be used on stable but shouldn't.
-    ungated!(reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing),
+    ungated!(
+        reexport_test_harness_main, CrateLevel, template!(NameValueStr: "name"), ErrorFollowing,
+        @only_local: true,
+    ),
 
     // Macros:
     ungated!(automatically_derived, Normal, template!(Word), WarnFollowing),
-    ungated!(macro_use, Normal, template!(Word, List: "name1, name2, ..."), WarnFollowingWordOnly),
-    ungated!(macro_escape, Normal, template!(Word), WarnFollowing), // Deprecated synonym for `macro_use`.
+    ungated!(
+        macro_use, Normal, template!(Word, List: "name1, name2, ..."), WarnFollowingWordOnly,
+        @only_local: true,
+    ),
+    ungated!(macro_escape, Normal, template!(Word), WarnFollowing, @only_local: true), // Deprecated synonym for `macro_use`.
     ungated!(macro_export, Normal, template!(Word, List: "local_inner_macros"), WarnFollowing),
-    ungated!(proc_macro, Normal, template!(Word), ErrorFollowing),
+    ungated!(proc_macro, Normal, template!(Word), ErrorFollowing, @only_local: true),
     ungated!(
-        proc_macro_derive, Normal,
-        template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"), ErrorFollowing,
+        proc_macro_derive, Normal, template!(List: "TraitName, /*opt*/ attributes(name1, name2, ...)"),
+        ErrorFollowing, @only_local: true,
     ),
-    ungated!(proc_macro_attribute, Normal, template!(Word), ErrorFollowing),
+    ungated!(proc_macro_attribute, Normal, template!(Word), ErrorFollowing, @only_local: true),
 
     // Lints:
     ungated!(
@@ -308,7 +318,7 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
     gated!(
         expect, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#), DuplicatesOk,
-        lint_reasons, experimental!(expect)
+        @only_local: true, lint_reasons, experimental!(expect)
     ),
     ungated!(
         forbid, Normal, template!(List: r#"lint1, lint2, ..., /*opt*/ reason = "...""#),
@@ -334,32 +344,48 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
     ),
 
     // Crate properties:
-    ungated!(crate_name, CrateLevel, template!(NameValueStr: "name"), FutureWarnFollowing),
-    ungated!(crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), DuplicatesOk),
+    ungated!(
+        crate_name, CrateLevel, template!(NameValueStr: "name"), FutureWarnFollowing,
+        @only_local: true,
+    ),
+    ungated!(
+        crate_type, CrateLevel, template!(NameValueStr: "bin|lib|..."), DuplicatesOk,
+        @only_local: true,
+    ),
     // crate_id is deprecated
-    ungated!(crate_id, CrateLevel, template!(NameValueStr: "ignored"), FutureWarnFollowing),
+    ungated!(
+        crate_id, CrateLevel, template!(NameValueStr: "ignored"), FutureWarnFollowing,
+        @only_local: true,
+    ),
 
     // ABI, linking, symbols, and FFI
     ungated!(
         link, Normal,
         template!(List: r#"name = "...", /*opt*/ kind = "dylib|static|...", /*opt*/ wasm_import_module = "...", /*opt*/ import_name_type = "decorated|noprefix|undecorated""#),
         DuplicatesOk,
+        @only_local: true,
     ),
     ungated!(link_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
-    ungated!(no_link, Normal, template!(Word), WarnFollowing),
+    ungated!(no_link, Normal, template!(Word), WarnFollowing, @only_local: true),
     ungated!(repr, Normal, template!(List: "C"), DuplicatesOk, @only_local: true),
-    ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
-    ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding),
+    ungated!(export_name, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, @only_local: true),
+    ungated!(link_section, Normal, template!(NameValueStr: "name"), FutureWarnPreceding, @only_local: true),
     ungated!(no_mangle, Normal, template!(Word), WarnFollowing, @only_local: true),
     ungated!(used, Normal, template!(Word, List: "compiler|linker"), WarnFollowing, @only_local: true),
     ungated!(link_ordinal, Normal, template!(List: "ordinal"), ErrorPreceding),
 
     // Limits:
-    ungated!(recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
-    ungated!(type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing),
+    ungated!(
+        recursion_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
+        @only_local: true
+    ),
+    ungated!(
+        type_length_limit, CrateLevel, template!(NameValueStr: "N"), FutureWarnFollowing,
+        @only_local: true
+    ),
     gated!(
         move_size_limit, CrateLevel, template!(NameValueStr: "N"), ErrorFollowing,
-        large_assignments, experimental!(move_size_limit)
+        @only_local: true, large_assignments, experimental!(move_size_limit)
     ),
 
     // Entry point:
diff --git a/compiler/rustc_feature/src/removed.rs b/compiler/rustc_feature/src/removed.rs
index 008c59e1be3..05bb7480732 100644
--- a/compiler/rustc_feature/src/removed.rs
+++ b/compiler/rustc_feature/src/removed.rs
@@ -156,6 +156,9 @@ declare_features! (
      Some("removed in favor of `#![feature(marker_trait_attr)]`")),
     (removed, panic_implementation, "1.28.0", Some(44489),
      Some("subsumed by `#[panic_handler]`")),
+    /// Allows `extern "platform-intrinsic" { ... }`.
+    (removed, platform_intrinsics, "1.4.0", Some(27731),
+     Some("SIMD intrinsics use the regular intrinsics ABI now")),
     /// Allows using `#![plugin(myplugin)]`.
     (removed, plugin, "1.75.0", Some(29597),
      Some("plugins are no longer supported")),
diff --git a/compiler/rustc_feature/src/unstable.rs b/compiler/rustc_feature/src/unstable.rs
index 8eea4b7d8a8..53254d567cc 100644
--- a/compiler/rustc_feature/src/unstable.rs
+++ b/compiler/rustc_feature/src/unstable.rs
@@ -259,8 +259,6 @@ declare_features! (
     (internal, needs_panic_runtime, "1.10.0", Some(32837)),
     /// Allows using the `#![panic_runtime]` attribute.
     (internal, panic_runtime, "1.10.0", Some(32837)),
-    /// Allows `extern "platform-intrinsic" { ... }`.
-    (internal, platform_intrinsics, "1.4.0", Some(27731)),
     /// Allows using `#[rustc_allow_const_fn_unstable]`.
     /// This is an attribute on `const fn` for the same
     /// purpose as `#[allow_internal_unstable]`.
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index deabb9c3738..3d9aa428c74 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -612,17 +612,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
                     }
                 }
 
-                Abi::PlatformIntrinsic => {
-                    for item in items {
-                        intrinsic::check_platform_intrinsic_type(
-                            tcx,
-                            item.id.owner_id.def_id,
-                            item.span,
-                            item.ident.name,
-                        );
-                    }
-                }
-
                 _ => {
                     for item in items {
                         let def_id = item.id.owner_id.def_id;
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index d7277b22c84..3b7a7817279 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 use rustc_span::def_id::LocalDefId;
-use rustc_span::symbol::{kw, sym};
+use rustc_span::symbol::sym;
 use rustc_span::{Span, Symbol};
 use rustc_target::spec::abi::Abi;
 
@@ -445,7 +445,7 @@ pub fn check_intrinsic_type(
                 )
             }
 
-            kw::Try => {
+            sym::catch_unwind => {
                 let mut_u8 = Ty::new_mut_ptr(tcx, tcx.types.u8);
                 let try_fn_ty = ty::Binder::dummy(tcx.mk_fn_sig(
                     [mut_u8],
@@ -510,6 +510,77 @@ pub fn check_intrinsic_type(
 
             sym::debug_assertions => (0, 1, Vec::new(), tcx.types.bool),
 
+            sym::simd_eq
+            | sym::simd_ne
+            | sym::simd_lt
+            | sym::simd_le
+            | sym::simd_gt
+            | sym::simd_ge => (2, 0, vec![param(0), param(0)], param(1)),
+            sym::simd_add
+            | sym::simd_sub
+            | sym::simd_mul
+            | sym::simd_rem
+            | sym::simd_div
+            | sym::simd_shl
+            | sym::simd_shr
+            | sym::simd_and
+            | sym::simd_or
+            | sym::simd_xor
+            | sym::simd_fmin
+            | sym::simd_fmax
+            | sym::simd_fpow
+            | sym::simd_saturating_add
+            | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
+            sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
+            sym::simd_neg
+            | sym::simd_bswap
+            | sym::simd_bitreverse
+            | sym::simd_ctlz
+            | sym::simd_cttz
+            | sym::simd_fsqrt
+            | sym::simd_fsin
+            | sym::simd_fcos
+            | sym::simd_fexp
+            | sym::simd_fexp2
+            | sym::simd_flog2
+            | sym::simd_flog10
+            | sym::simd_flog
+            | sym::simd_fabs
+            | sym::simd_ceil
+            | sym::simd_floor
+            | sym::simd_round
+            | sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
+            sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)),
+            sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)),
+            sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
+            sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
+            sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
+            sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
+            sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
+            sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
+            sym::simd_cast
+            | sym::simd_as
+            | sym::simd_cast_ptr
+            | sym::simd_expose_addr
+            | sym::simd_from_exposed_addr => (2, 0, vec![param(0)], param(1)),
+            sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
+            sym::simd_select | sym::simd_select_bitmask => {
+                (2, 0, vec![param(0), param(1), param(1)], param(1))
+            }
+            sym::simd_reduce_all | sym::simd_reduce_any => (1, 0, vec![param(0)], tcx.types.bool),
+            sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => {
+                (2, 0, vec![param(0), param(1)], param(1))
+            }
+            sym::simd_reduce_add_unordered
+            | sym::simd_reduce_mul_unordered
+            | sym::simd_reduce_and
+            | sym::simd_reduce_or
+            | sym::simd_reduce_xor
+            | sym::simd_reduce_min
+            | sym::simd_reduce_max => (2, 0, vec![param(0)], param(1)),
+            sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)),
+            sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)),
+
             other => {
                 tcx.dcx().emit_err(UnrecognizedIntrinsicFunction { span, name: other });
                 return;
@@ -521,102 +592,3 @@ pub fn check_intrinsic_type(
     let sig = ty::Binder::bind_with_vars(sig, bound_vars);
     equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, n_lts, n_cts, sig)
 }
-
-/// Type-check `extern "platform-intrinsic" { ... }` functions.
-pub fn check_platform_intrinsic_type(
-    tcx: TyCtxt<'_>,
-    intrinsic_id: LocalDefId,
-    span: Span,
-    name: Symbol,
-) {
-    let generics = tcx.generics_of(intrinsic_id);
-    let param = |n| {
-        if let Some(&ty::GenericParamDef {
-            name, kind: ty::GenericParamDefKind::Type { .. }, ..
-        }) = generics.opt_param_at(n as usize, tcx)
-        {
-            Ty::new_param(tcx, n, name)
-        } else {
-            Ty::new_error_with_message(tcx, span, "expected param")
-        }
-    };
-
-    let (n_tps, n_cts, inputs, output) = match name {
-        sym::simd_eq | sym::simd_ne | sym::simd_lt | sym::simd_le | sym::simd_gt | sym::simd_ge => {
-            (2, 0, vec![param(0), param(0)], param(1))
-        }
-        sym::simd_add
-        | sym::simd_sub
-        | sym::simd_mul
-        | sym::simd_rem
-        | sym::simd_div
-        | sym::simd_shl
-        | sym::simd_shr
-        | sym::simd_and
-        | sym::simd_or
-        | sym::simd_xor
-        | sym::simd_fmin
-        | sym::simd_fmax
-        | sym::simd_fpow
-        | sym::simd_saturating_add
-        | sym::simd_saturating_sub => (1, 0, vec![param(0), param(0)], param(0)),
-        sym::simd_arith_offset => (2, 0, vec![param(0), param(1)], param(0)),
-        sym::simd_neg
-        | sym::simd_bswap
-        | sym::simd_bitreverse
-        | sym::simd_ctlz
-        | sym::simd_cttz
-        | sym::simd_fsqrt
-        | sym::simd_fsin
-        | sym::simd_fcos
-        | sym::simd_fexp
-        | sym::simd_fexp2
-        | sym::simd_flog2
-        | sym::simd_flog10
-        | sym::simd_flog
-        | sym::simd_fabs
-        | sym::simd_ceil
-        | sym::simd_floor
-        | sym::simd_round
-        | sym::simd_trunc => (1, 0, vec![param(0)], param(0)),
-        sym::simd_fpowi => (1, 0, vec![param(0), tcx.types.i32], param(0)),
-        sym::simd_fma => (1, 0, vec![param(0), param(0), param(0)], param(0)),
-        sym::simd_gather => (3, 0, vec![param(0), param(1), param(2)], param(0)),
-        sym::simd_masked_load => (3, 0, vec![param(0), param(1), param(2)], param(2)),
-        sym::simd_masked_store => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
-        sym::simd_scatter => (3, 0, vec![param(0), param(1), param(2)], Ty::new_unit(tcx)),
-        sym::simd_insert => (2, 0, vec![param(0), tcx.types.u32, param(1)], param(0)),
-        sym::simd_extract => (2, 0, vec![param(0), tcx.types.u32], param(1)),
-        sym::simd_cast
-        | sym::simd_as
-        | sym::simd_cast_ptr
-        | sym::simd_expose_addr
-        | sym::simd_from_exposed_addr => (2, 0, vec![param(0)], param(1)),
-        sym::simd_bitmask => (2, 0, vec![param(0)], param(1)),
-        sym::simd_select | sym::simd_select_bitmask => {
-            (2, 0, vec![param(0), param(1), param(1)], param(1))
-        }
-        sym::simd_reduce_all | sym::simd_reduce_any => (1, 0, vec![param(0)], tcx.types.bool),
-        sym::simd_reduce_add_ordered | sym::simd_reduce_mul_ordered => {
-            (2, 0, vec![param(0), param(1)], param(1))
-        }
-        sym::simd_reduce_add_unordered
-        | sym::simd_reduce_mul_unordered
-        | sym::simd_reduce_and
-        | sym::simd_reduce_or
-        | sym::simd_reduce_xor
-        | sym::simd_reduce_min
-        | sym::simd_reduce_max => (2, 0, vec![param(0)], param(1)),
-        sym::simd_shuffle => (3, 0, vec![param(0), param(0), param(1)], param(2)),
-        sym::simd_shuffle_generic => (2, 1, vec![param(0), param(0)], param(1)),
-        _ => {
-            let msg = format!("unrecognized platform-specific intrinsic function: `{name}`");
-            tcx.dcx().span_err(span, msg);
-            return;
-        }
-    };
-
-    let sig = tcx.mk_fn_sig(inputs, output, false, hir::Unsafety::Unsafe, Abi::PlatformIntrinsic);
-    let sig = ty::Binder::dummy(sig);
-    equate_intrinsic_type(tcx, span, intrinsic_id, n_tps, 0, n_cts, sig)
-}
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 36a92a4cf7c..24280dbf0b3 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -142,7 +142,7 @@ fn get_owner_return_paths(
 /// as they must always be defined by the compiler.
 // FIXME: Move this to a more appropriate place.
 pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: Abi) {
-    if let Abi::RustIntrinsic | Abi::PlatformIntrinsic = abi {
+    if let Abi::RustIntrinsic = abi {
         tcx.dcx().span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index e9c9ec6ba53..126766ce278 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -1677,10 +1677,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
 
     // Feature gate SIMD types in FFI, since I am not sure that the
     // ABIs are handled at all correctly. -huonw
-    if abi != abi::Abi::RustIntrinsic
-        && abi != abi::Abi::PlatformIntrinsic
-        && !tcx.features().simd_ffi
-    {
+    if abi != abi::Abi::RustIntrinsic && !tcx.features().simd_ffi {
         let check = |ast_ty: &hir::Ty<'_>, ty: Ty<'_>| {
             if ty.is_simd() {
                 let snip = tcx
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 efde4e11c79..22beac14b24 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1331,7 +1331,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
             }
         }
 
-        self.tcx.dcx().span_bug(
+        self.tcx.dcx().span_delayed_bug(
             lifetime_ref.ident.span,
             format!("Could not resolve {:?} in scope {:#?}", lifetime_ref, self.scope,),
         );
diff --git a/compiler/rustc_hir_typeck/src/coercion.rs b/compiler/rustc_hir_typeck/src/coercion.rs
index 9f6175eac13..8f4f028fc07 100644
--- a/compiler/rustc_hir_typeck/src/coercion.rs
+++ b/compiler/rustc_hir_typeck/src/coercion.rs
@@ -44,6 +44,8 @@ use rustc_hir::Expr;
 use rustc_hir_analysis::astconv::AstConv;
 use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use rustc_infer::infer::{Coercion, DefineOpaqueTypes, InferOk, InferResult};
+use rustc_infer::traits::TraitEngine;
+use rustc_infer::traits::TraitEngineExt as _;
 use rustc_infer::traits::{Obligation, PredicateObligation};
 use rustc_middle::lint::in_external_macro;
 use rustc_middle::traits::BuiltinImplSource;
@@ -61,6 +63,7 @@ use rustc_target::spec::abi::Abi;
 use rustc_trait_selection::infer::InferCtxtExt as _;
 use rustc_trait_selection::traits::error_reporting::TypeErrCtxtExt as _;
 use rustc_trait_selection::traits::query::evaluate_obligation::InferCtxtExt;
+use rustc_trait_selection::traits::TraitEngineExt as _;
 use rustc_trait_selection::traits::{
     self, NormalizeExt, ObligationCause, ObligationCauseCode, ObligationCtxt,
 };
@@ -157,17 +160,19 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
             // In the new solver, lazy norm may allow us to shallowly equate
             // more types, but we emit possibly impossible-to-satisfy obligations.
             // Filter these cases out to make sure our coercion is more accurate.
-            if self.next_trait_solver() {
-                if let Ok(res) = &res {
-                    for obligation in &res.obligations {
-                        if !self.predicate_may_hold(obligation) {
-                            return Err(TypeError::Mismatch);
-                        }
+            match res {
+                Ok(InferOk { value, obligations }) if self.next_trait_solver() => {
+                    let mut fulfill_cx = <dyn TraitEngine<'tcx>>::new(self);
+                    fulfill_cx.register_predicate_obligations(self, obligations);
+                    let errs = fulfill_cx.select_where_possible(self);
+                    if errs.is_empty() {
+                        Ok(InferOk { value, obligations: fulfill_cx.pending_obligations() })
+                    } else {
+                        Err(TypeError::Mismatch)
                     }
                 }
+                res => res,
             }
-
-            res
         })
     }
 
@@ -625,19 +630,18 @@ impl<'f, 'tcx> Coerce<'f, 'tcx> {
         let traits = [coerce_unsized_did, unsize_did];
         while !queue.is_empty() {
             let obligation = queue.remove(0);
-            debug!("coerce_unsized resolve step: {:?}", obligation);
             let trait_pred = match obligation.predicate.kind().no_bound_vars() {
                 Some(ty::PredicateKind::Clause(ty::ClauseKind::Trait(trait_pred)))
                     if traits.contains(&trait_pred.def_id()) =>
                 {
-                    trait_pred
+                    self.resolve_vars_if_possible(trait_pred)
                 }
                 _ => {
                     coercion.obligations.push(obligation);
                     continue;
                 }
             };
-            let trait_pred = self.resolve_vars_if_possible(trait_pred);
+            debug!("coerce_unsized resolve step: {:?}", trait_pred);
             match selcx.select(&obligation.with(selcx.tcx(), trait_pred)) {
                 // Uncertain or unimplemented.
                 Ok(None) => {
@@ -1173,11 +1177,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         };
         if let (Some(a_sig), Some(b_sig)) = (a_sig, b_sig) {
             // Intrinsics are not coercible to function pointers.
-            if a_sig.abi() == Abi::RustIntrinsic
-                || a_sig.abi() == Abi::PlatformIntrinsic
-                || b_sig.abi() == Abi::RustIntrinsic
-                || b_sig.abi() == Abi::PlatformIntrinsic
-            {
+            if a_sig.abi() == Abi::RustIntrinsic || b_sig.abi() == Abi::RustIntrinsic {
                 return Err(TypeError::IntrinsicCast);
             }
             // The signature must match.
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
index 7d448820ceb..cc591fcf8c4 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/_impl.rs
@@ -1516,6 +1516,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// In case there is still ambiguity, the returned type may be an inference
     /// variable. This is different from `structurally_resolve_type` which errors
     /// in this case.
+    #[instrument(level = "debug", skip(self, sp), ret)]
     pub fn try_structurally_resolve_type(&self, sp: Span, ty: Ty<'tcx>) -> Ty<'tcx> {
         let ty = self.resolve_vars_with_obligations(ty);
 
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 7117a59c409..bdc796aca3a 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -804,10 +804,11 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
         let trait_ref = principal.with_self_ty(self.tcx, self_ty);
         self.elaborate_bounds(iter::once(trait_ref), |this, new_trait_ref, item| {
             if new_trait_ref.has_non_region_bound_vars() {
-                this.dcx().span_bug(
+                this.dcx().span_delayed_bug(
                     this.span,
                     "tried to select method from HRTB with non-lifetime bound vars",
                 );
+                return;
             }
 
             let new_trait_ref = this.instantiate_bound_regions_with_erased(new_trait_ref);
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 05b9479c7b0..cc09a094688 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -302,7 +302,23 @@ impl<'a, 'tcx> Trace<'a, 'tcx> {
         let Trace { at, trace, a_is_expected } = self;
         let mut fields = at.infcx.combine_fields(trace, at.param_env, define_opaque_types);
         fields
-            .equate(a_is_expected)
+            .equate(StructurallyRelateAliases::No, a_is_expected)
+            .relate(a, b)
+            .map(move |_| InferOk { value: (), obligations: fields.obligations })
+    }
+
+    /// Equates `a` and `b` while structurally relating aliases. This should only
+    /// be used inside of the next generation trait solver when relating rigid aliases.
+    #[instrument(skip(self), level = "debug")]
+    pub fn eq_structurally_relating_aliases<T>(self, a: T, b: T) -> InferResult<'tcx, ()>
+    where
+        T: Relate<'tcx>,
+    {
+        let Trace { at, trace, a_is_expected } = self;
+        debug_assert!(at.infcx.next_trait_solver());
+        let mut fields = at.infcx.combine_fields(trace, at.param_env, DefineOpaqueTypes::No);
+        fields
+            .equate(StructurallyRelateAliases::Yes, a_is_expected)
             .relate(a, b)
             .map(move |_| InferOk { value: (), obligations: fields.obligations })
     }
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index c30f42c1656..89dbc36906d 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -54,6 +54,7 @@ use self::region_constraints::{
     RegionConstraintCollector, RegionConstraintStorage, RegionSnapshot,
 };
 pub use self::relate::combine::CombineFields;
+pub use self::relate::StructurallyRelateAliases;
 use self::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 
 pub mod at;
diff --git a/compiler/rustc_infer/src/infer/relate/combine.rs b/compiler/rustc_infer/src/infer/relate/combine.rs
index f7690831c2a..0852bb4f993 100644
--- a/compiler/rustc_infer/src/infer/relate/combine.rs
+++ b/compiler/rustc_infer/src/infer/relate/combine.rs
@@ -26,6 +26,7 @@ use super::equate::Equate;
 use super::glb::Glb;
 use super::lub::Lub;
 use super::sub::Sub;
+use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, TypeTrace};
 use crate::traits::{Obligation, PredicateObligations};
 use rustc_middle::infer::canonical::OriginalQueryValues;
@@ -116,8 +117,15 @@ impl<'tcx> InferCtxt<'tcx> {
             }
 
             (_, ty::Alias(..)) | (ty::Alias(..), _) if self.next_trait_solver() => {
-                relation.register_type_relate_obligation(a, b);
-                Ok(a)
+                match relation.structurally_relate_aliases() {
+                    StructurallyRelateAliases::Yes => {
+                        ty::relate::structurally_relate_tys(relation, a, b)
+                    }
+                    StructurallyRelateAliases::No => {
+                        relation.register_type_relate_obligation(a, b);
+                        Ok(a)
+                    }
+                }
             }
 
             // All other cases of inference are errors
@@ -240,19 +248,26 @@ impl<'tcx> InferCtxt<'tcx> {
             (ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
                 if self.tcx.features().generic_const_exprs || self.next_trait_solver() =>
             {
-                let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
-
-                relation.register_predicates([if self.next_trait_solver() {
-                    ty::PredicateKind::AliasRelate(
-                        a.into(),
-                        b.into(),
-                        ty::AliasRelationDirection::Equate,
-                    )
-                } else {
-                    ty::PredicateKind::ConstEquate(a, b)
-                }]);
-
-                Ok(b)
+                match relation.structurally_relate_aliases() {
+                    StructurallyRelateAliases::No => {
+                        let (a, b) = if relation.a_is_expected() { (a, b) } else { (b, a) };
+
+                        relation.register_predicates([if self.next_trait_solver() {
+                            ty::PredicateKind::AliasRelate(
+                                a.into(),
+                                b.into(),
+                                ty::AliasRelationDirection::Equate,
+                            )
+                        } else {
+                            ty::PredicateKind::ConstEquate(a, b)
+                        }]);
+
+                        Ok(b)
+                    }
+                    StructurallyRelateAliases::Yes => {
+                        ty::relate::structurally_relate_consts(relation, a, b)
+                    }
+                }
             }
             _ => ty::relate::structurally_relate_consts(relation, a, b),
         }
@@ -303,8 +318,12 @@ impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
         self.infcx.tcx
     }
 
-    pub fn equate<'a>(&'a mut self, a_is_expected: bool) -> Equate<'a, 'infcx, 'tcx> {
-        Equate::new(self, a_is_expected)
+    pub fn equate<'a>(
+        &'a mut self,
+        structurally_relate_aliases: StructurallyRelateAliases,
+        a_is_expected: bool,
+    ) -> Equate<'a, 'infcx, 'tcx> {
+        Equate::new(self, structurally_relate_aliases, a_is_expected)
     }
 
     pub fn sub<'a>(&'a mut self, a_is_expected: bool) -> Sub<'a, 'infcx, 'tcx> {
@@ -335,6 +354,11 @@ pub trait ObligationEmittingRelation<'tcx>: TypeRelation<'tcx> {
 
     fn param_env(&self) -> ty::ParamEnv<'tcx>;
 
+    /// Whether aliases should be related structurally. This is pretty much
+    /// always `No` unless you're equating in some specific locations of the
+    /// new solver. See the comments in these use-cases for more details.
+    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases;
+
     /// Register obligations that must hold in order for this relation to hold
     fn register_obligations(&mut self, obligations: PredicateObligations<'tcx>);
 
diff --git a/compiler/rustc_infer/src/infer/relate/equate.rs b/compiler/rustc_infer/src/infer/relate/equate.rs
index aefa9a5a0d6..43d6aef3e15 100644
--- a/compiler/rustc_infer/src/infer/relate/equate.rs
+++ b/compiler/rustc_infer/src/infer/relate/equate.rs
@@ -1,4 +1,5 @@
 use super::combine::{CombineFields, ObligationEmittingRelation};
+use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, SubregionOrigin};
 use crate::traits::PredicateObligations;
 
@@ -13,15 +14,17 @@ use rustc_span::Span;
 /// Ensures `a` is made equal to `b`. Returns `a` on success.
 pub struct Equate<'combine, 'infcx, 'tcx> {
     fields: &'combine mut CombineFields<'infcx, 'tcx>,
+    structurally_relate_aliases: StructurallyRelateAliases,
     a_is_expected: bool,
 }
 
 impl<'combine, 'infcx, 'tcx> Equate<'combine, 'infcx, 'tcx> {
     pub fn new(
         fields: &'combine mut CombineFields<'infcx, 'tcx>,
+        structurally_relate_aliases: StructurallyRelateAliases,
         a_is_expected: bool,
     ) -> Equate<'combine, 'infcx, 'tcx> {
-        Equate { fields, a_is_expected }
+        Equate { fields, structurally_relate_aliases, a_is_expected }
     }
 }
 
@@ -99,7 +102,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: a_def_id, .. }),
                 &ty::Alias(ty::Opaque, ty::AliasTy { def_id: b_def_id, .. }),
             ) if a_def_id == b_def_id => {
-                self.fields.infcx.super_combine_tys(self, a, b)?;
+                infcx.super_combine_tys(self, a, b)?;
             }
             (&ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }), _)
             | (_, &ty::Alias(ty::Opaque, ty::AliasTy { def_id, .. }))
@@ -120,7 +123,7 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
                 );
             }
             _ => {
-                self.fields.infcx.super_combine_tys(self, a, b)?;
+                infcx.super_combine_tys(self, a, b)?;
             }
         }
 
@@ -180,6 +183,10 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Equate<'_, '_, 'tcx> {
         self.fields.trace.span()
     }
 
+    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
+        self.structurally_relate_aliases
+    }
+
     fn param_env(&self) -> ty::ParamEnv<'tcx> {
         self.fields.param_env
     }
diff --git a/compiler/rustc_infer/src/infer/relate/generalize.rs b/compiler/rustc_infer/src/infer/relate/generalize.rs
index 2e1ea19078c..e84d4ceaea8 100644
--- a/compiler/rustc_infer/src/infer/relate/generalize.rs
+++ b/compiler/rustc_infer/src/infer/relate/generalize.rs
@@ -1,5 +1,6 @@
 use std::mem;
 
+use super::StructurallyRelateAliases;
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind, TypeVariableValue};
 use crate::infer::{InferCtxt, ObligationEmittingRelation, RegionVariableOrigin};
 use rustc_data_structures::sso::SsoHashMap;
@@ -45,8 +46,14 @@ impl<'tcx> InferCtxt<'tcx> {
         // region/type inference variables.
         //
         // We then relate `generalized_ty <: source_ty`,adding constraints like `'x: '?2` and `?1 <: ?3`.
-        let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } =
-            self.generalize(relation.span(), target_vid, instantiation_variance, source_ty)?;
+        let Generalization { value_may_be_infer: generalized_ty, has_unconstrained_ty_var } = self
+            .generalize(
+                relation.span(),
+                relation.structurally_relate_aliases(),
+                target_vid,
+                instantiation_variance,
+                source_ty,
+            )?;
 
         // Constrain `b_vid` to the generalized type `generalized_ty`.
         if let &ty::Infer(ty::TyVar(generalized_vid)) = generalized_ty.kind() {
@@ -178,8 +185,14 @@ impl<'tcx> InferCtxt<'tcx> {
     ) -> RelateResult<'tcx, ()> {
         // FIXME(generic_const_exprs): Occurs check failures for unevaluated
         // constants and generic expressions are not yet handled correctly.
-        let Generalization { value_may_be_infer: generalized_ct, has_unconstrained_ty_var } =
-            self.generalize(relation.span(), target_vid, ty::Variance::Invariant, source_ct)?;
+        let Generalization { value_may_be_infer: generalized_ct, has_unconstrained_ty_var } = self
+            .generalize(
+                relation.span(),
+                relation.structurally_relate_aliases(),
+                target_vid,
+                ty::Variance::Invariant,
+                source_ct,
+            )?;
 
         debug_assert!(!generalized_ct.is_ct_infer());
         if has_unconstrained_ty_var {
@@ -217,6 +230,7 @@ impl<'tcx> InferCtxt<'tcx> {
     fn generalize<T: Into<Term<'tcx>> + Relate<'tcx>>(
         &self,
         span: Span,
+        structurally_relate_aliases: StructurallyRelateAliases,
         target_vid: impl Into<ty::TermVid>,
         ambient_variance: ty::Variance,
         source_term: T,
@@ -237,6 +251,7 @@ impl<'tcx> InferCtxt<'tcx> {
         let mut generalizer = Generalizer {
             infcx: self,
             span,
+            structurally_relate_aliases,
             root_vid,
             for_universe,
             ambient_variance,
@@ -270,6 +285,10 @@ struct Generalizer<'me, 'tcx> {
 
     span: Span,
 
+    /// Whether aliases should be related structurally. If not, we have to
+    /// be careful when generalizing aliases.
+    structurally_relate_aliases: StructurallyRelateAliases,
+
     /// The vid of the type variable that is in the process of being
     /// instantiated. If we find this within the value we are folding,
     /// that means we would have created a cyclic value.
@@ -314,13 +333,30 @@ impl<'tcx> Generalizer<'_, 'tcx> {
     /// to normalize the alias after all.
     ///
     /// We handle this by lazily equating the alias and generalizing
-    /// it to an inference variable.
+    /// it to an inference variable. In the new solver, we always
+    /// generalize to an infer var unless the alias contains escaping
+    /// bound variables.
     ///
-    /// This is incomplete and will hopefully soon get fixed by #119106.
+    /// Correctly handling aliases with escaping bound variables is
+    /// difficult and currently incomplete in two opposite ways:
+    /// - if we get an occurs check failure in the alias, replace it with a new infer var.
+    ///   This causes us to later emit an alias-relate goal and is incomplete in case the
+    ///   alias normalizes to type containing one of the bound variables.
+    /// - if the alias contains an inference variable not nameable by `for_universe`, we
+    ///   continue generalizing the alias. This ends up pulling down the universe of the
+    ///   inference variable and is incomplete in case the alias would normalize to a type
+    ///   which does not mention that inference variable.
     fn generalize_alias_ty(
         &mut self,
         alias: ty::AliasTy<'tcx>,
     ) -> Result<Ty<'tcx>, TypeError<'tcx>> {
+        if self.infcx.next_trait_solver() && !alias.has_escaping_bound_vars() {
+            return Ok(self.infcx.next_ty_var_in_universe(
+                TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span: self.span },
+                self.for_universe,
+            ));
+        }
+
         let is_nested_alias = mem::replace(&mut self.in_alias, true);
         let result = match self.relate(alias, alias) {
             Ok(alias) => Ok(alias.to_ty(self.tcx())),
@@ -490,7 +526,10 @@ impl<'tcx> TypeRelation<'tcx> for Generalizer<'_, 'tcx> {
                 }
             }
 
-            ty::Alias(_, data) => self.generalize_alias_ty(data),
+            ty::Alias(_, data) => match self.structurally_relate_aliases {
+                StructurallyRelateAliases::No => self.generalize_alias_ty(data),
+                StructurallyRelateAliases::Yes => relate::structurally_relate_tys(self, t, t),
+            },
 
             _ => relate::structurally_relate_tys(self, t, t),
         }?;
diff --git a/compiler/rustc_infer/src/infer/relate/glb.rs b/compiler/rustc_infer/src/infer/relate/glb.rs
index 6cf51354599..52a2f4c7347 100644
--- a/compiler/rustc_infer/src/infer/relate/glb.rs
+++ b/compiler/rustc_infer/src/infer/relate/glb.rs
@@ -6,6 +6,7 @@ use rustc_span::Span;
 
 use super::combine::{CombineFields, ObligationEmittingRelation};
 use super::lattice::{self, LatticeDir};
+use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 use crate::traits::{ObligationCause, PredicateObligations};
 
@@ -45,7 +46,9 @@ impl<'tcx> TypeRelation<'tcx> for Glb<'_, '_, 'tcx> {
         b: T,
     ) -> RelateResult<'tcx, T> {
         match variance {
-            ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
+            ty::Invariant => {
+                self.fields.equate(StructurallyRelateAliases::No, self.a_is_expected).relate(a, b)
+            }
             ty::Covariant => self.relate(a, b),
             // FIXME(#41044) -- not correct, need test
             ty::Bivariant => Ok(a),
@@ -139,6 +142,10 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Glb<'_, '_, 'tcx> {
         self.fields.trace.span()
     }
 
+    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
+        StructurallyRelateAliases::No
+    }
+
     fn param_env(&self) -> ty::ParamEnv<'tcx> {
         self.fields.param_env
     }
diff --git a/compiler/rustc_infer/src/infer/relate/lub.rs b/compiler/rustc_infer/src/infer/relate/lub.rs
index 5b4f80fd73a..fa0da64ca65 100644
--- a/compiler/rustc_infer/src/infer/relate/lub.rs
+++ b/compiler/rustc_infer/src/infer/relate/lub.rs
@@ -2,6 +2,7 @@
 
 use super::combine::{CombineFields, ObligationEmittingRelation};
 use super::lattice::{self, LatticeDir};
+use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, InferCtxt, SubregionOrigin};
 use crate::traits::{ObligationCause, PredicateObligations};
 
@@ -45,7 +46,9 @@ impl<'tcx> TypeRelation<'tcx> for Lub<'_, '_, 'tcx> {
         b: T,
     ) -> RelateResult<'tcx, T> {
         match variance {
-            ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
+            ty::Invariant => {
+                self.fields.equate(StructurallyRelateAliases::No, self.a_is_expected).relate(a, b)
+            }
             ty::Covariant => self.relate(a, b),
             // FIXME(#41044) -- not correct, need test
             ty::Bivariant => Ok(a),
@@ -139,6 +142,10 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Lub<'_, '_, 'tcx> {
         self.fields.trace.span()
     }
 
+    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
+        StructurallyRelateAliases::No
+    }
+
     fn param_env(&self) -> ty::ParamEnv<'tcx> {
         self.fields.param_env
     }
diff --git a/compiler/rustc_infer/src/infer/relate/mod.rs b/compiler/rustc_infer/src/infer/relate/mod.rs
index 1207377e857..8619cc502ad 100644
--- a/compiler/rustc_infer/src/infer/relate/mod.rs
+++ b/compiler/rustc_infer/src/infer/relate/mod.rs
@@ -9,3 +9,15 @@ mod higher_ranked;
 mod lattice;
 mod lub;
 mod sub;
+
+/// Whether aliases should be related structurally or not. Used
+/// to adjust the behavior of generalization and combine.
+///
+/// This should always be `No` unless in a few special-cases when
+/// instantiating canonical responses and in the new solver. Each
+/// such case should have a comment explaining why it is used.
+#[derive(Debug, Copy, Clone)]
+pub enum StructurallyRelateAliases {
+    Yes,
+    No,
+}
diff --git a/compiler/rustc_infer/src/infer/relate/sub.rs b/compiler/rustc_infer/src/infer/relate/sub.rs
index 5bd3a238a67..2cc8d0d3b10 100644
--- a/compiler/rustc_infer/src/infer/relate/sub.rs
+++ b/compiler/rustc_infer/src/infer/relate/sub.rs
@@ -1,4 +1,5 @@
 use super::combine::CombineFields;
+use super::StructurallyRelateAliases;
 use crate::infer::{DefineOpaqueTypes, ObligationEmittingRelation, SubregionOrigin};
 use crate::traits::{Obligation, PredicateObligations};
 
@@ -64,7 +65,9 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
         b: T,
     ) -> RelateResult<'tcx, T> {
         match variance {
-            ty::Invariant => self.fields.equate(self.a_is_expected).relate(a, b),
+            ty::Invariant => {
+                self.fields.equate(StructurallyRelateAliases::No, self.a_is_expected).relate(a, b)
+            }
             ty::Covariant => self.relate(a, b),
             ty::Bivariant => Ok(a),
             ty::Contravariant => self.with_expected_switched(|this| this.relate(b, a)),
@@ -204,6 +207,10 @@ impl<'tcx> ObligationEmittingRelation<'tcx> for Sub<'_, '_, 'tcx> {
         self.fields.trace.span()
     }
 
+    fn structurally_relate_aliases(&self) -> StructurallyRelateAliases {
+        StructurallyRelateAliases::No
+    }
+
     fn param_env(&self) -> ty::ParamEnv<'tcx> {
         self.fields.param_env
     }
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index f89cb8ed8b6..63e2fe47659 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -244,9 +244,28 @@ lint_hidden_unicode_codepoints = unicode codepoint changing visible direction of
 lint_identifier_non_ascii_char = identifier contains non-ASCII characters
 
 lint_identifier_uncommon_codepoints = identifier contains {$codepoints_len ->
-    [one] an uncommon Unicode codepoint
-    *[other] uncommon Unicode codepoints
+    [one] { $identifier_type ->
+        [Exclusion] a character from an archaic script
+        [Technical] a character that is for non-linguistic, specialized usage
+        [Limited_Use] a character from a script in limited use
+        [Not_NFKC] a non normalized (NFKC) character
+        *[other] an uncommon character
+    }
+    *[other] { $identifier_type ->
+        [Exclusion] {$codepoints_len} characters from archaic scripts
+        [Technical] {$codepoints_len} characters that are for non-linguistic, specialized usage
+        [Limited_Use] {$codepoints_len} characters from scripts in limited use
+        [Not_NFKC] {$codepoints_len} non normalized (NFKC) characters
+        *[other] uncommon characters
+    }
 }: {$codepoints}
+    .note = {$codepoints_len ->
+        [one] this character is
+        *[other] these characters are
+    } included in the{$identifier_type ->
+        [Restricted] {""}
+        *[other] {" "}{$identifier_type}
+    } Unicode general security profile
 
 lint_ignored_unless_crate_specified = {$level}({$name}) is ignored unless specified at crate level
 
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index 0e446e09d41..d5e5e0ec224 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -31,6 +31,7 @@
 #![feature(array_windows)]
 #![feature(box_patterns)]
 #![feature(control_flow_enum)]
+#![feature(extract_if)]
 #![feature(generic_nonzero)]
 #![feature(if_let_guard)]
 #![feature(iter_order_by)]
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index d8a0b75f8bd..80231d2e68a 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -1129,9 +1129,11 @@ pub struct IdentifierNonAsciiChar;
 
 #[derive(LintDiagnostic)]
 #[diag(lint_identifier_uncommon_codepoints)]
+#[note]
 pub struct IdentifierUncommonCodepoints {
     pub codepoints: Vec<char>,
     pub codepoints_len: usize,
+    pub identifier_type: &'static str,
 }
 
 #[derive(LintDiagnostic)]
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index e112cd6915c..5e66ade0357 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -7,6 +7,7 @@ use rustc_ast as ast;
 use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::unord::UnordMap;
 use rustc_span::symbol::Symbol;
+use unicode_security::general_security_profile::IdentifierType;
 
 declare_lint! {
     /// The `non_ascii_idents` lint detects non-ASCII identifiers.
@@ -189,17 +190,47 @@ impl EarlyLintPass for NonAsciiIdents {
             if check_uncommon_codepoints
                 && !symbol_str.chars().all(GeneralSecurityProfile::identifier_allowed)
             {
-                let codepoints: Vec<_> = symbol_str
+                let mut chars: Vec<_> = symbol_str
                     .chars()
-                    .filter(|c| !GeneralSecurityProfile::identifier_allowed(*c))
+                    .map(|c| (c, GeneralSecurityProfile::identifier_type(c)))
                     .collect();
-                let codepoints_len = codepoints.len();
 
-                cx.emit_span_lint(
-                    UNCOMMON_CODEPOINTS,
-                    sp,
-                    IdentifierUncommonCodepoints { codepoints, codepoints_len },
-                );
+                for (id_ty, id_ty_descr) in [
+                    (IdentifierType::Exclusion, "Exclusion"),
+                    (IdentifierType::Technical, "Technical"),
+                    (IdentifierType::Limited_Use, "Limited_Use"),
+                    (IdentifierType::Not_NFKC, "Not_NFKC"),
+                ] {
+                    let codepoints: Vec<_> =
+                        chars.extract_if(|(_, ty)| *ty == Some(id_ty)).collect();
+                    if codepoints.is_empty() {
+                        continue;
+                    }
+                    cx.emit_span_lint(
+                        UNCOMMON_CODEPOINTS,
+                        sp,
+                        IdentifierUncommonCodepoints {
+                            codepoints_len: codepoints.len(),
+                            codepoints: codepoints.into_iter().map(|(c, _)| c).collect(),
+                            identifier_type: id_ty_descr,
+                        },
+                    );
+                }
+
+                let remaining = chars
+                    .extract_if(|(c, _)| !GeneralSecurityProfile::identifier_allowed(*c))
+                    .collect::<Vec<_>>();
+                if !remaining.is_empty() {
+                    cx.emit_span_lint(
+                        UNCOMMON_CODEPOINTS,
+                        sp,
+                        IdentifierUncommonCodepoints {
+                            codepoints_len: remaining.len(),
+                            codepoints: remaining.into_iter().map(|(c, _)| c).collect(),
+                            identifier_type: "Restricted",
+                        },
+                    );
+                }
             }
         }
 
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index e4ebae2a973..2ea891ce04d 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1587,10 +1587,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
     }
 
     fn is_internal_abi(&self, abi: SpecAbi) -> bool {
-        matches!(
-            abi,
-            SpecAbi::Rust | SpecAbi::RustCall | SpecAbi::RustIntrinsic | SpecAbi::PlatformIntrinsic
-        )
+        matches!(abi, SpecAbi::Rust | SpecAbi::RustCall | SpecAbi::RustIntrinsic)
     }
 
     /// Find any fn-ptr types with external ABIs in `ty`.
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 35ee0c53046..3481c66da70 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -758,7 +758,7 @@ trait UnusedDelimLint {
         }
         impl<'ast> Visitor<'ast> for ErrExprVisitor {
             fn visit_expr(&mut self, expr: &'ast ast::Expr) {
-                if let ExprKind::Err = expr.kind {
+                if let ExprKind::Err(_) = expr.kind {
                     self.has_error = true;
                     return;
                 }
diff --git a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
index 54fdc84c77d..40723ff9f5e 100644
--- a/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/ArchiveWrapper.cpp
@@ -67,7 +67,7 @@ typedef RustArchiveIterator *LLVMRustArchiveIteratorRef;
 
 extern "C" LLVMRustArchiveRef LLVMRustOpenArchive(char *Path) {
   ErrorOr<std::unique_ptr<MemoryBuffer>> BufOr =
-      MemoryBuffer::getFile(Path, -1, false);
+      MemoryBuffer::getFile(Path, /*IsText*/false, /*RequiresNullTerminator=*/false);
   if (!BufOr) {
     LLVMRustSetLastError(BufOr.getError().message().c_str());
     return nullptr;
diff --git a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
index af2353fbb19..cb7cce4da0d 100644
--- a/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
+++ b/compiler/rustc_llvm/llvm-wrapper/RustWrapper.cpp
@@ -1262,7 +1262,7 @@ enum class LLVMRustDiagnosticLevel {
 extern "C" void
 LLVMRustUnpackInlineAsmDiagnostic(LLVMDiagnosticInfoRef DI,
                                   LLVMRustDiagnosticLevel *LevelOut,
-                                  unsigned *CookieOut,
+                                  uint64_t *CookieOut,
                                   LLVMTwineRef *MessageOut) {
   // Undefined to call this not on an inline assembly diagnostic!
   llvm::DiagnosticInfoInlineAsm *IA =
diff --git a/compiler/rustc_metadata/src/native_libs.rs b/compiler/rustc_metadata/src/native_libs.rs
index 5e20a03bbc0..cdcc586b09e 100644
--- a/compiler/rustc_metadata/src/native_libs.rs
+++ b/compiler/rustc_metadata/src/native_libs.rs
@@ -99,7 +99,7 @@ impl<'tcx> Collector<'tcx> {
 
         let sess = self.tcx.sess;
 
-        if matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic) {
+        if matches!(abi, Abi::Rust | Abi::RustIntrinsic) {
             return;
         }
 
diff --git a/compiler/rustc_middle/src/traits/solve/inspect.rs b/compiler/rustc_middle/src/traits/solve/inspect.rs
index e94ad4aa539..90180af3b16 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect.rs
@@ -58,8 +58,6 @@ pub struct GoalEvaluation<'tcx> {
     pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
     pub kind: GoalEvaluationKind<'tcx>,
     pub evaluation: CanonicalGoalEvaluation<'tcx>,
-    /// The nested goals from instantiating the query response.
-    pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
 }
 
 #[derive(Eq, PartialEq)]
diff --git a/compiler/rustc_middle/src/traits/solve/inspect/format.rs b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
index 54db8dbd336..89c5eb517e5 100644
--- a/compiler/rustc_middle/src/traits/solve/inspect/format.rs
+++ b/compiler/rustc_middle/src/traits/solve/inspect/format.rs
@@ -48,20 +48,7 @@ impl<'a, 'b> ProofTreeFormatter<'a, 'b> {
             },
         };
         writeln!(self.f, "{}: {:?}", goal_text, eval.uncanonicalized_goal)?;
-        self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))?;
-        if eval.returned_goals.len() > 0 {
-            writeln!(self.f, "NESTED GOALS ADDED TO CALLER: [")?;
-            self.nested(|this| {
-                for goal in eval.returned_goals.iter() {
-                    writeln!(this.f, "ADDED GOAL: {goal:?},")?;
-                }
-                Ok(())
-            })?;
-
-            writeln!(self.f, "]")
-        } else {
-            Ok(())
-        }
+        self.nested(|this| this.format_canonical_goal_evaluation(&eval.evaluation))
     }
 
     pub(super) fn format_canonical_goal_evaluation(
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index c1e33fe114f..38aca3326d3 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1244,7 +1244,6 @@ pub fn fn_can_unwind(tcx: TyCtxt<'_>, fn_def_id: Option<DefId>, abi: SpecAbi) ->
         | RiscvInterruptS
         | CCmseNonSecureCall
         | Wasm
-        | PlatformIntrinsic
         | Unadjusted => false,
         Rust | RustCall | RustCold | RustIntrinsic => {
             tcx.sess.panic_strategy() == PanicStrategy::Unwind
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index 72a1905c147..5ead620927c 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1643,7 +1643,7 @@ pub fn is_doc_notable_trait(tcx: TyCtxt<'_>, def_id: DefId) -> bool {
 
 /// Determines whether an item is an intrinsic by Abi. or by whether it has a `rustc_intrinsic` attribute
 pub fn intrinsic(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<Symbol> {
-    if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic | Abi::PlatformIntrinsic)
+    if matches!(tcx.fn_sig(def_id).skip_binder().abi(), Abi::RustIntrinsic)
         || tcx.has_attr(def_id, sym::rustc_intrinsic)
     {
         Some(tcx.item_name(def_id.into()))
diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
index 663abbece85..0dc06524c79 100644
--- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
+++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs
@@ -34,7 +34,6 @@ fn abi_can_unwind(abi: Abi) -> bool {
         | CCmseNonSecureCall
         | Wasm
         | RustIntrinsic
-        | PlatformIntrinsic
         | Unadjusted => false,
         Rust | RustCall | RustCold => true,
     }
diff --git a/compiler/rustc_next_trait_solver/src/canonicalizer.rs b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
index cd434fecce2..7b73e2aebf0 100644
--- a/compiler/rustc_next_trait_solver/src/canonicalizer.rs
+++ b/compiler/rustc_next_trait_solver/src/canonicalizer.rs
@@ -108,21 +108,22 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
         // universes `n`, this algorithm compresses them in place so that:
         //
         // - the new universe indices are as small as possible
-        // - we only create a new universe if we would otherwise put a placeholder in
-        //   the same compressed universe as an existential which cannot name it
+        // - we create a new universe if we would otherwise
+        //   1. put existentials from a different universe into the same one
+        //   2. put a placeholder in the same universe as an existential which cannot name it
         //
         // Let's walk through an example:
         // - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 0
         // - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 0, next_orig_uv: 1
         // - var_infos: [E0, U1, E5, U2, E2, E6, U6], curr_compressed_uv: 1, next_orig_uv: 2
         // - var_infos: [E0, U1, E5, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 5
-        // - var_infos: [E0, U1, E1, U1, E1, E6, U6], curr_compressed_uv: 1, next_orig_uv: 6
-        // - var_infos: [E0, U1, E1, U1, E1, E2, U2], curr_compressed_uv: 2, next_orig_uv: -
+        // - var_infos: [E0, U1, E2, U1, E1, E6, U6], curr_compressed_uv: 2, next_orig_uv: 6
+        // - var_infos: [E0, U1, E1, U1, E1, E3, U3], curr_compressed_uv: 2, next_orig_uv: -
         //
         // This algorithm runs in `O(n²)` where `n` is the number of different universe
         // indices in the input. This should be fine as `n` is expected to be small.
         let mut curr_compressed_uv = ty::UniverseIndex::ROOT;
-        let mut existential_in_new_uv = false;
+        let mut existential_in_new_uv = None;
         let mut next_orig_uv = Some(ty::UniverseIndex::ROOT);
         while let Some(orig_uv) = next_orig_uv.take() {
             let mut update_uv = |var: &mut CanonicalVarInfo<I>, orig_uv, is_existential| {
@@ -131,14 +132,29 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
                     Ordering::Less => (), // Already updated
                     Ordering::Equal => {
                         if is_existential {
-                            existential_in_new_uv = true;
-                        } else if existential_in_new_uv {
+                            if existential_in_new_uv.is_some_and(|uv| uv < orig_uv) {
+                                // Condition 1.
+                                //
+                                // We already put an existential from a outer universe
+                                // into the current compressed universe, so we need to
+                                // create a new one.
+                                curr_compressed_uv = curr_compressed_uv.next_universe();
+                            }
+
+                            // `curr_compressed_uv` will now contain an existential from
+                            // `orig_uv`. Trying to canonicalizing an existential from
+                            // a higher universe has to therefore use a new compressed
+                            // universe.
+                            existential_in_new_uv = Some(orig_uv);
+                        } else if existential_in_new_uv.is_some() {
+                            // Condition 2.
+                            //
                             //  `var` is a placeholder from a universe which is not nameable
                             // by an existential which we already put into the compressed
                             // universe `curr_compressed_uv`. We therefore have to create a
                             // new universe for `var`.
                             curr_compressed_uv = curr_compressed_uv.next_universe();
-                            existential_in_new_uv = false;
+                            existential_in_new_uv = None;
                         }
 
                         *var = var.with_updated_universe(curr_compressed_uv);
@@ -174,8 +190,14 @@ impl<'a, Infcx: InferCtxtLike<Interner = I>, I: Interner> Canonicalizer<'a, Infc
             }
         }
 
+        // We uniquify regions and always put them into their own universe
+        let mut first_region = true;
         for var in var_infos.iter_mut() {
             if var.is_region() {
+                if first_region {
+                    first_region = false;
+                    curr_compressed_uv = curr_compressed_uv.next_universe();
+                }
                 assert!(var.is_existential());
                 *var = var.with_updated_universe(curr_compressed_uv);
             }
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 517e3d82787..995e140b329 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -744,7 +744,8 @@ impl<'a> Parser<'a> {
         Err(err)
     }
 
-    pub(super) fn attr_on_non_tail_expr(&self, expr: &Expr) {
+    /// The user has written `#[attr] expr` which is unsupported. (#106020)
+    pub(super) fn attr_on_non_tail_expr(&self, expr: &Expr) -> ErrorGuaranteed {
         // Missing semicolon typo error.
         let span = self.prev_token.span.shrink_to_hi();
         let mut err = self.dcx().create_err(ExpectedSemi {
@@ -787,6 +788,8 @@ impl<'a> Parser<'a> {
                 ],
                 Applicability::MachineApplicable,
             );
+
+            // Special handling for `#[cfg(...)]` chains
             let mut snapshot = self.create_snapshot_for_diagnostic();
             if let [attr] = &expr.attrs[..]
                 && let ast::AttrKind::Normal(attr_kind) = &attr.kind
@@ -797,9 +800,8 @@ impl<'a> Parser<'a> {
                 {
                     Ok(next_attr) => next_attr,
                     Err(inner_err) => {
-                        err.cancel();
                         inner_err.cancel();
-                        return;
+                        return err.emit();
                     }
                 }
                 && let ast::AttrKind::Normal(next_attr_kind) = next_attr.kind
@@ -810,9 +812,8 @@ impl<'a> Parser<'a> {
                 let next_expr = match snapshot.parse_expr() {
                     Ok(next_expr) => next_expr,
                     Err(inner_err) => {
-                        err.cancel();
                         inner_err.cancel();
-                        return;
+                        return err.emit();
                     }
                 };
                 // We have for sure
@@ -845,7 +846,7 @@ impl<'a> Parser<'a> {
                 );
             }
         }
-        err.emit();
+        err.emit()
     }
 
     fn check_too_many_raw_str_terminators(&mut self, err: &mut DiagnosticBuilder<'_>) -> bool {
@@ -921,10 +922,10 @@ impl<'a> Parser<'a> {
                     // fn foo() -> Foo { Path {
                     //     field: value,
                     // } }
-                    err.delay_as_bug();
+                    let guar = err.delay_as_bug();
                     self.restore_snapshot(snapshot);
                     let mut tail = self.mk_block(
-                        thin_vec![self.mk_stmt_err(expr.span)],
+                        thin_vec![self.mk_stmt_err(expr.span, guar)],
                         s,
                         lo.to(self.prev_token.span),
                     );
@@ -990,7 +991,7 @@ impl<'a> Parser<'a> {
         decl_hi: Span,
     ) -> PResult<'a, P<Expr>> {
         err.span_label(lo.to(decl_hi), "while parsing the body of this closure");
-        match before.kind {
+        let guar = match before.kind {
             token::OpenDelim(Delimiter::Brace)
                 if !matches!(token.kind, token::OpenDelim(Delimiter::Brace)) =>
             {
@@ -1004,8 +1005,9 @@ impl<'a> Parser<'a> {
                     ],
                     Applicability::MaybeIncorrect,
                 );
-                err.emit();
+                let guar = err.emit();
                 self.eat_to_tokens(&[&token::CloseDelim(Delimiter::Brace)]);
+                guar
             }
             token::OpenDelim(Delimiter::Parenthesis)
                 if !matches!(token.kind, token::OpenDelim(Delimiter::Brace)) =>
@@ -1022,7 +1024,7 @@ impl<'a> Parser<'a> {
                     ],
                     Applicability::MaybeIncorrect,
                 );
-                err.emit();
+                err.emit()
             }
             _ if !matches!(token.kind, token::OpenDelim(Delimiter::Brace)) => {
                 // We don't have a heuristic to correctly identify where the block
@@ -1035,8 +1037,8 @@ impl<'a> Parser<'a> {
                 return Err(err);
             }
             _ => return Err(err),
-        }
-        Ok(self.mk_expr_err(lo.to(self.token.span)))
+        };
+        Ok(self.mk_expr_err(lo.to(self.token.span), guar))
     }
 
     /// Eats and discards tokens until one of `kets` is encountered. Respects token trees,
@@ -1214,7 +1216,7 @@ impl<'a> Parser<'a> {
         &mut self,
         mut e: DiagnosticBuilder<'a>,
         expr: &mut P<Expr>,
-    ) -> PResult<'a, ()> {
+    ) -> PResult<'a, ErrorGuaranteed> {
         if let ExprKind::Binary(binop, _, _) = &expr.kind
             && let ast::BinOpKind::Lt = binop.node
             && self.eat(&token::Comma)
@@ -1239,9 +1241,9 @@ impl<'a> Parser<'a> {
                                 // The subsequent expression is valid. Mark
                                 // `expr` as erroneous and emit `e` now, but
                                 // return `Ok` so parsing can continue.
-                                e.emit();
-                                *expr = self.mk_expr_err(expr.span.to(self.prev_token.span));
-                                return Ok(());
+                                let guar = e.emit();
+                                *expr = self.mk_expr_err(expr.span.to(self.prev_token.span), guar);
+                                return Ok(guar);
                             }
                             Err(err) => {
                                 err.cancel();
@@ -1393,7 +1395,8 @@ impl<'a> Parser<'a> {
             outer_op.node,
         );
 
-        let mk_err_expr = |this: &Self, span| Ok(Some(this.mk_expr(span, ExprKind::Err)));
+        let mk_err_expr =
+            |this: &Self, span, guar| Ok(Some(this.mk_expr(span, ExprKind::Err(guar))));
 
         match &inner_op.kind {
             ExprKind::Binary(op, l1, r1) if op.node.is_comparison() => {
@@ -1443,11 +1446,11 @@ impl<'a> Parser<'a> {
                         match self.parse_expr() {
                             Ok(_) => {
                                 // 99% certain that the suggestion is correct, continue parsing.
-                                self.dcx().emit_err(err);
+                                let guar = self.dcx().emit_err(err);
                                 // FIXME: actually check that the two expressions in the binop are
                                 // paths and resynthesize new fn call expression instead of using
                                 // `ExprKind::Err` placeholder.
-                                mk_err_expr(self, inner_op.span.to(self.prev_token.span))
+                                mk_err_expr(self, inner_op.span.to(self.prev_token.span), guar)
                             }
                             Err(expr_err) => {
                                 expr_err.cancel();
@@ -1471,11 +1474,11 @@ impl<'a> Parser<'a> {
                         match self.consume_fn_args() {
                             Err(()) => Err(self.dcx().create_err(err)),
                             Ok(()) => {
-                                self.dcx().emit_err(err);
+                                let guar = self.dcx().emit_err(err);
                                 // FIXME: actually check that the two expressions in the binop are
                                 // paths and resynthesize new fn call expression instead of using
                                 // `ExprKind::Err` placeholder.
-                                mk_err_expr(self, inner_op.span.to(self.prev_token.span))
+                                mk_err_expr(self, inner_op.span.to(self.prev_token.span), guar)
                             }
                         }
                     } else {
@@ -1492,8 +1495,8 @@ impl<'a> Parser<'a> {
                         let recovered = self
                             .attempt_chained_comparison_suggestion(&mut err, inner_op, outer_op);
                         if matches!(recovered, Recovered::Yes) {
-                            self.dcx().emit_err(err);
-                            mk_err_expr(self, inner_op.span.to(self.prev_token.span))
+                            let guar = self.dcx().emit_err(err);
+                            mk_err_expr(self, inner_op.span.to(self.prev_token.span), guar)
                         } else {
                             // These cases cause too many knock-down errors, bail out (#61329).
                             Err(self.dcx().create_err(err))
@@ -1502,9 +1505,9 @@ impl<'a> Parser<'a> {
                 }
                 let recover =
                     self.attempt_chained_comparison_suggestion(&mut err, inner_op, outer_op);
-                self.dcx().emit_err(err);
+                let guar = self.dcx().emit_err(err);
                 if matches!(recover, Recovered::Yes) {
-                    return mk_err_expr(self, inner_op.span.to(self.prev_token.span));
+                    return mk_err_expr(self, inner_op.span.to(self.prev_token.span), guar);
                 }
             }
             _ => {}
@@ -1925,8 +1928,8 @@ impl<'a> Parser<'a> {
         } else {
             self.recover_await_prefix(await_sp)?
         };
-        let sp = self.error_on_incorrect_await(lo, hi, &expr, is_question);
-        let expr = self.mk_expr(lo.to(sp), ExprKind::Err);
+        let (sp, guar) = self.error_on_incorrect_await(lo, hi, &expr, is_question);
+        let expr = self.mk_expr_err(lo.to(sp), guar);
         self.maybe_recover_from_bad_qpath(expr)
     }
 
@@ -1955,21 +1958,27 @@ impl<'a> Parser<'a> {
         Ok((expr.span, expr, is_question))
     }
 
-    fn error_on_incorrect_await(&self, lo: Span, hi: Span, expr: &Expr, is_question: bool) -> Span {
+    fn error_on_incorrect_await(
+        &self,
+        lo: Span,
+        hi: Span,
+        expr: &Expr,
+        is_question: bool,
+    ) -> (Span, ErrorGuaranteed) {
         let span = lo.to(hi);
         let applicability = match expr.kind {
             ExprKind::Try(_) => Applicability::MaybeIncorrect, // `await <expr>?`
             _ => Applicability::MachineApplicable,
         };
 
-        self.dcx().emit_err(IncorrectAwait {
+        let guar = self.dcx().emit_err(IncorrectAwait {
             span,
             sugg_span: (span, applicability),
             expr: self.span_to_snippet(expr.span).unwrap_or_else(|_| pprust::expr_to_string(expr)),
             question_mark: if is_question { "?" } else { "" },
         });
 
-        span
+        (span, guar)
     }
 
     /// If encountering `future.await()`, consumes and emits an error.
@@ -2013,8 +2022,8 @@ impl<'a> Parser<'a> {
                 );
             }
             err.span_suggestion(lo.shrink_to_lo(), format!("{prefix}you can still access the deprecated `try!()` macro using the \"raw identifier\" syntax"), "r#", Applicability::MachineApplicable);
-            err.emit();
-            Ok(self.mk_expr_err(lo.to(hi)))
+            let guar = err.emit();
+            Ok(self.mk_expr_err(lo.to(hi), guar))
         } else {
             Err(self.expected_expression_found()) // The user isn't trying to invoke the try! macro
         }
@@ -2059,10 +2068,10 @@ impl<'a> Parser<'a> {
         lo: Span,
         err: PErr<'a>,
     ) -> P<Expr> {
-        err.emit();
+        let guar = err.emit();
         // Recover from parse error, callers expect the closing delim to be consumed.
         self.consume_block(delim, ConsumeClosingDelim::Yes);
-        self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err)
+        self.mk_expr(lo.to(self.prev_token.span), ExprKind::Err(guar))
     }
 
     /// Eats tokens until we can be relatively sure we reached the end of the
@@ -2549,9 +2558,10 @@ impl<'a> Parser<'a> {
             }
             _ => None,
         };
-        self.dcx().emit_err(UnexpectedConstParamDeclaration { span: param.span(), sugg });
+        let guar =
+            self.dcx().emit_err(UnexpectedConstParamDeclaration { span: param.span(), sugg });
 
-        let value = self.mk_expr_err(param.span());
+        let value = self.mk_expr_err(param.span(), guar);
         Some(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }))
     }
 
@@ -2630,8 +2640,8 @@ impl<'a> Parser<'a> {
                         "=",
                         Applicability::MaybeIncorrect,
                     );
-                    let value = self.mk_expr_err(start.to(expr.span));
-                    err.emit();
+                    let guar = err.emit();
+                    let value = self.mk_expr_err(start.to(expr.span), guar);
                     return Ok(GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value }));
                 } else if token::Colon == snapshot.token.kind
                     && expr.span.lo() == snapshot.token.span.hi()
@@ -2701,8 +2711,8 @@ impl<'a> Parser<'a> {
             vec![(span.shrink_to_lo(), "{ ".to_string()), (span.shrink_to_hi(), " }".to_string())],
             Applicability::MaybeIncorrect,
         );
-        let value = self.mk_expr_err(span);
-        err.emit();
+        let guar = err.emit();
+        let value = self.mk_expr_err(span, guar);
         GenericArg::Const(AnonConst { id: ast::DUMMY_NODE_ID, value })
     }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 1ad637451b1..e1a5e17004f 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -34,7 +34,7 @@ use rustc_session::lint::builtin::BREAK_WITH_LABEL_AND_LOOP;
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_span::source_map::{self, Spanned};
 use rustc_span::symbol::{kw, sym, Ident, Symbol};
-use rustc_span::{BytePos, Pos, Span};
+use rustc_span::{BytePos, ErrorGuaranteed, Pos, Span};
 use thin_vec::{thin_vec, ThinVec};
 
 /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression
@@ -131,9 +131,9 @@ impl<'a> Parser<'a> {
                     if self.may_recover() && self.look_ahead(1, |t| t == &token::Comma) =>
                 {
                     // Special-case handling of `foo(_, _, _)`
-                    err.emit();
+                    let guar = err.emit();
                     self.bump();
-                    Ok(self.mk_expr(self.prev_token.span, ExprKind::Err))
+                    Ok(self.mk_expr(self.prev_token.span, ExprKind::Err(guar)))
                 }
                 _ => Err(err),
             },
@@ -667,8 +667,8 @@ impl<'a> Parser<'a> {
         let (span, _) = self.parse_expr_prefix_common(box_kw)?;
         let inner_span = span.with_lo(box_kw.hi());
         let code = self.sess.source_map().span_to_snippet(inner_span).unwrap();
-        self.dcx().emit_err(errors::BoxSyntaxRemoved { span: span, code: code.trim() });
-        Ok((span, ExprKind::Err))
+        let guar = self.dcx().emit_err(errors::BoxSyntaxRemoved { span: span, code: code.trim() });
+        Ok((span, ExprKind::Err(guar)))
     }
 
     fn is_mistaken_not_ident_negation(&self) -> bool {
@@ -860,7 +860,7 @@ impl<'a> Parser<'a> {
                     ExprKind::MethodCall(_) => "a method call",
                     ExprKind::Call(_, _) => "a function call",
                     ExprKind::Await(_, _) => "`.await`",
-                    ExprKind::Err => return Ok(with_postfix),
+                    ExprKind::Err(_) => return Ok(with_postfix),
                     _ => unreachable!("parse_dot_or_call_expr_with_ shouldn't produce this"),
                 }
             );
@@ -1315,7 +1315,7 @@ impl<'a> Parser<'a> {
                         let fields: Vec<_> =
                             fields.into_iter().filter(|field| !field.is_shorthand).collect();
 
-                        if !fields.is_empty() &&
+                        let guar = if !fields.is_empty() &&
                             // `token.kind` should not be compared here.
                             // This is because the `snapshot.token.kind` is treated as the same as
                             // that of the open delim in `TokenTreesReader::parse_token_tree`, even
@@ -1338,11 +1338,11 @@ impl<'a> Parser<'a> {
                                             .collect(),
                                     },
                                 })
-                                .emit();
+                                .emit()
                         } else {
-                            err.emit();
-                        }
-                        Ok(self.mk_expr_err(span))
+                            err.emit()
+                        };
+                        Ok(self.mk_expr_err(span, guar))
                     }
                     Ok(_) => Err(err),
                     Err(err2) => {
@@ -1684,13 +1684,13 @@ impl<'a> Parser<'a> {
             && (self.check_noexpect(&TokenKind::Comma) || self.check_noexpect(&TokenKind::Gt))
         {
             // We're probably inside of a `Path<'a>` that needs a turbofish
-            self.dcx().emit_err(errors::UnexpectedTokenAfterLabel {
+            let guar = self.dcx().emit_err(errors::UnexpectedTokenAfterLabel {
                 span: self.token.span,
                 remove_label: None,
                 enclose_in_block: None,
             });
             consume_colon = false;
-            Ok(self.mk_expr_err(lo))
+            Ok(self.mk_expr_err(lo, guar))
         } else {
             let mut err = errors::UnexpectedTokenAfterLabel {
                 span: self.token.span,
@@ -2039,7 +2039,7 @@ impl<'a> Parser<'a> {
     ) -> PResult<'a, L> {
         if let token::Interpolated(nt) = &self.token.kind
             && let token::NtExpr(e) | token::NtLiteral(e) = &nt.0
-            && matches!(e.kind, ExprKind::Err)
+            && matches!(e.kind, ExprKind::Err(_))
         {
             let mut err = self
                 .dcx()
@@ -2207,7 +2207,7 @@ impl<'a> Parser<'a> {
         let mut snapshot = self.create_snapshot_for_diagnostic();
         match snapshot.parse_expr_array_or_repeat(Delimiter::Brace) {
             Ok(arr) => {
-                self.dcx().emit_err(errors::ArrayBracketsInsteadOfSpaces {
+                let guar = self.dcx().emit_err(errors::ArrayBracketsInsteadOfSpaces {
                     span: arr.span,
                     sub: errors::ArrayBracketsInsteadOfSpacesSugg {
                         left: lo,
@@ -2216,7 +2216,7 @@ impl<'a> Parser<'a> {
                 });
 
                 self.restore_snapshot(snapshot);
-                Some(self.mk_expr_err(arr.span))
+                Some(self.mk_expr_err(arr.span, guar))
             }
             Err(e) => {
                 e.cancel();
@@ -2370,7 +2370,10 @@ impl<'a> Parser<'a> {
             // It is likely that the closure body is a block but where the
             // braces have been removed. We will recover and eat the next
             // statements later in the parsing process.
-            body = self.mk_expr_err(body.span);
+            body = self.mk_expr_err(
+                body.span,
+                self.dcx().span_delayed_bug(body.span, "recovered a closure body as a block"),
+            );
         }
 
         let body_span = body.span;
@@ -2485,7 +2488,7 @@ impl<'a> Parser<'a> {
                 ExprKind::Binary(Spanned { span: binop_span, .. }, _, right)
                     if let ExprKind::Block(_, None) = right.kind =>
                 {
-                    this.dcx().emit_err(errors::IfExpressionMissingThenBlock {
+                    let guar = this.dcx().emit_err(errors::IfExpressionMissingThenBlock {
                         if_span: lo,
                         missing_then_block_sub:
                             errors::IfExpressionMissingThenBlockSub::UnfinishedCondition(
@@ -2493,14 +2496,14 @@ impl<'a> Parser<'a> {
                             ),
                         let_else_sub: None,
                     });
-                    std::mem::replace(right, this.mk_expr_err(binop_span.shrink_to_hi()))
+                    std::mem::replace(right, this.mk_expr_err(binop_span.shrink_to_hi(), guar))
                 }
                 ExprKind::Block(_, None) => {
-                    this.dcx().emit_err(errors::IfExpressionMissingCondition {
+                    let guar = this.dcx().emit_err(errors::IfExpressionMissingCondition {
                         if_span: lo.with_neighbor(cond.span).shrink_to_hi(),
                         block_span: self.sess.source_map().start_point(cond_span),
                     });
-                    std::mem::replace(&mut cond, this.mk_expr_err(cond_span.shrink_to_hi()))
+                    std::mem::replace(&mut cond, this.mk_expr_err(cond_span.shrink_to_hi(), guar))
                 }
                 _ => {
                     return None;
@@ -2520,14 +2523,14 @@ impl<'a> Parser<'a> {
                 let let_else_sub = matches!(cond.kind, ExprKind::Let(..))
                     .then(|| errors::IfExpressionLetSomeSub { if_span: lo.until(cond_span) });
 
-                self.dcx().emit_err(errors::IfExpressionMissingThenBlock {
+                let guar = self.dcx().emit_err(errors::IfExpressionMissingThenBlock {
                     if_span: lo,
                     missing_then_block_sub: errors::IfExpressionMissingThenBlockSub::AddThenBlock(
                         cond_span.shrink_to_hi(),
                     ),
                     let_else_sub,
                 });
-                self.mk_block_err(cond_span.shrink_to_hi())
+                self.mk_block_err(cond_span.shrink_to_hi(), guar)
             }
         } else {
             let attrs = self.parse_outer_attributes()?; // For recovery.
@@ -2797,9 +2800,10 @@ impl<'a> Parser<'a> {
             && !matches!(self.token.kind, token::OpenDelim(Delimiter::Brace))
             && self.may_recover()
         {
-            self.dcx()
+            let guar = self
+                .dcx()
                 .emit_err(errors::MissingExpressionInForLoop { span: expr.span.shrink_to_lo() });
-            let err_expr = self.mk_expr(expr.span, ExprKind::Err);
+            let err_expr = self.mk_expr(expr.span, ExprKind::Err(guar));
             let block = self.mk_block(thin_vec![], BlockCheckMode::Default, self.prev_token.span);
             return Ok(self.mk_expr(
                 lo.to(self.prev_token.span),
@@ -2924,7 +2928,7 @@ impl<'a> Parser<'a> {
                         attrs: Default::default(),
                         pat: self.mk_pat(span, ast::PatKind::Err(guar)),
                         guard: None,
-                        body: Some(self.mk_expr_err(span)),
+                        body: Some(self.mk_expr_err(span, guar)),
                         span,
                         id: DUMMY_NODE_ID,
                         is_placeholder: false,
@@ -2959,7 +2963,7 @@ impl<'a> Parser<'a> {
         let err = |this: &Parser<'_>, stmts: Vec<ast::Stmt>| {
             let span = stmts[0].span.to(stmts[stmts.len() - 1].span);
 
-            this.dcx().emit_err(errors::MatchArmBodyWithoutBraces {
+            let guar = this.dcx().emit_err(errors::MatchArmBodyWithoutBraces {
                 statements: span,
                 arrow: arrow_span,
                 num_statements: stmts.len(),
@@ -2972,7 +2976,7 @@ impl<'a> Parser<'a> {
                     errors::MatchArmBodyWithoutBracesSugg::UseComma { semicolon: semi_sp }
                 },
             });
-            this.mk_expr_err(span)
+            this.mk_expr_err(span, guar)
         };
         // We might have either a `,` -> `;` typo, or a block without braces. We need
         // a more subtle parsing strategy.
@@ -3433,14 +3437,20 @@ impl<'a> Parser<'a> {
         pth: ast::Path,
         recover: bool,
         close_delim: Delimiter,
-    ) -> PResult<'a, (ThinVec<ExprField>, ast::StructRest, bool)> {
+    ) -> PResult<
+        'a,
+        (
+            ThinVec<ExprField>,
+            ast::StructRest,
+            Option<ErrorGuaranteed>, /* async blocks are forbidden in Rust 2015 */
+        ),
+    > {
         let mut fields = ThinVec::new();
         let mut base = ast::StructRest::None;
-        let mut recover_async = false;
+        let mut recovered_async = None;
         let in_if_guard = self.restrictions.contains(Restrictions::IN_IF_GUARD);
 
-        let mut async_block_err = |e: &mut DiagnosticBuilder<'_>, span: Span| {
-            recover_async = true;
+        let async_block_err = |e: &mut DiagnosticBuilder<'_>, span: Span| {
             errors::AsyncBlockIn2015 { span }.add_to_diagnostic(e);
             errors::HelpUseLatestEdition::new().add_to_diagnostic(e);
         };
@@ -3465,9 +3475,34 @@ impl<'a> Parser<'a> {
                 break;
             }
 
-            let recovery_field = self.find_struct_error_after_field_looking_code();
+            // Peek the field's ident before parsing its expr in order to emit better diagnostics.
+            let peek = self
+                .token
+                .ident()
+                .filter(|(ident, is_raw)| {
+                    (!ident.is_reserved() || matches!(is_raw, IdentIsRaw::Yes))
+                        && self.look_ahead(1, |tok| *tok == token::Colon)
+                })
+                .map(|(ident, _)| ident);
+
+            // We still want a field even if its expr didn't parse.
+            let field_ident = |this: &Self, guar: ErrorGuaranteed| {
+                peek.map(|ident| {
+                    let span = ident.span;
+                    ExprField {
+                        ident,
+                        span,
+                        expr: this.mk_expr_err(span, guar),
+                        is_shorthand: false,
+                        attrs: AttrVec::new(),
+                        id: DUMMY_NODE_ID,
+                        is_placeholder: false,
+                    }
+                })
+            };
+
             let parsed_field = match self.parse_expr_field() {
-                Ok(f) => Some(f),
+                Ok(f) => Ok(f),
                 Err(mut e) => {
                     if pth == kw::Async {
                         async_block_err(&mut e, pth.span);
@@ -3499,7 +3534,10 @@ impl<'a> Parser<'a> {
                         return Err(e);
                     }
 
-                    e.emit();
+                    let guar = e.emit();
+                    if pth == kw::Async {
+                        recovered_async = Some(guar);
+                    }
 
                     // If the next token is a comma, then try to parse
                     // what comes next as additional fields, rather than
@@ -3511,18 +3549,20 @@ impl<'a> Parser<'a> {
                         }
                     }
 
-                    None
+                    Err(guar)
                 }
             };
 
-            let is_shorthand = parsed_field.as_ref().is_some_and(|f| f.is_shorthand);
+            let is_shorthand = parsed_field.as_ref().is_ok_and(|f| f.is_shorthand);
             // A shorthand field can be turned into a full field with `:`.
             // We should point this out.
             self.check_or_expected(!is_shorthand, TokenType::Token(token::Colon));
 
             match self.expect_one_of(&[token::Comma], &[token::CloseDelim(close_delim)]) {
                 Ok(_) => {
-                    if let Some(f) = parsed_field.or(recovery_field) {
+                    if let Some(f) =
+                        parsed_field.or_else(|guar| field_ident(self, guar).ok_or(guar)).ok()
+                    {
                         // Only include the field if there's no parse error for the field name.
                         fields.push(f);
                     }
@@ -3532,8 +3572,7 @@ impl<'a> Parser<'a> {
                         async_block_err(&mut e, pth.span);
                     } else {
                         e.span_label(pth.span, "while parsing this struct");
-                        if let Some(f) = recovery_field {
-                            fields.push(f);
+                        if peek.is_some() {
                             e.span_suggestion(
                                 self.prev_token.span.shrink_to_hi(),
                                 "try adding a comma",
@@ -3545,13 +3584,18 @@ impl<'a> Parser<'a> {
                     if !recover {
                         return Err(e);
                     }
-                    e.emit();
+                    let guar = e.emit();
+                    if pth == kw::Async {
+                        recovered_async = Some(guar);
+                    } else if let Some(f) = field_ident(self, guar) {
+                        fields.push(f);
+                    }
                     self.recover_stmt_(SemiColonMode::Comma, BlockMode::Ignore);
                     self.eat(&token::Comma);
                 }
             }
         }
-        Ok((fields, base, recover_async))
+        Ok((fields, base, recovered_async))
     }
 
     /// Precondition: already parsed the '{'.
@@ -3562,39 +3606,18 @@ impl<'a> Parser<'a> {
         recover: bool,
     ) -> PResult<'a, P<Expr>> {
         let lo = pth.span;
-        let (fields, base, recover_async) =
+        let (fields, base, recovered_async) =
             self.parse_struct_fields(pth.clone(), recover, Delimiter::Brace)?;
         let span = lo.to(self.token.span);
         self.expect(&token::CloseDelim(Delimiter::Brace))?;
-        let expr = if recover_async {
-            ExprKind::Err
+        let expr = if let Some(guar) = recovered_async {
+            ExprKind::Err(guar)
         } else {
             ExprKind::Struct(P(ast::StructExpr { qself, path: pth, fields, rest: base }))
         };
         Ok(self.mk_expr(span, expr))
     }
 
-    /// Use in case of error after field-looking code: `S { foo: () with a }`.
-    fn find_struct_error_after_field_looking_code(&self) -> Option<ExprField> {
-        match self.token.ident() {
-            Some((ident, is_raw))
-                if (matches!(is_raw, IdentIsRaw::Yes) || !ident.is_reserved())
-                    && self.look_ahead(1, |t| *t == token::Colon) =>
-            {
-                Some(ast::ExprField {
-                    ident,
-                    span: self.token.span,
-                    expr: self.mk_expr_err(self.token.span),
-                    is_shorthand: false,
-                    attrs: AttrVec::new(),
-                    id: DUMMY_NODE_ID,
-                    is_placeholder: false,
-                })
-            }
-            _ => None,
-        }
-    }
-
     fn recover_struct_comma_after_dotdot(&mut self, span: Span) {
         if self.token != token::Comma {
             return;
@@ -3718,8 +3741,8 @@ impl<'a> Parser<'a> {
         limits: RangeLimits,
     ) -> ExprKind {
         if end.is_none() && limits == RangeLimits::Closed {
-            self.inclusive_range_with_incorrect_end();
-            ExprKind::Err
+            let guar = self.inclusive_range_with_incorrect_end();
+            ExprKind::Err(guar)
         } else {
             ExprKind::Range(start, end, limits)
         }
@@ -3756,8 +3779,8 @@ impl<'a> Parser<'a> {
         self.mk_expr_with_attrs(span, kind, AttrVec::new())
     }
 
-    pub(super) fn mk_expr_err(&self, span: Span) -> P<Expr> {
-        self.mk_expr(span, ExprKind::Err)
+    pub(super) fn mk_expr_err(&self, span: Span, guar: ErrorGuaranteed) -> P<Expr> {
+        self.mk_expr(span, ExprKind::Err(guar))
     }
 
     /// Create expression span ensuring the span of the parent node
@@ -3949,7 +3972,8 @@ impl MutVisitor for CondChecker<'_> {
             | ExprKind::Become(_)
             | ExprKind::IncludedBytes(_)
             | ExprKind::FormatArgs(_)
-            | ExprKind::Err => {
+            | ExprKind::Err(_)
+            | ExprKind::Dummy => {
                 // These would forbid any let expressions they contain already.
             }
         }
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 2e049ca908f..a678194372e 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -2328,11 +2328,11 @@ impl<'a> Parser<'a> {
             let _ = self.parse_expr()?;
             self.expect_semi()?; // `;`
             let span = eq_sp.to(self.prev_token.span);
-            self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
+            let guar = self.dcx().emit_err(errors::FunctionBodyEqualsExpr {
                 span,
                 sugg: errors::FunctionBodyEqualsExprSugg { eq: eq_sp, semi: self.prev_token.span },
             });
-            (AttrVec::new(), Some(self.mk_block_err(span)))
+            (AttrVec::new(), Some(self.mk_block_err(span, guar)))
         } else {
             let expected = if req_body {
                 &[token::OpenDelim(Delimiter::Brace)][..]
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index 2ede19b11e0..9bff5b93092 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -388,7 +388,7 @@ impl<'a> Parser<'a> {
         // Parse `?`, `.f`, `(arg0, arg1, ...)` or `[expr]` until they've all been eaten.
         if let Ok(expr) = snapshot
             .parse_expr_dot_or_call_with(
-                self.mk_expr_err(pat_span), // equivalent to transforming the parsed pattern into an `Expr`
+                self.mk_expr(pat_span, ExprKind::Dummy), // equivalent to transforming the parsed pattern into an `Expr`
                 pat_span,
                 AttrVec::new(),
             )
@@ -566,7 +566,7 @@ impl<'a> Parser<'a> {
             match self.parse_literal_maybe_minus() {
                 Ok(begin) => {
                     let begin = match self.maybe_recover_trailing_expr(begin.span, false) {
-                        Some(_) => self.mk_expr_err(begin.span),
+                        Some(guar) => self.mk_expr_err(begin.span, guar),
                         None => begin,
                     };
 
@@ -719,7 +719,7 @@ impl<'a> Parser<'a> {
                     self.parse_pat_range_begin_with(begin.clone(), form)
                 }
                 // recover ranges with parentheses around the `(start)..`
-                PatKind::Err(_)
+                PatKind::Err(guar)
                     if self.may_recover()
                         && let Some(form) = self.parse_range_end() =>
                 {
@@ -731,7 +731,7 @@ impl<'a> Parser<'a> {
                         },
                     });
 
-                    self.parse_pat_range_begin_with(self.mk_expr(pat.span, ExprKind::Err), form)
+                    self.parse_pat_range_begin_with(self.mk_expr_err(pat.span, *guar), form)
                 }
 
                 // (pat) with optional parentheses
@@ -886,7 +886,7 @@ impl<'a> Parser<'a> {
         Ok(PatKind::Range(Some(begin), end, re))
     }
 
-    pub(super) fn inclusive_range_with_incorrect_end(&mut self) {
+    pub(super) fn inclusive_range_with_incorrect_end(&mut self) -> ErrorGuaranteed {
         let tok = &self.token;
         let span = self.prev_token.span;
         // If the user typed "..==" instead of "..=", we want to give them
@@ -905,15 +905,13 @@ impl<'a> Parser<'a> {
                     let _ = self.parse_pat_range_end().map_err(|e| e.cancel());
                 }
 
-                self.dcx().emit_err(InclusiveRangeExtraEquals { span: span_with_eq });
+                self.dcx().emit_err(InclusiveRangeExtraEquals { span: span_with_eq })
             }
             token::Gt if no_space => {
                 let after_pat = span.with_hi(span.hi() - rustc_span::BytePos(1)).shrink_to_hi();
-                self.dcx().emit_err(InclusiveRangeMatchArrow { span, arrow: tok.span, after_pat });
-            }
-            _ => {
-                self.dcx().emit_err(InclusiveRangeNoEnd { span });
+                self.dcx().emit_err(InclusiveRangeMatchArrow { span, arrow: tok.span, after_pat })
             }
+            _ => self.dcx().emit_err(InclusiveRangeNoEnd { span }),
         }
     }
 
@@ -987,7 +985,7 @@ impl<'a> Parser<'a> {
         }
 
         Ok(match recovered {
-            Some(_) => self.mk_expr_err(bound.span),
+            Some(guar) => self.mk_expr_err(bound.span, guar),
             None => bound,
         })
     }
diff --git a/compiler/rustc_parse/src/parser/stmt.rs b/compiler/rustc_parse/src/parser/stmt.rs
index ee02b69c614..15f8124823f 100644
--- a/compiler/rustc_parse/src/parser/stmt.rs
+++ b/compiler/rustc_parse/src/parser/stmt.rs
@@ -22,7 +22,7 @@ use rustc_ast::{Block, BlockCheckMode, Expr, ExprKind, HasAttrs, Local, Stmt};
 use rustc_ast::{StmtKind, DUMMY_NODE_ID};
 use rustc_errors::{Applicability, DiagnosticBuilder, PResult};
 use rustc_span::symbol::{kw, sym, Ident};
-use rustc_span::{BytePos, Span};
+use rustc_span::{BytePos, ErrorGuaranteed, Span};
 
 use std::borrow::Cow;
 use std::mem;
@@ -610,9 +610,9 @@ impl<'a> Parser<'a> {
                         }
                     }
 
-                    err.emit();
+                    let guar = err.emit();
                     self.recover_stmt_(SemiColonMode::Ignore, BlockMode::Ignore);
-                    Some(self.mk_stmt_err(self.token.span))
+                    Some(self.mk_stmt_err(self.token.span, guar))
                 }
                 Ok(stmt) => stmt,
                 Err(err) => return Err(err),
@@ -651,10 +651,10 @@ impl<'a> Parser<'a> {
                         .contains(&self.token.kind) =>
             {
                 // The user has written `#[attr] expr` which is unsupported. (#106020)
-                self.attr_on_non_tail_expr(&expr);
+                let guar = self.attr_on_non_tail_expr(&expr);
                 // We already emitted an error, so don't emit another type error
                 let sp = expr.span.to(self.prev_token.span);
-                *expr = self.mk_expr_err(sp);
+                *expr = self.mk_expr_err(sp, guar);
             }
 
             // Expression without semicolon.
@@ -666,10 +666,18 @@ impl<'a> Parser<'a> {
                 let expect_result =
                     self.expect_one_of(&[], &[token::Semi, token::CloseDelim(Delimiter::Brace)]);
 
+                // Try to both emit a better diagnostic, and avoid further errors by replacing
+                // the `expr` with `ExprKind::Err`.
                 let replace_with_err = 'break_recover: {
                     match expect_result {
-                        // Recover from parser, skip type error to avoid extra errors.
-                        Ok(Recovered::Yes) => true,
+                        Ok(Recovered::No) => None,
+                        Ok(Recovered::Yes) => {
+                            // Skip type error to avoid extra errors.
+                            let guar = self
+                                .dcx()
+                                .span_delayed_bug(self.prev_token.span, "expected `;` or `}`");
+                            Some(guar)
+                        }
                         Err(e) => {
                             if self.recover_colon_as_semi() {
                                 // recover_colon_as_semi has already emitted a nicer error.
@@ -677,7 +685,7 @@ impl<'a> Parser<'a> {
                                 add_semi_to_stmt = true;
                                 eat_semi = false;
 
-                                break 'break_recover false;
+                                break 'break_recover None;
                             }
 
                             match &expr.kind {
@@ -705,13 +713,13 @@ impl<'a> Parser<'a> {
                                         };
                                         match self.parse_expr_labeled(label, false) {
                                             Ok(labeled_expr) => {
-                                                e.delay_as_bug();
+                                                e.cancel();
                                                 self.dcx().emit_err(MalformedLoopLabel {
                                                     span: label.ident.span,
                                                     correct_label: label.ident,
                                                 });
                                                 *expr = labeled_expr;
-                                                break 'break_recover false;
+                                                break 'break_recover None;
                                             }
                                             Err(err) => {
                                                 err.cancel();
@@ -723,26 +731,26 @@ impl<'a> Parser<'a> {
                                 _ => {}
                             }
 
-                            if let Err(e) =
-                                self.check_mistyped_turbofish_with_multiple_type_params(e, expr)
-                            {
-                                if recover.no() {
-                                    return Err(e);
-                                }
-                                e.emit();
-                                self.recover_stmt();
-                            }
-
-                            true
+                            let res =
+                                self.check_mistyped_turbofish_with_multiple_type_params(e, expr);
+
+                            Some(if recover.no() {
+                                res?
+                            } else {
+                                res.unwrap_or_else(|e| {
+                                    let guar = e.emit();
+                                    self.recover_stmt();
+                                    guar
+                                })
+                            })
                         }
-                        Ok(Recovered::No) => false,
                     }
                 };
 
-                if replace_with_err {
+                if let Some(guar) = replace_with_err {
                     // We already emitted an error, so don't emit another type error
                     let sp = expr.span.to(self.prev_token.span);
-                    *expr = self.mk_expr_err(sp);
+                    *expr = self.mk_expr_err(sp, guar);
                 }
             }
             StmtKind::Expr(_) | StmtKind::MacCall(_) => {}
@@ -791,11 +799,11 @@ impl<'a> Parser<'a> {
         Stmt { id: DUMMY_NODE_ID, kind, span }
     }
 
-    pub(super) fn mk_stmt_err(&self, span: Span) -> Stmt {
-        self.mk_stmt(span, StmtKind::Expr(self.mk_expr_err(span)))
+    pub(super) fn mk_stmt_err(&self, span: Span, guar: ErrorGuaranteed) -> Stmt {
+        self.mk_stmt(span, StmtKind::Expr(self.mk_expr_err(span, guar)))
     }
 
-    pub(super) fn mk_block_err(&self, span: Span) -> P<Block> {
-        self.mk_block(thin_vec![self.mk_stmt_err(span)], BlockCheckMode::Default, span)
+    pub(super) fn mk_block_err(&self, span: Span, guar: ErrorGuaranteed) -> P<Block> {
+        self.mk_block(thin_vec![self.mk_stmt_err(span, guar)], BlockCheckMode::Default, span)
     }
 }
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 5d46581f646..73c92708eb3 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -90,7 +90,7 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
                     //   been reported.
                     let msg = "attribute value must be a literal";
                     let mut err = sess.dcx.struct_span_err(expr.span, msg);
-                    if let ast::ExprKind::Err = expr.kind {
+                    if let ast::ExprKind::Err(_) = expr.kind {
                         err.downgrade_to_delayed_bug();
                     }
                     return Err(err);
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index d8ae82d11bc..194533047d4 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -1389,7 +1389,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         if target == Target::ForeignMod
             && let hir::Node::Item(item) = self.tcx.hir_node(hir_id)
             && let Item { kind: ItemKind::ForeignMod { abi, .. }, .. } = item
-            && !matches!(abi, Abi::Rust | Abi::RustIntrinsic | Abi::PlatformIntrinsic)
+            && !matches!(abi, Abi::Rust | Abi::RustIntrinsic)
         {
             return;
         }
@@ -2071,7 +2071,7 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
     ) -> bool {
         if let Target::ForeignFn = target
             && let hir::Node::Item(Item {
-                kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic | Abi::PlatformIntrinsic, .. },
+                kind: ItemKind::ForeignMod { abi: Abi::RustIntrinsic, .. },
                 ..
             }) = self.tcx.parent_hir_node(hir_id)
         {
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index 96429bb7788..be6ba585d20 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -589,7 +589,7 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
                 If, While, ForLoop, Loop, Match, Closure, Block, Await, TryBlock, Assign,
                 AssignOp, Field, Index, Range, Underscore, Path, AddrOf, Break, Continue, Ret,
                 InlineAsm, FormatArgs, OffsetOf, MacCall, Struct, Repeat, Paren, Try, Yield, Yeet,
-                Become, IncludedBytes, Gen, Err
+                Become, IncludedBytes, Gen, Err, Dummy
             ]
         );
         ast_visit::walk_expr(self, e)
diff --git a/compiler/rustc_passes/src/stability.rs b/compiler/rustc_passes/src/stability.rs
index 19272b52b32..05c833cdfb6 100644
--- a/compiler/rustc_passes/src/stability.rs
+++ b/compiler/rustc_passes/src/stability.rs
@@ -173,10 +173,7 @@ impl<'a, 'tcx> Annotator<'a, 'tcx> {
         // If the current node is a function, has const stability attributes and if it doesn not have an intrinsic ABI,
         // check if the function/method is const or the parent impl block is const
         if let (Some(const_span), Some(fn_sig)) = (const_span, fn_sig) {
-            if fn_sig.header.abi != Abi::RustIntrinsic
-                && fn_sig.header.abi != Abi::PlatformIntrinsic
-                && !fn_sig.header.is_const()
-            {
+            if fn_sig.header.abi != Abi::RustIntrinsic && !fn_sig.header.is_const() {
                 if !self.in_trait_impl
                     || (self.in_trait_impl && !self.tcx.is_const_fn_raw(def_id.to_def_id()))
                 {
diff --git a/compiler/rustc_smir/src/rustc_internal/internal.rs b/compiler/rustc_smir/src/rustc_internal/internal.rs
index 6bbfcff5e87..2cc9bc31873 100644
--- a/compiler/rustc_smir/src/rustc_internal/internal.rs
+++ b/compiler/rustc_smir/src/rustc_internal/internal.rs
@@ -457,7 +457,6 @@ impl RustcInternal for Abi {
             Abi::System { unwind } => rustc_target::spec::abi::Abi::System { unwind },
             Abi::RustIntrinsic => rustc_target::spec::abi::Abi::RustIntrinsic,
             Abi::RustCall => rustc_target::spec::abi::Abi::RustCall,
-            Abi::PlatformIntrinsic => rustc_target::spec::abi::Abi::PlatformIntrinsic,
             Abi::Unadjusted => rustc_target::spec::abi::Abi::Unadjusted,
             Abi::RustCold => rustc_target::spec::abi::Abi::RustCold,
             Abi::RiscvInterruptM => rustc_target::spec::abi::Abi::RiscvInterruptM,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
index 29081418200..a066b9ed3aa 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/ty.rs
@@ -833,7 +833,6 @@ impl<'tcx> Stable<'tcx> for rustc_target::spec::abi::Abi {
             abi::Abi::System { unwind } => Abi::System { unwind },
             abi::Abi::RustIntrinsic => Abi::RustIntrinsic,
             abi::Abi::RustCall => Abi::RustCall,
-            abi::Abi::PlatformIntrinsic => Abi::PlatformIntrinsic,
             abi::Abi::Unadjusted => Abi::Unadjusted,
             abi::Abi::RustCold => Abi::RustCold,
             abi::Abi::RiscvInterruptM => Abi::RiscvInterruptM,
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 609ab054da2..a66d38e5b53 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -487,6 +487,7 @@ symbols! {
         call_once,
         caller_location,
         capture_disjoint_fields,
+        catch_unwind,
         cause,
         cdylib,
         ceilf32,
diff --git a/compiler/rustc_target/src/spec/abi/mod.rs b/compiler/rustc_target/src/spec/abi/mod.rs
index 6231787bb9f..388e76d83e2 100644
--- a/compiler/rustc_target/src/spec/abi/mod.rs
+++ b/compiler/rustc_target/src/spec/abi/mod.rs
@@ -54,7 +54,6 @@ pub enum Abi {
     },
     RustIntrinsic,
     RustCall,
-    PlatformIntrinsic,
     Unadjusted,
     /// For things unlikely to be called, where reducing register pressure in
     /// `extern "Rust"` callers is worth paying extra cost in the callee.
@@ -129,7 +128,6 @@ const AbiDatas: &[AbiData] = &[
     AbiData { abi: Abi::System { unwind: true }, name: "system-unwind" },
     AbiData { abi: Abi::RustIntrinsic, name: "rust-intrinsic" },
     AbiData { abi: Abi::RustCall, name: "rust-call" },
-    AbiData { abi: Abi::PlatformIntrinsic, name: "platform-intrinsic" },
     AbiData { abi: Abi::Unadjusted, name: "unadjusted" },
     AbiData { abi: Abi::RustCold, name: "rust-cold" },
     AbiData { abi: Abi::RiscvInterruptM, name: "riscv-interrupt-m" },
@@ -199,10 +197,6 @@ pub fn is_stable(name: &str) -> Result<(), AbiDisabled> {
             feature: sym::intrinsics,
             explain: "intrinsics are subject to change",
         }),
-        "platform-intrinsic" => Err(AbiDisabled::Unstable {
-            feature: sym::platform_intrinsics,
-            explain: "platform intrinsics are experimental and possibly buggy",
-        }),
         "vectorcall" => Err(AbiDisabled::Unstable {
             feature: sym::abi_vectorcall,
             explain: "vectorcall is experimental and subject to change",
@@ -299,11 +293,10 @@ impl Abi {
             System { unwind: true } => 28,
             RustIntrinsic => 29,
             RustCall => 30,
-            PlatformIntrinsic => 31,
-            Unadjusted => 32,
-            RustCold => 33,
-            RiscvInterruptM => 34,
-            RiscvInterruptS => 35,
+            Unadjusted => 31,
+            RustCold => 32,
+            RiscvInterruptM => 33,
+            RiscvInterruptS => 34,
         };
         debug_assert!(
             AbiDatas
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index d04bcb2d78a..084a8b9db81 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -2448,7 +2448,6 @@ impl Target {
             | System { .. }
             | RustIntrinsic
             | RustCall
-            | PlatformIntrinsic
             | Unadjusted
             | Cdecl { .. }
             | RustCold => true,
diff --git a/compiler/rustc_trait_selection/src/solve/alias_relate.rs b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
index 81be5c09164..afd9d95cb57 100644
--- a/compiler/rustc_trait_selection/src/solve/alias_relate.rs
+++ b/compiler/rustc_trait_selection/src/solve/alias_relate.rs
@@ -8,8 +8,9 @@
 //!
 //! (1.) If we end up with two rigid aliases, then we relate them structurally.
 //!
-//! (2.) If we end up with an infer var and a rigid alias, then
-//! we assign the alias to the infer var.
+//! (2.) If we end up with an infer var and a rigid alias, then we instantiate
+//! the infer var with the constructor of the alias and then recursively relate
+//! the terms.
 //!
 //! (3.) Otherwise, if we end with two rigid (non-projection) or infer types,
 //! relate them structurally.
@@ -53,22 +54,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             }
 
-            (Some(_), None) => {
-                if rhs.is_infer() {
-                    self.relate(param_env, lhs, variance, rhs)?;
-                    self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-                } else {
-                    Err(NoSolution)
-                }
-            }
-            (None, Some(_)) => {
-                if lhs.is_infer() {
-                    self.relate(param_env, lhs, variance, rhs)?;
-                    self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
-                } else {
-                    Err(NoSolution)
-                }
+            (Some(alias), None) => {
+                self.relate_rigid_alias_non_alias(param_env, alias, variance, rhs)
             }
+            (None, Some(alias)) => self.relate_rigid_alias_non_alias(
+                param_env,
+                alias,
+                variance.xform(ty::Variance::Contravariant),
+                lhs,
+            ),
 
             (Some(alias_lhs), Some(alias_rhs)) => {
                 self.relate(param_env, alias_lhs, variance, alias_rhs)?;
@@ -77,6 +71,39 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
+    /// Relate a rigid alias with another type. This is the same as
+    /// an ordinary relate except that we treat the outer most alias
+    /// constructor as rigid.
+    #[instrument(level = "debug", skip(self, param_env), ret)]
+    fn relate_rigid_alias_non_alias(
+        &mut self,
+        param_env: ty::ParamEnv<'tcx>,
+        alias: ty::AliasTy<'tcx>,
+        variance: ty::Variance,
+        term: ty::Term<'tcx>,
+    ) -> QueryResult<'tcx> {
+        // NOTE: this check is purely an optimization, the structural eq would
+        // always fail if the term is not an inference variable.
+        if term.is_infer() {
+            let tcx = self.tcx();
+            // We need to relate `alias` to `term` treating only the outermost
+            // constructor as rigid, relating any contained generic arguments as
+            // normal. We do this by first structurally equating the `term`
+            // with the alias constructor instantiated with unconstrained infer vars,
+            // and then relate this with the whole `alias`.
+            //
+            // Alternatively we could modify `Equate` for this case by adding another
+            // variant to `StructurallyRelateAliases`.
+            let identity_args = self.fresh_args_for_item(alias.def_id);
+            let rigid_ctor = ty::AliasTy::new(tcx, alias.def_id, identity_args);
+            self.eq_structurally_relating_aliases(param_env, term, rigid_ctor.to_ty(tcx).into())?;
+            self.eq(param_env, alias, rigid_ctor)?;
+            self.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
+        } else {
+            Err(NoSolution)
+        }
+    }
+
     // FIXME: This needs a name that reflects that it's okay to bottom-out with an inference var.
     /// Normalize the `term` to equate it later.
     #[instrument(level = "debug", skip(self, param_env), ret)]
@@ -105,6 +132,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         }
     }
 
+    #[instrument(level = "debug", skip(self, param_env), ret)]
     fn try_normalize_ty_recur(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
@@ -128,10 +156,9 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             );
             this.add_goal(GoalSource::Misc, normalizes_to_goal);
             this.try_evaluate_added_goals()?;
-            let ty = this.resolve_vars_if_possible(normalized_ty);
-            Ok(this.try_normalize_ty_recur(param_env, depth + 1, ty))
+            Ok(this.resolve_vars_if_possible(normalized_ty))
         }) {
-            Ok(ty) => ty,
+            Ok(ty) => self.try_normalize_ty_recur(param_env, depth + 1, ty),
             Err(NoSolution) => Some(ty),
         }
     }
diff --git a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
index 8e66b1d580f..4c4cd2af779 100644
--- a/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/assembly/mod.rs
@@ -777,6 +777,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     // FIXME(@lcnr): The current structure here makes me unhappy and feels ugly. idk how
     // to improve this however. However, this should make it fairly straightforward to refine
     // the filtering going forward, so it seems alright-ish for now.
+    #[instrument(level = "debug", skip(self, goal))]
     fn discard_impls_shadowed_by_env<G: GoalKind<'tcx>>(
         &mut self,
         goal: Goal<'tcx, G>,
@@ -799,7 +800,10 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 // This feels dangerous.
                 Certainty::Yes => {
                     candidates.retain(|c| match c.source {
-                        CandidateSource::Impl(_) | CandidateSource::BuiltinImpl(_) => false,
+                        CandidateSource::Impl(_) | CandidateSource::BuiltinImpl(_) => {
+                            debug!(?c, "discard impl candidate");
+                            false
+                        }
                         CandidateSource::ParamEnv(_) | CandidateSource::AliasBound => true,
                     });
                 }
@@ -807,6 +811,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 // to be ambig and wait for inference constraints. See
                 // tests/ui/traits/next-solver/env-shadows-impls/ambig-env-no-shadow.rs
                 Certainty::Maybe(cause) => {
+                    debug!(?cause, "force ambiguity");
                     *candidates = self.forced_ambiguity(cause);
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
index 1a6aa3f144c..251b0a193f1 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/canonical.rs
@@ -18,7 +18,7 @@ use rustc_infer::infer::canonical::query_response::make_query_region_constraints
 use rustc_infer::infer::canonical::CanonicalVarValues;
 use rustc_infer::infer::canonical::{CanonicalExt, QueryRegionConstraints};
 use rustc_infer::infer::resolve::EagerResolver;
-use rustc_infer::infer::{DefineOpaqueTypes, InferCtxt, InferOk};
+use rustc_infer::infer::{InferCtxt, InferOk};
 use rustc_middle::infer::canonical::Canonical;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{
@@ -80,7 +80,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ///   the values inferred while solving the instantiated goal.
     /// - `external_constraints`: additional constraints which aren't expressible
     ///   using simple unification of inference variables.
-    #[instrument(level = "debug", skip(self))]
+    #[instrument(level = "debug", skip(self), ret)]
     pub(in crate::solve) fn evaluate_added_goals_and_make_canonical_response(
         &mut self,
         certainty: Certainty,
@@ -191,7 +191,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         original_values: Vec<ty::GenericArg<'tcx>>,
         response: CanonicalResponse<'tcx>,
-    ) -> Result<(Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution> {
+    ) -> Certainty {
         let instantiation = Self::compute_query_response_instantiation_values(
             self.infcx,
             &original_values,
@@ -201,15 +201,13 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let Response { var_values, external_constraints, certainty } =
             response.instantiate(self.tcx(), &instantiation);
 
-        let nested_goals =
-            Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values)?;
+        Self::unify_query_var_values(self.infcx, param_env, &original_values, var_values);
 
         let ExternalConstraintsData { region_constraints, opaque_types } =
             external_constraints.deref();
         self.register_region_constraints(region_constraints);
-        self.register_opaque_types(param_env, opaque_types)?;
-
-        Ok((certainty, nested_goals))
+        self.register_new_opaque_types(param_env, opaque_types);
+        certainty
     }
 
     /// This returns the canoncial variable values to instantiate the bound variables of
@@ -296,32 +294,36 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         CanonicalVarValues { var_values }
     }
 
-    #[instrument(level = "debug", skip(infcx, param_env), ret)]
+    /// Unify the `original_values` with the `var_values` returned by the canonical query..
+    ///
+    /// This assumes that this unification will always succeed. This is the case when
+    /// applying a query response right away. However, calling a canonical query, doing any
+    /// other kind of trait solving, and only then instantiating the result of the query
+    /// can cause the instantiation to fail. This is not supported and we ICE in this case.
+    ///
+    /// We always structurally instantiate aliases. Relating aliases needs to be different
+    /// depending on whether the alias is *rigid* or not. We're only really able to tell
+    /// whether an alias is rigid by using the trait solver. When instantiating a response
+    /// from the solver we assume that the solver correctly handled aliases and therefore
+    /// always relate them structurally here.
+    #[instrument(level = "debug", skip(infcx), ret)]
     fn unify_query_var_values(
         infcx: &InferCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         original_values: &[ty::GenericArg<'tcx>],
         var_values: CanonicalVarValues<'tcx>,
-    ) -> Result<Vec<Goal<'tcx, ty::Predicate<'tcx>>>, NoSolution> {
+    ) {
         assert_eq!(original_values.len(), var_values.len());
 
-        let mut nested_goals = vec![];
+        let cause = ObligationCause::dummy();
         for (&orig, response) in iter::zip(original_values, var_values.var_values) {
-            nested_goals.extend(
-                infcx
-                    .at(&ObligationCause::dummy(), param_env)
-                    .eq(DefineOpaqueTypes::No, orig, response)
-                    .map(|InferOk { value: (), obligations }| {
-                        obligations.into_iter().map(|o| Goal::from(o))
-                    })
-                    .map_err(|e| {
-                        debug!(?e, "failed to equate");
-                        NoSolution
-                    })?,
-            );
+            let InferOk { value: (), obligations } = infcx
+                .at(&cause, param_env)
+                .trace(orig, response)
+                .eq_structurally_relating_aliases(orig, response)
+                .unwrap();
+            assert!(obligations.is_empty());
         }
-
-        Ok(nested_goals)
     }
 
     fn register_region_constraints(&mut self, region_constraints: &QueryRegionConstraints<'tcx>) {
@@ -333,21 +335,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             }
         }
 
-        for member_constraint in &region_constraints.member_constraints {
-            // FIXME: Deal with member constraints :<
-            let _ = member_constraint;
-        }
+        assert!(region_constraints.member_constraints.is_empty());
     }
 
-    fn register_opaque_types(
+    fn register_new_opaque_types(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
         opaque_types: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
-    ) -> Result<(), NoSolution> {
+    ) {
         for &(key, ty) in opaque_types {
-            self.insert_hidden_type(key, param_env, ty)?;
+            self.insert_hidden_type(key, param_env, ty).unwrap();
         }
-        Ok(())
     }
 }
 
@@ -366,19 +364,21 @@ impl<'tcx> inspect::ProofTreeBuilder<'tcx> {
         )
     }
 
+    /// Instantiate a `CanonicalState`. This assumes that unifying the var values
+    /// trivially succeeds. Adding any inference constraints which weren't present when
+    /// originally computing the canonical query can result in bugs.
     pub fn instantiate_canonical_state<T: TypeFoldable<TyCtxt<'tcx>>>(
         infcx: &InferCtxt<'tcx>,
         param_env: ty::ParamEnv<'tcx>,
         original_values: &[ty::GenericArg<'tcx>],
         state: inspect::CanonicalState<'tcx, T>,
-    ) -> Result<(Vec<Goal<'tcx, ty::Predicate<'tcx>>>, T), NoSolution> {
+    ) -> T {
         let instantiation =
             EvalCtxt::compute_query_response_instantiation_values(infcx, original_values, &state);
 
         let inspect::State { var_values, data } = state.instantiate(infcx.tcx, &instantiation);
 
-        let nested_goals =
-            EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values)?;
-        Ok((nested_goals, data))
+        EvalCtxt::unify_query_var_values(infcx, param_env, original_values, var_values);
+        data
     }
 }
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
index 5c1e8bf616f..ed428bb8e66 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/mod.rs
@@ -17,8 +17,8 @@ use rustc_middle::traits::solve::{
 };
 use rustc_middle::traits::{specialization_graph, DefiningAnchor};
 use rustc_middle::ty::{
-    self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable,
-    TypeVisitableExt, TypeVisitor,
+    self, InferCtxtLike, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable,
+    TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
 use rustc_session::config::DumpSolverProofTree;
 use rustc_span::DUMMY_SP;
@@ -142,10 +142,7 @@ impl<'tcx> InferCtxt<'tcx> {
         &self,
         goal: Goal<'tcx, ty::Predicate<'tcx>>,
         generate_proof_tree: GenerateProofTree,
-    ) -> (
-        Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
-        Option<inspect::GoalEvaluation<'tcx>>,
-    ) {
+    ) -> (Result<(bool, Certainty), NoSolution>, Option<inspect::GoalEvaluation<'tcx>>) {
         EvalCtxt::enter_root(self, generate_proof_tree, |ecx| {
             ecx.evaluate_goal(GoalEvaluationKind::Root, GoalSource::Misc, goal)
         })
@@ -327,7 +324,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         goal_evaluation_kind: GoalEvaluationKind,
         source: GoalSource,
         goal: Goal<'tcx, ty::Predicate<'tcx>>,
-    ) -> Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution> {
+    ) -> Result<(bool, Certainty), NoSolution> {
         let (orig_values, canonical_goal) = self.canonicalize_goal(goal);
         let mut goal_evaluation =
             self.inspect.new_goal_evaluation(goal, &orig_values, goal_evaluation_kind);
@@ -345,26 +342,13 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
             Ok(response) => response,
         };
 
-        let (certainty, has_changed, nested_goals) = match self
-            .instantiate_response_discarding_overflow(
-                goal.param_env,
-                source,
-                orig_values,
-                canonical_response,
-            ) {
-            Err(e) => {
-                self.inspect.goal_evaluation(goal_evaluation);
-                return Err(e);
-            }
-            Ok(response) => response,
-        };
-        goal_evaluation.returned_goals(&nested_goals);
+        let (certainty, has_changed) = self.instantiate_response_discarding_overflow(
+            goal.param_env,
+            source,
+            orig_values,
+            canonical_response,
+        );
         self.inspect.goal_evaluation(goal_evaluation);
-
-        if !has_changed && !nested_goals.is_empty() {
-            bug!("an unchanged goal shouldn't have any side-effects on instantiation");
-        }
-
         // FIXME: We previously had an assert here that checked that recomputing
         // a goal after applying its constraints did not change its response.
         //
@@ -375,7 +359,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         // Once we have decided on how to handle trait-system-refactor-initiative#75,
         // we should re-add an assert here.
 
-        Ok((has_changed, certainty, nested_goals))
+        Ok((has_changed, certainty))
     }
 
     fn instantiate_response_discarding_overflow(
@@ -384,7 +368,7 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         source: GoalSource,
         original_values: Vec<ty::GenericArg<'tcx>>,
         response: CanonicalResponse<'tcx>,
-    ) -> Result<(Certainty, bool, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution> {
+    ) -> (Certainty, bool) {
         // The old solver did not evaluate nested goals when normalizing.
         // It returned the selection constraints allowing a `Projection`
         // obligation to not hold in coherence while avoiding the fatal error
@@ -405,14 +389,14 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         };
 
         if response.value.certainty == Certainty::OVERFLOW && !keep_overflow_constraints() {
-            Ok((Certainty::OVERFLOW, false, Vec::new()))
+            (Certainty::OVERFLOW, false)
         } else {
             let has_changed = !response.value.var_values.is_identity_modulo_regions()
                 || !response.value.external_constraints.opaque_types.is_empty();
 
-            let (certainty, nested_goals) =
-                self.instantiate_and_apply_query_response(param_env, original_values, response)?;
-            Ok((certainty, has_changed, nested_goals))
+            let certainty =
+                self.instantiate_and_apply_query_response(param_env, original_values, response);
+            (certainty, has_changed)
         }
     }
 
@@ -537,12 +521,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
                 ty::NormalizesTo { alias: goal.predicate.alias, term: unconstrained_rhs },
             );
 
-            let (_, certainty, instantiate_goals) = self.evaluate_goal(
+            let (_, certainty) = self.evaluate_goal(
                 GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::Yes },
                 GoalSource::Misc,
                 unconstrained_goal,
             )?;
-            self.nested_goals.goals.extend(with_misc_source(instantiate_goals));
 
             // Finally, equate the goal's RHS with the unconstrained var.
             // We put the nested goals from this into goals instead of
@@ -573,12 +556,11 @@ impl<'a, 'tcx> EvalCtxt<'a, 'tcx> {
         }
 
         for (source, goal) in goals.goals.drain(..) {
-            let (has_changed, certainty, instantiate_goals) = self.evaluate_goal(
+            let (has_changed, certainty) = self.evaluate_goal(
                 GoalEvaluationKind::Nested { is_normalizes_to_hack: IsNormalizesToHack::No },
                 source,
                 goal,
             )?;
-            self.nested_goals.goals.extend(with_misc_source(instantiate_goals));
             if has_changed {
                 unchanged_certainty = None;
             }
@@ -626,76 +608,101 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
 
     /// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
     ///
-    /// This is the case if the `term` is an inference variable in the innermost universe
-    /// and does not occur in any other part of the predicate.
+    /// This is the case if the `term` does not occur in any other part of the predicate
+    /// and is able to name all other placeholder and inference variables.
     #[instrument(level = "debug", skip(self), ret)]
     pub(super) fn term_is_fully_unconstrained(
         &self,
         goal: Goal<'tcx, ty::NormalizesTo<'tcx>>,
     ) -> bool {
-        let term_is_infer = match goal.predicate.term.unpack() {
+        let universe_of_term = match goal.predicate.term.unpack() {
             ty::TermKind::Ty(ty) => {
                 if let &ty::Infer(ty::TyVar(vid)) = ty.kind() {
-                    match self.infcx.probe_ty_var(vid) {
-                        Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
-                        Err(universe) => universe == self.infcx.universe(),
-                    }
+                    self.infcx.universe_of_ty(vid).unwrap()
                 } else {
-                    false
+                    return false;
                 }
             }
             ty::TermKind::Const(ct) => {
                 if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = ct.kind() {
-                    match self.infcx.probe_const_var(vid) {
-                        Ok(value) => bug!("resolved var in query: {goal:?} {value:?}"),
-                        Err(universe) => universe == self.infcx.universe(),
-                    }
+                    self.infcx.universe_of_ct(vid).unwrap()
                 } else {
-                    false
+                    return false;
                 }
             }
         };
 
-        // Guard against `<T as Trait<?0>>::Assoc = ?0>`.
-        struct ContainsTerm<'a, 'tcx> {
+        struct ContainsTermOrNotNameable<'a, 'tcx> {
             term: ty::Term<'tcx>,
+            universe_of_term: ty::UniverseIndex,
             infcx: &'a InferCtxt<'tcx>,
         }
-        impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTerm<'_, 'tcx> {
+
+        impl<'a, 'tcx> ContainsTermOrNotNameable<'a, 'tcx> {
+            fn check_nameable(&self, universe: ty::UniverseIndex) -> ControlFlow<()> {
+                if self.universe_of_term.can_name(universe) {
+                    ControlFlow::Continue(())
+                } else {
+                    ControlFlow::Break(())
+                }
+            }
+        }
+
+        impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ContainsTermOrNotNameable<'_, 'tcx> {
             type BreakTy = ();
             fn visit_ty(&mut self, t: Ty<'tcx>) -> ControlFlow<Self::BreakTy> {
-                if let Some(vid) = t.ty_vid()
-                    && let ty::TermKind::Ty(term) = self.term.unpack()
-                    && let Some(term_vid) = term.ty_vid()
-                    && self.infcx.root_var(vid) == self.infcx.root_var(term_vid)
-                {
-                    ControlFlow::Break(())
-                } else if t.has_non_region_infer() {
-                    t.super_visit_with(self)
-                } else {
-                    ControlFlow::Continue(())
+                match *t.kind() {
+                    ty::Infer(ty::TyVar(vid)) => {
+                        if let ty::TermKind::Ty(term) = self.term.unpack()
+                            && let Some(term_vid) = term.ty_vid()
+                            && self.infcx.root_var(vid) == self.infcx.root_var(term_vid)
+                        {
+                            ControlFlow::Break(())
+                        } else {
+                            self.check_nameable(self.infcx.universe_of_ty(vid).unwrap())
+                        }
+                    }
+                    ty::Placeholder(p) => self.check_nameable(p.universe),
+                    _ => {
+                        if t.has_non_region_infer() || t.has_placeholders() {
+                            t.super_visit_with(self)
+                        } else {
+                            ControlFlow::Continue(())
+                        }
+                    }
                 }
             }
 
             fn visit_const(&mut self, c: ty::Const<'tcx>) -> ControlFlow<Self::BreakTy> {
-                if let ty::ConstKind::Infer(ty::InferConst::Var(vid)) = c.kind()
-                    && let ty::TermKind::Const(term) = self.term.unpack()
-                    && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
-                    && self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
-                {
-                    ControlFlow::Break(())
-                } else if c.has_non_region_infer() {
-                    c.super_visit_with(self)
-                } else {
-                    ControlFlow::Continue(())
+                match c.kind() {
+                    ty::ConstKind::Infer(ty::InferConst::Var(vid)) => {
+                        if let ty::TermKind::Const(term) = self.term.unpack()
+                            && let ty::ConstKind::Infer(ty::InferConst::Var(term_vid)) = term.kind()
+                            && self.infcx.root_const_var(vid) == self.infcx.root_const_var(term_vid)
+                        {
+                            ControlFlow::Break(())
+                        } else {
+                            self.check_nameable(self.infcx.universe_of_ct(vid).unwrap())
+                        }
+                    }
+                    ty::ConstKind::Placeholder(p) => self.check_nameable(p.universe),
+                    _ => {
+                        if c.has_non_region_infer() || c.has_placeholders() {
+                            c.super_visit_with(self)
+                        } else {
+                            ControlFlow::Continue(())
+                        }
+                    }
                 }
             }
         }
 
-        let mut visitor = ContainsTerm { infcx: self.infcx, term: goal.predicate.term };
-
-        term_is_infer
-            && goal.predicate.alias.visit_with(&mut visitor).is_continue()
+        let mut visitor = ContainsTermOrNotNameable {
+            infcx: self.infcx,
+            universe_of_term,
+            term: goal.predicate.term,
+        };
+        goal.predicate.alias.visit_with(&mut visitor).is_continue()
             && goal.param_env.visit_with(&mut visitor).is_continue()
     }
 
@@ -718,6 +725,26 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             })
     }
 
+    /// This sohuld only be used when we're either instantiating a previously
+    /// unconstrained "return value" or when we're sure that all aliases in
+    /// the types are rigid.
+    #[instrument(level = "debug", skip(self, param_env), ret)]
+    pub(super) fn eq_structurally_relating_aliases<T: ToTrace<'tcx>>(
+        &mut self,
+        param_env: ty::ParamEnv<'tcx>,
+        lhs: T,
+        rhs: T,
+    ) -> Result<(), NoSolution> {
+        let cause = ObligationCause::dummy();
+        let InferOk { value: (), obligations } = self
+            .infcx
+            .at(&cause, param_env)
+            .trace(lhs, rhs)
+            .eq_structurally_relating_aliases(lhs, rhs)?;
+        assert!(obligations.is_empty());
+        Ok(())
+    }
+
     #[instrument(level = "debug", skip(self, param_env), ret)]
     pub(super) fn sub<T: ToTrace<'tcx>>(
         &mut self,
diff --git a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
index 7196a5af259..3262d64cb7d 100644
--- a/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
+++ b/compiler/rustc_trait_selection/src/solve/eval_ctxt/select.rs
@@ -58,44 +58,26 @@ impl<'tcx> InferCtxt<'tcx> {
                 }
 
                 let candidate = candidates.pop().unwrap();
-                let (certainty, nested_goals) = ecx
-                    .instantiate_and_apply_query_response(
-                        trait_goal.param_env,
-                        orig_values,
-                        candidate.result,
-                    )
-                    .map_err(|_| SelectionError::Unimplemented)?;
-
-                Ok(Some((candidate, certainty, nested_goals)))
+                let certainty = ecx.instantiate_and_apply_query_response(
+                    trait_goal.param_env,
+                    orig_values,
+                    candidate.result,
+                );
+
+                Ok(Some((candidate, certainty)))
             });
 
-            let (candidate, certainty, nested_goals) = match result {
-                Ok(Some((candidate, certainty, nested_goals))) => {
-                    (candidate, certainty, nested_goals)
-                }
+            let (candidate, certainty) = match result {
+                Ok(Some(result)) => result,
                 Ok(None) => return Ok(None),
                 Err(e) => return Err(e),
             };
 
-            let nested_obligations: Vec<_> = nested_goals
-                .into_iter()
-                .map(|goal| {
-                    Obligation::new(
-                        self.tcx,
-                        ObligationCause::dummy(),
-                        goal.param_env,
-                        goal.predicate,
-                    )
-                })
-                .collect();
-
             let goal = self.resolve_vars_if_possible(trait_goal);
             match (certainty, candidate.source) {
                 // Rematching the implementation will instantiate the same nested goals that
                 // would have caused the ambiguity, so we can still make progress here regardless.
-                (_, CandidateSource::Impl(def_id)) => {
-                    rematch_impl(self, goal, def_id, nested_obligations)
-                }
+                (_, CandidateSource::Impl(def_id)) => rematch_impl(self, goal, def_id),
 
                 // If an unsize goal is ambiguous, then we can manually rematch it to make
                 // selection progress for coercion during HIR typeck. If it is *not* ambiguous,
@@ -108,20 +90,20 @@ impl<'tcx> InferCtxt<'tcx> {
                 | (Certainty::Yes, CandidateSource::BuiltinImpl(src @ BuiltinImplSource::Misc))
                     if self.tcx.lang_items().unsize_trait() == Some(goal.predicate.def_id()) =>
                 {
-                    rematch_unsize(self, goal, nested_obligations, src, certainty)
+                    rematch_unsize(self, goal, src, certainty)
                 }
 
                 // Technically some builtin impls have nested obligations, but if
                 // `Certainty::Yes`, then they should've all been verified and don't
                 // need re-checking.
                 (Certainty::Yes, CandidateSource::BuiltinImpl(src)) => {
-                    Ok(Some(ImplSource::Builtin(src, nested_obligations)))
+                    Ok(Some(ImplSource::Builtin(src, vec![])))
                 }
 
                 // It's fine not to do anything to rematch these, since there are no
                 // nested obligations.
                 (Certainty::Yes, CandidateSource::ParamEnv(_) | CandidateSource::AliasBound) => {
-                    Ok(Some(ImplSource::Param(nested_obligations)))
+                    Ok(Some(ImplSource::Param(vec![])))
                 }
 
                 (Certainty::Maybe(_), _) => Ok(None),
@@ -192,19 +174,16 @@ fn rematch_impl<'tcx>(
     infcx: &InferCtxt<'tcx>,
     goal: Goal<'tcx, ty::TraitPredicate<'tcx>>,
     impl_def_id: DefId,
-    mut nested: Vec<PredicateObligation<'tcx>>,
 ) -> SelectionResult<'tcx, Selection<'tcx>> {
     let args = infcx.fresh_args_for_item(DUMMY_SP, impl_def_id);
     let impl_trait_ref =
         infcx.tcx.impl_trait_ref(impl_def_id).unwrap().instantiate(infcx.tcx, args);
 
-    nested.extend(
-        infcx
-            .at(&ObligationCause::dummy(), goal.param_env)
-            .eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref)
-            .map_err(|_| SelectionError::Unimplemented)?
-            .into_obligations(),
-    );
+    let mut nested = infcx
+        .at(&ObligationCause::dummy(), goal.param_env)
+        .eq(DefineOpaqueTypes::No, goal.predicate.trait_ref, impl_trait_ref)
+        .map_err(|_| SelectionError::Unimplemented)?
+        .into_obligations();
 
     nested.extend(
         infcx.tcx.predicates_of(impl_def_id).instantiate(infcx.tcx, args).into_iter().map(
@@ -221,11 +200,11 @@ fn rematch_impl<'tcx>(
 fn rematch_unsize<'tcx>(
     infcx: &InferCtxt<'tcx>,
     goal: Goal<'tcx, ty::TraitPredicate<'tcx>>,
-    mut nested: Vec<PredicateObligation<'tcx>>,
     source: BuiltinImplSource,
     certainty: Certainty,
 ) -> SelectionResult<'tcx, Selection<'tcx>> {
     let tcx = infcx.tcx;
+    let mut nested = vec![];
     let a_ty = structurally_normalize(goal.predicate.self_ty(), infcx, goal.param_env, &mut nested);
     let b_ty = structurally_normalize(
         goal.predicate.trait_ref.args.type_at(1),
diff --git a/compiler/rustc_trait_selection/src/solve/fulfill.rs b/compiler/rustc_trait_selection/src/solve/fulfill.rs
index 97f715b6386..c1b07765e50 100644
--- a/compiler/rustc_trait_selection/src/solve/fulfill.rs
+++ b/compiler/rustc_trait_selection/src/solve/fulfill.rs
@@ -2,7 +2,6 @@ use std::mem;
 
 use rustc_infer::infer::InferCtxt;
 use rustc_infer::traits::solve::MaybeCause;
-use rustc_infer::traits::Obligation;
 use rustc_infer::traits::{
     query::NoSolution, FulfillmentError, FulfillmentErrorCode, MismatchedProjectionTypes,
     PredicateObligation, SelectionError, TraitEngine,
@@ -11,7 +10,7 @@ use rustc_middle::ty;
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
 
 use super::eval_ctxt::GenerateProofTree;
-use super::{Certainty, Goal, InferCtxtEvalExt};
+use super::{Certainty, InferCtxtEvalExt};
 
 /// A trait engine using the new trait solver.
 ///
@@ -48,11 +47,11 @@ impl<'tcx> FulfillmentCtxt<'tcx> {
         &self,
         infcx: &InferCtxt<'tcx>,
         obligation: &PredicateObligation<'tcx>,
-        result: &Result<(bool, Certainty, Vec<Goal<'tcx, ty::Predicate<'tcx>>>), NoSolution>,
+        result: &Result<(bool, Certainty), NoSolution>,
     ) {
         if let Some(inspector) = infcx.obligation_inspector.get() {
             let result = match result {
-                Ok((_, c, _)) => Ok(*c),
+                Ok((_, c)) => Ok(*c),
                 Err(NoSolution) => Err(NoSolution),
             };
             (inspector)(infcx, &obligation, result);
@@ -80,13 +79,13 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
                         .evaluate_root_goal(obligation.clone().into(), GenerateProofTree::IfEnabled)
                         .0
                     {
-                        Ok((_, Certainty::Maybe(MaybeCause::Ambiguity), _)) => {
+                        Ok((_, Certainty::Maybe(MaybeCause::Ambiguity))) => {
                             FulfillmentErrorCode::Ambiguity { overflow: false }
                         }
-                        Ok((_, Certainty::Maybe(MaybeCause::Overflow), _)) => {
+                        Ok((_, Certainty::Maybe(MaybeCause::Overflow))) => {
                             FulfillmentErrorCode::Ambiguity { overflow: true }
                         }
-                        Ok((_, Certainty::Yes, _)) => {
+                        Ok((_, Certainty::Yes)) => {
                             bug!("did not expect successful goal when collecting ambiguity errors")
                         }
                         Err(_) => {
@@ -120,7 +119,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
                 let goal = obligation.clone().into();
                 let result = infcx.evaluate_root_goal(goal, GenerateProofTree::IfEnabled).0;
                 self.inspect_evaluated_obligation(infcx, &obligation, &result);
-                let (changed, certainty, nested_goals) = match result {
+                let (changed, certainty) = match result {
                     Ok(result) => result,
                     Err(NoSolution) => {
                         errors.push(FulfillmentError {
@@ -178,16 +177,6 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentCtxt<'tcx> {
                         continue;
                     }
                 };
-                // Push any nested goals that we get from unifying our canonical response
-                // with our obligation onto the fulfillment context.
-                self.obligations.extend(nested_goals.into_iter().map(|goal| {
-                    Obligation::new(
-                        infcx.tcx,
-                        obligation.cause.clone(),
-                        goal.param_env,
-                        goal.predicate,
-                    )
-                }));
                 has_changed |= changed;
                 match certainty {
                     Certainty::Yes => {}
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
index c5d4ce33d86..52b900af853 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/analyse.rs
@@ -63,21 +63,12 @@ impl<'a, 'tcx> InspectCandidate<'a, 'tcx> {
             infcx.probe(|_| {
                 let mut instantiated_goals = vec![];
                 for goal in &self.nested_goals {
-                    let goal = match ProofTreeBuilder::instantiate_canonical_state(
+                    let goal = ProofTreeBuilder::instantiate_canonical_state(
                         infcx,
                         self.goal.goal.param_env,
                         self.goal.orig_values,
                         *goal,
-                    ) {
-                        Ok((_goals, goal)) => goal,
-                        Err(NoSolution) => {
-                            warn!(
-                                "unexpected failure when instantiating {:?}: {:?}",
-                                goal, self.nested_goals
-                            );
-                            return ControlFlow::Continue(());
-                        }
-                    };
+                    );
                     instantiated_goals.push(goal);
                 }
 
diff --git a/compiler/rustc_trait_selection/src/solve/inspect/build.rs b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
index b587a93b24c..f7b310a7abe 100644
--- a/compiler/rustc_trait_selection/src/solve/inspect/build.rs
+++ b/compiler/rustc_trait_selection/src/solve/inspect/build.rs
@@ -87,7 +87,6 @@ struct WipGoalEvaluation<'tcx> {
     pub uncanonicalized_goal: Goal<'tcx, ty::Predicate<'tcx>>,
     pub kind: WipGoalEvaluationKind<'tcx>,
     pub evaluation: Option<WipCanonicalGoalEvaluation<'tcx>>,
-    pub returned_goals: Vec<Goal<'tcx, ty::Predicate<'tcx>>>,
 }
 
 impl<'tcx> WipGoalEvaluation<'tcx> {
@@ -103,7 +102,6 @@ impl<'tcx> WipGoalEvaluation<'tcx> {
                 }
             },
             evaluation: self.evaluation.unwrap().finalize(),
-            returned_goals: self.returned_goals,
         }
     }
 }
@@ -312,7 +310,6 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
                 }
             },
             evaluation: None,
-            returned_goals: vec![],
         })
     }
 
@@ -369,17 +366,6 @@ impl<'tcx> ProofTreeBuilder<'tcx> {
         }
     }
 
-    pub fn returned_goals(&mut self, goals: &[Goal<'tcx, ty::Predicate<'tcx>>]) {
-        if let Some(this) = self.as_mut() {
-            match this {
-                DebugSolver::GoalEvaluation(evaluation) => {
-                    assert!(evaluation.returned_goals.is_empty());
-                    evaluation.returned_goals.extend(goals);
-                }
-                _ => unreachable!(),
-            }
-        }
-    }
     pub fn goal_evaluation(&mut self, goal_evaluation: ProofTreeBuilder<'tcx>) {
         if let Some(this) = self.as_mut() {
             match (this, *goal_evaluation.state.unwrap()) {
diff --git a/compiler/rustc_trait_selection/src/solve/mod.rs b/compiler/rustc_trait_selection/src/solve/mod.rs
index 8b163d47d34..51094b781c0 100644
--- a/compiler/rustc_trait_selection/src/solve/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/mod.rs
@@ -267,6 +267,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     /// This function is necessary in nearly all cases before matching on a type.
     /// Not doing so is likely to be incomplete and therefore unsound during
     /// coherence.
+    #[instrument(level = "debug", skip(self, param_env), ret)]
     fn structurally_normalize_ty(
         &mut self,
         param_env: ty::ParamEnv<'tcx>,
diff --git a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
index 5f625831156..aa8cc3667cd 100644
--- a/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs
@@ -68,6 +68,34 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
             kind => bug!("unknown DefKind {} in projection goal: {goal:#?}", kind.descr(def_id)),
         }
     }
+
+    /// When normalizing an associated item, constrain the result to `term`.
+    ///
+    /// While `NormalizesTo` goals have the normalized-to term as an argument,
+    /// this argument is always fully unconstrained for associated items.
+    /// It is therefore appropriate to instead think of these `NormalizesTo` goals
+    /// as function returning a term after normalizing.
+    ///
+    /// When equating an inference variable and an alias, we tend to emit `alias-relate`
+    /// goals and only actually instantiate the inference variable with an alias if the
+    /// alias is rigid. However, this means that constraining the expected term of
+    /// such goals ends up fully structurally normalizing the resulting type instead of
+    /// only by one step. To avoid this we instead use structural equality here, resulting
+    /// in each `NormalizesTo` only projects by a single step.
+    ///
+    /// Not doing so, currently causes issues because trying to normalize an opaque type
+    /// during alias-relate doesn't actually constrain the opaque if the concrete type
+    /// is an inference variable. This means that `NormalizesTo` for associated types
+    /// normalizing to an opaque type always resulted in ambiguity, breaking tests e.g.
+    /// tests/ui/type-alias-impl-trait/issue-78450.rs.
+    pub fn instantiate_normalizes_to_term(
+        &mut self,
+        goal: Goal<'tcx, NormalizesTo<'tcx>>,
+        term: ty::Term<'tcx>,
+    ) {
+        self.eq_structurally_relating_aliases(goal.param_env, goal.predicate.term, term)
+            .expect("expected goal term to be fully unconstrained");
+    }
 }
 
 impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
@@ -104,8 +132,8 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                         goal.predicate.alias,
                         assumption_projection_pred.projection_ty,
                     )?;
-                    ecx.eq(goal.param_env, goal.predicate.term, assumption_projection_pred.term)
-                        .expect("expected goal term to be fully unconstrained");
+
+                    ecx.instantiate_normalizes_to_term(goal, assumption_projection_pred.term);
 
                     // Add GAT where clauses from the trait's definition
                     ecx.add_goals(
@@ -192,8 +220,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                         "cannot project to an associated function"
                     ),
                 };
-                ecx.eq(goal.param_env, goal.predicate.term, error_term)
-                    .expect("expected goal term to be fully unconstrained");
+                ecx.instantiate_normalizes_to_term(goal, error_term);
                 ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
             };
 
@@ -248,8 +275,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                 ty::AssocKind::Fn => unreachable!("we should never project to a fn"),
             };
 
-            ecx.eq(goal.param_env, goal.predicate.term, term.instantiate(tcx, args))
-                .expect("expected goal term to be fully unconstrained");
+            ecx.instantiate_normalizes_to_term(goal, term.instantiate(tcx, args));
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
@@ -456,7 +482,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
             borrow_region.expect_region(),
         );
 
-        ecx.eq(goal.param_env, goal.predicate.term.ty().unwrap(), upvars_ty)?;
+        ecx.instantiate_normalizes_to_term(goal, upvars_ty.into());
         ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
     }
 
@@ -543,8 +569,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
                 ),
             };
 
-            ecx.eq(goal.param_env, goal.predicate.term, metadata_ty.into())
-                .expect("expected goal term to be fully unconstrained");
+            ecx.instantiate_normalizes_to_term(goal, metadata_ty.into());
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
@@ -627,20 +652,22 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
         }
 
         ecx.probe_misc_candidate("builtin AsyncIterator kind").enter(|ecx| {
+            let expected_ty = ecx.next_ty_infer();
             // Take `AsyncIterator<Item = I>` and turn it into the corresponding
             // coroutine yield ty `Poll<Option<I>>`.
-            let expected_ty = Ty::new_adt(
+            let wrapped_expected_ty = Ty::new_adt(
                 tcx,
                 tcx.adt_def(tcx.require_lang_item(LangItem::Poll, None)),
                 tcx.mk_args(&[Ty::new_adt(
                     tcx,
                     tcx.adt_def(tcx.require_lang_item(LangItem::Option, None)),
-                    tcx.mk_args(&[goal.predicate.term.into()]),
+                    tcx.mk_args(&[expected_ty.into()]),
                 )
                 .into()]),
             );
             let yield_ty = args.as_coroutine().yield_ty();
-            ecx.eq(goal.param_env, expected_ty, yield_ty)?;
+            ecx.eq(goal.param_env, wrapped_expected_ty, yield_ty)?;
+            ecx.instantiate_normalizes_to_term(goal, expected_ty.into());
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
@@ -742,8 +769,7 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
         };
 
         ecx.probe_misc_candidate("builtin discriminant kind").enter(|ecx| {
-            ecx.eq(goal.param_env, goal.predicate.term, discriminant_ty.into())
-                .expect("expected goal term to be fully unconstrained");
+            ecx.instantiate_normalizes_to_term(goal, discriminant_ty.into());
             ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
         })
     }
diff --git a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
index f76be876948..d316149731e 100644
--- a/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/confirmation.rs
@@ -934,7 +934,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
             }
             ty::Closure(_, args) => {
-                let sig = args.as_closure().sig();
+                let args = args.as_closure();
+                let sig = args.sig();
                 let trait_ref = sig.map_bound(|sig| {
                     ty::TraitRef::new(
                         self.tcx(),
@@ -950,7 +951,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         ty::TraitRef::new(tcx, future_trait_def_id, [sig.output()])
                     }),
                 ));
-                (trait_ref, Ty::from_closure_kind(tcx, ty::ClosureKind::Fn))
+                (trait_ref, args.kind_ty())
             }
             _ => bug!("expected callable type for AsyncFn candidate"),
         };
diff --git a/compiler/rustc_ty_utils/src/abi.rs b/compiler/rustc_ty_utils/src/abi.rs
index 638c9a53d22..43042dbd366 100644
--- a/compiler/rustc_ty_utils/src/abi.rs
+++ b/compiler/rustc_ty_utils/src/abi.rs
@@ -312,7 +312,7 @@ fn fn_sig_for_fn_abi<'tcx>(
 fn conv_from_spec_abi(tcx: TyCtxt<'_>, abi: SpecAbi, c_variadic: bool) -> Conv {
     use rustc_target::spec::abi::Abi::*;
     match tcx.sess.target.adjust_abi(abi, c_variadic) {
-        RustIntrinsic | PlatformIntrinsic | Rust | RustCall => Conv::Rust,
+        RustIntrinsic | Rust | RustCall => Conv::Rust,
 
         // This is intentionally not using `Conv::Cold`, as that has to preserve
         // even SIMD registers, which is generally not a good trade-off.
@@ -605,7 +605,7 @@ fn fn_abi_new_uncached<'tcx>(
     let linux_powerpc_gnu_like =
         target.os == "linux" && target.arch == "powerpc" && target_env_gnu_like;
     use SpecAbi::*;
-    let rust_abi = matches!(sig.abi, RustIntrinsic | PlatformIntrinsic | Rust | RustCall);
+    let rust_abi = matches!(sig.abi, RustIntrinsic | Rust | RustCall);
 
     let is_drop_in_place =
         fn_def_id.is_some() && fn_def_id == cx.tcx.lang_items().drop_in_place_fn();
@@ -713,11 +713,7 @@ fn fn_abi_adjust_for_abi<'tcx>(
         return Ok(());
     }
 
-    if abi == SpecAbi::Rust
-        || abi == SpecAbi::RustCall
-        || abi == SpecAbi::RustIntrinsic
-        || abi == SpecAbi::PlatformIntrinsic
-    {
+    if abi == SpecAbi::Rust || abi == SpecAbi::RustCall || abi == SpecAbi::RustIntrinsic {
         // Look up the deduced parameter attributes for this function, if we have its def ID and
         // we're optimizing in non-incremental mode. We'll tag its parameters with those attributes
         // as appropriate.
@@ -753,12 +749,11 @@ fn fn_abi_adjust_for_abi<'tcx>(
                 // target feature sets. Some more information about this
                 // issue can be found in #44367.
                 //
-                // Note that the platform intrinsic ABI is exempt here as
+                // Note that the intrinsic ABI is exempt here as
                 // that's how we connect up to LLVM and it's unstable
                 // anyway, we control all calls to it in libstd.
                 Abi::Vector { .. }
-                    if abi != SpecAbi::PlatformIntrinsic
-                        && cx.tcx.sess.target.simd_types_indirect =>
+                    if abi != SpecAbi::RustIntrinsic && cx.tcx.sess.target.simd_types_indirect =>
                 {
                     arg.make_indirect();
                     return;
diff --git a/compiler/stable_mir/src/ty.rs b/compiler/stable_mir/src/ty.rs
index 658e8aa28b5..ed4a4290246 100644
--- a/compiler/stable_mir/src/ty.rs
+++ b/compiler/stable_mir/src/ty.rs
@@ -906,7 +906,6 @@ pub enum Abi {
     System { unwind: bool },
     RustIntrinsic,
     RustCall,
-    PlatformIntrinsic,
     Unadjusted,
     RustCold,
     RiscvInterruptM,
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index 6dadbc8e364..1d3c04f7807 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -864,7 +864,7 @@ impl String {
         }
     }
 
-    /// Decomposes a `String` into its raw components.
+    /// Decomposes a `String` into its raw components: `(pointer, length, capacity)`.
     ///
     /// Returns the raw pointer to the underlying data, the length of
     /// the string (in bytes), and the allocated capacity of the data
@@ -896,7 +896,7 @@ impl String {
         self.vec.into_raw_parts()
     }
 
-    /// Creates a new `String` from a length, capacity, and pointer.
+    /// Creates a new `String` from a pointer, a length and a capacity.
     ///
     /// # Safety
     ///
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index b59699219eb..7bd19875584 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -481,7 +481,7 @@ impl<T> Vec<T> {
         Self::with_capacity_in(capacity, Global)
     }
 
-    /// Creates a `Vec<T>` directly from a pointer, a capacity, and a length.
+    /// Creates a `Vec<T>` directly from a pointer, a length, and a capacity.
     ///
     /// # Safety
     ///
@@ -672,7 +672,7 @@ impl<T, A: Allocator> Vec<T, A> {
         Vec { buf: RawVec::with_capacity_in(capacity, alloc), len: 0 }
     }
 
-    /// Creates a `Vec<T, A>` directly from a pointer, a capacity, a length,
+    /// Creates a `Vec<T, A>` directly from a pointer, a length, a capacity,
     /// and an allocator.
     ///
     /// # Safety
@@ -786,7 +786,7 @@ impl<T, A: Allocator> Vec<T, A> {
         unsafe { Vec { buf: RawVec::from_raw_parts_in(ptr, capacity, alloc), len: length } }
     }
 
-    /// Decomposes a `Vec<T>` into its raw components.
+    /// Decomposes a `Vec<T>` into its raw components: `(pointer, length, capacity)`.
     ///
     /// Returns the raw pointer to the underlying data, the length of
     /// the vector (in elements), and the allocated capacity of the
@@ -824,7 +824,7 @@ impl<T, A: Allocator> Vec<T, A> {
         (me.as_mut_ptr(), me.len(), me.capacity())
     }
 
-    /// Decomposes a `Vec<T>` into its raw components.
+    /// Decomposes a `Vec<T>` into its raw components: `(pointer, length, capacity, allocator)`.
     ///
     /// Returns the raw pointer to the underlying data, the length of the vector (in elements),
     /// the allocated capacity of the data (in elements), and the allocator. These are the same
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index f9d89795a99..6fd3895bb9c 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -75,6 +75,9 @@ pub unsafe fn drop_in_place<T: ?Sized>(to_drop: *mut T) {
     unsafe { crate::ptr::drop_in_place(to_drop) }
 }
 
+#[cfg(bootstrap)]
+pub use self::r#try as catch_unwind;
+
 extern "rust-intrinsic" {
     // N.B., these intrinsics take raw pointers because they mutate aliased
     // memory, which is not valid for either `&` or `&mut`.
@@ -2382,16 +2385,24 @@ extern "rust-intrinsic" {
     #[rustc_nounwind]
     pub fn variant_count<T>() -> usize;
 
-    /// Rust's "try catch" construct which invokes the function pointer `try_fn`
-    /// with the data pointer `data`.
-    ///
-    /// The third argument is a function called if a panic occurs. This function
-    /// takes the data pointer and a pointer to the target-specific exception
-    /// object that was caught. For more information see the compiler's
-    /// source as well as std's catch implementation.
+    /// Rust's "try catch" construct for unwinding. Invokes the function pointer `try_fn` with the
+    /// data pointer `data`, and calls `catch_fn` if unwinding occurs while `try_fn` runs.
     ///
     /// `catch_fn` must not unwind.
+    ///
+    /// The third argument is a function called if an unwind occurs (both Rust unwinds and foreign
+    /// unwinds). This function takes the data pointer and a pointer to the target-specific
+    /// exception object that was caught. For more information, see the compiler's source as well as
+    /// std's `catch_unwind` implementation.
+    ///
+    /// The stable version of this intrinsic is `std::panic::catch_unwind`.
+    #[rustc_nounwind]
+    #[cfg(not(bootstrap))]
+    pub fn catch_unwind(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;
+
+    /// For bootstrap only, see `catch_unwind`.
     #[rustc_nounwind]
+    #[cfg(bootstrap)]
     pub fn r#try(try_fn: fn(*mut u8), data: *mut u8, catch_fn: fn(*mut u8, *mut u8)) -> i32;
 
     /// Emits a `!nontemporal` store according to LLVM (see their docs).
diff --git a/library/core/src/intrinsics/simd.rs b/library/core/src/intrinsics/simd.rs
index d8a1ad778d7..2eaca3b6fe4 100644
--- a/library/core/src/intrinsics/simd.rs
+++ b/library/core/src/intrinsics/simd.rs
@@ -2,7 +2,11 @@
 //!
 //! In this module, a "vector" is any `repr(simd)` type.
 
-extern "platform-intrinsic" {
+// Temporary macro while we switch the ABI from "platform-intrinsics" to "intrinsics".
+#[rustfmt::skip]
+macro_rules! declare_intrinsics {
+($abi:tt) => {
+extern $abi {
     /// Insert an element into a vector, returning the updated vector.
     ///
     /// `T` must be a vector with element type `U`.
@@ -10,6 +14,7 @@ extern "platform-intrinsic" {
     /// # Safety
     ///
     /// `idx` must be in-bounds of the vector.
+    #[rustc_nounwind]
     pub fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
 
     /// Extract an element from a vector.
@@ -19,21 +24,25 @@ extern "platform-intrinsic" {
     /// # Safety
     ///
     /// `idx` must be in-bounds of the vector.
+    #[rustc_nounwind]
     pub fn simd_extract<T, U>(x: T, idx: u32) -> U;
 
     /// Add two simd vectors elementwise.
     ///
     /// `T` must be a vector of integer or floating point primitive types.
+    #[rustc_nounwind]
     pub fn simd_add<T>(x: T, y: T) -> T;
 
     /// Subtract `rhs` from `lhs` elementwise.
     ///
     /// `T` must be a vector of integer or floating point primitive types.
+    #[rustc_nounwind]
     pub fn simd_sub<T>(lhs: T, rhs: T) -> T;
 
     /// Multiply two simd vectors elementwise.
     ///
     /// `T` must be a vector of integer or floating point primitive types.
+    #[rustc_nounwind]
     pub fn simd_mul<T>(x: T, y: T) -> T;
 
     /// Divide `lhs` by `rhs` elementwise.
@@ -43,6 +52,7 @@ extern "platform-intrinsic" {
     /// # Safety
     /// For integers, `rhs` must not contain any zero elements.
     /// Additionally for signed integers, `<int>::MIN / -1` is undefined behavior.
+    #[rustc_nounwind]
     pub fn simd_div<T>(lhs: T, rhs: T) -> T;
 
     /// Remainder of two vectors elementwise
@@ -52,6 +62,7 @@ extern "platform-intrinsic" {
     /// # Safety
     /// For integers, `rhs` must not contain any zero elements.
     /// Additionally for signed integers, `<int>::MIN / -1` is undefined behavior.
+    #[rustc_nounwind]
     pub fn simd_rem<T>(lhs: T, rhs: T) -> T;
 
     /// Elementwise vector left shift, with UB on overflow.
@@ -63,6 +74,7 @@ extern "platform-intrinsic" {
     /// # Safety
     ///
     /// Each element of `rhs` must be less than `<int>::BITS`.
+    #[rustc_nounwind]
     pub fn simd_shl<T>(lhs: T, rhs: T) -> T;
 
     /// Elementwise vector right shift, with UB on overflow.
@@ -74,21 +86,25 @@ extern "platform-intrinsic" {
     /// # Safety
     ///
     /// Each element of `rhs` must be less than `<int>::BITS`.
+    #[rustc_nounwind]
     pub fn simd_shr<T>(lhs: T, rhs: T) -> T;
 
     /// Elementwise vector "and".
     ///
     /// `T` must be a vector of integer primitive types.
+    #[rustc_nounwind]
     pub fn simd_and<T>(x: T, y: T) -> T;
 
     /// Elementwise vector "or".
     ///
     /// `T` must be a vector of integer primitive types.
+    #[rustc_nounwind]
     pub fn simd_or<T>(x: T, y: T) -> T;
 
     /// Elementwise vector "exclusive or".
     ///
     /// `T` must be a vector of integer primitive types.
+    #[rustc_nounwind]
     pub fn simd_xor<T>(x: T, y: T) -> T;
 
     /// Numerically cast a vector, elementwise.
@@ -109,6 +125,7 @@ extern "platform-intrinsic" {
     /// * Not be `NaN`
     /// * Not be infinite
     /// * Be representable in the return type, after truncating off its fractional part
+    #[rustc_nounwind]
     pub fn simd_cast<T, U>(x: T) -> U;
 
     /// Numerically cast a vector, elementwise.
@@ -122,6 +139,7 @@ extern "platform-intrinsic" {
     /// When casting floats to integers, the result is truncated.
     /// When casting integers to floats, the result is rounded.
     /// Otherwise, truncates or extends the value, maintaining the sign for signed integers.
+    #[rustc_nounwind]
     pub fn simd_as<T, U>(x: T) -> U;
 
     /// Elementwise negation of a vector.
@@ -129,11 +147,13 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of integer or floating-point primitive types.
     ///
     /// Rust panics for `-<int>::Min` due to overflow, but it is not UB with this intrinsic.
+    #[rustc_nounwind]
     pub fn simd_neg<T>(x: T) -> T;
 
     /// Elementwise absolute value of a vector.
     ///
     /// `T` must be a vector of floating-point primitive types.
+    #[rustc_nounwind]
     pub fn simd_fabs<T>(x: T) -> T;
 
     /// Elementwise minimum of a vector.
@@ -141,6 +161,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of floating-point primitive types.
     ///
     /// Follows IEEE-754 `minNum` semantics.
+    #[rustc_nounwind]
     pub fn simd_fmin<T>(x: T, y: T) -> T;
 
     /// Elementwise maximum of a vector.
@@ -148,6 +169,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of floating-point primitive types.
     ///
     /// Follows IEEE-754 `maxNum` semantics.
+    #[rustc_nounwind]
     pub fn simd_fmax<T>(x: T, y: T) -> T;
 
     /// Tests elementwise equality of two vectors.
@@ -157,6 +179,7 @@ extern "platform-intrinsic" {
     /// `U` must be a vector of integers with the same number of elements and element size as `T`.
     ///
     /// Returns `0` for false and `!0` for true.
+    #[rustc_nounwind]
     pub fn simd_eq<T, U>(x: T, y: T) -> U;
 
     /// Tests elementwise inequality equality of two vectors.
@@ -166,6 +189,7 @@ extern "platform-intrinsic" {
     /// `U` must be a vector of integers with the same number of elements and element size as `T`.
     ///
     /// Returns `0` for false and `!0` for true.
+    #[rustc_nounwind]
     pub fn simd_ne<T, U>(x: T, y: T) -> U;
 
     /// Tests if `x` is less than `y`, elementwise.
@@ -175,6 +199,7 @@ extern "platform-intrinsic" {
     /// `U` must be a vector of integers with the same number of elements and element size as `T`.
     ///
     /// Returns `0` for false and `!0` for true.
+    #[rustc_nounwind]
     pub fn simd_lt<T, U>(x: T, y: T) -> U;
 
     /// Tests if `x` is less than or equal to `y`, elementwise.
@@ -184,6 +209,7 @@ extern "platform-intrinsic" {
     /// `U` must be a vector of integers with the same number of elements and element size as `T`.
     ///
     /// Returns `0` for false and `!0` for true.
+    #[rustc_nounwind]
     pub fn simd_le<T, U>(x: T, y: T) -> U;
 
     /// Tests if `x` is greater than `y`, elementwise.
@@ -193,6 +219,7 @@ extern "platform-intrinsic" {
     /// `U` must be a vector of integers with the same number of elements and element size as `T`.
     ///
     /// Returns `0` for false and `!0` for true.
+    #[rustc_nounwind]
     pub fn simd_gt<T, U>(x: T, y: T) -> U;
 
     /// Tests if `x` is greater than or equal to `y`, elementwise.
@@ -202,6 +229,7 @@ extern "platform-intrinsic" {
     /// `U` must be a vector of integers with the same number of elements and element size as `T`.
     ///
     /// Returns `0` for false and `!0` for true.
+    #[rustc_nounwind]
     pub fn simd_ge<T, U>(x: T, y: T) -> U;
 
     /// Shuffle two vectors by const indices.
@@ -216,6 +244,7 @@ extern "platform-intrinsic" {
     /// Returns a new vector such that element `i` is selected from `xy[idx[i]]`, where `xy`
     /// is the concatenation of `x` and `y`. It is a compile-time error if `idx[i]` is out-of-bounds
     /// of `xy`.
+    #[rustc_nounwind]
     pub fn simd_shuffle<T, U, V>(x: T, y: T, idx: U) -> V;
 
     /// Shuffle two vectors by const indices.
@@ -227,6 +256,7 @@ extern "platform-intrinsic" {
     /// Returns a new vector such that element `i` is selected from `xy[IDX[i]]`, where `xy`
     /// is the concatenation of `x` and `y`. It is a compile-time error if `IDX[i]` is out-of-bounds
     /// of `xy`.
+    #[rustc_nounwind]
     pub fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
 
     /// Read a vector of pointers.
@@ -249,6 +279,7 @@ extern "platform-intrinsic" {
     /// type).
     ///
     /// `mask` must only contain `0` or `!0` values.
+    #[rustc_nounwind]
     pub fn simd_gather<T, U, V>(val: T, ptr: U, mask: V) -> T;
 
     /// Write to a vector of pointers.
@@ -271,6 +302,7 @@ extern "platform-intrinsic" {
     /// type).
     ///
     /// `mask` must only contain `0` or `!0` values.
+    #[rustc_nounwind]
     pub fn simd_scatter<T, U, V>(val: T, ptr: U, mask: V);
 
     /// Read a vector of pointers.
@@ -292,6 +324,7 @@ extern "platform-intrinsic" {
     /// type).
     ///
     /// `mask` must only contain `0` or `!0` values.
+    #[rustc_nounwind]
     pub fn simd_masked_load<V, U, T>(mask: V, ptr: U, val: T) -> T;
 
     /// Write to a vector of pointers.
@@ -312,11 +345,13 @@ extern "platform-intrinsic" {
     /// type).
     ///
     /// `mask` must only contain `0` or `!0` values.
+    #[rustc_nounwind]
     pub fn simd_masked_store<V, U, T>(mask: V, ptr: U, val: T);
 
     /// Add two simd vectors elementwise, with saturation.
     ///
     /// `T` must be a vector of integer primitive types.
+    #[rustc_nounwind]
     pub fn simd_saturating_add<T>(x: T, y: T) -> T;
 
     /// Subtract two simd vectors elementwise, with saturation.
@@ -324,6 +359,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of integer primitive types.
     ///
     /// Subtract `rhs` from `lhs`.
+    #[rustc_nounwind]
     pub fn simd_saturating_sub<T>(lhs: T, rhs: T) -> T;
 
     /// Add elements within a vector from left to right.
@@ -333,6 +369,7 @@ extern "platform-intrinsic" {
     /// `U` must be the element type of `T`.
     ///
     /// Starting with the value `y`, add the elements of `x` and accumulate.
+    #[rustc_nounwind]
     pub fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
 
     /// Add elements within a vector in arbitrary order. May also be re-associated with
@@ -341,6 +378,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of integer or floating-point primitive types.
     ///
     /// `U` must be the element type of `T`.
+    #[rustc_nounwind]
     pub fn simd_reduce_add_unordered<T, U>(x: T) -> U;
 
     /// Multiply elements within a vector from left to right.
@@ -350,6 +388,7 @@ extern "platform-intrinsic" {
     /// `U` must be the element type of `T`.
     ///
     /// Starting with the value `y`, multiply the elements of `x` and accumulate.
+    #[rustc_nounwind]
     pub fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
 
     /// Add elements within a vector in arbitrary order. May also be re-associated with
@@ -358,6 +397,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of integer or floating-point primitive types.
     ///
     /// `U` must be the element type of `T`.
+    #[rustc_nounwind]
     pub fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
 
     /// Check if all mask values are true.
@@ -366,6 +406,7 @@ extern "platform-intrinsic" {
     ///
     /// # Safety
     /// `x` must contain only `0` or `!0`.
+    #[rustc_nounwind]
     pub fn simd_reduce_all<T>(x: T) -> bool;
 
     /// Check if all mask values are true.
@@ -374,6 +415,7 @@ extern "platform-intrinsic" {
     ///
     /// # Safety
     /// `x` must contain only `0` or `!0`.
+    #[rustc_nounwind]
     pub fn simd_reduce_any<T>(x: T) -> bool;
 
     /// Return the maximum element of a vector.
@@ -383,6 +425,7 @@ extern "platform-intrinsic" {
     /// `U` must be the element type of `T`.
     ///
     /// For floating-point values, uses IEEE-754 `maxNum`.
+    #[rustc_nounwind]
     pub fn simd_reduce_max<T, U>(x: T) -> U;
 
     /// Return the minimum element of a vector.
@@ -392,6 +435,7 @@ extern "platform-intrinsic" {
     /// `U` must be the element type of `T`.
     ///
     /// For floating-point values, uses IEEE-754 `minNum`.
+    #[rustc_nounwind]
     pub fn simd_reduce_min<T, U>(x: T) -> U;
 
     /// Logical "and" all elements together.
@@ -399,6 +443,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of integer or floating-point primitive types.
     ///
     /// `U` must be the element type of `T`.
+    #[rustc_nounwind]
     pub fn simd_reduce_and<T, U>(x: T) -> U;
 
     /// Logical "or" all elements together.
@@ -406,6 +451,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of integer or floating-point primitive types.
     ///
     /// `U` must be the element type of `T`.
+    #[rustc_nounwind]
     pub fn simd_reduce_or<T, U>(x: T) -> U;
 
     /// Logical "exclusive or" all elements together.
@@ -413,6 +459,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of integer or floating-point primitive types.
     ///
     /// `U` must be the element type of `T`.
+    #[rustc_nounwind]
     pub fn simd_reduce_xor<T, U>(x: T) -> U;
 
     /// Truncate an integer vector to a bitmask.
@@ -441,6 +488,7 @@ extern "platform-intrinsic" {
     ///
     /// # Safety
     /// `x` must contain only `0` and `!0`.
+    #[rustc_nounwind]
     pub fn simd_bitmask<T, U>(x: T) -> U;
 
     /// Select elements from a mask.
@@ -455,6 +503,7 @@ extern "platform-intrinsic" {
     ///
     /// # Safety
     /// `mask` must only contain `0` and `!0`.
+    #[rustc_nounwind]
     pub fn simd_select<M, T>(mask: M, if_true: T, if_false: T) -> T;
 
     /// Select elements from a bitmask.
@@ -471,6 +520,7 @@ extern "platform-intrinsic" {
     ///
     /// # Safety
     /// Padding bits must be all zero.
+    #[rustc_nounwind]
     pub fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T;
 
     /// Elementwise calculates the offset from a pointer vector, potentially wrapping.
@@ -480,11 +530,13 @@ extern "platform-intrinsic" {
     /// `U` must be a vector of `isize` or `usize` with the same number of elements as `T`.
     ///
     /// Operates as if by `<ptr>::wrapping_offset`.
+    #[rustc_nounwind]
     pub fn simd_arith_offset<T, U>(ptr: T, offset: U) -> T;
 
     /// Cast a vector of pointers.
     ///
     /// `T` and `U` must be vectors of pointers with the same number of elements.
+    #[rustc_nounwind]
     pub fn simd_cast_ptr<T, U>(ptr: T) -> U;
 
     /// Expose a vector of pointers as a vector of addresses.
@@ -492,6 +544,7 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of pointers.
     ///
     /// `U` must be a vector of `usize` with the same length as `T`.
+    #[rustc_nounwind]
     pub fn simd_expose_addr<T, U>(ptr: T) -> U;
 
     /// Create a vector of pointers from a vector of addresses.
@@ -499,92 +552,117 @@ extern "platform-intrinsic" {
     /// `T` must be a vector of `usize`.
     ///
     /// `U` must be a vector of pointers, with the same length as `T`.
+    #[rustc_nounwind]
     pub fn simd_from_exposed_addr<T, U>(addr: T) -> U;
 
     /// Swap bytes of each element.
     ///
     /// `T` must be a vector of integers.
+    #[rustc_nounwind]
     pub fn simd_bswap<T>(x: T) -> T;
 
     /// Reverse bits of each element.
     ///
     /// `T` must be a vector of integers.
+    #[rustc_nounwind]
     pub fn simd_bitreverse<T>(x: T) -> T;
 
     /// Count the leading zeros of each element.
     ///
     /// `T` must be a vector of integers.
+    #[rustc_nounwind]
     pub fn simd_ctlz<T>(x: T) -> T;
 
     /// Count the trailing zeros of each element.
     ///
     /// `T` must be a vector of integers.
+    #[rustc_nounwind]
     pub fn simd_cttz<T>(x: T) -> T;
 
     /// Round up each element to the next highest integer-valued float.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_ceil<T>(x: T) -> T;
 
     /// Round down each element to the next lowest integer-valued float.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_floor<T>(x: T) -> T;
 
     /// Round each element to the closest integer-valued float.
     /// Ties are resolved by rounding away from 0.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_round<T>(x: T) -> T;
 
     /// Return the integer part of each element as an integer-valued float.
     /// In other words, non-integer values are truncated towards zero.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_trunc<T>(x: T) -> T;
 
     /// Takes the square root of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_fsqrt<T>(x: T) -> T;
 
     /// Computes `(x*y) + z` for each element, but without any intermediate rounding.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_fma<T>(x: T, y: T, z: T) -> T;
 
     // Computes the sine of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_fsin<T>(a: T) -> T;
 
     // Computes the cosine of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_fcos<T>(a: T) -> T;
 
     // Computes the exponential function of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_fexp<T>(a: T) -> T;
 
     // Computes 2 raised to the power of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_fexp2<T>(a: T) -> T;
 
     // Computes the base 10 logarithm of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_flog10<T>(a: T) -> T;
 
     // Computes the base 2 logarithm of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_flog2<T>(a: T) -> T;
 
     // Computes the natural logarithm of each element.
     ///
     /// `T` must be a vector of floats.
+    #[rustc_nounwind]
     pub fn simd_flog<T>(a: T) -> T;
 }
+}
+}
+
+#[cfg(bootstrap)]
+declare_intrinsics!("platform-intrinsic");
+#[cfg(not(bootstrap))]
+declare_intrinsics!("rust-intrinsic");
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 49cead680e3..7b735d48bdf 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -202,6 +202,7 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(platform_intrinsics))]
 #![feature(abi_unadjusted)]
 #![feature(adt_const_params)]
 #![feature(allow_internal_unsafe)]
@@ -246,7 +247,6 @@
 #![feature(never_type)]
 #![feature(no_core)]
 #![feature(no_sanitize)]
-#![feature(platform_intrinsics)]
 #![feature(prelude_import)]
 #![feature(repr_simd)]
 #![feature(rustc_allow_const_fn_unstable)]
diff --git a/library/panic_unwind/src/miri.rs b/library/panic_unwind/src/miri.rs
index d941b73b5fa..4d21e846010 100644
--- a/library/panic_unwind/src/miri.rs
+++ b/library/panic_unwind/src/miri.rs
@@ -8,14 +8,14 @@ type Payload = Box<Box<dyn Any + Send>>;
 
 extern "Rust" {
     /// Miri-provided extern function to begin unwinding.
-    fn miri_start_panic(payload: *mut u8) -> !;
+    fn miri_start_unwind(payload: *mut u8) -> !;
 }
 
 pub unsafe fn panic(payload: Box<dyn Any + Send>) -> u32 {
-    // The payload we pass to `miri_start_panic` will be exactly the argument we get
+    // The payload we pass to `miri_start_unwind` will be exactly the argument we get
     // in `cleanup` below. So we just box it up once, to get something pointer-sized.
     let payload_box: Payload = Box::new(payload);
-    miri_start_panic(Box::into_raw(payload_box) as *mut u8)
+    miri_start_unwind(Box::into_raw(payload_box) as *mut u8)
 }
 
 pub unsafe fn cleanup(payload_box: *mut u8) -> Box<dyn Any + Send> {
diff --git a/library/std/src/lib.rs b/library/std/src/lib.rs
index c6cd2c6786a..288cce3aa08 100644
--- a/library/std/src/lib.rs
+++ b/library/std/src/lib.rs
@@ -270,6 +270,7 @@
 //
 // Language features:
 // tidy-alphabetical-start
+#![cfg_attr(bootstrap, feature(platform_intrinsics))]
 #![feature(alloc_error_handler)]
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
@@ -301,7 +302,6 @@
 #![feature(negative_impls)]
 #![feature(never_type)]
 #![feature(no_sanitize)]
-#![feature(platform_intrinsics)]
 #![feature(prelude_import)]
 #![feature(rustc_attrs)]
 #![feature(rustdoc_internals)]
diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs
index ef701d3867a..464a46264cb 100644
--- a/library/std/src/panicking.rs
+++ b/library/std/src/panicking.rs
@@ -508,12 +508,12 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // Access to the union's fields: this is `std` and we know that the `r#try`
     // intrinsic fills in the `r` or `p` union field based on its return value.
     //
-    // The call to `intrinsics::r#try` is made safe by:
+    // The call to `intrinsics::catch_unwind` is made safe by:
     // - `do_call`, the first argument, can be called with the initial `data_ptr`.
     // - `do_catch`, the second argument, can be called with the `data_ptr` as well.
     // See their safety preconditions for more information
     unsafe {
-        return if intrinsics::r#try(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
+        return if intrinsics::catch_unwind(do_call::<F, R>, data_ptr, do_catch::<F, R>) == 0 {
             Ok(ManuallyDrop::into_inner(data.r))
         } else {
             Err(ManuallyDrop::into_inner(data.p))
@@ -540,7 +540,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // Its must contains a valid `f` (type: F) value that can be use to fill
     // `data.r`.
     //
-    // This function cannot be marked as `unsafe` because `intrinsics::r#try`
+    // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
     // expects normal function pointers.
     #[inline]
     fn do_call<F: FnOnce() -> R, R>(data: *mut u8) {
@@ -562,7 +562,7 @@ pub unsafe fn r#try<R, F: FnOnce() -> R>(f: F) -> Result<R, Box<dyn Any + Send>>
     // Since this uses `cleanup` it also hinges on a correct implementation of
     // `__rustc_panic_cleanup`.
     //
-    // This function cannot be marked as `unsafe` because `intrinsics::r#try`
+    // This function cannot be marked as `unsafe` because `intrinsics::catch_unwind`
     // expects normal function pointers.
     #[inline]
     #[rustc_nounwind] // `intrinsic::r#try` requires catch fn to be nounwind
diff --git a/library/std/src/sync/mpmc/list.rs b/library/std/src/sync/mpmc/list.rs
index 406a331a309..a1b275112a1 100644
--- a/library/std/src/sync/mpmc/list.rs
+++ b/library/std/src/sync/mpmc/list.rs
@@ -547,7 +547,7 @@ impl<T> Channel<T> {
         }
 
         let mut head = self.head.index.load(Ordering::Acquire);
-        let mut block = self.head.block.load(Ordering::Acquire);
+        let mut block = self.head.block.swap(ptr::null_mut(), Ordering::AcqRel);
 
         // If we're going to be dropping messages we need to synchronize with initialization
         if head >> SHIFT != tail >> SHIFT {
@@ -588,8 +588,8 @@ impl<T> Channel<T> {
                 drop(Box::from_raw(block));
             }
         }
+
         head &= !MARK_BIT;
-        self.head.block.store(ptr::null_mut(), Ordering::Release);
         self.head.index.store(head, Ordering::Release);
     }
 
diff --git a/library/std/src/sys/pal/windows/c.rs b/library/std/src/sys/pal/windows/c.rs
index ad8e01bfa9b..b007796722b 100644
--- a/library/std/src/sys/pal/windows/c.rs
+++ b/library/std/src/sys/pal/windows/c.rs
@@ -28,17 +28,14 @@ pub type SIZE_T = usize;
 pub type WORD = u16;
 pub type CHAR = c_char;
 pub type ULONG = c_ulong;
-pub type ACCESS_MASK = DWORD;
 
 pub type LPCVOID = *const c_void;
-pub type LPHANDLE = *mut HANDLE;
 pub type LPOVERLAPPED = *mut OVERLAPPED;
 pub type LPSECURITY_ATTRIBUTES = *mut SECURITY_ATTRIBUTES;
 pub type LPVOID = *mut c_void;
 pub type LPWCH = *mut WCHAR;
 pub type LPWSTR = *mut WCHAR;
 
-pub type PLARGE_INTEGER = *mut c_longlong;
 pub type PSRWLOCK = *mut SRWLOCK;
 
 pub type socklen_t = c_int;
@@ -360,6 +357,19 @@ compat_fn_with_fallback! {
     }
 }
 
+#[cfg(not(target_vendor = "win7"))]
+#[link(name = "synchronization")]
+extern "system" {
+    pub fn WaitOnAddress(
+        address: *const c_void,
+        compareaddress: *const c_void,
+        addresssize: usize,
+        dwmilliseconds: u32,
+    ) -> BOOL;
+    pub fn WakeByAddressSingle(address: *const c_void);
+}
+
+#[cfg(target_vendor = "win7")]
 compat_fn_optional! {
     crate::sys::compat::load_synch_functions();
     pub fn WaitOnAddress(
@@ -371,30 +381,34 @@ compat_fn_optional! {
     pub fn WakeByAddressSingle(address: *const ::core::ffi::c_void);
 }
 
+#[cfg(any(target_vendor = "win7", target_vendor = "uwp"))]
 compat_fn_with_fallback! {
     pub static NTDLL: &CStr = c"ntdll";
 
+    #[cfg(target_vendor = "win7")]
     pub fn NtCreateKeyedEvent(
-        KeyedEventHandle: LPHANDLE,
-        DesiredAccess: ACCESS_MASK,
+        KeyedEventHandle: *mut HANDLE,
+        DesiredAccess: DWORD,
         ObjectAttributes: LPVOID,
         Flags: ULONG
     ) -> NTSTATUS {
         panic!("keyed events not available")
     }
+    #[cfg(target_vendor = "win7")]
     pub fn NtReleaseKeyedEvent(
         EventHandle: HANDLE,
         Key: LPVOID,
         Alertable: BOOLEAN,
-        Timeout: PLARGE_INTEGER
+        Timeout: *mut c_longlong
     ) -> NTSTATUS {
         panic!("keyed events not available")
     }
+    #[cfg(target_vendor = "win7")]
     pub fn NtWaitForKeyedEvent(
         EventHandle: HANDLE,
         Key: LPVOID,
         Alertable: BOOLEAN,
-        Timeout: PLARGE_INTEGER
+        Timeout: *mut c_longlong
     ) -> NTSTATUS {
         panic!("keyed events not available")
     }
diff --git a/library/std/src/sys/pal/windows/compat.rs b/library/std/src/sys/pal/windows/compat.rs
index f60b3a2c700..f5d57a28db6 100644
--- a/library/std/src/sys/pal/windows/compat.rs
+++ b/library/std/src/sys/pal/windows/compat.rs
@@ -21,7 +21,6 @@
 
 use crate::ffi::{c_void, CStr};
 use crate::ptr::NonNull;
-use crate::sync::atomic::Ordering;
 use crate::sys::c;
 
 // This uses a static initializer to preload some imported functions.
@@ -38,6 +37,7 @@ use crate::sys::c;
 // file an issue for discussion; currently we don't guarantee any functionality
 // before main.
 // See https://docs.microsoft.com/en-us/cpp/c-runtime-library/crt-initialization?view=msvc-170
+#[cfg(target_vendor = "win7")]
 #[used]
 #[link_section = ".CRT$XCT"]
 static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
@@ -52,6 +52,7 @@ static INIT_TABLE_ENTRY: unsafe extern "C" fn() = init;
 /// negative performance impact in practical situations.
 ///
 /// Currently we only preload `WaitOnAddress` and `WakeByAddressSingle`.
+#[cfg(target_vendor = "win7")]
 unsafe extern "C" fn init() {
     // In an exe this code is executed before main() so is single threaded.
     // In a DLL the system's loader lock will be held thereby synchronizing
@@ -183,6 +184,7 @@ macro_rules! compat_fn_with_fallback {
                 func($($argname),*)
             }
         }
+        #[allow(unused)]
         $(#[$meta])*
         $vis use $symbol::call as $symbol;
     )*)
@@ -191,6 +193,7 @@ macro_rules! compat_fn_with_fallback {
 /// Optionally loaded functions.
 ///
 /// Actual loading of the function defers to $load_functions.
+#[cfg(target_vendor = "win7")]
 macro_rules! compat_fn_optional {
     ($load_functions:expr;
     $(
@@ -218,13 +221,19 @@ macro_rules! compat_fn_optional {
                     NonNull::new(PTR.load(Ordering::Relaxed)).map(|f| unsafe { mem::transmute(f) })
                 }
             }
+            #[inline]
+            pub unsafe extern "system" fn $symbol($($argname: $argtype),*) $(-> $rettype)? {
+                $symbol::option().unwrap()($($argname),*)
+            }
         )+
     )
 }
 
 /// Load all needed functions from "api-ms-win-core-synch-l1-2-0".
+#[cfg(target_vendor = "win7")]
 pub(super) fn load_synch_functions() {
     fn try_load() -> Option<()> {
+        use crate::sync::atomic::Ordering;
         const MODULE_NAME: &CStr = c"api-ms-win-core-synch-l1-2-0";
         const WAIT_ON_ADDRESS: &CStr = c"WaitOnAddress";
         const WAKE_BY_ADDRESS_SINGLE: &CStr = c"WakeByAddressSingle";
diff --git a/library/std/src/sys/pal/windows/thread_parking.rs b/library/std/src/sys/pal/windows/thread_parking.rs
index ea485d71f5a..4b8102d505a 100644
--- a/library/std/src/sys/pal/windows/thread_parking.rs
+++ b/library/std/src/sys/pal/windows/thread_parking.rs
@@ -58,10 +58,9 @@
 // [4]: Windows Internals, Part 1, ISBN 9780735671300
 
 use crate::pin::Pin;
-use crate::ptr;
 use crate::sync::atomic::{
-    AtomicI8, AtomicPtr,
-    Ordering::{Acquire, Relaxed, Release},
+    AtomicI8,
+    Ordering::{Acquire, Release},
 };
 use crate::sys::{c, dur2timeout};
 use crate::time::Duration;
@@ -111,26 +110,21 @@ impl Parker {
             return;
         }
 
-        if let Some(wait_on_address) = c::WaitOnAddress::option() {
-            loop {
-                // Wait for something to happen, assuming it's still set to PARKED.
-                wait_on_address(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, c::INFINITE);
-                // Change NOTIFIED=>EMPTY but leave PARKED alone.
-                if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Acquire).is_ok() {
-                    // Actually woken up by unpark().
-                    return;
-                } else {
-                    // Spurious wake up. We loop to try again.
-                }
+        #[cfg(target_vendor = "win7")]
+        if c::WaitOnAddress::option().is_none() {
+            return keyed_events::park(self);
+        }
+
+        loop {
+            // Wait for something to happen, assuming it's still set to PARKED.
+            c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, c::INFINITE);
+            // Change NOTIFIED=>EMPTY but leave PARKED alone.
+            if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Acquire).is_ok() {
+                // Actually woken up by unpark().
+                return;
+            } else {
+                // Spurious wake up. We loop to try again.
             }
-        } else {
-            // Wait for unpark() to produce this event.
-            c::NtWaitForKeyedEvent(keyed_event_handle(), self.ptr(), 0, ptr::null_mut());
-            // Set the state back to EMPTY (from either PARKED or NOTIFIED).
-            // Note that we don't just write EMPTY, but use swap() to also
-            // include an acquire-ordered read to synchronize with unpark()'s
-            // release-ordered write.
-            self.state.swap(EMPTY, Acquire);
         }
     }
 
@@ -144,47 +138,23 @@ impl Parker {
             return;
         }
 
-        if let Some(wait_on_address) = c::WaitOnAddress::option() {
-            // Wait for something to happen, assuming it's still set to PARKED.
-            wait_on_address(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, dur2timeout(timeout));
-            // Set the state back to EMPTY (from either PARKED or NOTIFIED).
-            // Note that we don't just write EMPTY, but use swap() to also
-            // include an acquire-ordered read to synchronize with unpark()'s
-            // release-ordered write.
-            if self.state.swap(EMPTY, Acquire) == NOTIFIED {
-                // Actually woken up by unpark().
-            } else {
-                // Timeout or spurious wake up.
-                // We return either way, because we can't easily tell if it was the
-                // timeout or not.
-            }
+        #[cfg(target_vendor = "win7")]
+        if c::WaitOnAddress::option().is_none() {
+            return keyed_events::park_timeout(self, timeout);
+        }
+
+        // Wait for something to happen, assuming it's still set to PARKED.
+        c::WaitOnAddress(self.ptr(), &PARKED as *const _ as c::LPVOID, 1, dur2timeout(timeout));
+        // Set the state back to EMPTY (from either PARKED or NOTIFIED).
+        // Note that we don't just write EMPTY, but use swap() to also
+        // include an acquire-ordered read to synchronize with unpark()'s
+        // release-ordered write.
+        if self.state.swap(EMPTY, Acquire) == NOTIFIED {
+            // Actually woken up by unpark().
         } else {
-            // Need to wait for unpark() using NtWaitForKeyedEvent.
-            let handle = keyed_event_handle();
-
-            // NtWaitForKeyedEvent uses a unit of 100ns, and uses negative
-            // values to indicate a relative time on the monotonic clock.
-            // This is documented here for the underlying KeWaitForSingleObject function:
-            // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-kewaitforsingleobject
-            let mut timeout = match i64::try_from((timeout.as_nanos() + 99) / 100) {
-                Ok(t) => -t,
-                Err(_) => i64::MIN,
-            };
-
-            // Wait for unpark() to produce this event.
-            let unparked =
-                c::NtWaitForKeyedEvent(handle, self.ptr(), 0, &mut timeout) == c::STATUS_SUCCESS;
-
-            // Set the state back to EMPTY (from either PARKED or NOTIFIED).
-            let prev_state = self.state.swap(EMPTY, Acquire);
-
-            if !unparked && prev_state == NOTIFIED {
-                // We were awoken by a timeout, not by unpark(), but the state
-                // was set to NOTIFIED, which means we *just* missed an
-                // unpark(), which is now blocked on us to wait for it.
-                // Wait for it to consume the event and unblock that thread.
-                c::NtWaitForKeyedEvent(handle, self.ptr(), 0, ptr::null_mut());
-            }
+            // Timeout or spurious wake up.
+            // We return either way, because we can't easily tell if it was the
+            // timeout or not.
         }
     }
 
@@ -198,18 +168,11 @@ impl Parker {
         // with park().
         if self.state.swap(NOTIFIED, Release) == PARKED {
             unsafe {
-                if let Some(wake_by_address_single) = c::WakeByAddressSingle::option() {
-                    wake_by_address_single(self.ptr());
-                } else {
-                    // If we run NtReleaseKeyedEvent before the waiting thread runs
-                    // NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
-                    // If the waiting thread wakes up before we run NtReleaseKeyedEvent
-                    // (e.g. due to a timeout), this blocks until we do wake up a thread.
-                    // To prevent this thread from blocking indefinitely in that case,
-                    // park_impl() will, after seeing the state set to NOTIFIED after
-                    // waking up, call NtWaitForKeyedEvent again to unblock us.
-                    c::NtReleaseKeyedEvent(keyed_event_handle(), self.ptr(), 0, ptr::null_mut());
+                #[cfg(target_vendor = "win7")]
+                if c::WakeByAddressSingle::option().is_none() {
+                    return keyed_events::unpark(self);
                 }
+                c::WakeByAddressSingle(self.ptr());
             }
         }
     }
@@ -219,35 +182,97 @@ impl Parker {
     }
 }
 
-fn keyed_event_handle() -> c::HANDLE {
-    const INVALID: c::HANDLE = ptr::without_provenance_mut(!0);
-    static HANDLE: AtomicPtr<crate::ffi::c_void> = AtomicPtr::new(INVALID);
-    match HANDLE.load(Relaxed) {
-        INVALID => {
-            let mut handle = c::INVALID_HANDLE_VALUE;
-            unsafe {
-                match c::NtCreateKeyedEvent(
-                    &mut handle,
-                    c::GENERIC_READ | c::GENERIC_WRITE,
-                    ptr::null_mut(),
-                    0,
-                ) {
-                    c::STATUS_SUCCESS => {}
-                    r => panic!("Unable to create keyed event handle: error {r}"),
+#[cfg(target_vendor = "win7")]
+mod keyed_events {
+    use super::{Parker, EMPTY, NOTIFIED};
+    use crate::sys::c;
+    use core::pin::Pin;
+    use core::ptr;
+    use core::sync::atomic::{
+        AtomicPtr,
+        Ordering::{Acquire, Relaxed},
+    };
+    use core::time::Duration;
+
+    pub unsafe fn park(parker: Pin<&Parker>) {
+        // Wait for unpark() to produce this event.
+        c::NtWaitForKeyedEvent(keyed_event_handle(), parker.ptr(), 0, ptr::null_mut());
+        // Set the state back to EMPTY (from either PARKED or NOTIFIED).
+        // Note that we don't just write EMPTY, but use swap() to also
+        // include an acquire-ordered read to synchronize with unpark()'s
+        // release-ordered write.
+        parker.state.swap(EMPTY, Acquire);
+        return;
+    }
+    pub unsafe fn park_timeout(parker: Pin<&Parker>, timeout: Duration) {
+        // Need to wait for unpark() using NtWaitForKeyedEvent.
+        let handle = keyed_event_handle();
+
+        // NtWaitForKeyedEvent uses a unit of 100ns, and uses negative
+        // values to indicate a relative time on the monotonic clock.
+        // This is documented here for the underlying KeWaitForSingleObject function:
+        // https://docs.microsoft.com/en-us/windows-hardware/drivers/ddi/wdm/nf-wdm-kewaitforsingleobject
+        let mut timeout = match i64::try_from((timeout.as_nanos() + 99) / 100) {
+            Ok(t) => -t,
+            Err(_) => i64::MIN,
+        };
+
+        // Wait for unpark() to produce this event.
+        let unparked =
+            c::NtWaitForKeyedEvent(handle, parker.ptr(), 0, &mut timeout) == c::STATUS_SUCCESS;
+
+        // Set the state back to EMPTY (from either PARKED or NOTIFIED).
+        let prev_state = parker.state.swap(EMPTY, Acquire);
+
+        if !unparked && prev_state == NOTIFIED {
+            // We were awoken by a timeout, not by unpark(), but the state
+            // was set to NOTIFIED, which means we *just* missed an
+            // unpark(), which is now blocked on us to wait for it.
+            // Wait for it to consume the event and unblock that thread.
+            c::NtWaitForKeyedEvent(handle, parker.ptr(), 0, ptr::null_mut());
+        }
+    }
+    pub unsafe fn unpark(parker: Pin<&Parker>) {
+        // If we run NtReleaseKeyedEvent before the waiting thread runs
+        // NtWaitForKeyedEvent, this (shortly) blocks until we can wake it up.
+        // If the waiting thread wakes up before we run NtReleaseKeyedEvent
+        // (e.g. due to a timeout), this blocks until we do wake up a thread.
+        // To prevent this thread from blocking indefinitely in that case,
+        // park_impl() will, after seeing the state set to NOTIFIED after
+        // waking up, call NtWaitForKeyedEvent again to unblock us.
+        c::NtReleaseKeyedEvent(keyed_event_handle(), parker.ptr(), 0, ptr::null_mut());
+    }
+
+    fn keyed_event_handle() -> c::HANDLE {
+        const INVALID: c::HANDLE = ptr::without_provenance_mut(!0);
+        static HANDLE: AtomicPtr<crate::ffi::c_void> = AtomicPtr::new(INVALID);
+        match HANDLE.load(Relaxed) {
+            INVALID => {
+                let mut handle = c::INVALID_HANDLE_VALUE;
+                unsafe {
+                    match c::NtCreateKeyedEvent(
+                        &mut handle,
+                        c::GENERIC_READ | c::GENERIC_WRITE,
+                        ptr::null_mut(),
+                        0,
+                    ) {
+                        c::STATUS_SUCCESS => {}
+                        r => panic!("Unable to create keyed event handle: error {r}"),
+                    }
                 }
-            }
-            match HANDLE.compare_exchange(INVALID, handle, Relaxed, Relaxed) {
-                Ok(_) => handle,
-                Err(h) => {
-                    // Lost the race to another thread initializing HANDLE before we did.
-                    // Closing our handle and using theirs instead.
-                    unsafe {
-                        c::CloseHandle(handle);
+                match HANDLE.compare_exchange(INVALID, handle, Relaxed, Relaxed) {
+                    Ok(_) => handle,
+                    Err(h) => {
+                        // Lost the race to another thread initializing HANDLE before we did.
+                        // Closing our handle and using theirs instead.
+                        unsafe {
+                            c::CloseHandle(handle);
+                        }
+                        h
                     }
-                    h
                 }
             }
+            handle => handle,
         }
-        handle => handle,
     }
 }
diff --git a/src/doc/book b/src/doc/book
-Subproject 71352deb20727b4dda9ebfe8182709d5bf17dfe
+Subproject 19c40bfd2d57641d962f3119a1c343355f1b3c5
diff --git a/src/doc/edition-guide b/src/doc/edition-guide
-Subproject 76bd48a273a0e0413a3bf22c699112d41497b99
+Subproject e1eead1181a691e56299294d5f1d62fe7a26d31
diff --git a/src/doc/reference b/src/doc/reference
-Subproject 8227666de13f6e7bb32dea9dc42e841adb5ce4b
+Subproject 3417f866932cb1c09c6be0f31d2a02ee01b4b95
diff --git a/src/doc/rust-by-example b/src/doc/rust-by-example
-Subproject e188d5d466f7f3ff9f1d518393235f4fe951be4
+Subproject 57f1e708f5d5850562bc385aaf610e6af14d6ec
diff --git a/src/doc/rustc-dev-guide b/src/doc/rustc-dev-guide
-Subproject 1f30cc7cca9a3433bc1872abdc98960b36c21ca
+Subproject 7b0ef5b0bea5e3ce3b9764aa5754a60e2cc05c5
diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js
index b26efb75ff6..b9a769a7c6d 100644
--- a/src/librustdoc/html/static/js/main.js
+++ b/src/librustdoc/html/static/js/main.js
@@ -185,9 +185,12 @@ function preLoadCss(cssUrl) {
 (function() {
     const isHelpPage = window.location.pathname.endsWith("/help.html");
 
-    function loadScript(url) {
+    function loadScript(url, errorCallback) {
         const script = document.createElement("script");
         script.src = url;
+        if (errorCallback !== undefined) {
+            script.onerror = errorCallback;
+        }
         document.head.append(script);
     }
 
@@ -292,11 +295,16 @@ function preLoadCss(cssUrl) {
                 return;
             }
             let searchLoaded = false;
+            // If you're browsing the nightly docs, the page might need to be refreshed for the
+            // search to work because the hash of the JS scripts might have changed.
+            function sendSearchForm() {
+                document.getElementsByClassName("search-form")[0].submit();
+            }
             function loadSearch() {
                 if (!searchLoaded) {
                     searchLoaded = true;
-                    loadScript(getVar("static-root-path") + getVar("search-js"));
-                    loadScript(resourcePath("search-index", ".js"));
+                    loadScript(getVar("static-root-path") + getVar("search-js"), sendSearchForm);
+                    loadScript(resourcePath("search-index", ".js"), sendSearchForm);
                 }
             }
 
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index 0467a8a6570..c52a4e0d8b7 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -143,7 +143,8 @@ pub fn eq_expr(l: &Expr, r: &Expr) -> bool {
     match (&l.kind, &r.kind) {
         (Paren(l), _) => eq_expr(l, r),
         (_, Paren(r)) => eq_expr(l, r),
-        (Err, Err) => true,
+        (Err(_), Err(_)) => true,
+        (Dummy, _) | (_, Dummy) => unreachable!("comparing `ExprKind::Dummy`"),
         (Try(l), Try(r)) | (Await(l, _), Await(r, _)) => eq_expr(l, r),
         (Array(l), Array(r)) => over(l, r, |l, r| eq_expr(l, r)),
         (Tup(l), Tup(r)) => over(l, r, |l, r| eq_expr(l, r)),
diff --git a/src/tools/clippy/clippy_utils/src/sugg.rs b/src/tools/clippy/clippy_utils/src/sugg.rs
index b355e66b7b1..1f6446b8746 100644
--- a/src/tools/clippy/clippy_utils/src/sugg.rs
+++ b/src/tools/clippy/clippy_utils/src/sugg.rs
@@ -222,7 +222,8 @@ impl<'a> Sugg<'a> {
             | ast::ExprKind::Array(..)
             | ast::ExprKind::While(..)
             | ast::ExprKind::Await(..)
-            | ast::ExprKind::Err => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
+            | ast::ExprKind::Err(_)
+            | ast::ExprKind::Dummy => Sugg::NonParen(snippet_with_context(cx, expr.span, ctxt, default, app).0),
             ast::ExprKind::Range(ref lhs, ref rhs, RangeLimits::HalfOpen) => Sugg::BinOp(
                 AssocOp::DotDot,
                 lhs.as_ref().map_or("".into(), |lhs| {
diff --git a/src/tools/compiletest/src/header.rs b/src/tools/compiletest/src/header.rs
index c76cba824a3..6de445a5783 100644
--- a/src/tools/compiletest/src/header.rs
+++ b/src/tools/compiletest/src/header.rs
@@ -197,6 +197,8 @@ pub struct TestProps {
     /// Extra flags to pass to `llvm-cov` when producing coverage reports.
     /// Only used by the "coverage-run" test mode.
     pub llvm_cov_flags: Vec<String>,
+    /// Extra flags to pass to LLVM's `filecheck` tool, in tests that use it.
+    pub filecheck_flags: Vec<String>,
 }
 
 mod directives {
@@ -236,6 +238,7 @@ mod directives {
     pub const REMAP_SRC_BASE: &'static str = "remap-src-base";
     pub const COMPARE_OUTPUT_LINES_BY_SUBSET: &'static str = "compare-output-lines-by-subset";
     pub const LLVM_COV_FLAGS: &'static str = "llvm-cov-flags";
+    pub const FILECHECK_FLAGS: &'static str = "filecheck-flags";
     // This isn't a real directive, just one that is probably mistyped often
     pub const INCORRECT_COMPILER_FLAGS: &'static str = "compiler-flags";
 }
@@ -286,6 +289,7 @@ impl TestProps {
             mir_unit_test: None,
             remap_src_base: false,
             llvm_cov_flags: vec![],
+            filecheck_flags: vec![],
         }
     }
 
@@ -542,6 +546,10 @@ impl TestProps {
                     if let Some(flags) = config.parse_name_value_directive(ln, LLVM_COV_FLAGS) {
                         self.llvm_cov_flags.extend(split_flags(&flags));
                     }
+
+                    if let Some(flags) = config.parse_name_value_directive(ln, FILECHECK_FLAGS) {
+                        self.filecheck_flags.extend(split_flags(&flags));
+                    }
                 },
             );
 
diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs
index 61211a7d675..f1ba9ab4767 100644
--- a/src/tools/compiletest/src/runtest.rs
+++ b/src/tools/compiletest/src/runtest.rs
@@ -2909,25 +2909,32 @@ impl<'test> TestCx<'test> {
     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);
-        // It would be more appropriate to make most of the arguments configurable through
-        // a comment-attribute similar to `compile-flags`. For example, --check-prefixes is a very
-        // useful flag.
-        //
-        // For now, though…
-        let prefix_for_target =
-            if self.config.target.contains("msvc") { "MSVC" } else { "NONMSVC" };
-        let prefixes = if let Some(rev) = self.revision {
-            format!("CHECK,{},{}", prefix_for_target, rev)
-        } else {
-            format!("CHECK,{}", prefix_for_target)
-        };
-        if self.config.llvm_version.unwrap_or(0) >= 130000 {
-            filecheck.args(&["--allow-unused-prefixes", "--check-prefixes", &prefixes]);
-        } else {
-            filecheck.args(&["--check-prefixes", &prefixes]);
+
+        // FIXME: Consider making some of these prefix flags opt-in per test,
+        // via `filecheck-flags` or by adding new header directives.
+
+        // Because we use custom prefixes, we also have to register the default prefix.
+        filecheck.arg("--check-prefix=CHECK");
+
+        // Some tests use the current revision name as a check prefix.
+        if let Some(rev) = self.revision {
+            filecheck.arg("--check-prefix").arg(rev);
         }
+
+        // Some tests also expect either the MSVC or NONMSVC prefix to be defined.
+        let msvc_or_not = if self.config.target.contains("msvc") { "MSVC" } else { "NONMSVC" };
+        filecheck.arg("--check-prefix").arg(msvc_or_not);
+
+        // The filecheck tool normally fails if a prefix is defined but not used.
+        // However, we define several prefixes globally for all tests.
+        filecheck.arg("--allow-unused-prefixes");
+
         // Provide more context on failures.
         filecheck.args(&["--dump-input-context", "100"]);
+
+        // Add custom flags supplied by the `filecheck-flags:` test header.
+        filecheck.args(&self.props.filecheck_flags);
+
         self.compose_and_run(filecheck, "", None, None)
     }
 
diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version
index e62c61b1043..37273d9183a 100644
--- a/src/tools/miri/rust-version
+++ b/src/tools/miri/rust-version
@@ -1 +1 @@
-0250ef2571185b05701ed9d74fc904c17508a397
+71ffdf7ff7ac6df5f9f64de7e780b8345797e8a0
diff --git a/src/tools/miri/src/concurrency/thread.rs b/src/tools/miri/src/concurrency/thread.rs
index 64e1f3c5b55..822ba8bf922 100644
--- a/src/tools/miri/src/concurrency/thread.rs
+++ b/src/tools/miri/src/concurrency/thread.rs
@@ -143,7 +143,7 @@ pub struct Thread<'mir, 'tcx> {
     join_status: ThreadJoinStatus,
 
     /// Stack of active panic payloads for the current thread. Used for storing
-    /// the argument of the call to `miri_start_panic` (the panic payload) when unwinding.
+    /// the argument of the call to `miri_start_unwind` (the panic payload) when unwinding.
     /// This is pointer-sized, and matches the `Payload` type in `src/libpanic_unwind/miri.rs`.
     ///
     /// In real unwinding, the payload gets passed as an argument to the landing pad,
diff --git a/src/tools/miri/src/shims/foreign_items.rs b/src/tools/miri/src/shims/foreign_items.rs
index 0645c1f176e..4ae607e98da 100644
--- a/src/tools/miri/src/shims/foreign_items.rs
+++ b/src/tools/miri/src/shims/foreign_items.rs
@@ -68,9 +68,9 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         let ret = match ret {
             None =>
                 match link_name.as_str() {
-                    "miri_start_panic" => {
-                        // `check_shim` happens inside `handle_miri_start_panic`.
-                        this.handle_miri_start_panic(abi, link_name, args, unwind)?;
+                    "miri_start_unwind" => {
+                        // `check_shim` happens inside `handle_miri_start_unwind`.
+                        this.handle_miri_start_unwind(abi, link_name, args, unwind)?;
                         return Ok(None);
                     }
                     // This matches calls to the foreign item `panic_impl`.
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index 602e8b31b01..b67d588dbc9 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -54,7 +54,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
 
         // Some intrinsics are special and need the "ret".
         match intrinsic_name {
-            "try" => return this.handle_try(args, dest, ret),
+            "catch_unwind" => return this.handle_catch_unwind(args, dest, ret),
             _ => {}
         }
 
diff --git a/src/tools/miri/src/shims/panic.rs b/src/tools/miri/src/shims/panic.rs
index 4c054d8dc8a..65b5838cd14 100644
--- a/src/tools/miri/src/shims/panic.rs
+++ b/src/tools/miri/src/shims/panic.rs
@@ -3,9 +3,9 @@
 //! The core pieces of the runtime are:
 //! - An implementation of `__rust_maybe_catch_panic` that pushes the invoked stack frame with
 //!   some extra metadata derived from the panic-catching arguments of `__rust_maybe_catch_panic`.
-//! - A hack in `libpanic_unwind` that calls the `miri_start_panic` intrinsic instead of the
+//! - A hack in `libpanic_unwind` that calls the `miri_start_unwind` intrinsic instead of the
 //!   target-native panic runtime. (This lives in the rustc repo.)
-//! - An implementation of `miri_start_panic` that stores its argument (the panic payload), and then
+//! - An implementation of `miri_start_unwind` that stores its argument (the panic payload), and then
 //!   immediately returns, but on the *unwind* edge (not the normal return edge), thus initiating unwinding.
 //! - A hook executed each time a frame is popped, such that if the frame pushed by `__rust_maybe_catch_panic`
 //!   gets popped *during unwinding*, we take the panic payload and store it according to the extra
@@ -44,9 +44,9 @@ impl VisitProvenance for CatchUnwindData<'_> {
 
 impl<'mir, 'tcx: 'mir> EvalContextExt<'mir, 'tcx> for crate::MiriInterpCx<'mir, 'tcx> {}
 pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
-    /// Handles the special `miri_start_panic` intrinsic, which is called
+    /// Handles the special `miri_start_unwind` intrinsic, which is called
     /// by libpanic_unwind to delegate the actual unwinding process to Miri.
-    fn handle_miri_start_panic(
+    fn handle_miri_start_unwind(
         &mut self,
         abi: Abi,
         link_name: Symbol,
@@ -55,7 +55,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     ) -> InterpResult<'tcx> {
         let this = self.eval_context_mut();
 
-        trace!("miri_start_panic: {:?}", this.frame().instance);
+        trace!("miri_start_unwind: {:?}", this.frame().instance);
 
         // Get the raw pointer stored in arg[0] (the panic payload).
         let [payload] = this.check_shim(abi, Abi::Rust, link_name, args)?;
@@ -69,7 +69,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
     }
 
     /// Handles the `try` intrinsic, the underlying implementation of `std::panicking::try`.
-    fn handle_try(
+    fn handle_catch_unwind(
         &mut self,
         args: &[OpTy<'tcx, Provenance>],
         dest: &PlaceTy<'tcx, Provenance>,
@@ -85,7 +85,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
         // what that is), and returns 1.
         // The `payload` is passed (by libstd) to `__rust_panic_cleanup`, which is then expected to
         // return a `Box<dyn Any + Send + 'static>`.
-        // In Miri, `miri_start_panic` is passed exactly that type, so we make the `payload` simply
+        // In Miri, `miri_start_unwind` is passed exactly that type, so we make the `payload` simply
         // a pointer to `Box<dyn Any + Send + 'static>`.
 
         // Get all the arguments.
@@ -141,7 +141,7 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             // We set the return value of `try` to 1, since there was a panic.
             this.write_scalar(Scalar::from_i32(1), &catch_unwind.dest)?;
 
-            // The Thread's `panic_payload` holds what was passed to `miri_start_panic`.
+            // The Thread's `panic_payload` holds what was passed to `miri_start_unwind`.
             // This is exactly the second argument we need to pass to `catch_fn`.
             let payload = this.active_thread_mut().panic_payloads.pop().unwrap();
 
diff --git a/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs b/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs
index 883d5ae8096..fd667fbe454 100644
--- a/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs
+++ b/src/tools/miri/tests/fail/function_calls/check_callback_abi.rs
@@ -8,7 +8,7 @@ fn main() {
     unsafe {
         // Make sure we check the ABI when Miri itself invokes a function
         // as part of a shim implementation.
-        std::intrinsics::r#try(
+        std::intrinsics::catch_unwind(
             //~^ ERROR: calling a function with ABI C using caller ABI Rust
             std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
             std::ptr::null_mut(),
diff --git a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr
index f948d08bdbe..501f17c86d6 100644
--- a/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr
+++ b/src/tools/miri/tests/fail/function_calls/check_callback_abi.stderr
@@ -1,7 +1,7 @@
 error: Undefined Behavior: calling a function with ABI C using caller ABI Rust
   --> $DIR/check_callback_abi.rs:LL:CC
    |
-LL | /         std::intrinsics::r#try(
+LL | /         std::intrinsics::catch_unwind(
 LL | |
 LL | |             std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
 LL | |             std::ptr::null_mut(),
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs b/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs
index 5fa6f69d005..ba474332b81 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-div-by-zero.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    pub(crate) fn simd_div<T>(x: T, y: T) -> T;
-}
+use std::intrinsics::simd::simd_div;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs b/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs
index 57712b1b836..d01e41de0e4 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-div-overflow.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    pub(crate) fn simd_div<T>(x: T, y: T) -> T;
-}
+use std::intrinsics::simd::simd_div;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs b/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs
index 354f8213120..a194f0dd18a 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-reduce-invalid-bool.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    pub(crate) fn simd_reduce_any<T>(x: T) -> bool;
-}
+use std::intrinsics::simd::simd_reduce_any;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs b/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs
index 625889bb67b..cd1e4b8162b 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-rem-by-zero.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    pub(crate) fn simd_rem<T>(x: T, y: T) -> T;
-}
+use std::intrinsics::simd::simd_rem;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs b/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs
index 8a3895ac14c..96802fae49c 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-select-bitmask-invalid.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T;
-}
+use std::intrinsics::simd::simd_select_bitmask;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs b/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs
index 7f7ee3af495..388fb2e2a84 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-select-invalid-bool.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    fn simd_select<M, T>(m: M, yes: T, no: T) -> T;
-}
+use std::intrinsics::simd::simd_select;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs b/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs
index 5c517c17b3a..8a49c8403ae 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-shl-too-far.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    pub(crate) fn simd_shl<T>(x: T, y: T) -> T;
-}
+use std::intrinsics::simd::simd_shl;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs b/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs
index 5f1475a6778..433998cbde6 100644
--- a/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs
+++ b/src/tools/miri/tests/fail/intrinsics/simd-shr-too-far.rs
@@ -1,8 +1,6 @@
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(core_intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
-    pub(crate) fn simd_shr<T>(x: T, y: T) -> T;
-}
+use std::intrinsics::simd::simd_shr;
 
 #[repr(simd)]
 #[allow(non_camel_case_types)]
diff --git a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.rs
index 4b0ae60b101..deca836a36c 100644
--- a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.rs
+++ b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.rs
@@ -3,10 +3,10 @@
 #![feature(c_unwind)]
 
 extern "C" {
-    fn miri_start_panic(payload: *mut u8) -> !;
+    fn miri_start_unwind(payload: *mut u8) -> !;
 }
 
 fn main() {
-    unsafe { miri_start_panic(&mut 0) }
+    unsafe { miri_start_unwind(&mut 0) }
     //~^ ERROR: unwinding past a stack frame that does not allow unwinding
 }
diff --git a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.stderr
index 2d96ae4b7de..6c85aac050a 100644
--- a/src/tools/miri/tests/fail/panic/bad_miri_start_panic.stderr
+++ b/src/tools/miri/tests/fail/panic/bad_miri_start_unwind.stderr
@@ -1,15 +1,15 @@
 WARNING: the flag `-Zmiri-disable-abi-check` is deprecated and planned to be removed.
 If you have a use-case for it, please file an issue.
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
-  --> $DIR/bad_miri_start_panic.rs:LL:CC
+  --> $DIR/bad_miri_start_unwind.rs:LL:CC
    |
-LL |     unsafe { miri_start_panic(&mut 0) }
-   |              ^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
+LL |     unsafe { miri_start_unwind(&mut 0) }
+   |              ^^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
    = note: BACKTRACE:
-   = note: inside `main` at $DIR/bad_miri_start_panic.rs:LL:CC
+   = note: inside `main` at $DIR/bad_miri_start_unwind.rs:LL:CC
 
 note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
 
diff --git a/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs b/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs
index c21fa85a904..88419b1395c 100644
--- a/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs
+++ b/src/tools/miri/tests/fail/panic/unwind_panic_abort.rs
@@ -3,11 +3,11 @@
 //! Unwinding despite `-C panic=abort` is an error.
 
 extern "Rust" {
-    fn miri_start_panic(payload: *mut u8) -> !;
+    fn miri_start_unwind(payload: *mut u8) -> !;
 }
 
 fn main() {
     unsafe {
-        miri_start_panic(&mut 0); //~ ERROR: unwinding past a stack frame that does not allow unwinding
+        miri_start_unwind(&mut 0); //~ ERROR: unwinding past a stack frame that does not allow unwinding
     }
 }
diff --git a/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr b/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr
index 4739c7f2ac6..26afe8830cf 100644
--- a/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr
+++ b/src/tools/miri/tests/fail/panic/unwind_panic_abort.stderr
@@ -1,8 +1,8 @@
 error: Undefined Behavior: unwinding past a stack frame that does not allow unwinding
   --> $DIR/unwind_panic_abort.rs:LL:CC
    |
-LL |         miri_start_panic(&mut 0);
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
+LL |         miri_start_unwind(&mut 0);
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ unwinding past a stack frame that does not allow unwinding
    |
    = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
    = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
diff --git a/src/tools/miri/tests/pass/float_nan.rs b/src/tools/miri/tests/pass/float_nan.rs
index 4bfd12245ef..cadbbd58af5 100644
--- a/src/tools/miri/tests/pass/float_nan.rs
+++ b/src/tools/miri/tests/pass/float_nan.rs
@@ -1,4 +1,4 @@
-#![feature(float_gamma, portable_simd, core_intrinsics, platform_intrinsics)]
+#![feature(float_gamma, portable_simd, core_intrinsics)]
 use std::collections::HashSet;
 use std::fmt;
 use std::hash::Hash;
@@ -525,12 +525,6 @@ fn test_simd() {
     use std::intrinsics::simd::*;
     use std::simd::*;
 
-    extern "platform-intrinsic" {
-        fn simd_fsqrt<T>(x: T) -> T;
-        fn simd_ceil<T>(x: T) -> T;
-        fn simd_fma<T>(x: T, y: T, z: T) -> T;
-    }
-
     let nan = F32::nan(Neg, Quiet, 0).as_f32();
     check_all_outcomes(
         HashSet::from_iter([F32::nan(Pos, Quiet, 0), F32::nan(Neg, Quiet, 0)]),
diff --git a/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs b/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs
index e6251b53558..0f41047c603 100644
--- a/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs
+++ b/src/tools/miri/tests/pass/function_calls/disable_abi_check.rs
@@ -15,7 +15,7 @@ fn main() {
     unsafe {
         let _ = malloc(0);
         std::mem::transmute::<fn(), extern "C" fn()>(foo)();
-        std::intrinsics::r#try(
+        std::intrinsics::catch_unwind(
             std::mem::transmute::<extern "C" fn(*mut u8), _>(try_fn),
             std::ptr::null_mut(),
             |_, _| unreachable!(),
diff --git a/src/tools/miri/tests/pass/portable-simd-ptrs.rs b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
index a73b1d03cfa..70ba5636c60 100644
--- a/src/tools/miri/tests/pass/portable-simd-ptrs.rs
+++ b/src/tools/miri/tests/pass/portable-simd-ptrs.rs
@@ -1,6 +1,6 @@
 // Separate test without strict provenance
 //@compile-flags: -Zmiri-permissive-provenance
-#![feature(portable_simd, platform_intrinsics)]
+#![feature(portable_simd)]
 use std::ptr;
 use std::simd::prelude::*;
 
diff --git a/src/tools/miri/tests/pass/portable-simd.rs b/src/tools/miri/tests/pass/portable-simd.rs
index d4b3ab8ac09..399913a757b 100644
--- a/src/tools/miri/tests/pass/portable-simd.rs
+++ b/src/tools/miri/tests/pass/portable-simd.rs
@@ -1,5 +1,5 @@
 //@compile-flags: -Zmiri-strict-provenance
-#![feature(portable_simd, platform_intrinsics, adt_const_params, inline_const, core_intrinsics)]
+#![feature(portable_simd, adt_const_params, inline_const, core_intrinsics)]
 #![allow(incomplete_features, internal_features)]
 use std::intrinsics::simd as intrinsics;
 use std::ptr;
@@ -216,10 +216,7 @@ fn simd_ops_i32() {
 }
 
 fn simd_mask() {
-    extern "platform-intrinsic" {
-        pub(crate) fn simd_bitmask<T, U>(x: T) -> U;
-        pub(crate) fn simd_select_bitmask<M, T>(m: M, yes: T, no: T) -> T;
-    }
+    use std::intrinsics::simd::*;
 
     let intmask = Mask::from_int(i32x4::from_array([0, -1, 0, 0]));
     assert_eq!(intmask, Mask::from_array([false, true, false, false]));
@@ -493,9 +490,6 @@ fn simd_round() {
 
 fn simd_intrinsics() {
     use intrinsics::*;
-    extern "platform-intrinsic" {
-        fn simd_shuffle_generic<T, U, const IDX: &'static [u32]>(x: T, y: T) -> U;
-    }
 
     unsafe {
         // Make sure simd_eq returns all-1 for `true`
diff --git a/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs b/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs
index 5958357c8b7..4a87f8c3ca7 100644
--- a/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs
+++ b/src/tools/miri/tests/pass/simd-intrinsic-generic-elements.rs
@@ -1,4 +1,4 @@
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, Debug, PartialEq)]
diff --git a/src/tools/miri/tests/utils/miri_extern.rs b/src/tools/miri/tests/utils/miri_extern.rs
index ff7990561f2..e2983f6c71a 100644
--- a/src/tools/miri/tests/utils/miri_extern.rs
+++ b/src/tools/miri/tests/utils/miri_extern.rs
@@ -56,7 +56,7 @@ extern "Rust" {
     ///
     /// This is internal and unstable and should not be used; we give it here
     /// just to be complete.
-    pub fn miri_start_panic(payload: *mut u8) -> !;
+    pub fn miri_start_unwind(payload: *mut u8) -> !;
 
     /// Miri-provided extern function to get the internal unique identifier for the allocation that a pointer
     /// points to. If this pointer is invalid (not pointing to an allocation), interpretation will abort.
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 4b86c2acdc5..c500b30b998 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -404,7 +404,7 @@ pub(crate) fn format_expr(
             // These do not occur in the AST because macros aren't expanded.
             unreachable!()
         }
-        ast::ExprKind::Err => None,
+        ast::ExprKind::Err(_) | ast::ExprKind::Dummy => None,
     };
 
     expr_rw
diff --git a/src/tools/rustfmt/src/formatting.rs b/src/tools/rustfmt/src/formatting.rs
index cd57a025b67..323ae83fe6e 100644
--- a/src/tools/rustfmt/src/formatting.rs
+++ b/src/tools/rustfmt/src/formatting.rs
@@ -109,7 +109,7 @@ fn format_project<T: FormatHandler>(
     let main_file = input.file_name();
     let input_is_stdin = main_file == FileName::Stdin;
 
-    let parse_session = ParseSess::new(config)?;
+    let mut parse_session = ParseSess::new(config)?;
     if config.skip_children() && parse_session.ignore_file(&main_file) {
         return Ok(FormatReport::new());
     }
@@ -117,11 +117,21 @@ fn format_project<T: FormatHandler>(
     // Parse the crate.
     let mut report = FormatReport::new();
     let directory_ownership = input.to_directory_ownership();
-    let krate = match Parser::parse_crate(input, &parse_session) {
-        Ok(krate) => krate,
-        // Surface parse error via Session (errors are merged there from report)
-        Err(e) => {
-            let forbid_verbose = input_is_stdin || e != ParserError::ParsePanicError;
+
+    // rustfmt doesn't use `run_compiler` like other tools, so it must emit any
+    // stashed diagnostics itself, otherwise the `DiagCtxt` will assert when
+    // dropped. The final result here combines the parsing result and the
+    // `emit_stashed_diagnostics` result.
+    let parse_res = Parser::parse_crate(input, &parse_session);
+    let stashed_res = parse_session.emit_stashed_diagnostics();
+    let krate = match (parse_res, stashed_res) {
+        (Ok(krate), None) => krate,
+        (parse_res, _) => {
+            // Surface parse error via Session (errors are merged there from report).
+            let forbid_verbose = match parse_res {
+                Err(e) if e != ParserError::ParsePanicError => true,
+                _ => input_is_stdin,
+            };
             should_emit_verbose(forbid_verbose, config, || {
                 eprintln!("The Rust parser panicked");
             });
diff --git a/src/tools/rustfmt/src/parse/parser.rs b/src/tools/rustfmt/src/parse/parser.rs
index cca14353b5c..3269fe7c7c7 100644
--- a/src/tools/rustfmt/src/parse/parser.rs
+++ b/src/tools/rustfmt/src/parse/parser.rs
@@ -162,22 +162,14 @@ impl<'a> Parser<'a> {
 
     fn parse_crate_mod(&mut self) -> Result<ast::Crate, ParserError> {
         let mut parser = AssertUnwindSafe(&mut self.parser);
-
-        // rustfmt doesn't use `run_compiler` like other tools, so it must emit
-        // any stashed diagnostics itself, otherwise the `DiagCtxt` will assert
-        // when dropped. The final result here combines the parsing result and
-        // the `emit_stashed_diagnostics` result.
-        let parse_res = catch_unwind(move || parser.parse_crate_mod());
-        let stashed_res = self.parser.dcx().emit_stashed_diagnostics();
         let err = Err(ParserError::ParsePanicError);
-        match (parse_res, stashed_res) {
-            (Ok(Ok(k)), None) => Ok(k),
-            (Ok(Ok(_)), Some(_guar)) => err,
-            (Ok(Err(db)), _) => {
+        match catch_unwind(move || parser.parse_crate_mod()) {
+            Ok(Ok(k)) => Ok(k),
+            Ok(Err(db)) => {
                 db.emit();
                 err
             }
-            (Err(_), _) => err,
+            Err(_) => err,
         }
     }
 }
diff --git a/src/tools/rustfmt/src/parse/session.rs b/src/tools/rustfmt/src/parse/session.rs
index cff025cf2ab..decd3b167e0 100644
--- a/src/tools/rustfmt/src/parse/session.rs
+++ b/src/tools/rustfmt/src/parse/session.rs
@@ -6,7 +6,7 @@ use rustc_data_structures::sync::{IntoDynSyncSend, Lrc};
 use rustc_errors::emitter::{DynEmitter, Emitter, HumanEmitter};
 use rustc_errors::translation::Translate;
 use rustc_errors::{
-    ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, Level as DiagnosticLevel,
+    ColorConfig, DiagCtxt, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, Level as DiagnosticLevel,
 };
 use rustc_session::parse::ParseSess as RawParseSess;
 use rustc_span::{
@@ -230,6 +230,10 @@ impl ParseSess {
         self.ignore_path_set.as_ref().is_match(path)
     }
 
+    pub(crate) fn emit_stashed_diagnostics(&mut self) -> Option<ErrorGuaranteed> {
+        self.parse_sess.dcx.emit_stashed_diagnostics()
+    }
+
     pub(crate) fn set_silent_emitter(&mut self) {
         self.parse_sess.dcx = DiagCtxt::with_emitter(silent_emitter());
     }
diff --git a/src/tools/rustfmt/src/test/parser.rs b/src/tools/rustfmt/src/test/parser.rs
index da2a2ba62e0..d951c8469e6 100644
--- a/src/tools/rustfmt/src/test/parser.rs
+++ b/src/tools/rustfmt/src/test/parser.rs
@@ -62,3 +62,10 @@ fn crate_parsing_stashed_diag() {
     let filename = "tests/parser/stashed-diag.rs";
     assert_parser_error(filename);
 }
+
+#[test]
+fn crate_parsing_stashed_diag2() {
+    // See also https://github.com/rust-lang/rust/issues/121517
+    let filename = "tests/parser/stashed-diag2.rs";
+    assert_parser_error(filename);
+}
diff --git a/src/tools/rustfmt/src/utils.rs b/src/tools/rustfmt/src/utils.rs
index 642b6603b1e..d4218cff75a 100644
--- a/src/tools/rustfmt/src/utils.rs
+++ b/src/tools/rustfmt/src/utils.rs
@@ -497,7 +497,8 @@ pub(crate) fn is_block_expr(context: &RewriteContext<'_>, expr: &ast::Expr, repr
         | ast::ExprKind::Break(..)
         | ast::ExprKind::Cast(..)
         | ast::ExprKind::Continue(..)
-        | ast::ExprKind::Err
+        | ast::ExprKind::Dummy
+        | ast::ExprKind::Err(_)
         | ast::ExprKind::Field(..)
         | ast::ExprKind::IncludedBytes(..)
         | ast::ExprKind::InlineAsm(..)
diff --git a/src/tools/rustfmt/tests/parser/stashed-diag2.rs b/src/tools/rustfmt/tests/parser/stashed-diag2.rs
new file mode 100644
index 00000000000..579a69def16
--- /dev/null
+++ b/src/tools/rustfmt/tests/parser/stashed-diag2.rs
@@ -0,0 +1,3 @@
+trait Trait<'1> { s> {}
+
+fn main() {}
diff --git a/tests/assembly/wasm_exceptions.rs b/tests/assembly/wasm_exceptions.rs
index 2ca62a78688..45df444dca4 100644
--- a/tests/assembly/wasm_exceptions.rs
+++ b/tests/assembly/wasm_exceptions.rs
@@ -41,7 +41,7 @@ pub fn test_cleanup() {
 #[no_mangle]
 pub fn test_rtry() {
     unsafe {
-        core::intrinsics::r#try(|_| {
+        core::intrinsics::catch_unwind(|_| {
             may_panic();
         }, core::ptr::null_mut(), |data, exception| {
             log_number(data as usize);
diff --git a/tests/codegen/instrument-coverage-off.rs b/tests/codegen/instrument-coverage/instrument-coverage-off.rs
index fda3c541a25..fda3c541a25 100644
--- a/tests/codegen/instrument-coverage-off.rs
+++ b/tests/codegen/instrument-coverage/instrument-coverage-off.rs
diff --git a/tests/codegen/instrument-coverage.rs b/tests/codegen/instrument-coverage/instrument-coverage.rs
index f7d96ea3467..f7d96ea3467 100644
--- a/tests/codegen/instrument-coverage.rs
+++ b/tests/codegen/instrument-coverage/instrument-coverage.rs
diff --git a/tests/codegen/instrument-coverage/testprog.rs b/tests/codegen/instrument-coverage/testprog.rs
new file mode 100644
index 00000000000..b352cbdb755
--- /dev/null
+++ b/tests/codegen/instrument-coverage/testprog.rs
@@ -0,0 +1,120 @@
+//@ edition: 2021
+//@ needs-profiler-support
+//@ compile-flags: -Cinstrument-coverage -Copt-level=0
+//@ revisions: LINUX DARWIN WINDOWS
+
+//@ [LINUX] only-linux
+//@ [LINUX] filecheck-flags: -DINSTR_PROF_DATA=__llvm_prf_data
+//@ [LINUX] filecheck-flags: -DINSTR_PROF_NAME=__llvm_prf_names
+//@ [LINUX] filecheck-flags: -DINSTR_PROF_CNTS=__llvm_prf_cnts
+//@ [LINUX] filecheck-flags: -DINSTR_PROF_COVMAP=__llvm_covmap
+//@ [LINUX] filecheck-flags: -DINSTR_PROF_COVFUN=__llvm_covfun
+//@ [LINUX] filecheck-flags: '-DCOMDAT_IF_SUPPORTED=, comdat'
+
+//@ [DARWIN] only-macos
+//@ [DARWIN] filecheck-flags: -DINSTR_PROF_DATA=__DATA,__llvm_prf_data,regular,live_support
+//@ [DARWIN] filecheck-flags: -DINSTR_PROF_NAME=__DATA,__llvm_prf_names
+//@ [DARWIN] filecheck-flags: -DINSTR_PROF_CNTS=__DATA,__llvm_prf_cnts
+//@ [DARWIN] filecheck-flags: -DINSTR_PROF_COVMAP=__LLVM_COV,__llvm_covmap
+//@ [DARWIN] filecheck-flags: -DINSTR_PROF_COVFUN=__LLVM_COV,__llvm_covfun
+//@ [DARWIN] filecheck-flags: -DCOMDAT_IF_SUPPORTED=
+
+//@ [WINDOWS] only-windows
+//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_DATA=.lprfd$M
+//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_NAME=.lprfn$M
+//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_CNTS=.lprfc$M
+//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_COVMAP=.lcovmap$M
+//@ [WINDOWS] filecheck-flags: -DINSTR_PROF_COVFUN=.lcovfun$M
+//@ [WINDOWS] filecheck-flags: '-DCOMDAT_IF_SUPPORTED=, comdat'
+
+// ignore-tidy-linelength
+
+pub fn will_be_called() -> &'static str {
+    let val = "called";
+    println!("{}", val);
+    val
+}
+
+pub fn will_not_be_called() -> bool {
+    println!("should not have been called");
+    false
+}
+
+pub fn print<T>(left: &str, value: T, right: &str)
+where
+    T: std::fmt::Display,
+{
+    println!("{}{}{}", left, value, right);
+}
+
+pub fn wrap_with<F, T>(inner: T, should_wrap: bool, wrapper: F)
+where
+    F: FnOnce(&T)
+{
+    if should_wrap {
+        wrapper(&inner)
+    }
+}
+
+fn main() {
+    let less = 1;
+    let more = 100;
+
+    if less < more {
+        wrap_with(will_be_called(), less < more, |inner| print(" ***", inner, "*** "));
+        wrap_with(will_be_called(), more < less, |inner| print(" ***", inner, "*** "));
+    } else {
+        wrap_with(will_not_be_called(), true, |inner| print("wrapped result is: ", inner, ""));
+    }
+}
+
+// Check for metadata, variables, declarations, and function definitions injected
+// into LLVM IR when compiling with -Cinstrument-coverage.
+
+// WINDOWS:      $__llvm_profile_runtime_user = comdat any
+
+// CHECK:        @__llvm_coverage_mapping = private constant
+// CHECK-SAME:   section "[[INSTR_PROF_COVMAP]]", align 8
+
+// CHECK:        @__covrec_{{[A-F0-9]+}}u = linkonce_odr hidden constant
+// CHECK-SAME:   section "[[INSTR_PROF_COVFUN]]"[[COMDAT_IF_SUPPORTED]], align 8
+
+// WINDOWS:      @__llvm_profile_runtime = external{{.*}}global i32
+
+// CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
+// CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
+
+// CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
+// CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called
+// CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
+
+// CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
+// CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
+
+// CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
+// CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog4main
+// CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
+
+// CHECK:        @__llvm_prf_nm = private constant
+// CHECK-SAME:   section "[[INSTR_PROF_NAME]]", align 1
+
+// CHECK:        @llvm.used = appending global
+// CHECK-SAME:   @__llvm_coverage_mapping
+// CHECK-SAME:   @__llvm_prf_nm
+// CHECK-SAME:   section "llvm.metadata"
+
+// CHECK:        define internal { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} {
+// CHECK-NEXT:   start:
+// CHECK-NOT:    define internal
+// CHECK:        atomicrmw add ptr
+// CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
+
+// CHECK:        declare void @llvm.instrprof.increment(ptr, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
+
+// WINDOWS:      define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {
+// WINDOWS-NEXT: %1 = load i32, ptr @__llvm_profile_runtime
+// WINDOWS-NEXT: ret i32 %1
+// WINDOWS-NEXT: }
+
+// CHECK:        attributes #[[LLVM_INSTRPROF_INCREMENT_ATTR]] = { nounwind }
+// WINDOWS:      attributes #[[LLVM_PROFILE_RUNTIME_USER_ATTR]] = { noinline }
diff --git a/tests/codegen/issues/issue-84268.rs b/tests/codegen/issues/issue-84268.rs
index 379ee4f13f6..1e3950609b3 100644
--- a/tests/codegen/issues/issue-84268.rs
+++ b/tests/codegen/issues/issue-84268.rs
@@ -1,7 +1,7 @@
 //@ compile-flags: -O --crate-type=rlib
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fabs<T>(x: T) -> T;
     fn simd_eq<T, U>(x: T, y: T) -> U;
 }
diff --git a/tests/codegen/meta-filecheck/check-prefix.rs b/tests/codegen/meta-filecheck/check-prefix.rs
new file mode 100644
index 00000000000..98bec68627e
--- /dev/null
+++ b/tests/codegen/meta-filecheck/check-prefix.rs
@@ -0,0 +1,4 @@
+// Simple test that uses the default CHECK prefix and should always succeed.
+
+// CHECK: main
+fn main() {}
diff --git a/tests/codegen/meta-filecheck/filecheck-flags.rs b/tests/codegen/meta-filecheck/filecheck-flags.rs
new file mode 100644
index 00000000000..8e451cf4fdc
--- /dev/null
+++ b/tests/codegen/meta-filecheck/filecheck-flags.rs
@@ -0,0 +1,8 @@
+// Arguments provided via `filecheck-flags` should be passed to `filecheck`.
+
+//@ revisions: good bad
+//@ [good] filecheck-flags: --check-prefix=CUSTOM
+//@ [bad] should-fail
+
+// CUSTOM: main
+fn main() {}
diff --git a/tests/codegen/meta-filecheck/msvc-prefix-bad.rs b/tests/codegen/meta-filecheck/msvc-prefix-bad.rs
new file mode 100644
index 00000000000..f9984c74e2a
--- /dev/null
+++ b/tests/codegen/meta-filecheck/msvc-prefix-bad.rs
@@ -0,0 +1,7 @@
+// This is exactly like `msvc-prefix-good.rs`, except that it should always fail.
+
+//@ should-fail
+
+// MSVC: text that should not match
+// NONMSVC: text that should not match
+fn main() {}
diff --git a/tests/codegen/meta-filecheck/msvc-prefix-good.rs b/tests/codegen/meta-filecheck/msvc-prefix-good.rs
new file mode 100644
index 00000000000..580d20d5438
--- /dev/null
+++ b/tests/codegen/meta-filecheck/msvc-prefix-good.rs
@@ -0,0 +1,7 @@
+// One of MSVC or NONMSVC should always be defined, so this test should pass.
+
+// (one of these should always be present)
+
+// MSVC: main
+// NONMSVC: main
+fn main() {}
diff --git a/tests/codegen/meta-filecheck/no-directives.rs b/tests/codegen/meta-filecheck/no-directives.rs
new file mode 100644
index 00000000000..2cab263604e
--- /dev/null
+++ b/tests/codegen/meta-filecheck/no-directives.rs
@@ -0,0 +1,5 @@
+// A test that doesn't include any filecheck directives should fail.
+
+//@ should-fail
+
+fn main() {}
diff --git a/tests/codegen/meta-filecheck/revision-prefix.rs b/tests/codegen/meta-filecheck/revision-prefix.rs
new file mode 100644
index 00000000000..431066e3acc
--- /dev/null
+++ b/tests/codegen/meta-filecheck/revision-prefix.rs
@@ -0,0 +1,8 @@
+// The current revision name is registered as a filecheck prefix.
+
+//@ revisions: GOOD BAD
+//@ [BAD] should-fail
+
+// GOOD: main
+// BAD: text that should not match
+fn main() {}
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
index 3eb1c9d4051..f8efb678f76 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-abs.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fabs<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
index 05c2c0f6d04..a3ebec174b6 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-ceil.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_ceil<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
index 8b51e76a515..00f97eef6f0 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-cos.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fcos<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
index 370bacdaee9..48c1a8ec489 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fexp<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
index 888ec6ec42c..23c38d81621 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-exp2.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fexp2<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
index b15d89a15b2..978f263031a 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-floor.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_floor<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
index 16017526c34..200d6718026 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fma.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fma<T>(x: T, b: T, c: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
index 9e0f7edd62b..f70de3e2753 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-fsqrt.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fsqrt<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
index 0324411c91b..c0edd3ea48f 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_flog<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
index e7e2b0838cc..766307f47ed 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log10.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_flog10<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
index 912e15c6a1d..90c5918c33e 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-log2.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_flog2<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
index ad297952916..d949112bae7 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-minmax.rs
@@ -2,14 +2,14 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fmin<T>(x: T, y: T) -> T;
     fn simd_fmax<T>(x: T, y: T) -> T;
 }
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
index 1ae983ca20b..21641c80d31 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-pow.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fpow<T>(x: T, b: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
index 638b78b2d72..3985bdd50df 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-powi.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fpowi<T>(x: T, b: i32) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
index c0caedb7498..f6978e32df7 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-float-sin.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -25,7 +25,7 @@ pub struct f32x16(pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32,
                   pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fsin<T>(x: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
index 1426b439c44..809f9a32226 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-arithmetic-saturating.rs
@@ -3,7 +3,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 #![deny(unused)]
 
@@ -111,7 +111,7 @@
 #[repr(simd)] #[derive(Copy, Clone)] pub struct u128x2(u128, u128);
 #[repr(simd)] #[derive(Copy, Clone)] pub struct u128x4(u128, u128, u128, u128);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_saturating_add<T>(x: T, y: T) -> T;
     fn simd_saturating_sub<T>(x: T, y: T) -> T;
 }
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
index 43012dece62..44a4c52d64a 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-bitmask.rs
@@ -3,7 +3,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -22,7 +22,7 @@ pub struct i8x16(
 );
 
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_bitmask<T, U>(x: T) -> U;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
index 29d9e4018e0..863a9606c7e 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-gather.rs
@@ -4,7 +4,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -15,7 +15,7 @@ pub struct Vec2<T>(pub T, pub T);
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub struct Vec4<T>(pub T, pub T, pub T, pub T);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_gather<T, P, M>(value: T, pointers: P, mask: M) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
index 7c48f7d5120..b41c42810aa 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-load.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -13,7 +13,7 @@ pub struct Vec2<T>(pub T, pub T);
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub struct Vec4<T>(pub T, pub T, pub T, pub T);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
index 366592ba3f1..066392bcde6 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-masked-store.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -13,7 +13,7 @@ pub struct Vec2<T>(pub T, pub T);
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub struct Vec4<T>(pub T, pub T, pub T, pub T);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
index ccfedb31dc5..e85bd61c7f8 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-scatter.rs
@@ -4,7 +4,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -15,7 +15,7 @@ pub struct Vec2<T>(pub T, pub T);
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub struct Vec4<T>(pub T, pub T, pub T, pub T);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_scatter<T, P, M>(value: T, pointers: P, mask: M);
 }
 
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs
index 903bd3f4dc6..05d2bf627ef 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-generic-select.rs
@@ -2,7 +2,7 @@
 
 #![crate_type = "lib"]
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #[allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -17,7 +17,7 @@ pub struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32);
 #[derive(Copy, Clone, PartialEq, Debug)]
 pub struct b8x4(pub i8, pub i8, pub i8, pub i8);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
     fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
 }
diff --git a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
index c92ae4163ae..488be2a8629 100644
--- a/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
+++ b/tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs
@@ -3,7 +3,7 @@
 
 #![crate_type = "lib"]
 #![allow(non_camel_case_types)]
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![feature(inline_const)]
 
 #[repr(simd)]
diff --git a/tests/codegen/simd/simd_arith_offset.rs b/tests/codegen/simd/simd_arith_offset.rs
index 9f1ef27053e..e14fce1d418 100644
--- a/tests/codegen/simd/simd_arith_offset.rs
+++ b/tests/codegen/simd/simd_arith_offset.rs
@@ -3,9 +3,9 @@
 //
 
 #![crate_type = "lib"]
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     pub(crate) fn simd_arith_offset<T, U>(ptrs: T, offsets: U) -> T;
 }
 
diff --git a/tests/codegen/wasm_exceptions.rs b/tests/codegen/wasm_exceptions.rs
index 48a7357bfd8..66d2bbed709 100644
--- a/tests/codegen/wasm_exceptions.rs
+++ b/tests/codegen/wasm_exceptions.rs
@@ -35,7 +35,7 @@ pub fn test_cleanup() {
 #[no_mangle]
 pub fn test_rtry() {
     unsafe {
-        core::intrinsics::r#try(|_| {
+        core::intrinsics::catch_unwind(|_| {
             may_panic();
         }, core::ptr::null_mut(), |data, exception| {
             log_number(data as usize);
diff --git a/tests/incremental/issue-61530.rs b/tests/incremental/issue-61530.rs
index 0197beb48d8..e4ee8ccbc4b 100644
--- a/tests/incremental/issue-61530.rs
+++ b/tests/incremental/issue-61530.rs
@@ -1,11 +1,11 @@
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 //@ revisions:rpass1 rpass2
 
 #[repr(simd)]
 struct I32x2(i32, i32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 }
 
diff --git a/tests/run-make/coverage-llvmir/Makefile b/tests/run-make/coverage-llvmir/Makefile
deleted file mode 100644
index be92f8ac8fc..00000000000
--- a/tests/run-make/coverage-llvmir/Makefile
+++ /dev/null
@@ -1,64 +0,0 @@
-# needs-profiler-support
-
-# Rust coverage maps support LLVM Coverage Mapping Format versions 5 and 6,
-# corresponding with LLVM versions 12 and 13, respectively.
-# When upgrading LLVM versions, consider whether to enforce a minimum LLVM
-# version during testing, with an additional directive at the top of this file
-# that sets, for example: `min-llvm-version: 12.0`
-
-include ../tools.mk
-
-BASEDIR=../coverage-llvmir
-
-ifeq ($(UNAME),Darwin)
-	INSTR_PROF_DATA_SUFFIX=,regular,live_support
-	DATA_SECTION_PREFIX=__DATA,
-	LLVM_COV_SECTION_PREFIX=__LLVM_COV,
-	COMDAT_IF_SUPPORTED=
-else
-	INSTR_PROF_DATA_SUFFIX=
-	DATA_SECTION_PREFIX=
-	LLVM_COV_SECTION_PREFIX=
-	COMDAT_IF_SUPPORTED=, comdat
-endif
-
-DEFINE_INTERNAL=define internal
-
-ifdef IS_WINDOWS
-	LLVM_FILECHECK_OPTIONS=\
-		-check-prefixes=CHECK,WINDOWS \
-		-DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
-		-DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
-		-DINSTR_PROF_DATA='.lprfd$$M' \
-		-DINSTR_PROF_NAME='.lprfn$$M' \
-		-DINSTR_PROF_CNTS='.lprfc$$M' \
-		-DINSTR_PROF_VALS='.lprfv$$M' \
-		-DINSTR_PROF_VNODES='.lprfnd$$M' \
-		-DINSTR_PROF_COVMAP='.lcovmap$$M' \
-		-DINSTR_PROF_COVFUN='.lcovfun$$M' \
-		-DINSTR_PROF_ORDERFILE='.lorderfile$$M'
-else
-	LLVM_FILECHECK_OPTIONS=\
-		-check-prefixes=CHECK \
-		-DDEFINE_INTERNAL='$(DEFINE_INTERNAL)' \
-		-DCOMDAT_IF_SUPPORTED='$(COMDAT_IF_SUPPORTED)' \
-		-DINSTR_PROF_DATA='$(DATA_SECTION_PREFIX)__llvm_prf_data$(INSTR_PROF_DATA_SUFFIX)' \
-		-DINSTR_PROF_NAME='$(DATA_SECTION_PREFIX)__llvm_prf_names' \
-		-DINSTR_PROF_CNTS='$(DATA_SECTION_PREFIX)__llvm_prf_cnts' \
-		-DINSTR_PROF_VALS='$(DATA_SECTION_PREFIX)__llvm_prf_vals' \
-		-DINSTR_PROF_VNODES='$(DATA_SECTION_PREFIX)__llvm_prf_vnds' \
-		-DINSTR_PROF_COVMAP='$(LLVM_COV_SECTION_PREFIX)__llvm_covmap' \
-		-DINSTR_PROF_COVFUN='$(LLVM_COV_SECTION_PREFIX)__llvm_covfun' \
-		-DINSTR_PROF_ORDERFILE='$(DATA_SECTION_PREFIX)__llvm_orderfile'
-endif
-
-all: test_llvm_ir
-
-test_llvm_ir:
-	# Compile the test program with non-experimental coverage instrumentation, and generate LLVM IR
-	$(RUSTC) $(BASEDIR)/testprog.rs \
-			-Cinstrument-coverage \
-			--emit=llvm-ir
-
-	cat "$(TMPDIR)"/testprog.ll | \
-			"$(LLVM_FILECHECK)" $(BASEDIR)/filecheck.testprog.txt $(LLVM_FILECHECK_OPTIONS)
diff --git a/tests/run-make/coverage-llvmir/filecheck.testprog.txt b/tests/run-make/coverage-llvmir/filecheck.testprog.txt
deleted file mode 100644
index 8ab18da21a2..00000000000
--- a/tests/run-make/coverage-llvmir/filecheck.testprog.txt
+++ /dev/null
@@ -1,50 +0,0 @@
-# Check for metadata, variables, declarations, and function definitions injected
-# into LLVM IR when compiling with -Cinstrument-coverage.
-
-WINDOWS:      $__llvm_profile_runtime_user = comdat any
-
-CHECK:        @__llvm_coverage_mapping = private constant
-CHECK-SAME:   section "[[INSTR_PROF_COVMAP]]", align 8
-
-CHECK:        @__covrec_{{[A-F0-9]+}}u = linkonce_odr hidden constant
-CHECK-SAME:   section "[[INSTR_PROF_COVFUN]]"[[COMDAT_IF_SUPPORTED]], align 8
-
-WINDOWS:      @__llvm_profile_runtime = external{{.*}}global i32
-
-CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
-CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
-
-CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog14will_be_called = {{private|internal}} global
-CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called
-CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
-
-CHECK:        @__profc__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
-CHECK-SAME:   section "[[INSTR_PROF_CNTS]]"{{.*}}, align 8
-
-CHECK:        @__profd__R{{[a-zA-Z0-9_]+}}testprog4main = {{private|internal}} global
-CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog4main
-CHECK-SAME:   section "[[INSTR_PROF_DATA]]"{{.*}}, align 8
-
-CHECK:        @__llvm_prf_nm = private constant
-CHECK-SAME:   section "[[INSTR_PROF_NAME]]", align 1
-
-CHECK:        @llvm.used = appending global
-CHECK-SAME:   @__llvm_coverage_mapping
-CHECK-SAME:   @__llvm_prf_nm
-CHECK-SAME:   section "llvm.metadata"
-
-CHECK:        [[DEFINE_INTERNAL]] { {{.*}} } @_R{{[a-zA-Z0-9_]+}}testprog14will_be_called() unnamed_addr #{{[0-9]+}} {
-CHECK-NEXT:   start:
-CHECK-NOT:    [[DEFINE_INTERNAL]]
-CHECK:        atomicrmw add ptr
-CHECK-SAME:   @__profc__R{{[a-zA-Z0-9_]+}}testprog14will_be_called,
-
-CHECK:        declare void @llvm.instrprof.increment(ptr, i64, i32, i32) #[[LLVM_INSTRPROF_INCREMENT_ATTR:[0-9]+]]
-
-WINDOWS:      define linkonce_odr hidden i32 @__llvm_profile_runtime_user() #[[LLVM_PROFILE_RUNTIME_USER_ATTR:[0-9]+]] comdat {
-WINDOWS-NEXT: %1 = load i32, ptr @__llvm_profile_runtime
-WINDOWS-NEXT: ret i32 %1
-WINDOWS-NEXT: }
-
-CHECK:        attributes #[[LLVM_INSTRPROF_INCREMENT_ATTR]] = { nounwind }
-WINDOWS:      attributes #[[LLVM_PROFILE_RUNTIME_USER_ATTR]] = { noinline }
diff --git a/tests/run-make/coverage-llvmir/testprog.rs b/tests/run-make/coverage-llvmir/testprog.rs
deleted file mode 100644
index 358c25677ae..00000000000
--- a/tests/run-make/coverage-llvmir/testprog.rs
+++ /dev/null
@@ -1,38 +0,0 @@
-pub fn will_be_called() -> &'static str {
-    let val = "called";
-    println!("{}", val);
-    val
-}
-
-pub fn will_not_be_called() -> bool {
-    println!("should not have been called");
-    false
-}
-
-pub fn print<T>(left: &str, value: T, right: &str)
-where
-    T: std::fmt::Display,
-{
-    println!("{}{}{}", left, value, right);
-}
-
-pub fn wrap_with<F, T>(inner: T, should_wrap: bool, wrapper: F)
-where
-    F: FnOnce(&T)
-{
-    if should_wrap {
-        wrapper(&inner)
-    }
-}
-
-fn main() {
-    let less = 1;
-    let more = 100;
-
-    if less < more {
-        wrap_with(will_be_called(), less < more, |inner| print(" ***", inner, "*** "));
-        wrap_with(will_be_called(), more < less, |inner| print(" ***", inner, "*** "));
-    } else {
-        wrap_with(will_not_be_called(), true, |inner| print("wrapped result is: ", inner, ""));
-    }
-}
diff --git a/tests/run-make/tools.mk b/tests/run-make/tools.mk
index 1d4e9111389..b1e872a202a 100644
--- a/tests/run-make/tools.mk
+++ b/tests/run-make/tools.mk
@@ -134,9 +134,9 @@ endif
 # Extra flags needed to compile a working executable with the standard library
 ifdef IS_WINDOWS
 ifdef IS_MSVC
-	EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib
+	EXTRACFLAGS := ws2_32.lib userenv.lib advapi32.lib bcrypt.lib ntdll.lib synchronization.lib
 else
-	EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll
+	EXTRACFLAGS := -lws2_32 -luserenv -lbcrypt -lntdll -lsynchronization
 	EXTRACXXFLAGS := -lstdc++
 	# So this is a bit hacky: we can't use the DLL version of libstdc++ because
 	# it pulls in the DLL version of libgcc, which means that we end up with 2
diff --git a/tests/run-make/wasm-exceptions-nostd/src/lib.rs b/tests/run-make/wasm-exceptions-nostd/src/lib.rs
index 7049d2fd9e0..9d336510469 100644
--- a/tests/run-make/wasm-exceptions-nostd/src/lib.rs
+++ b/tests/run-make/wasm-exceptions-nostd/src/lib.rs
@@ -39,7 +39,7 @@ pub extern "C" fn start() -> usize {
     let data = 0x1234usize as *mut u8; // Something to recognize
 
     unsafe {
-        core::intrinsics::r#try(|data: *mut u8| {
+        core::intrinsics::catch_unwind(|data: *mut u8| {
             let _log_on_drop = LogOnDrop;
 
             logging::log_str(&alloc::format!("`r#try` called with ptr {:?}", data));
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.rs b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
index 7c3c7337e2e..8502bb6e2d4 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.rs
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
@@ -1,7 +1,5 @@
 //@ edition:2021
 
-// FIXME(async_closures): This needs a better error message!
-
 #![feature(async_closure)]
 
 fn main() {
@@ -12,4 +10,10 @@ fn main() {
         //~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
         x += 1;
     });
+
+    let x = String::new();
+    needs_async_fn(move || async move {
+        //~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
+        println!("{x}");
+    });
 }
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
index 34a6b3a485a..d0f1948e48f 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
@@ -1,5 +1,5 @@
 error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
-  --> $DIR/wrong-fn-kind.rs:11:20
+  --> $DIR/wrong-fn-kind.rs:9:20
    |
 LL |       needs_async_fn(async || {
    |       -------------- -^^^^^^^
@@ -14,11 +14,32 @@ LL | |     });
    | |_____- the requirement to implement `async Fn` derives from here
    |
 note: required by a bound in `needs_async_fn`
-  --> $DIR/wrong-fn-kind.rs:8:31
+  --> $DIR/wrong-fn-kind.rs:6:31
    |
 LL |     fn needs_async_fn(_: impl async Fn()) {}
    |                               ^^^^^^^^^^ required by this bound in `needs_async_fn`
 
-error: aborting due to 1 previous error
+error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnOnce`
+  --> $DIR/wrong-fn-kind.rs:15:20
+   |
+LL |       needs_async_fn(move || async move {
+   |       -------------- -^^^^^^
+   |       |              |
+   |  _____|______________this closure implements `async FnOnce`, not `async Fn`
+   | |     |
+   | |     required by a bound introduced by this call
+LL | |
+LL | |         println!("{x}");
+   | |                    - closure is `async FnOnce` because it moves the variable `x` out of its environment
+LL | |     });
+   | |_____- the requirement to implement `async Fn` derives from here
+   |
+note: required by a bound in `needs_async_fn`
+  --> $DIR/wrong-fn-kind.rs:6:31
+   |
+LL |     fn needs_async_fn(_: impl async Fn()) {}
+   |                               ^^^^^^^^^^ required by this bound in `needs_async_fn`
+
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0525`.
diff --git a/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs b/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
index 74fbae0350e..3d93d50ca3f 100644
--- a/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
+++ b/tests/ui/attributes/unix_sigpipe/auxiliary/sigpipe-utils.rs
@@ -17,17 +17,17 @@ pub fn assert_sigpipe_handler(expected_handler: SignalHandler) {
         target_os = "android",
     )))]
     {
-        let prev = unsafe { libc::signal(libc::SIGPIPE, libc::SIG_IGN) };
+        let actual = unsafe {
+            let mut actual: libc::sigaction = std::mem::zeroed();
+            libc::sigaction(libc::SIGPIPE, std::ptr::null(), &mut actual);
+            actual.sa_sigaction
+        };
 
         let expected = match expected_handler {
             SignalHandler::Ignore => libc::SIG_IGN,
             SignalHandler::Default => libc::SIG_DFL,
         };
-        assert_eq!(prev, expected, "expected sigpipe value matches actual value");
 
-        // Unlikely to matter, but restore the old value anyway
-        unsafe {
-            libc::signal(libc::SIGPIPE, prev);
-        };
+        assert_eq!(actual, expected, "actual and expected SIGPIPE disposition differs");
     }
 }
diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr
index 6119e6149a7..50b83b90b0b 100644
--- a/tests/ui/coherence/occurs-check/associated-type.next.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr
@@ -1,11 +1,7 @@
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:27 ~ associated_type[f554]::{impl#3}::'a#1), 'a) })], def_id: DefId(0:5 ~ associated_type[f554]::ToUnit::Unit) }
 error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
   --> $DIR/associated-type.rs:31:1
    |
diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr
index 4ad8257d2c1..a5182eb5d9c 100644
--- a/tests/ui/coherence/occurs-check/opaques.next.stderr
+++ b/tests/ui/coherence/occurs-check/opaques.next.stderr
@@ -1,17 +1,17 @@
-error[E0119]: conflicting implementations of trait `Trait<Alias<_>>` for type `Alias<_>`
+error[E0119]: conflicting implementations of trait `Trait<_>`
   --> $DIR/opaques.rs:30:1
    |
 LL | impl<T> Trait<T> for T {
    | ---------------------- first implementation here
 ...
 LL | impl<T> Trait<T> for defining_scope::Alias<T> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Alias<_>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0282]: type annotations needed
   --> $DIR/opaques.rs:13:20
    |
 LL |     pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
-   |                    ^ cannot infer type for struct `Container<Alias<T>, T>`
+   |                    ^ cannot infer type for struct `Container<T, T>`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/consts/const-eval/simd/insert_extract.rs b/tests/ui/consts/const-eval/simd/insert_extract.rs
index c0113904edf..fc7dbd5a41c 100644
--- a/tests/ui/consts/const-eval/simd/insert_extract.rs
+++ b/tests/ui/consts/const-eval/simd/insert_extract.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![feature(repr_simd)]
-#![feature(platform_intrinsics)]
+#![feature(intrinsics)]
 #![feature(staged_api)]
 #![stable(feature = "foo", since = "1.3.37")]
 #![allow(non_camel_case_types)]
@@ -11,7 +11,7 @@
 #[repr(simd)] struct i8x1_arr([i8; 1]);
 #[repr(simd)] struct f32x4([f32; 4]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     #[rustc_const_stable(feature = "foo", since = "1.3.37")]
     fn simd_insert<T, U>(x: T, idx: u32, val: U) -> T;
     #[rustc_const_stable(feature = "foo", since = "1.3.37")]
diff --git a/tests/ui/error-codes/E0511.rs b/tests/ui/error-codes/E0511.rs
index 8c79bcf5a67..81656c71088 100644
--- a/tests/ui/error-codes/E0511.rs
+++ b/tests/ui/error-codes/E0511.rs
@@ -1,8 +1,8 @@
 //@ build-fail
 
-#![feature(platform_intrinsics)]
+#![feature(intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(a: T, b: T) -> T;
 }
 
diff --git a/tests/ui/feature-gates/feature-gate-abi.rs b/tests/ui/feature-gates/feature-gate-abi.rs
index 02568b4778b..1c3a732a497 100644
--- a/tests/ui/feature-gates/feature-gate-abi.rs
+++ b/tests/ui/feature-gates/feature-gate-abi.rs
@@ -1,5 +1,4 @@
 // gate-test-intrinsics
-// gate-test-platform_intrinsics
 //@ compile-flags: --crate-type=rlib
 
 #![feature(no_core, lang_items)]
@@ -15,7 +14,7 @@ trait Tuple { }
 extern "rust-intrinsic" fn f1() {} //~ ERROR intrinsics are subject to change
                                    //~^ ERROR intrinsic must be in
                                    //~| ERROR unrecognized intrinsic function: `f1`
-extern "platform-intrinsic" fn f2() {} //~ ERROR platform intrinsics are experimental
+extern "rust-intrinsic" fn f2() {} //~ ERROR intrinsics are subject to change
                                        //~^ ERROR intrinsic must be in
                                        //~| ERROR unrecognized intrinsic function: `f2`
 extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change
@@ -24,7 +23,7 @@ extern "rust-call" fn f4(_: ()) {} //~ ERROR rust-call ABI is subject to change
 trait Tr {
     extern "rust-intrinsic" fn m1(); //~ ERROR intrinsics are subject to change
                                      //~^ ERROR intrinsic must be in
-    extern "platform-intrinsic" fn m2(); //~ ERROR platform intrinsics are experimental
+    extern "rust-intrinsic" fn m2(); //~ ERROR intrinsics are subject to change
                                          //~^ ERROR intrinsic must be in
     extern "rust-call" fn m4(_: ()); //~ ERROR rust-call ABI is subject to change
 
@@ -37,7 +36,7 @@ struct S;
 impl Tr for S {
     extern "rust-intrinsic" fn m1() {} //~ ERROR intrinsics are subject to change
                                        //~^ ERROR intrinsic must be in
-    extern "platform-intrinsic" fn m2() {} //~ ERROR platform intrinsics are experimental
+    extern "rust-intrinsic" fn m2() {} //~ ERROR intrinsics are subject to change
                                            //~^ ERROR intrinsic must be in
     extern "rust-call" fn m4(_: ()) {} //~ ERROR rust-call ABI is subject to change
 }
@@ -46,17 +45,17 @@ impl Tr for S {
 impl S {
     extern "rust-intrinsic" fn im1() {} //~ ERROR intrinsics are subject to change
                                         //~^ ERROR intrinsic must be in
-    extern "platform-intrinsic" fn im2() {} //~ ERROR platform intrinsics are experimental
+    extern "rust-intrinsic" fn im2() {} //~ ERROR intrinsics are subject to change
                                             //~^ ERROR intrinsic must be in
     extern "rust-call" fn im4(_: ()) {} //~ ERROR rust-call ABI is subject to change
 }
 
 // Function pointer types
 type A1 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change
-type A2 = extern "platform-intrinsic" fn(); //~ ERROR platform intrinsics are experimental
+type A2 = extern "rust-intrinsic" fn(); //~ ERROR intrinsics are subject to change
 type A4 = extern "rust-call" fn(_: ()); //~ ERROR rust-call ABI is subject to change
 
 // Foreign modules
 extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
-extern "platform-intrinsic" {} //~ ERROR platform intrinsics are experimental
+extern "rust-intrinsic" {} //~ ERROR intrinsics are subject to change
 extern "rust-call" {} //~ ERROR rust-call ABI is subject to change
diff --git a/tests/ui/feature-gates/feature-gate-abi.stderr b/tests/ui/feature-gates/feature-gate-abi.stderr
index 3fd1e1189ab..c28cd05a96a 100644
--- a/tests/ui/feature-gates/feature-gate-abi.stderr
+++ b/tests/ui/feature-gates/feature-gate-abi.stderr
@@ -1,5 +1,5 @@
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:15:8
+  --> $DIR/feature-gate-abi.rs:14:8
    |
 LL | extern "rust-intrinsic" fn f1() {}
    |        ^^^^^^^^^^^^^^^^
@@ -7,18 +7,17 @@ LL | extern "rust-intrinsic" fn f1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:18:8
+error[E0658]: intrinsics are subject to change
+  --> $DIR/feature-gate-abi.rs:17:8
    |
-LL | extern "platform-intrinsic" fn f2() {}
-   |        ^^^^^^^^^^^^^^^^^^^^
+LL | extern "rust-intrinsic" fn f2() {}
+   |        ^^^^^^^^^^^^^^^^
    |
-   = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
-   = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
+   = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:21:8
+  --> $DIR/feature-gate-abi.rs:20:8
    |
 LL | extern "rust-call" fn f4(_: ()) {}
    |        ^^^^^^^^^^^
@@ -28,7 +27,7 @@ LL | extern "rust-call" fn f4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:25:12
+  --> $DIR/feature-gate-abi.rs:24:12
    |
 LL |     extern "rust-intrinsic" fn m1();
    |            ^^^^^^^^^^^^^^^^
@@ -36,18 +35,17 @@ LL |     extern "rust-intrinsic" fn m1();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:27:12
+error[E0658]: intrinsics are subject to change
+  --> $DIR/feature-gate-abi.rs:26:12
    |
-LL |     extern "platform-intrinsic" fn m2();
-   |            ^^^^^^^^^^^^^^^^^^^^
+LL |     extern "rust-intrinsic" fn m2();
+   |            ^^^^^^^^^^^^^^^^
    |
-   = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
-   = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
+   = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:29:12
+  --> $DIR/feature-gate-abi.rs:28:12
    |
 LL |     extern "rust-call" fn m4(_: ());
    |            ^^^^^^^^^^^
@@ -57,7 +55,7 @@ LL |     extern "rust-call" fn m4(_: ());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:31:12
+  --> $DIR/feature-gate-abi.rs:30:12
    |
 LL |     extern "rust-call" fn dm4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -67,7 +65,7 @@ LL |     extern "rust-call" fn dm4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:38:12
+  --> $DIR/feature-gate-abi.rs:37:12
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -75,18 +73,17 @@ LL |     extern "rust-intrinsic" fn m1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:40:12
+error[E0658]: intrinsics are subject to change
+  --> $DIR/feature-gate-abi.rs:39:12
    |
-LL |     extern "platform-intrinsic" fn m2() {}
-   |            ^^^^^^^^^^^^^^^^^^^^
+LL |     extern "rust-intrinsic" fn m2() {}
+   |            ^^^^^^^^^^^^^^^^
    |
-   = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
-   = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
+   = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:42:12
+  --> $DIR/feature-gate-abi.rs:41:12
    |
 LL |     extern "rust-call" fn m4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -96,7 +93,7 @@ LL |     extern "rust-call" fn m4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:47:12
+  --> $DIR/feature-gate-abi.rs:46:12
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |            ^^^^^^^^^^^^^^^^
@@ -104,18 +101,17 @@ LL |     extern "rust-intrinsic" fn im1() {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:49:12
+error[E0658]: intrinsics are subject to change
+  --> $DIR/feature-gate-abi.rs:48:12
    |
-LL |     extern "platform-intrinsic" fn im2() {}
-   |            ^^^^^^^^^^^^^^^^^^^^
+LL |     extern "rust-intrinsic" fn im2() {}
+   |            ^^^^^^^^^^^^^^^^
    |
-   = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
-   = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
+   = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:51:12
+  --> $DIR/feature-gate-abi.rs:50:12
    |
 LL |     extern "rust-call" fn im4(_: ()) {}
    |            ^^^^^^^^^^^
@@ -125,7 +121,7 @@ LL |     extern "rust-call" fn im4(_: ()) {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:55:18
+  --> $DIR/feature-gate-abi.rs:54:18
    |
 LL | type A1 = extern "rust-intrinsic" fn();
    |                  ^^^^^^^^^^^^^^^^
@@ -133,18 +129,17 @@ LL | type A1 = extern "rust-intrinsic" fn();
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:56:18
+error[E0658]: intrinsics are subject to change
+  --> $DIR/feature-gate-abi.rs:55:18
    |
-LL | type A2 = extern "platform-intrinsic" fn();
-   |                  ^^^^^^^^^^^^^^^^^^^^
+LL | type A2 = extern "rust-intrinsic" fn();
+   |                  ^^^^^^^^^^^^^^^^
    |
-   = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
-   = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
+   = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:57:18
+  --> $DIR/feature-gate-abi.rs:56:18
    |
 LL | type A4 = extern "rust-call" fn(_: ());
    |                  ^^^^^^^^^^^
@@ -154,7 +149,7 @@ LL | type A4 = extern "rust-call" fn(_: ());
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: intrinsics are subject to change
-  --> $DIR/feature-gate-abi.rs:60:8
+  --> $DIR/feature-gate-abi.rs:59:8
    |
 LL | extern "rust-intrinsic" {}
    |        ^^^^^^^^^^^^^^^^
@@ -162,18 +157,17 @@ LL | extern "rust-intrinsic" {}
    = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: platform intrinsics are experimental and possibly buggy
-  --> $DIR/feature-gate-abi.rs:61:8
+error[E0658]: intrinsics are subject to change
+  --> $DIR/feature-gate-abi.rs:60:8
    |
-LL | extern "platform-intrinsic" {}
-   |        ^^^^^^^^^^^^^^^^^^^^
+LL | extern "rust-intrinsic" {}
+   |        ^^^^^^^^^^^^^^^^
    |
-   = note: see issue #27731 <https://github.com/rust-lang/rust/issues/27731> for more information
-   = help: add `#![feature(platform_intrinsics)]` to the crate attributes to enable
+   = help: add `#![feature(intrinsics)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: rust-call ABI is subject to change
-  --> $DIR/feature-gate-abi.rs:62:8
+  --> $DIR/feature-gate-abi.rs:61:8
    |
 LL | extern "rust-call" {}
    |        ^^^^^^^^^^^
@@ -183,7 +177,7 @@ LL | extern "rust-call" {}
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0093]: unrecognized intrinsic function: `f1`
-  --> $DIR/feature-gate-abi.rs:15:28
+  --> $DIR/feature-gate-abi.rs:14:28
    |
 LL | extern "rust-intrinsic" fn f1() {}
    |                            ^^ unrecognized intrinsic
@@ -191,60 +185,60 @@ LL | extern "rust-intrinsic" fn f1() {}
    = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
 
 error[E0093]: unrecognized intrinsic function: `f2`
-  --> $DIR/feature-gate-abi.rs:18:32
+  --> $DIR/feature-gate-abi.rs:17:28
    |
-LL | extern "platform-intrinsic" fn f2() {}
-   |                                ^^ unrecognized intrinsic
+LL | extern "rust-intrinsic" fn f2() {}
+   |                            ^^ unrecognized intrinsic
    |
    = help: if you're adding an intrinsic, be sure to update `check_intrinsic_type`
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:25:32
+  --> $DIR/feature-gate-abi.rs:24:32
    |
 LL |     extern "rust-intrinsic" fn m1();
    |                                ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:27:36
+  --> $DIR/feature-gate-abi.rs:26:32
    |
-LL |     extern "platform-intrinsic" fn m2();
-   |                                    ^^
+LL |     extern "rust-intrinsic" fn m2();
+   |                                ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:15:33
+  --> $DIR/feature-gate-abi.rs:14:33
    |
 LL | extern "rust-intrinsic" fn f1() {}
    |                                 ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:18:37
+  --> $DIR/feature-gate-abi.rs:17:33
    |
-LL | extern "platform-intrinsic" fn f2() {}
-   |                                     ^^
+LL | extern "rust-intrinsic" fn f2() {}
+   |                                 ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:38:37
+  --> $DIR/feature-gate-abi.rs:37:37
    |
 LL |     extern "rust-intrinsic" fn m1() {}
    |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:40:41
+  --> $DIR/feature-gate-abi.rs:39:37
    |
-LL |     extern "platform-intrinsic" fn m2() {}
-   |                                         ^^
+LL |     extern "rust-intrinsic" fn m2() {}
+   |                                     ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:47:38
+  --> $DIR/feature-gate-abi.rs:46:38
    |
 LL |     extern "rust-intrinsic" fn im1() {}
    |                                      ^^
 
 error: intrinsic must be in `extern "rust-intrinsic" { ... }` block
-  --> $DIR/feature-gate-abi.rs:49:42
+  --> $DIR/feature-gate-abi.rs:48:38
    |
-LL |     extern "platform-intrinsic" fn im2() {}
-   |                                          ^^
+LL |     extern "rust-intrinsic" fn im2() {}
+   |                                      ^^
 
 error: aborting due to 29 previous errors
 
diff --git a/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.rs b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.rs
new file mode 100644
index 00000000000..aeace9f2158
--- /dev/null
+++ b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.rs
@@ -0,0 +1,20 @@
+#![allow(incomplete_features)]
+#![feature(non_lifetime_binders)]
+
+trait Foo: for<T> Bar<T> {}
+
+trait Bar<T: ?Sized> {
+    fn method(&self) {}
+}
+
+struct Type2;
+fn needs_bar(_: *mut Type2) {}
+
+fn main() {
+    let x: &dyn Foo = &();
+    //~^ ERROR the trait `Foo` cannot be made into an object
+    //~| ERROR the trait `Foo` cannot be made into an object
+
+    needs_bar(x);
+    //~^ ERROR mismatched types
+}
diff --git a/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr
new file mode 100644
index 00000000000..27f82563aae
--- /dev/null
+++ b/tests/ui/higher-ranked/trait-bounds/span-bug-issue-121597.stderr
@@ -0,0 +1,49 @@
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/span-bug-issue-121597.rs:14:23
+   |
+LL |     let x: &dyn Foo = &();
+   |                       ^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/span-bug-issue-121597.rs:4:12
+   |
+LL | trait Foo: for<T> Bar<T> {}
+   |       ---  ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables
+   |       |
+   |       this trait cannot be made into an object...
+   = note: required for the cast from `&()` to `&dyn Foo`
+
+error[E0038]: the trait `Foo` cannot be made into an object
+  --> $DIR/span-bug-issue-121597.rs:14:12
+   |
+LL |     let x: &dyn Foo = &();
+   |            ^^^^^^^^ `Foo` cannot be made into an object
+   |
+note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
+  --> $DIR/span-bug-issue-121597.rs:4:12
+   |
+LL | trait Foo: for<T> Bar<T> {}
+   |       ---  ^^^^^^^^^^^^^ ...because where clause cannot reference non-lifetime `for<...>` variables
+   |       |
+   |       this trait cannot be made into an object...
+
+error[E0308]: mismatched types
+  --> $DIR/span-bug-issue-121597.rs:18:15
+   |
+LL |     needs_bar(x);
+   |     --------- ^ types differ in mutability
+   |     |
+   |     arguments to this function are incorrect
+   |
+   = note: expected raw pointer `*mut Type2`
+                found reference `&dyn Foo`
+note: function defined here
+  --> $DIR/span-bug-issue-121597.rs:11:4
+   |
+LL | fn needs_bar(_: *mut Type2) {}
+   |    ^^^^^^^^^ -------------
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0038, E0308.
+For more information about an error, try `rustc --explain E0038`.
diff --git a/tests/ui/impl-trait/auto-trait-coherence.next.stderr b/tests/ui/impl-trait/auto-trait-coherence.next.stderr
index 3f979d1a50b..cd91bfcb48d 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.next.stderr
+++ b/tests/ui/impl-trait/auto-trait-coherence.next.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>`
   --> $DIR/auto-trait-coherence.rs:24:1
    |
 LL | impl<T: Send> AnotherTrait for T {}
    | -------------------------------- first implementation here
 ...
 LL | impl AnotherTrait for D<OpaqueType> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/auto-trait-coherence.rs b/tests/ui/impl-trait/auto-trait-coherence.rs
index 0f089c5adbd..e3036fd0fe2 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.rs
+++ b/tests/ui/impl-trait/auto-trait-coherence.rs
@@ -22,7 +22,8 @@ impl<T: Send> AnotherTrait for T {}
 // (We treat opaque types as "foreign types" that could grow more impls
 // in the future.)
 impl AnotherTrait for D<OpaqueType> {
-    //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+    //[old]~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+    //[next]~^^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>`
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
index 33866451c6b..c5c9ae33f4d 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.current.stderr
@@ -7,7 +7,7 @@ LL | type A = impl Foo;
    = note: `A` must be used in combination with a concrete type within the same module
 
 error: opaque type's hidden type cannot be another opaque type from the same scope
-  --> $DIR/two_tait_defining_each_other2.rs:11:5
+  --> $DIR/two_tait_defining_each_other2.rs:12:5
    |
 LL |     x // B's hidden type is A (opaquely)
    |     ^ one of the two opaque types used here has to be outside its defining scope
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr
index 69328e20583..7e2b05618c4 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.next.stderr
@@ -1,8 +1,8 @@
-error[E0284]: type annotations needed: cannot satisfy `A == B`
-  --> $DIR/two_tait_defining_each_other2.rs:11:5
+error[E0284]: type annotations needed: cannot satisfy `_ == A`
+  --> $DIR/two_tait_defining_each_other2.rs:10:8
    |
-LL |     x // B's hidden type is A (opaquely)
-   |     ^ cannot satisfy `A == B`
+LL | fn muh(x: A) -> B {
+   |        ^ cannot satisfy `_ == A`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/two_tait_defining_each_other2.rs b/tests/ui/impl-trait/two_tait_defining_each_other2.rs
index 229a7411951..faa1fed22d3 100644
--- a/tests/ui/impl-trait/two_tait_defining_each_other2.rs
+++ b/tests/ui/impl-trait/two_tait_defining_each_other2.rs
@@ -8,9 +8,9 @@ type B = impl Foo;
 trait Foo {}
 
 fn muh(x: A) -> B {
+    //[next]~^ ERROR type annotations needed: cannot satisfy `_ == A`
     x // B's hidden type is A (opaquely)
     //[current]~^ ERROR opaque type's hidden type cannot be another opaque type
-    //[next]~^^ ERROR type annotations needed: cannot satisfy `A == B`
 }
 
 struct Bar;
diff --git a/tests/ui/inline-const/instance-doesnt-depend-on-type.rs b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs
index 17208a23088..e69106a43af 100644
--- a/tests/ui/inline-const/instance-doesnt-depend-on-type.rs
+++ b/tests/ui/inline-const/instance-doesnt-depend-on-type.rs
@@ -6,5 +6,5 @@
 fn main() {
     const { core::mem::transmute::<u8, u8> };
     // Don't resolve the instance of this inline constant to be an intrinsic,
-    // even if the type of the constant is `extern "intrinsic" fn(u8) -> u8`.
+    // even if the type of the constant is `extern "rust-intrinsic" fn(u8) -> u8`.
 }
diff --git a/tests/ui/interior-mutability/interior-mutability.stderr b/tests/ui/interior-mutability/interior-mutability.stderr
index 7b08a645405..29b250c1b07 100644
--- a/tests/ui/interior-mutability/interior-mutability.stderr
+++ b/tests/ui/interior-mutability/interior-mutability.stderr
@@ -15,7 +15,7 @@ note: required because it's used within this closure
    |
 LL |     catch_unwind(|| { x.set(23); });
    |                  ^^
-note: required by a bound in `catch_unwind`
+note: required by a bound in `std::panic::catch_unwind`
   --> $SRC_DIR/std/src/panic.rs:LL:COL
 
 error: aborting due to 1 previous error
diff --git a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs
index a9c92f23cdd..fa9cbe4400c 100644
--- a/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs
+++ b/tests/ui/intrinsics/bad-intrinsic-monomorphization.rs
@@ -1,13 +1,13 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics, core_intrinsics)]
+#![feature(repr_simd, intrinsics, core_intrinsics)]
 #![allow(warnings)]
 #![crate_type = "rlib"]
 
 // Bad monomorphizations could previously cause LLVM asserts even though the
 // error was caught in the compiler.
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(x: T, y: T) -> T;
 }
 
diff --git a/tests/ui/lexer/lex-emoji-identifiers.rs b/tests/ui/lexer/lex-emoji-identifiers.rs
index bbc088521b7..4fcd102018b 100644
--- a/tests/ui/lexer/lex-emoji-identifiers.rs
+++ b/tests/ui/lexer/lex-emoji-identifiers.rs
@@ -4,7 +4,7 @@ fn invalid_emoji_usages() {
     let wireless🛜 = "basic emoji"; //~ ERROR: identifiers cannot contain emoji
     // FIXME
     let key1️⃣ = "keycap sequence"; //~ ERROR: unknown start of token
-                                    //~^ WARN: identifier contains an uncommon Unicode codepoint
+                                    //~^ WARN: identifier contains an uncommon character: '\u{fe0f}'
     let flag🇺🇳 = "flag sequence"; //~ ERROR: identifiers cannot contain emoji
     let wales🏴 = "tag sequence"; //~ ERROR: identifiers cannot contain emoji
     let folded🙏🏿 = "modifier sequence"; //~ ERROR: identifiers cannot contain emoji
diff --git a/tests/ui/lexer/lex-emoji-identifiers.stderr b/tests/ui/lexer/lex-emoji-identifiers.stderr
index 679b7422bc1..8e2daa6d1d3 100644
--- a/tests/ui/lexer/lex-emoji-identifiers.stderr
+++ b/tests/ui/lexer/lex-emoji-identifiers.stderr
@@ -40,12 +40,13 @@ error: identifiers cannot contain emoji: `folded🙏🏿`
 LL |     let folded🙏🏿 = "modifier sequence";
    |         ^^^^^^^^^^
 
-warning: identifier contains an uncommon Unicode codepoint: '\u{fe0f}'
+warning: identifier contains an uncommon character: '\u{fe0f}'
   --> $DIR/lex-emoji-identifiers.rs:6:9
    |
 LL |     let key1️⃣ = "keycap sequence";
    |         ^^^^
    |
+   = note: this character is included in the Unicode general security profile
    = note: `#[warn(uncommon_codepoints)]` on by default
 
 error: aborting due to 7 previous errors; 1 warning emitted
diff --git a/tests/ui/lifetimes/could-not-resolve-issue-121503.rs b/tests/ui/lifetimes/could-not-resolve-issue-121503.rs
new file mode 100644
index 00000000000..6bc70a907d9
--- /dev/null
+++ b/tests/ui/lifetimes/could-not-resolve-issue-121503.rs
@@ -0,0 +1,13 @@
+//@ edition:2018
+
+#![feature(allocator_api)]
+struct Struct;
+impl Struct {
+    async fn box_ref_Struct(self: Box<Self, impl FnMut(&mut Self)>) -> &u32 {
+    //~^ ERROR the trait bound `impl FnMut(&mut Self): Allocator` is not satisfied
+    //~| ERROR Box<Struct, impl FnMut(&mut Self)>` cannot be used as the type of `self` without
+        &1
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr
new file mode 100644
index 00000000000..a5d8239a2df
--- /dev/null
+++ b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr
@@ -0,0 +1,28 @@
+error[E0277]: the trait bound `impl FnMut(&mut Self): Allocator` is not satisfied
+  --> $DIR/could-not-resolve-issue-121503.rs:6:5
+   |
+LL |     async fn box_ref_Struct(self: Box<Self, impl FnMut(&mut Self)>) -> &u32 {
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Allocator` is not implemented for `impl FnMut(&mut Self)`
+   |
+note: required by a bound in `Box`
+  --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
+help: consider further restricting this bound
+   |
+LL |     async fn box_ref_Struct(self: Box<Self, impl FnMut(&mut Self) + std::alloc::Allocator>) -> &u32 {
+   |                                                                   +++++++++++++++++++++++
+
+error[E0658]: `Box<Struct, impl FnMut(&mut Self)>` cannot be used as the type of `self` without the `arbitrary_self_types` feature
+  --> $DIR/could-not-resolve-issue-121503.rs:6:35
+   |
+LL |     async fn box_ref_Struct(self: Box<Self, impl FnMut(&mut Self)>) -> &u32 {
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #44874 <https://github.com/rust-lang/rust/issues/44874> for more information
+   = help: add `#![feature(arbitrary_self_types)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+   = help: consider changing to `self`, `&self`, `&mut self`, `self: Box<Self>`, `self: Rc<Self>`, `self: Arc<Self>`, or `self: Pin<P>` (where P is one of the previous types except `Self`)
+
+error: aborting due to 2 previous errors
+
+Some errors have detailed explanations: E0277, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs
index c3459930a94..a51452f0695 100644
--- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.rs
@@ -1,12 +1,13 @@
 #![deny(uncommon_codepoints)]
 
-const µ: f64 = 0.000001; //~ ERROR identifier contains an uncommon Unicode codepoint
+const µ: f64 = 0.000001; //~ identifier contains a non normalized (NFKC) character: 'µ'
 //~| WARNING should have an upper case name
 
-fn dijkstra() {} //~ ERROR identifier contains an uncommon Unicode codepoint
+fn dijkstra() {}
+//~^ ERROR identifier contains a non normalized (NFKC) character: 'ij'
 
 fn main() {
-    let ㇻㇲㇳ = "rust"; //~ ERROR identifier contains uncommon Unicode codepoints
+    let ㇻㇲㇳ = "rust"; //~ ERROR identifier contains uncommon characters: 'ㇻ', 'ㇲ', and 'ㇳ'
 
     // using the same identifier the second time won't trigger the lint.
     println!("{}", ㇻㇲㇳ);
diff --git a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr
index bae5ac654d3..000545a0600 100644
--- a/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr
+++ b/tests/ui/lint/rfc-2457-non-ascii-idents/lint-uncommon-codepoints.stderr
@@ -1,26 +1,31 @@
-error: identifier contains an uncommon Unicode codepoint: 'µ'
+error: identifier contains a non normalized (NFKC) character: 'µ'
   --> $DIR/lint-uncommon-codepoints.rs:3:7
    |
 LL | const µ: f64 = 0.000001;
    |       ^
    |
+   = note: this character is included in the Not_NFKC Unicode general security profile
 note: the lint level is defined here
   --> $DIR/lint-uncommon-codepoints.rs:1:9
    |
 LL | #![deny(uncommon_codepoints)]
    |         ^^^^^^^^^^^^^^^^^^^
 
-error: identifier contains an uncommon Unicode codepoint: 'ij'
+error: identifier contains a non normalized (NFKC) character: 'ij'
   --> $DIR/lint-uncommon-codepoints.rs:6:4
    |
 LL | fn dijkstra() {}
    |    ^^^^^^^
+   |
+   = note: this character is included in the Not_NFKC Unicode general security profile
 
-error: identifier contains uncommon Unicode codepoints: 'ㇻ', 'ㇲ', and 'ㇳ'
-  --> $DIR/lint-uncommon-codepoints.rs:9:9
+error: identifier contains uncommon characters: 'ㇻ', 'ㇲ', and 'ㇳ'
+  --> $DIR/lint-uncommon-codepoints.rs:10:9
    |
 LL |     let ㇻㇲㇳ = "rust";
    |         ^^^^^^
+   |
+   = note: these characters are included in the Unicode general security profile
 
 warning: constant `µ` should have an upper case name
   --> $DIR/lint-uncommon-codepoints.rs:3:7
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.rs
index a7412f51782..a7412f51782 100644
--- a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.rs
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.rs
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.stderr
index dd0081cc2df..dcc2e92c47a 100644
--- a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body.stderr
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-1.stderr
@@ -1,5 +1,5 @@
 error: expected `;`, found `#`
-  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:4:47
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body-1.rs:4:47
    |
 LL |     #[cfg(feature = )]
    |     ------------------ only `;` terminated statements or tail expressions are allowed after this attribute
@@ -18,7 +18,7 @@ LL |     { [1, 2, 3].iter().map().collect::<String>() }
    |     +                                            +
 
 error: expected statement after outer attribute
-  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body.rs:5:5
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body-1.rs:5:5
    |
 LL |     #[attr]
    |     ^^^^^^^
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs
new file mode 100644
index 00000000000..ad9e7ad707b
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.rs
@@ -0,0 +1,15 @@
+// Issue #121647: recovery path leaving unemitted error behind
+
+macro_rules! the_macro {
+    ( $foo:stmt ; $bar:stmt ; ) => {
+        #[cfg()]
+        $foo //~ ERROR expected `;`, found `#`
+
+        #[cfg(bar)]
+        $bar
+    };
+}
+
+fn main() {
+    the_macro!( (); (); );
+}
diff --git a/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr
new file mode 100644
index 00000000000..7b9b8319674
--- /dev/null
+++ b/tests/ui/parser/attribute/properly-recover-from-trailing-outer-attribute-in-body-2.stderr
@@ -0,0 +1,26 @@
+error: expected `;`, found `#`
+  --> $DIR/properly-recover-from-trailing-outer-attribute-in-body-2.rs:6:13
+   |
+LL |         #[cfg()]
+   |         -------- only `;` terminated statements or tail expressions are allowed after this attribute
+LL |         $foo
+   |             ^ expected `;` here
+LL |
+LL |         #[cfg(bar)]
+   |         - unexpected token
+...
+LL |     the_macro!( (); (); );
+   |     --------------------- in this macro invocation
+   |
+   = note: this error originates in the macro `the_macro` (in Nightly builds, run with -Z macro-backtrace for more info)
+help: add `;` here
+   |
+LL |         $foo;
+   |             +
+help: alternatively, consider surrounding the expression with a block
+   |
+LL |     the_macro!( { () }; (); );
+   |                 +    +
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/simd/array-trait.rs b/tests/ui/simd/array-trait.rs
index 55fec7a3948..d2f246a2146 100644
--- a/tests/ui/simd/array-trait.rs
+++ b/tests/ui/simd/array-trait.rs
@@ -4,7 +4,7 @@
 
 //@ pretty-expanded FIXME #23616
 
-#![feature(repr_simd, platform_intrinsics, generic_const_exprs)]
+#![feature(repr_simd, intrinsics, generic_const_exprs)]
 #![allow(non_camel_case_types, incomplete_features)]
 
 pub trait Simd {
@@ -25,7 +25,7 @@ pub struct T<S: Simd>([S::Lane; S::SIZE]);
 //~| ERROR SIMD vector element type should be a primitive scalar
 //~| ERROR unconstrained generic constant
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
     fn simd_extract<T, E>(x: T, idx: u32) -> E;
 }
diff --git a/tests/ui/simd/array-type.rs b/tests/ui/simd/array-type.rs
index 0864c3e7418..4063dcd703c 100644
--- a/tests/ui/simd/array-type.rs
+++ b/tests/ui/simd/array-type.rs
@@ -3,7 +3,7 @@
 
 //@ pretty-expanded FIXME #23616
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -13,7 +13,7 @@ struct S([i32; 4]);
 #[derive(Copy, Clone)]
 struct T<const N: usize>([i32; N]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
     fn simd_extract<T, E>(x: T, idx: u32) -> E;
 }
diff --git a/tests/ui/simd/generics.rs b/tests/ui/simd/generics.rs
index 9b54de809ed..bd048b19ca8 100644
--- a/tests/ui/simd/generics.rs
+++ b/tests/ui/simd/generics.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 #![allow(non_camel_case_types)]
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 use std::ops;
 
@@ -21,7 +21,7 @@ struct B<T>([T; 4]);
 struct C<T, const N: usize>([T; N]);
 
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(x: T, y: T) -> T;
 }
 
diff --git a/tests/ui/simd/intrinsic/float-math-pass.rs b/tests/ui/simd/intrinsic/float-math-pass.rs
index c1ba50a910b..ea31e2a7c57 100644
--- a/tests/ui/simd/intrinsic/float-math-pass.rs
+++ b/tests/ui/simd/intrinsic/float-math-pass.rs
@@ -8,14 +8,14 @@
 
 // Test that the simd floating-point math intrinsics produce correct results.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_fsqrt<T>(x: T) -> T;
     fn simd_fabs<T>(x: T) -> T;
     fn simd_fsin<T>(x: T) -> T;
diff --git a/tests/ui/simd/intrinsic/float-minmax-pass.rs b/tests/ui/simd/intrinsic/float-minmax-pass.rs
index a773c79dbe9..d6cbcd4e05a 100644
--- a/tests/ui/simd/intrinsic/float-minmax-pass.rs
+++ b/tests/ui/simd/intrinsic/float-minmax-pass.rs
@@ -3,17 +3,14 @@
 
 // Test that the simd_f{min,max} intrinsics produce the correct results.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, core_intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
-    fn simd_fmin<T>(x: T, y: T) -> T;
-    fn simd_fmax<T>(x: T, y: T) -> T;
-}
+use std::intrinsics::simd::*;
 
 fn main() {
     let x = f32x4(1.0, 2.0, 3.0, 4.0);
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
index b337a77c24c..4ad98d56711 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-2.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -14,7 +14,7 @@ pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
 #[derive(Copy, Clone)]
 pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(x: T, y: T) -> T;
     fn simd_sub<T>(x: T, y: T) -> T;
     fn simd_mul<T>(x: T, y: T) -> T;
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
index fa54228bbcf..33143b1f7b5 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-pass.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 #![allow(non_camel_case_types)]
 //@ ignore-emscripten FIXME(#45351) hits an LLVM assert
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -31,7 +31,7 @@ macro_rules! all_eq_ {
     }};
 }
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(x: T, y: T) -> T;
     fn simd_sub<T>(x: T, y: T) -> T;
     fn simd_mul<T>(x: T, y: T) -> T;
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
index b31a604cb14..36be8cc62a8 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-2.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 //@ ignore-emscripten
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -14,7 +14,7 @@ pub struct x4<T>(pub T, pub T, pub T, pub T);
 #[derive(Copy, Clone)]
 pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_saturating_add<T>(x: T, y: T) -> T;
     fn simd_saturating_sub<T>(x: T, y: T) -> T;
 }
diff --git a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
index 1a4ba3659c1..deee9c2ac41 100644
--- a/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-arithmetic-saturating-pass.rs
@@ -2,7 +2,7 @@
 //@ ignore-emscripten
 
 #![allow(non_camel_case_types)]
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
@@ -12,7 +12,7 @@ struct u32x4(pub u32, pub u32, pub u32, pub u32);
 #[derive(Copy, Clone)]
 struct I32<const N: usize>([i32; N]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_saturating_add<T>(x: T, y: T) -> T;
     fn simd_saturating_sub<T>(x: T, y: T) -> T;
 }
diff --git a/tests/ui/simd/intrinsic/generic-as.rs b/tests/ui/simd/intrinsic/generic-as.rs
index 807cd927734..e97bf12c144 100644
--- a/tests/ui/simd/intrinsic/generic-as.rs
+++ b/tests/ui/simd/intrinsic/generic-as.rs
@@ -1,8 +1,8 @@
 //@ run-pass
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_as<T, U>(x: T) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
index 3063a0a4a3a..5c6a07876e3 100644
--- a/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-bitmask-pass.rs
@@ -6,7 +6,7 @@
 
 // Test that the simd_bitmask intrinsic produces correct results.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #[allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -21,7 +21,7 @@ struct u8x4(pub u8, pub u8, pub u8, pub u8);
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct Tx4<T>(pub T, pub T, pub T, pub T);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_bitmask<T, U>(x: T) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/generic-bitmask.rs b/tests/ui/simd/intrinsic/generic-bitmask.rs
index f1bda34a85e..29b9279c370 100644
--- a/tests/ui/simd/intrinsic/generic-bitmask.rs
+++ b/tests/ui/simd/intrinsic/generic-bitmask.rs
@@ -3,7 +3,7 @@
 // Test that the simd_bitmask intrinsic produces ok-ish error
 // messages when misused.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -30,7 +30,7 @@ struct u8x32([u8; 32]);
 #[derive(Copy, Clone)]
 struct u8x64([u8; 64]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_bitmask<T, U>(x: T) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/generic-bswap-byte.rs b/tests/ui/simd/intrinsic/generic-bswap-byte.rs
index d86db6601b2..f1702538165 100644
--- a/tests/ui/simd/intrinsic/generic-bswap-byte.rs
+++ b/tests/ui/simd/intrinsic/generic-bswap-byte.rs
@@ -1,5 +1,5 @@
 //@ run-pass
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -10,7 +10,7 @@ struct i8x4([i8; 4]);
 #[derive(Copy, Clone)]
 struct u8x4([u8; 4]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_bswap<T>(x: T) -> T;
 }
 
diff --git a/tests/ui/simd/intrinsic/generic-cast-pass.rs b/tests/ui/simd/intrinsic/generic-cast-pass.rs
index 24ec910f534..e0319a6461a 100644
--- a/tests/ui/simd/intrinsic/generic-cast-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-cast-pass.rs
@@ -1,9 +1,9 @@
 //@ run-pass
 //@ ignore-emscripten FIXME(#45351) hits an LLVM assert
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_cast<T, U>(x: T) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
index ade52086bc4..1c09a9fbf3b 100644
--- a/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
+++ b/tests/ui/simd/intrinsic/generic-cast-pointer-width.rs
@@ -1,7 +1,7 @@
 //@ run-pass
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_cast<T, U>(x: T) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/generic-cast.rs b/tests/ui/simd/intrinsic/generic-cast.rs
index 9488d9a42ab..f3fdbe3403f 100644
--- a/tests/ui/simd/intrinsic/generic-cast.rs
+++ b/tests/ui/simd/intrinsic/generic-cast.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -23,7 +23,7 @@ struct f32x8(f32, f32, f32, f32,
              f32, f32, f32, f32);
 
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_cast<T, U>(x: T) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/generic-comparison-pass.rs b/tests/ui/simd/intrinsic/generic-comparison-pass.rs
index 083236387e4..a4df836b6f8 100644
--- a/tests/ui/simd/intrinsic/generic-comparison-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-comparison-pass.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 //@ ignore-emscripten FIXME(#45351) hits an LLVM assert
 
-#![feature(repr_simd, platform_intrinsics, concat_idents)]
+#![feature(repr_simd, intrinsics, concat_idents)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -14,7 +14,7 @@ struct u32x4(pub u32, pub u32, pub u32, pub u32);
 #[derive(Copy, Clone)]
 struct f32x4(pub f32, pub f32, pub f32, pub f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_eq<T, U>(x: T, y: T) -> U;
     fn simd_ne<T, U>(x: T, y: T) -> U;
     fn simd_lt<T, U>(x: T, y: T) -> U;
diff --git a/tests/ui/simd/intrinsic/generic-comparison.rs b/tests/ui/simd/intrinsic/generic-comparison.rs
index 710e660d9cb..bb2720f615f 100644
--- a/tests/ui/simd/intrinsic/generic-comparison.rs
+++ b/tests/ui/simd/intrinsic/generic-comparison.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
@@ -12,7 +12,7 @@ struct i32x4(i32, i32, i32, i32);
 struct i16x8(i16, i16, i16, i16,
              i16, i16, i16, i16);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_eq<T, U>(x: T, y: T) -> U;
     fn simd_ne<T, U>(x: T, y: T) -> U;
     fn simd_lt<T, U>(x: T, y: T) -> U;
diff --git a/tests/ui/simd/intrinsic/generic-elements-pass.rs b/tests/ui/simd/intrinsic/generic-elements-pass.rs
index e3b527fa4fe..73003087819 100644
--- a/tests/ui/simd/intrinsic/generic-elements-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-elements-pass.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 //@ ignore-emscripten FIXME(#45351) hits an LLVM assert
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![feature(inline_const)]
 
 #[repr(simd)]
@@ -18,7 +18,7 @@ struct i32x4(i32, i32, i32, i32);
 struct i32x8(i32, i32, i32, i32,
              i32, i32, i32, i32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
     fn simd_extract<T, E>(x: T, idx: u32) -> E;
 
diff --git a/tests/ui/simd/intrinsic/generic-elements.rs b/tests/ui/simd/intrinsic/generic-elements.rs
index a8ee4cf3965..abceb08ecc5 100644
--- a/tests/ui/simd/intrinsic/generic-elements.rs
+++ b/tests/ui/simd/intrinsic/generic-elements.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics, rustc_attrs, adt_const_params)]
+#![feature(repr_simd, intrinsics, rustc_attrs, adt_const_params)]
 #![allow(incomplete_features)]
 
 #[repr(simd)]
@@ -31,7 +31,7 @@ struct f32x4(f32, f32, f32, f32);
 struct f32x8(f32, f32, f32, f32,
              f32, f32, f32, f32);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_insert<T, E>(x: T, idx: u32, y: E) -> T;
     fn simd_extract<T, E>(x: T, idx: u32) -> E;
 
diff --git a/tests/ui/simd/intrinsic/generic-gather-pass.rs b/tests/ui/simd/intrinsic/generic-gather-pass.rs
index ca9e9de2afa..a00bc67e73b 100644
--- a/tests/ui/simd/intrinsic/generic-gather-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-gather-pass.rs
@@ -3,14 +3,14 @@
 
 // Test that the simd_{gather,scatter} intrinsics produce the correct results.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct x4<T>(pub T, pub T, pub T, pub T);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
     fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
 }
diff --git a/tests/ui/simd/intrinsic/generic-reduction-pass.rs b/tests/ui/simd/intrinsic/generic-reduction-pass.rs
index cf4669cd61f..64902788709 100644
--- a/tests/ui/simd/intrinsic/generic-reduction-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-reduction-pass.rs
@@ -5,7 +5,7 @@
 
 // Test that the simd_reduce_{op} intrinsics produce the correct results.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #[allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -24,7 +24,7 @@ struct f32x4(pub f32, pub f32, pub f32, pub f32);
 #[derive(Copy, Clone)]
 struct b8x4(pub i8, pub i8, pub i8, pub i8);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_reduce_add_unordered<T, U>(x: T) -> U;
     fn simd_reduce_mul_unordered<T, U>(x: T) -> U;
     fn simd_reduce_add_ordered<T, U>(x: T, acc: U) -> U;
diff --git a/tests/ui/simd/intrinsic/generic-reduction.rs b/tests/ui/simd/intrinsic/generic-reduction.rs
index 5e3debb411e..96df7359169 100644
--- a/tests/ui/simd/intrinsic/generic-reduction.rs
+++ b/tests/ui/simd/intrinsic/generic-reduction.rs
@@ -4,7 +4,7 @@
 // Test that the simd_reduce_{op} intrinsics produce ok-ish error
 // messages when misused.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -16,7 +16,7 @@ pub struct f32x4(pub f32, pub f32, pub f32, pub f32);
 pub struct u32x4(pub u32, pub u32, pub u32, pub u32);
 
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_reduce_add_ordered<T, U>(x: T, y: U) -> U;
     fn simd_reduce_mul_ordered<T, U>(x: T, y: U) -> U;
     fn simd_reduce_and<T, U>(x: T) -> U;
diff --git a/tests/ui/simd/intrinsic/generic-select-pass.rs b/tests/ui/simd/intrinsic/generic-select-pass.rs
index df8a89e26c9..98e1534e6e6 100644
--- a/tests/ui/simd/intrinsic/generic-select-pass.rs
+++ b/tests/ui/simd/intrinsic/generic-select-pass.rs
@@ -6,7 +6,7 @@
 
 // Test that the simd_select intrinsics produces correct results.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #[allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -29,7 +29,7 @@ struct f32x4(pub f32, pub f32, pub f32, pub f32);
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct b8x4(pub i8, pub i8, pub i8, pub i8);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
     fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
 }
diff --git a/tests/ui/simd/intrinsic/generic-select.rs b/tests/ui/simd/intrinsic/generic-select.rs
index ab963ed942f..215ae405c37 100644
--- a/tests/ui/simd/intrinsic/generic-select.rs
+++ b/tests/ui/simd/intrinsic/generic-select.rs
@@ -3,7 +3,7 @@
 // Test that the simd_select intrinsic produces ok-ish error
 // messages when misused.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -22,7 +22,7 @@ struct b8x4(pub i8, pub i8, pub i8, pub i8);
 #[derive(Copy, Clone, PartialEq)]
 struct b8x8(pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8, pub i8);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_select<T, U>(x: T, a: U, b: U) -> U;
     fn simd_select_bitmask<T, U>(x: T, a: U, b: U) -> U;
 }
diff --git a/tests/ui/simd/intrinsic/generic-shuffle.rs b/tests/ui/simd/intrinsic/generic-shuffle.rs
index db814f02c8b..c0888f67784 100644
--- a/tests/ui/simd/intrinsic/generic-shuffle.rs
+++ b/tests/ui/simd/intrinsic/generic-shuffle.rs
@@ -3,13 +3,13 @@
 // Test that the simd_shuffle intrinsic produces ok-ish error
 // messages when misused.
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone)]
 pub struct Simd<T, const N: usize>([T; N]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
index 5b49f4f7203..928d3824703 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557-ice.rs
@@ -3,9 +3,9 @@
 //
 //@ run-pass
 //@ compile-flags: -Zmir-opt-level=4
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/inlining-issue67557.rs b/tests/ui/simd/intrinsic/inlining-issue67557.rs
index 3d6284ef1c6..b8b8dbba547 100644
--- a/tests/ui/simd/intrinsic/inlining-issue67557.rs
+++ b/tests/ui/simd/intrinsic/inlining-issue67557.rs
@@ -3,9 +3,9 @@
 //
 //@ run-pass
 //@ compile-flags: -Zmir-opt-level=4
-#![feature(platform_intrinsics, repr_simd)]
+#![feature(intrinsics, repr_simd)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(x: T, y: T, idx: I) -> U;
 }
 
diff --git a/tests/ui/simd/intrinsic/issue-85855.rs b/tests/ui/simd/intrinsic/issue-85855.rs
index f276fbd6694..dc04699f7f8 100644
--- a/tests/ui/simd/intrinsic/issue-85855.rs
+++ b/tests/ui/simd/intrinsic/issue-85855.rs
@@ -2,10 +2,10 @@
 // with the wrong number of generic lifetime/type/const parameters, and
 // that no ICE occurs in these cases.
 
-#![feature(platform_intrinsics)]
+#![feature(intrinsics)]
 #![crate_type="lib"]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_saturating_add<'a, T: 'a>(x: T, y: T);
     //~^ ERROR: intrinsic has wrong number of lifetime parameters
 
diff --git a/tests/ui/simd/intrinsic/ptr-cast.rs b/tests/ui/simd/intrinsic/ptr-cast.rs
index 109e1d0039a..83d86baf334 100644
--- a/tests/ui/simd/intrinsic/ptr-cast.rs
+++ b/tests/ui/simd/intrinsic/ptr-cast.rs
@@ -1,8 +1,8 @@
 //@ run-pass
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_cast_ptr<T, U>(x: T) -> U;
     fn simd_expose_addr<T, U>(x: T) -> U;
     fn simd_from_exposed_addr<T, U>(x: T) -> U;
diff --git a/tests/ui/simd/issue-105439.rs b/tests/ui/simd/issue-105439.rs
index 3eb137e4ee7..3cb43fc8b1a 100644
--- a/tests/ui/simd/issue-105439.rs
+++ b/tests/ui/simd/issue-105439.rs
@@ -2,14 +2,14 @@
 //@ compile-flags: -O -Zverify-llvm-ir
 
 #![feature(repr_simd)]
-#![feature(platform_intrinsics)]
+#![feature(intrinsics)]
 
 #[allow(non_camel_case_types)]
 #[derive(Clone, Copy)]
 #[repr(simd)]
 struct i32x4([i32; 4]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     pub(crate) fn simd_add<T>(x: T, y: T) -> T;
 }
 
diff --git a/tests/ui/simd/issue-39720.rs b/tests/ui/simd/issue-39720.rs
index ea6e893b79d..4610b1d5004 100644
--- a/tests/ui/simd/issue-39720.rs
+++ b/tests/ui/simd/issue-39720.rs
@@ -1,7 +1,7 @@
 //@ run-pass
 //@ ignore-emscripten FIXME(#45351)
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, Debug)]
@@ -11,7 +11,7 @@ pub struct Char3(pub i8, pub i8, pub i8);
 #[derive(Copy, Clone, Debug)]
 pub struct Short3(pub i16, pub i16, pub i16);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_cast<T, U>(x: T) -> U;
 }
 
diff --git a/tests/ui/simd/issue-85915-simd-ptrs.rs b/tests/ui/simd/issue-85915-simd-ptrs.rs
index 96ac76f0590..edf60e0205c 100644
--- a/tests/ui/simd/issue-85915-simd-ptrs.rs
+++ b/tests/ui/simd/issue-85915-simd-ptrs.rs
@@ -3,7 +3,7 @@
 
 // Short form of the generic gather/scatter tests,
 // verifying simd([*const T; N]) and simd([*mut T; N]) pass typeck and work.
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
@@ -22,7 +22,7 @@ struct f32x4([f32; 4]);
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct i32x4([i32; 4]);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
     fn simd_scatter<T, U, V>(x: T, y: U, z: V) -> ();
 }
diff --git a/tests/ui/simd/issue-89193.rs b/tests/ui/simd/issue-89193.rs
index f34242e7bf8..a4ed9be9962 100644
--- a/tests/ui/simd/issue-89193.rs
+++ b/tests/ui/simd/issue-89193.rs
@@ -3,14 +3,14 @@
 // Test that simd gather instructions on slice of usize don't cause crash
 // See issue #89183 - https://github.com/rust-lang/rust/issues/89193
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd)]
 #[derive(Copy, Clone, PartialEq, Debug)]
 struct x4<T>(pub T, pub T, pub T, pub T);
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_gather<T, U, V>(x: T, y: U, z: V) -> T;
 }
 
diff --git a/tests/ui/simd/masked-load-store-build-fail.rs b/tests/ui/simd/masked-load-store-build-fail.rs
index 7b414dfcc93..fbd657763c9 100644
--- a/tests/ui/simd/masked-load-store-build-fail.rs
+++ b/tests/ui/simd/masked-load-store-build-fail.rs
@@ -1,7 +1,7 @@
 //@ build-fail
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
     fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
 }
diff --git a/tests/ui/simd/masked-load-store-check-fail.rs b/tests/ui/simd/masked-load-store-check-fail.rs
index a86979d8faf..39c82c41385 100644
--- a/tests/ui/simd/masked-load-store-check-fail.rs
+++ b/tests/ui/simd/masked-load-store-check-fail.rs
@@ -1,7 +1,7 @@
 //@ check-fail
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
     fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
 }
diff --git a/tests/ui/simd/masked-load-store.rs b/tests/ui/simd/masked-load-store.rs
index b2f5490727f..902143f9261 100644
--- a/tests/ui/simd/masked-load-store.rs
+++ b/tests/ui/simd/masked-load-store.rs
@@ -1,7 +1,7 @@
 //@ run-pass
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_masked_load<M, P, T>(mask: M, pointer: P, values: T) -> T;
     fn simd_masked_store<M, P, T>(mask: M, pointer: P, values: T) -> ();
 }
diff --git a/tests/ui/simd/monomorphize-shuffle-index.rs b/tests/ui/simd/monomorphize-shuffle-index.rs
index 052f0eec472..379616884a1 100644
--- a/tests/ui/simd/monomorphize-shuffle-index.rs
+++ b/tests/ui/simd/monomorphize-shuffle-index.rs
@@ -1,10 +1,10 @@
 //@[old]run-pass
 //@[generic_with_fn]run-pass
 //@ revisions: old generic generic_with_fn
-#![feature(repr_simd, platform_intrinsics, adt_const_params, generic_const_exprs)]
+#![feature(repr_simd, intrinsics, adt_const_params, generic_const_exprs)]
 #![allow(incomplete_features)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     #[cfg(old)]
     fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
     #[cfg(any(generic, generic_with_fn))]
diff --git a/tests/ui/simd/repr_packed.rs b/tests/ui/simd/repr_packed.rs
index 395751e86f1..411bba3454e 100644
--- a/tests/ui/simd/repr_packed.rs
+++ b/tests/ui/simd/repr_packed.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(non_camel_case_types)]
 
 #[repr(simd, packed)]
@@ -25,7 +25,7 @@ fn check_ty<T>() {
     check_size_align::<T, 15>();
 }
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_add<T>(a: T, b: T) -> T;
 }
 
diff --git a/tests/ui/simd/shuffle.rs b/tests/ui/simd/shuffle.rs
index 5022afc5b49..09926d95557 100644
--- a/tests/ui/simd/shuffle.rs
+++ b/tests/ui/simd/shuffle.rs
@@ -2,11 +2,11 @@
 //@ revisions: opt noopt
 //@[noopt] compile-flags: -Copt-level=0
 //@[opt] compile-flags: -O
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 #![allow(incomplete_features)]
 #![feature(adt_const_params)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_shuffle<T, I, U>(a: T, b: T, i: I) -> U;
 }
 
diff --git a/tests/ui/simd/simd-bitmask.rs b/tests/ui/simd/simd-bitmask.rs
index a3717c9e21a..4a7c3bc7750 100644
--- a/tests/ui/simd/simd-bitmask.rs
+++ b/tests/ui/simd/simd-bitmask.rs
@@ -1,8 +1,8 @@
 //@run-pass
 //@ignore-endian-big behavior of simd_select_bitmask is endian-specific
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
-extern "platform-intrinsic" {
+extern "rust-intrinsic" {
     fn simd_bitmask<T, U>(v: T) -> U;
     fn simd_select_bitmask<T, U>(m: T, a: U, b: U) -> U;
 }
diff --git a/tests/ui/simd/type-generic-monomorphisation-empty.rs b/tests/ui/simd/type-generic-monomorphisation-empty.rs
index 38c5581105d..4700f642065 100644
--- a/tests/ui/simd/type-generic-monomorphisation-empty.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-empty.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 //@ error-pattern:monomorphising SIMD type `Simd<0>` of zero length
 
diff --git a/tests/ui/simd/type-generic-monomorphisation-oversized.rs b/tests/ui/simd/type-generic-monomorphisation-oversized.rs
index 53f66f1d596..9949f913c44 100644
--- a/tests/ui/simd/type-generic-monomorphisation-oversized.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-oversized.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 //@ error-pattern:monomorphising SIMD type `Simd<65536>` of length greater than 32768
 
diff --git a/tests/ui/simd/type-generic-monomorphisation-power-of-two.rs b/tests/ui/simd/type-generic-monomorphisation-power-of-two.rs
index 26269335bc4..b3e228970d0 100644
--- a/tests/ui/simd/type-generic-monomorphisation-power-of-two.rs
+++ b/tests/ui/simd/type-generic-monomorphisation-power-of-two.rs
@@ -1,6 +1,6 @@
 //@ run-pass
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 #[repr(simd)]
 struct Simd<const N: usize>([f32; N]);
diff --git a/tests/ui/simd/type-generic-monomorphisation.rs b/tests/ui/simd/type-generic-monomorphisation.rs
index 90ddd1dde0f..2eeba55ef91 100644
--- a/tests/ui/simd/type-generic-monomorphisation.rs
+++ b/tests/ui/simd/type-generic-monomorphisation.rs
@@ -1,6 +1,6 @@
 //@ build-fail
 
-#![feature(repr_simd, platform_intrinsics)]
+#![feature(repr_simd, intrinsics)]
 
 
 //@ error-pattern:monomorphising SIMD type `Simd2<X>` with a non-primitive-scalar (integer/float/pointer) element type `X`
diff --git a/tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-1.rs b/tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-1.rs
new file mode 100644
index 00000000000..3ac1639cfba
--- /dev/null
+++ b/tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-1.rs
@@ -0,0 +1,26 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#84.
+//
+// We try to infer `T::Rigid: Into<?0>` and have 2 candidates from where-clauses:
+//
+// - `Into<String>`
+// - `Into<<T::Rigid as Elaborate>::Assoc>`
+//
+// This causes ambiguity unless we normalize the alias in the second candidate
+// to detect that they actually result in the same constraints.
+trait Trait {
+    type Rigid: Elaborate<Assoc = String> + Into<String> + Default;
+}
+
+trait Elaborate: Into<Self::Assoc> {
+    type Assoc;
+}
+
+fn test<T: Trait>() {
+    let rigid: T::Rigid = Default::default();
+    drop(rigid.into());
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-2.rs b/tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-2.rs
new file mode 100644
index 00000000000..a1b736184f1
--- /dev/null
+++ b/tests/ui/traits/next-solver/assembly/candidates-equal-modulo-norm-2.rs
@@ -0,0 +1,26 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// Regression test for trait-system-refactor-initiative#86. This previously
+// failed with ambiguity due to multiple candidates with different
+// normalization.
+
+trait Bar {
+    type Item;
+    type Assoc: AsRef<[Self::Item]>;
+}
+
+struct Foo<T: Bar> {
+    t: <T as Bar>::Assoc,
+}
+
+impl<T: Bar<Item = u32>> Foo<T>
+where
+    <T as Bar>::Assoc: AsRef<[u32]>,
+{
+    fn hello(&self) {
+        println!("{}", self.t.as_ref().len());
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
index 66409f171e6..3238f028362 100644
--- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.rs
@@ -16,6 +16,6 @@ trait Trait {}
 impl<T: Copy> Trait for T {}
 struct LocalTy;
 impl Trait for <LocalTy as Overflow>::Assoc {}
-//~^ ERROR conflicting implementations of trait `Trait` for type `<LocalTy as Overflow>::Assoc`
+//~^ ERROR conflicting implementations of trait `Trait`
 
 fn main() {}
diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
index 583945723d5..fc145b81196 100644
--- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-norm-overflow.stderr
@@ -1,11 +1,11 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `<LocalTy as Overflow>::Assoc`
+error[E0119]: conflicting implementations of trait `Trait`
   --> $DIR/trait_ref_is_knowable-norm-overflow.rs:18:1
    |
 LL | impl<T: Copy> Trait for T {}
    | ------------------------- first implementation here
 LL | struct LocalTy;
 LL | impl Trait for <LocalTy as Overflow>::Assoc {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<LocalTy as Overflow>::Assoc`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0275]: overflow evaluating the requirement `<T as Overflow>::Assoc: Sized`
   --> $DIR/trait_ref_is_knowable-norm-overflow.rs:10:18
diff --git a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
index 98fd98ac282..70d8d74d5ea 100644
--- a/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
+++ b/tests/ui/traits/next-solver/coherence/trait_ref_is_knowable-normalization-3.rs
@@ -9,7 +9,7 @@ impl<T> Id for T {
 }
 
 
-// Coherence should be able to reason that `(): PartialEq<<T as Id>::Assoc>>`
+// Coherence should be able to reason that `(): PartialEq<<LocalTy as Id>::Assoc>>`
 // does not hold.
 //
 // See https://github.com/rust-lang/trait-system-refactor-initiative/issues/51
diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs
index 4de5eda3a79..91793e59f1a 100644
--- a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs
+++ b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.rs
@@ -1,8 +1,8 @@
 //@ compile-flags: -Znext-solver
-//@ known-bug: trait-system-refactor-initiative#60
+//@ check-pass
 
 // Generalizing a projection containing an inference variable
-// which cannot be named by the `root_vid` can result in ambiguity.
+// which cannot be named by the `root_vid` previously resulted in ambiguity.
 //
 // Because we do not decrement the universe index when exiting a forall,
 // this can cause unexpected failures.
diff --git a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr b/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr
deleted file mode 100644
index 4548ab1e297..00000000000
--- a/tests/ui/traits/next-solver/generalize/generalize-proj-new-universe-index-2.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0284]: type annotations needed
-  --> $DIR/generalize-proj-new-universe-index-2.rs:74:5
-   |
-LL |     bound::<<Rigid as IdHigherRankedBound>::Assoc, <Wrapper<Leaf> as Id>::Assoc, _>()
-   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type of the type parameter `V` declared on the function `bound`
-   |
-   = note: cannot satisfy `<<Rigid as IdHigherRankedBound>::Assoc as WithAssoc<<Wrapper<Leaf> as Id>::Assoc>>::Assoc == _`
-note: required by a bound in `bound`
-  --> $DIR/generalize-proj-new-universe-index-2.rs:69:21
-   |
-LL | fn bound<T: ?Sized, U: ?Sized, V: ?Sized>()
-   |    ----- required by a bound in this function
-LL | where
-LL |     T: WithAssoc<U, Assoc = V>,
-   |                     ^^^^^^^^^ required by this bound in `bound`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/next-solver/generalize/instantiate-canonical-occurs-check-failure.rs b/tests/ui/traits/next-solver/generalize/instantiate-canonical-occurs-check-failure.rs
new file mode 100644
index 00000000000..37d91fe2c7d
--- /dev/null
+++ b/tests/ui/traits/next-solver/generalize/instantiate-canonical-occurs-check-failure.rs
@@ -0,0 +1,29 @@
+//@ compile-flags: -Znext-solver
+//@ check-pass
+
+// With #119106 generalization now results in `AliasRelate` if the generalized
+// alias contains an inference variable which is not nameable.
+//
+// We previously proved alias-relate after canonicalization, which does not keep track
+// of universe indices, so all inference vars were nameable inside of `AliasRelate`.
+//
+// If we now have a rigid projection containing an unnameable inference variable,
+// we should emit an alias-relate obligation, which constrains the type of `x` to
+// an alias. This caused us to emit yet another equivalent alias-relate obligation
+// when trying to instantiate the query result, resulting in overflow.
+trait Trait<'a> {
+    type Assoc: Default;
+}
+
+fn takes_alias<'a, T: Trait<'a>>(_: <T as Trait<'a>>::Assoc) {}
+
+fn foo<T: for<'a> Trait<'a>>() {
+    let x = Default::default();
+
+    let _incr_universe: for<'a, 'b> fn(&'a (), &'b ()) =
+        (|&(), &()| ()) as for<'a> fn(&'a (), &'a ());
+
+    takes_alias::<T>(x);
+}
+
+fn main() {}
diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
deleted file mode 100644
index cde925db184..00000000000
--- a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.next.stderr
+++ /dev/null
@@ -1,9 +0,0 @@
-error[E0284]: type annotations needed: cannot satisfy `_ == <<T as Id<_>>::Id as Unnormalizable>::Assoc`
-  --> $DIR/occurs-check-nested-alias.rs:36:9
-   |
-LL |     x = y;
-   |         ^ cannot satisfy `_ == <<T as Id<_>>::Id as Unnormalizable>::Assoc`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0284`.
diff --git a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs
index 78fbe441527..536e7e97c40 100644
--- a/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs
+++ b/tests/ui/traits/next-solver/generalize/occurs-check-nested-alias.rs
@@ -1,10 +1,8 @@
 //@ revisions: old next
-//@[old] check-pass
-
-// Currently always fails to generalize the outer alias, even if it
-// is treated as rigid by `alias-relate`.
 //@[next] compile-flags: -Znext-solver
-//@[next] known-bug: trait-system-refactor-initiative#8
+//@ check-pass
+
+// case 3 of https://github.com/rust-lang/trait-system-refactor-initiative/issues/8.
 #![crate_type = "lib"]
 #![allow(unused)]
 trait Unnormalizable {
@@ -14,8 +12,8 @@ trait Unnormalizable {
 trait Id<T> {
     type Id;
 }
-impl<T, U> Id<T> for U {
-    type Id = U;
+impl<T, U> Id<U> for T {
+    type Id = T;
 }
 
 struct Inv<T>(*mut T);
@@ -24,15 +22,23 @@ fn unconstrained<T>() -> T {
     todo!()
 }
 
-fn create<T, U: Unnormalizable>(
-    x: &U,
-) -> (Inv<T>, Inv<<<U as Id<T>>::Id as Unnormalizable>::Assoc>) {
+fn create<T: Unnormalizable, U>(
+    x: &T,
+) -> (Inv<U>, Inv<<<T as Id<U>>::Id as Unnormalizable>::Assoc>) {
     todo!()
 }
 
 fn foo<T: Unnormalizable>() {
-    let q = unconstrained();
-    let (mut x, y) = create::<_, _>(&q);
-    x = y;
-    drop::<T>(q);
+    let t = unconstrained();
+    let (mut u, assoc) = create::<_, _>(&t);
+    u = assoc;
+    // Instantiating `?u` with `<<?t as Id<?u>>::Id as Unnormalizable>::Assoc` would
+    // result in a cyclic type. However, we can still unify these types by first
+    // normalizing the inner associated type. Emitting an error here would be incomplete.
+    drop::<T>(t);
+
+    // FIXME(-Znext-solver): This line is necessary due to an unrelated solver bug
+    // and should get removed in the future.
+    //   https://github.com/rust-lang/trait-system-refactor-initiative/issues/96
+    drop::<Inv<<T as Unnormalizable>::Assoc>>(u);
 }
diff --git a/tests/ui/traits/next-solver/issue-118950-root-region.stderr b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
index e33320ed9e6..931c46c6887 100644
--- a/tests/ui/traits/next-solver/issue-118950-root-region.stderr
+++ b/tests/ui/traits/next-solver/issue-118950-root-region.stderr
@@ -14,13 +14,9 @@ LL | #![feature(lazy_type_alias)]
    = note: `#[warn(incomplete_features)]` on by default
 
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
 WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [ReBound(DebruijnIndex(0), BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
-WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [RePlaceholder(!1_BoundRegion { var: 0, kind: BrNamed(DefId(0:15 ~ issue_118950_root_region[d54f]::{impl#1}::'a), 'a) }), ?1t], def_id: DefId(0:8 ~ issue_118950_root_region[d54f]::Assoc) }
 error[E0119]: conflicting implementations of trait `Overlap<fn(_)>` for type `fn(_)`
   --> $DIR/issue-118950-root-region.rs:19:1
    |