about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules4
-rw-r--r--RELEASES.md4
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs4
-rw-r--r--compiler/rustc_ast/src/token.rs18
-rw-r--r--compiler/rustc_ast/src/tokenstream.rs4
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs13
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs3
-rw-r--r--compiler/rustc_borrowck/src/diagnostics/mod.rs4
-rw-r--r--compiler/rustc_borrowck/src/lib.rs2
-rw-r--r--compiler/rustc_borrowck/src/type_check/mod.rs71
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs14
-rw-r--r--compiler/rustc_codegen_llvm/src/attributes.rs46
-rw-r--r--compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/intrinsic.rs17
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/metadata.rs33
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/rvalue.rs2
-rw-r--r--compiler/rustc_codegen_ssa/src/mir/statement.rs7
-rw-r--r--compiler/rustc_const_eval/src/interpret/call.rs2
-rw-r--r--compiler/rustc_data_structures/src/steal.rs1
-rw-r--r--compiler/rustc_driver_impl/src/lib.rs6
-rw-r--r--compiler/rustc_expand/src/mbe/macro_parser.rs6
-rw-r--r--compiler/rustc_expand/src/mbe/transcribe.rs4
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs9
-rw-r--r--compiler/rustc_feature/src/builtin_attrs.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect/generics_of.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs16
-rw-r--r--compiler/rustc_hir_analysis/src/delegation.rs445
-rw-r--r--compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs3
-rw-r--r--compiler/rustc_hir_typeck/src/method/probe.rs5
-rw-r--r--compiler/rustc_hir_typeck/src/method/suggest.rs9
-rw-r--r--compiler/rustc_hir_typeck/src/upvar.rs59
-rw-r--r--compiler/rustc_interface/src/tests.rs2
-rw-r--r--compiler/rustc_lexer/src/lib.rs39
-rw-r--r--compiler/rustc_lint/messages.ftl8
-rw-r--r--compiler/rustc_lint/src/builtin.rs20
-rw-r--r--compiler/rustc_lint/src/context/diagnostics.rs25
-rw-r--r--compiler/rustc_lint/src/internal.rs24
-rw-r--r--compiler/rustc_lint/src/lib.rs1
-rw-r--r--compiler/rustc_lint/src/lints.rs75
-rw-r--r--compiler/rustc_lint/src/shadowed_into_iter.rs7
-rw-r--r--compiler/rustc_lint/src/types.rs6
-rw-r--r--compiler/rustc_lint/src/unused.rs5
-rw-r--r--compiler/rustc_lint_defs/src/lib.rs19
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs2
-rw-r--r--compiler/rustc_middle/src/mir/syntax.rs3
-rw-r--r--compiler/rustc_middle/src/ty/closure.rs3
-rw-r--r--compiler/rustc_middle/src/ty/context.rs6
-rw-r--r--compiler/rustc_middle/src/ty/fast_reject.rs10
-rw-r--r--compiler/rustc_middle/src/ty/layout.rs6
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs15
-rw-r--r--compiler/rustc_middle/src/ty/trait_def.rs12
-rw-r--r--compiler/rustc_middle/src/ty/util.rs2
-rw-r--r--compiler/rustc_mir_transform/src/coroutine/by_move_body.rs11
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans.rs34
-rw-r--r--compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs22
-rw-r--r--compiler/rustc_mir_transform/src/coverage/unexpand.rs15
-rw-r--r--compiler/rustc_mir_transform/src/elaborate_box_derefs.rs12
-rw-r--r--compiler/rustc_mir_transform/src/validate.rs13
-rw-r--r--compiler/rustc_monomorphize/src/collector.rs7
-rw-r--r--compiler/rustc_monomorphize/src/lib.rs2
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs10
-rw-r--r--compiler/rustc_next_trait_solver/src/solve/trait_goals.rs11
-rw-r--r--compiler/rustc_parse/messages.ftl6
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs90
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs85
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs6
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/nonterminal.rs6
-rw-r--r--compiler/rustc_parse/src/parser/pat.rs6
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs7
-rw-r--r--compiler/rustc_passes/src/check_attr.rs40
-rw-r--r--compiler/rustc_resolve/src/late.rs14
-rw-r--r--compiler/rustc_session/src/config.rs5
-rw-r--r--compiler/rustc_session/src/options.rs31
-rw-r--r--compiler/rustc_span/src/symbol.rs43
-rw-r--r--compiler/rustc_target/src/spec/base/apple/mod.rs329
-rw-r--r--compiler/rustc_target/src/spec/base/apple/tests.rs9
-rw-r--r--compiler/rustc_target/src/spec/mod.rs4
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs24
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs18
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs14
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs18
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs14
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs14
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs14
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs11
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs24
-rw-r--r--compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs18
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs10
-rw-r--r--compiler/rustc_target/src/spec/targets/i386_apple_ios.rs15
-rw-r--r--compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs26
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs30
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs17
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs17
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs11
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs13
-rw-r--r--compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs26
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs3
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs3
-rw-r--r--compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/coherence.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/engine.rs4
-rw-r--r--compiler/rustc_trait_selection/src/traits/project.rs8
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs12
-rw-r--r--compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs6
-rw-r--r--compiler/rustc_type_ir/src/fast_reject.rs319
-rw-r--r--config.example.toml3
-rw-r--r--library/core/src/lib.rs3
-rw-r--r--library/core/src/num/f128.rs16
-rw-r--r--library/core/src/num/f16.rs16
-rw-r--r--library/core/src/num/f32.rs16
-rw-r--r--library/core/src/num/f64.rs16
-rw-r--r--library/core/src/ptr/mod.rs8
-rw-r--r--library/core/src/time.rs28
-rw-r--r--library/std/src/ffi/os_str.rs2
-rw-r--r--library/std/src/path.rs2
-rw-r--r--library/std/src/sync/condvar.rs8
-rw-r--r--src/bootstrap/bootstrap.py21
-rwxr-xr-xsrc/bootstrap/configure.py1
-rw-r--r--src/bootstrap/src/core/build_steps/check.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/clippy.rs2
-rw-r--r--src/bootstrap/src/core/build_steps/compile.rs34
-rw-r--r--src/bootstrap/src/core/build_steps/doc.rs5
-rw-r--r--src/bootstrap/src/core/build_steps/llvm.rs95
-rw-r--r--src/bootstrap/src/core/build_steps/test.rs8
-rw-r--r--src/bootstrap/src/core/builder.rs17
-rw-r--r--src/bootstrap/src/core/config/config.rs8
-rw-r--r--src/bootstrap/src/core/download.rs31
-rw-r--r--src/bootstrap/src/core/metadata.rs10
-rw-r--r--src/bootstrap/src/lib.rs51
-rw-r--r--src/bootstrap/src/utils/cc_detect.rs32
-rw-r--r--src/bootstrap/src/utils/change_tracker.rs5
-rw-r--r--src/librustdoc/html/highlight.rs4
-rw-r--r--src/librustdoc/html/render/write_shared.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/escape.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/mod.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/methods/utils.rs4
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/mod.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs6
-rw-r--r--src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs6
-rw-r--r--src/tools/clippy/clippy_utils/src/ty.rs4
-rw-r--r--src/tools/clippy/tests/ui/transmute.rs12
-rw-r--r--src/tools/clippy/tests/ui/transmute.stderr112
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.fixed28
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.rs12
-rw-r--r--src/tools/clippy/tests/ui/transmute_float_to_int.stderr50
m---------src/tools/enzyme0
-rw-r--r--src/tools/lint-docs/src/lib.rs5
-rw-r--r--src/tools/lint-docs/src/main.rs8
-rw-r--r--src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs3
-rw-r--r--src/tools/rust-analyzer/crates/parser/src/lexed_str.rs7
-rw-r--r--src/tools/rustfmt/src/expr.rs12
-rw-r--r--src/tools/rustfmt/src/macros.rs6
-rw-r--r--src/tools/rustfmt/src/types.rs2
-rw-r--r--src/tools/rustfmt/tests/target/raw-lifetimes.rs15
-rw-r--r--src/tools/tidy/config/black.toml1
-rw-r--r--src/tools/tidy/config/ruff.toml2
-rw-r--r--src/tools/tidy/src/walk.rs1
-rw-r--r--tests/assembly/asm/aarch64-modifiers.rs7
-rw-r--r--tests/assembly/asm/aarch64-types.rs13
-rw-r--r--tests/assembly/asm/arm-modifiers.rs7
-rw-r--r--tests/assembly/asm/arm-types.rs13
-rw-r--r--tests/assembly/asm/hexagon-types.rs25
-rw-r--r--tests/assembly/asm/loongarch-type.rs10
-rw-r--r--tests/assembly/asm/mips-types.rs10
-rw-r--r--tests/assembly/asm/powerpc-types.rs10
-rw-r--r--tests/assembly/asm/riscv-types.rs13
-rw-r--r--tests/assembly/asm/s390x-types.rs10
-rw-r--r--tests/assembly/asm/x86-modifiers.rs7
-rw-r--r--tests/assembly/asm/x86-types.rs13
-rw-r--r--tests/assembly/s390x-backchain-toggle.rs46
-rw-r--r--tests/codegen/intrinsics/likely.rs2
-rw-r--r--tests/codegen/naked-asan.rs22
-rw-r--r--tests/coverage/async.cov-map48
-rw-r--r--tests/coverage/async.coverage4
-rw-r--r--tests/coverage/await_ready.cov-map25
-rw-r--r--tests/coverage/await_ready.coverage38
-rw-r--r--tests/coverage/await_ready.rs37
-rw-r--r--tests/crashes/118987.rs17
-rw-r--r--tests/crashes/123629.rs10
-rw-r--r--tests/crashes/127033.rs18
-rw-r--r--tests/crashes/129372.rs52
-rw-r--r--tests/ui-fulldeps/internal-lints/query_completeness.rs16
-rw-r--r--tests/ui-fulldeps/internal-lints/query_completeness.stderr15
-rw-r--r--tests/ui/asm/const-refs-to-static.rs21
-rw-r--r--tests/ui/asm/const-refs-to-static.stderr22
-rw-r--r--tests/ui/associated-types/associated-types-coherence-failure.stderr8
-rw-r--r--tests/ui/async-await/async-closures/tainted-body-2.rs18
-rw-r--r--tests/ui/async-await/async-closures/tainted-body-2.stderr9
-rw-r--r--tests/ui/async-await/async-closures/validate-synthetic-body.rs19
-rw-r--r--tests/ui/auto-traits/opaque_type_candidate_selection.rs30
-rw-r--r--tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr2
-rw-r--r--tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr2
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr23
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream-inherent.rs3
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream-inherent.stderr (renamed from tests/ui/coherence/coherence-overlap-downstream-inherent.next.stderr)4
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream.next.stderr21
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream.rs3
-rw-r--r--tests/ui/coherence/coherence-overlap-downstream.stderr (renamed from tests/ui/coherence/coherence-overlap-downstream.old.stderr)4
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr14
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs3
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr (renamed from tests/ui/coherence/coherence-overlap-issue-23516-inherent.next.stderr)2
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516.old.stderr13
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516.rs3
-rw-r--r--tests/ui/coherence/coherence-overlap-issue-23516.stderr (renamed from tests/ui/coherence/coherence-overlap-issue-23516.next.stderr)2
-rw-r--r--tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr2
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr19
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs3
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.stderr (renamed from tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr)2
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr19
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs3
-rw-r--r--tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr (renamed from tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr)2
-rw-r--r--tests/ui/coherence/coherent-due-to-fulfill.rs2
-rw-r--r--tests/ui/coherence/incoherent-even-though-we-fulfill.rs2
-rw-r--r--tests/ui/coherence/incoherent-even-though-we-fulfill.stderr2
-rw-r--r--tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr17
-rw-r--r--tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs3
-rw-r--r--tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr (renamed from tests/ui/coherence/inter-crate-ambiguity-causes-notes.next.stderr)2
-rw-r--r--tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr2
-rw-r--r--tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr2
-rw-r--r--tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr1
-rw-r--r--tests/ui/coherence/normalize-for-errors.current.stderr14
-rw-r--r--tests/ui/coherence/normalize-for-errors.rs6
-rw-r--r--tests/ui/coherence/normalize-for-errors.stderr (renamed from tests/ui/coherence/normalize-for-errors.next.stderr)2
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.next.stderr4
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.old.stderr10
-rw-r--r--tests/ui/coherence/occurs-check/associated-type.rs1
-rw-r--r--tests/ui/coherence/occurs-check/opaques.current.stderr12
-rw-r--r--tests/ui/coherence/occurs-check/opaques.next.stderr4
-rw-r--r--tests/ui/coherence/occurs-check/opaques.rs8
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr21
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.rs3
-rw-r--r--tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr (renamed from tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr)4
-rw-r--r--tests/ui/coherence/orphan-check-projections-covering.rs3
-rw-r--r--tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr12
-rw-r--r--tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs3
-rw-r--r--tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr (renamed from tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr)2
-rw-r--r--tests/ui/coherence/skip-reporting-if-references-err.current.stderr27
-rw-r--r--tests/ui/coherence/skip-reporting-if-references-err.rs6
-rw-r--r--tests/ui/coherence/skip-reporting-if-references-err.stderr (renamed from tests/ui/coherence/skip-reporting-if-references-err.next.stderr)2
-rw-r--r--tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr13
-rw-r--r--tests/ui/coherence/super-traits/super-trait-knowable-1.rs6
-rw-r--r--tests/ui/coherence/super-traits/super-trait-knowable-2.rs3
-rw-r--r--tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr13
-rw-r--r--tests/ui/coherence/super-traits/super-trait-knowable-3.rs6
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr23
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs1
-rw-r--r--tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr14
-rw-r--r--tests/ui/const-generics/invariant.rs2
-rw-r--r--tests/ui/consts/const-float-bits-conv.rs5
-rw-r--r--tests/ui/consts/const-float-classify.rs1
-rw-r--r--tests/ui/consts/const-float-classify.stderr2
-rw-r--r--tests/ui/consts/missing_assoc_const_type.rs2
-rw-r--r--tests/ui/consts/missing_assoc_const_type.stderr8
-rw-r--r--tests/ui/delegation/generics/impl-to-free-fn-pass.rs29
-rw-r--r--tests/ui/delegation/generics/impl-to-trait-method.rs44
-rw-r--r--tests/ui/delegation/generics/impl-to-trait-method.stderr49
-rw-r--r--tests/ui/delegation/generics/impl-trait-to-trait-method-pass.rs77
-rw-r--r--tests/ui/delegation/generics/inherent-impl-to-trait-method-pass.rs23
-rw-r--r--tests/ui/delegation/generics/trait-method-to-other-pass.rs30
-rw-r--r--tests/ui/delegation/ice-issue-124347.rs4
-rw-r--r--tests/ui/delegation/ice-issue-124347.stderr14
-rw-r--r--tests/ui/delegation/not-supported.rs116
-rw-r--r--tests/ui/delegation/not-supported.stderr204
-rw-r--r--tests/ui/delegation/unsupported.rs57
-rw-r--r--tests/ui/delegation/unsupported.stderr95
-rw-r--r--tests/ui/error-codes/e0119/issue-23563.stderr2
-rw-r--r--tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr2
-rw-r--r--tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs6
-rw-r--r--tests/ui/higher-ranked/structually-relate-aliases.rs3
-rw-r--r--tests/ui/higher-ranked/structually-relate-aliases.stderr33
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.old.stderr4
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.rs6
-rw-r--r--tests/ui/impl-trait/auto-trait-coherence.stderr12
-rw-r--r--tests/ui/impl-trait/coherence-treats-tait-ambig.rs2
-rw-r--r--tests/ui/impl-trait/coherence-treats-tait-ambig.stderr2
-rw-r--r--tests/ui/impl-trait/negative-reasoning.rs2
-rw-r--r--tests/ui/impl-trait/negative-reasoning.stderr6
-rw-r--r--tests/ui/impl-unused-tps.rs46
-rw-r--r--tests/ui/impl-unused-tps.stderr84
-rw-r--r--tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-2.rs13
-rw-r--r--tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.rs13
-rw-r--r--tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.stderr10
-rw-r--r--tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.rs19
-rw-r--r--tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.stderr14
-rw-r--r--tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs7
-rw-r--r--tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.stderr10
-rw-r--r--tests/ui/issues/issue-48728.rs8
-rw-r--r--tests/ui/lexer/prefixed-lifetime.rs10
-rw-r--r--tests/ui/lexer/prefixed-lifetime.stderr14
-rw-r--r--tests/ui/lifetimes/raw/gen-lt.e2024.stderr8
-rw-r--r--tests/ui/lifetimes/raw/gen-lt.rs14
-rw-r--r--tests/ui/lifetimes/raw/lifetimes-eq.rs8
-rw-r--r--tests/ui/lifetimes/raw/macro-lt.rs12
-rw-r--r--tests/ui/lifetimes/raw/multiple-prefixes.rs6
-rw-r--r--tests/ui/lifetimes/raw/multiple-prefixes.stderr8
-rw-r--r--tests/ui/lifetimes/raw/prim-lt.rs8
-rw-r--r--tests/ui/lifetimes/raw/simple.rs21
-rw-r--r--tests/ui/lifetimes/raw/static-lt.rs8
-rw-r--r--tests/ui/lifetimes/raw/three-tokens.rs12
-rw-r--r--tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr4
-rw-r--r--tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr8
-rw-r--r--tests/ui/lint/elided-named-lifetimes/static.stderr19
-rw-r--r--tests/ui/parser/extern-crate-unexpected-token.stderr5
-rw-r--r--tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr33
-rw-r--r--tests/ui/parser/misspelled-keywords/assoc-type.rs6
-rw-r--r--tests/ui/parser/misspelled-keywords/assoc-type.stderr18
-rw-r--r--tests/ui/parser/misspelled-keywords/async-move.rs6
-rw-r--r--tests/ui/parser/misspelled-keywords/async-move.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/const-fn.rs5
-rw-r--r--tests/ui/parser/misspelled-keywords/const-fn.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/const-generics.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/const-generics.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/const.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/const.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/for-loop.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/for-loop.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/hrdt.rs16
-rw-r--r--tests/ui/parser/misspelled-keywords/hrdt.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-block.rs6
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-block.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-return.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-return.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-trait-for.rs6
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-trait-for.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-trait.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/impl-trait.stderr17
-rw-r--r--tests/ui/parser/misspelled-keywords/let-else.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/let-else.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/let-mut.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/let-mut.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/let.rs9
-rw-r--r--tests/ui/parser/misspelled-keywords/let.stderr24
-rw-r--r--tests/ui/parser/misspelled-keywords/match.rs5
-rw-r--r--tests/ui/parser/misspelled-keywords/match.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/mod.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/mod.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/pub-fn.rs5
-rw-r--r--tests/ui/parser/misspelled-keywords/pub-fn.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/ref.rs9
-rw-r--r--tests/ui/parser/misspelled-keywords/ref.stderr27
-rw-r--r--tests/ui/parser/misspelled-keywords/return.rs7
-rw-r--r--tests/ui/parser/misspelled-keywords/return.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/static-mut.rs5
-rw-r--r--tests/ui/parser/misspelled-keywords/static-mut.stderr24
-rw-r--r--tests/ui/parser/misspelled-keywords/static.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/static.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/struct.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/struct.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/unsafe-fn.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/unsafe-fn.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/use.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/use.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/where-clause.rs8
-rw-r--r--tests/ui/parser/misspelled-keywords/where-clause.stderr15
-rw-r--r--tests/ui/parser/misspelled-keywords/while-loop.rs5
-rw-r--r--tests/ui/parser/misspelled-keywords/while-loop.stderr13
-rw-r--r--tests/ui/parser/misspelled-keywords/while-without-identifiers.rs4
-rw-r--r--tests/ui/parser/misspelled-keywords/while-without-identifiers.stderr8
-rw-r--r--tests/ui/rust-2024/gen-kw.e2015.stderr11
-rw-r--r--tests/ui/rust-2024/gen-kw.e2018.stderr11
-rw-r--r--tests/ui/rust-2024/gen-kw.rs5
-rw-r--r--tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs (renamed from tests/crashes/118987-2.rs)4
-rw-r--r--tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr21
-rw-r--r--tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs (renamed from tests/crashes/74299.rs)5
-rw-r--r--tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr21
-rw-r--r--tests/ui/specialization/defaultimpl/specialization-no-default.rs3
-rw-r--r--tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr12
-rw-r--r--tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr2
-rw-r--r--tests/ui/specialization/specialization-default-items-drop-coherence.rs8
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.current.stderr22
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.next.stderr6
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.rs13
-rw-r--r--tests/ui/specialization/specialization-overlap-projection.stderr30
-rw-r--r--tests/ui/static/missing-type.rs (renamed from tests/crashes/124164.rs)3
-rw-r--r--tests/ui/static/missing-type.stderr8
-rw-r--r--tests/ui/traits/alias/issue-83613.rs2
-rw-r--r--tests/ui/traits/alias/issue-83613.stderr4
-rw-r--r--tests/ui/traits/issue-105231.rs3
-rw-r--r--tests/ui/traits/issue-105231.stderr22
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs2
-rw-r--r--tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr26
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.rs (renamed from tests/crashes/124207.rs)4
-rw-r--r--tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr27
-rw-r--r--tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-104817.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/issue-104817.stock.stderr4
-rw-r--r--tests/ui/type-alias-impl-trait/taint.rs (renamed from tests/crashes/126896.rs)8
-rw-r--r--tests/ui/type-alias-impl-trait/taint.stderr12
-rw-r--r--triagebot.toml1
399 files changed, 4389 insertions, 2204 deletions
diff --git a/.gitmodules b/.gitmodules
index b5250d49386..926807336d7 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -47,3 +47,7 @@
 	path = src/tools/rustc-perf
 	url = https://github.com/rust-lang/rustc-perf.git
 	shallow = true
+[submodule "src/tools/enzyme"]
+	path = src/tools/enzyme
+	url = https://github.com/EnzymeAD/Enzyme.git
+	shallow = true
diff --git a/RELEASES.md b/RELEASES.md
index 29c872eb448..b49470c3075 100644
--- a/RELEASES.md
+++ b/RELEASES.md
@@ -34,7 +34,6 @@ Compiler
   - [Add Tier 3 `std` Xtensa targets:](https://github.com/rust-lang/rust/pull/126380/) `xtensa-esp32-espidf`, `xtensa-esp32s2-espidf`, `xtensa-esp32s3-espidf`
   - [Add Tier 3 i686 Redox OS target:](https://github.com/rust-lang/rust/pull/126192/) `i686-unknown-redox`
   - [Promote `arm64ec-pc-windows-msvc` to Tier 2.](https://github.com/rust-lang/rust/pull/126039/)
-  - [Promote `wasm32-wasip2` to Tier 2.](https://github.com/rust-lang/rust/pull/126967/)
   - [Promote `loongarch64-unknown-linux-musl` to Tier 2 with host tools.](https://github.com/rust-lang/rust/pull/126298/)
   - [Enable full tools and profiler for LoongArch Linux targets.](https://github.com/rust-lang/rust/pull/127078/)
   - [Unconditionally warn on usage of `wasm32-wasi`.](https://github.com/rust-lang/rust/pull/126662/) (see compatibility note below)
@@ -100,6 +99,9 @@ Compatibility Notes
   The reason is that these types have different roles: `std::panic::PanicHookInfo` is the argument to the [panic hook](https://doc.rust-lang.org/stable/std/panic/fn.set_hook.html) in std context (where panics can have an arbitrary payload), while `core::panic::PanicInfo` is the argument to the [`#[panic_handler]`](https://doc.rust-lang.org/nomicon/panic-handler.html) in no_std context (where panics always carry a formatted *message*). Separating these types allows us to add more useful methods to these types, such as `std::panic::PanicHookInfo::payload_as_str()` and `core::panic::PanicInfo::message()`.
 
 * The new sort implementations may panic if a type's implementation of [`Ord`](https://doc.rust-lang.org/std/cmp/trait.Ord.html) (or the given comparison function) does not implement a [total order](https://en.wikipedia.org/wiki/Total_order) as the trait requires. `Ord`'s supertraits (`PartialOrd`, `Eq`, and `PartialEq`) must also be consistent. The previous implementations would not "notice" any problem, but the new implementations have a good chance of detecting inconsistencies, throwing a panic rather than returning knowingly unsorted data.
+* [In very rare cases, a change in the internal evaluation order of the trait
+  solver may result in new fatal overflow errors.](https://github.com/rust-lang/rust/pull/126128)
+
 
 <a id="1.81.0-Internal-Changes"></a>
 
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index 8a66894a356..7c8af6c4a55 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -752,7 +752,7 @@ fn visit_lazy_tts<T: MutVisitor>(vis: &mut T, lazy_tts: &mut Option<LazyAttrToke
 pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) {
     let Token { kind, span } = t;
     match kind {
-        token::Ident(name, _ /*raw*/) | token::Lifetime(name) => {
+        token::Ident(name, _is_raw) | token::Lifetime(name, _is_raw) => {
             let mut ident = Ident::new(*name, *span);
             vis.visit_ident(&mut ident);
             *name = ident.name;
@@ -762,7 +762,7 @@ pub fn visit_token<T: MutVisitor>(vis: &mut T, t: &mut Token) {
         token::NtIdent(ident, _is_raw) => {
             vis.visit_ident(ident);
         }
-        token::NtLifetime(ident) => {
+        token::NtLifetime(ident, _is_raw) => {
             vis.visit_ident(ident);
         }
         token::Interpolated(nt) => {
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index f1dddb3acac..a0082a41713 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -331,11 +331,11 @@ pub enum TokenKind {
     /// Do not forget about `NtLifetime` when you want to match on lifetime identifiers.
     /// It's recommended to use `Token::(lifetime,uninterpolate,uninterpolated_span)` to
     /// treat regular and interpolated lifetime identifiers in the same way.
-    Lifetime(Symbol),
+    Lifetime(Symbol, IdentIsRaw),
     /// This identifier (and its span) is the lifetime passed to the
     /// declarative macro. The span in the surrounding `Token` is the span of
     /// the `lifetime` metavariable in the macro's RHS.
-    NtLifetime(Ident),
+    NtLifetime(Ident, IdentIsRaw),
 
     /// An embedded AST node, as produced by a macro. This only exists for
     /// historical reasons. We'd like to get rid of it, for multiple reasons.
@@ -458,7 +458,7 @@ impl Token {
     /// if they keep spans or perform edition checks.
     pub fn uninterpolated_span(&self) -> Span {
         match self.kind {
-            NtIdent(ident, _) | NtLifetime(ident) => ident.span,
+            NtIdent(ident, _) | NtLifetime(ident, _) => ident.span,
             Interpolated(ref nt) => nt.use_span(),
             _ => self.span,
         }
@@ -661,7 +661,9 @@ impl Token {
     pub fn uninterpolate(&self) -> Cow<'_, Token> {
         match self.kind {
             NtIdent(ident, is_raw) => Cow::Owned(Token::new(Ident(ident.name, is_raw), ident.span)),
-            NtLifetime(ident) => Cow::Owned(Token::new(Lifetime(ident.name), ident.span)),
+            NtLifetime(ident, is_raw) => {
+                Cow::Owned(Token::new(Lifetime(ident.name, is_raw), ident.span))
+            }
             _ => Cow::Borrowed(self),
         }
     }
@@ -679,11 +681,11 @@ impl Token {
 
     /// Returns a lifetime identifier if this token is a lifetime.
     #[inline]
-    pub fn lifetime(&self) -> Option<Ident> {
+    pub fn lifetime(&self) -> Option<(Ident, IdentIsRaw)> {
         // We avoid using `Token::uninterpolate` here because it's slow.
         match self.kind {
-            Lifetime(name) => Some(Ident::new(name, self.span)),
-            NtLifetime(ident) => Some(ident),
+            Lifetime(name, is_raw) => Some((Ident::new(name, self.span), is_raw)),
+            NtLifetime(ident, is_raw) => Some((ident, is_raw)),
             _ => None,
         }
     }
@@ -865,7 +867,7 @@ impl Token {
                 _ => return None,
             },
             SingleQuote => match joint.kind {
-                Ident(name, IdentIsRaw::No) => Lifetime(Symbol::intern(&format!("'{name}"))),
+                Ident(name, is_raw) => Lifetime(Symbol::intern(&format!("'{name}")), is_raw),
                 _ => return None,
             },
 
diff --git a/compiler/rustc_ast/src/tokenstream.rs b/compiler/rustc_ast/src/tokenstream.rs
index 057b4455dca..fc1dd2caf68 100644
--- a/compiler/rustc_ast/src/tokenstream.rs
+++ b/compiler/rustc_ast/src/tokenstream.rs
@@ -482,11 +482,11 @@ impl TokenStream {
             token::NtIdent(ident, is_raw) => {
                 TokenTree::Token(Token::new(token::Ident(ident.name, is_raw), ident.span), spacing)
             }
-            token::NtLifetime(ident) => TokenTree::Delimited(
+            token::NtLifetime(ident, is_raw) => TokenTree::Delimited(
                 DelimSpan::from_single(token.span),
                 DelimSpacing::new(Spacing::JointHidden, spacing),
                 Delimiter::Invisible,
-                TokenStream::token_alone(token::Lifetime(ident.name), ident.span),
+                TokenStream::token_alone(token::Lifetime(ident.name, is_raw), ident.span),
             ),
             token::Interpolated(ref nt) => TokenTree::Delimited(
                 DelimSpan::from_single(token.span),
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index c7ff39d23ed..3b1449d9a91 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -11,7 +11,9 @@ use std::borrow::Cow;
 use ast::TraitBoundModifiers;
 use rustc_ast::attr::AttrIdGenerator;
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, BinOpToken, CommentKind, Delimiter, Nonterminal, Token, TokenKind};
+use rustc_ast::token::{
+    self, BinOpToken, CommentKind, Delimiter, IdentIsRaw, Nonterminal, Token, TokenKind,
+};
 use rustc_ast::tokenstream::{Spacing, TokenStream, TokenTree};
 use rustc_ast::util::classify;
 use rustc_ast::util::comments::{Comment, CommentStyle};
@@ -947,8 +949,13 @@ pub trait PrintState<'a>: std::ops::Deref<Target = pp::Printer> + std::ops::Dere
             token::NtIdent(ident, is_raw) => {
                 IdentPrinter::for_ast_ident(ident, is_raw.into()).to_string().into()
             }
-            token::Lifetime(name) => name.to_string().into(),
-            token::NtLifetime(ident) => ident.name.to_string().into(),
+
+            token::Lifetime(name, IdentIsRaw::No)
+            | token::NtLifetime(Ident { name, .. }, IdentIsRaw::No) => name.to_string().into(),
+            token::Lifetime(name, IdentIsRaw::Yes)
+            | token::NtLifetime(Ident { name, .. }, IdentIsRaw::Yes) => {
+                format!("'r#{}", &name.as_str()[1..]).into()
+            }
 
             /* Other */
             token::DocComment(comment_kind, attr_style, data) => {
diff --git a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
index 91b02a36d00..c720b0928fe 100644
--- a/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/explain_borrow.rs
@@ -662,9 +662,10 @@ impl<'tcx> MirBorrowckCtxt<'_, '_, '_, 'tcx> {
                                                 // `&dyn Trait`
                                                 ty::Ref(_, ty, _) if ty.is_trait() => true,
                                                 // `Box<dyn Trait>`
-                                                _ if ty.is_box() && ty.boxed_ty().is_trait() => {
+                                                _ if ty.boxed_ty().is_some_and(Ty::is_trait) => {
                                                     true
                                                 }
+
                                                 // `dyn Trait`
                                                 _ if ty.is_trait() => true,
                                                 // Anything else.
diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs
index 5ab66963409..878ce6162e0 100644
--- a/compiler/rustc_borrowck/src/diagnostics/mod.rs
+++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs
@@ -345,9 +345,9 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
         variant_index: Option<VariantIdx>,
         including_tuple_field: IncludingTupleField,
     ) -> Option<String> {
-        if ty.is_box() {
+        if let Some(boxed_ty) = ty.boxed_ty() {
             // If the type is a box, the field is described from the boxed type
-            self.describe_field_from_ty(ty.boxed_ty(), field, variant_index, including_tuple_field)
+            self.describe_field_from_ty(boxed_ty, field, variant_index, including_tuple_field)
         } else {
             match *ty.kind() {
                 ty::Adt(def, _) => {
diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index ffb350b1d1f..d40dcfa5805 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -2522,7 +2522,7 @@ mod diags {
         }
 
         pub(crate) fn emit_errors(&mut self) -> Option<ErrorGuaranteed> {
-            let mut res = None;
+            let mut res = self.infcx.tainted_by_errors();
 
             // Buffer any move errors that we collected and de-duplicated.
             for (_, (_, diag)) in std::mem::take(&mut self.diags.buffered_move_errors) {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 224f8d5c893..3c9a43883ad 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1979,19 +1979,76 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
 
                 match cast_kind {
                     CastKind::PointerCoercion(PointerCoercion::ReifyFnPointer) => {
-                        let fn_sig = op.ty(body, tcx).fn_sig(tcx);
+                        let src_sig = op.ty(body, tcx).fn_sig(tcx);
+
+                        // HACK: This shouldn't be necessary... We can remove this when we actually
+                        // get binders with where clauses, then elaborate implied bounds into that
+                        // binder, and implement a higher-ranked subtyping algorithm that actually
+                        // respects these implied bounds.
+                        //
+                        // This protects against the case where we are casting from a higher-ranked
+                        // fn item to a non-higher-ranked fn pointer, where the cast throws away
+                        // implied bounds that would've needed to be checked at the call site. This
+                        // only works when we're casting to a non-higher-ranked fn ptr, since
+                        // placeholders in the target signature could have untracked implied
+                        // bounds, resulting in incorrect errors.
+                        //
+                        // We check that this signature is WF before subtyping the signature with
+                        // the target fn sig.
+                        if src_sig.has_bound_regions()
+                            && let ty::FnPtr(target_fn_tys, target_hdr) = *ty.kind()
+                            && let target_sig = target_fn_tys.with(target_hdr)
+                            && let Some(target_sig) = target_sig.no_bound_vars()
+                        {
+                            let src_sig = self.infcx.instantiate_binder_with_fresh_vars(
+                                span,
+                                BoundRegionConversionTime::HigherRankedType,
+                                src_sig,
+                            );
+                            let src_ty = Ty::new_fn_ptr(self.tcx(), ty::Binder::dummy(src_sig));
+                            self.prove_predicate(
+                                ty::ClauseKind::WellFormed(src_ty.into()),
+                                location.to_locations(),
+                                ConstraintCategory::Cast { unsize_to: None },
+                            );
+
+                            let src_ty = self.normalize(src_ty, location);
+                            if let Err(terr) = self.sub_types(
+                                src_ty,
+                                *ty,
+                                location.to_locations(),
+                                ConstraintCategory::Cast { unsize_to: None },
+                            ) {
+                                span_mirbug!(
+                                    self,
+                                    rvalue,
+                                    "equating {:?} with {:?} yields {:?}",
+                                    target_sig,
+                                    src_sig,
+                                    terr
+                                );
+                            };
+                        }
+
+                        let src_ty = Ty::new_fn_ptr(tcx, src_sig);
+                        // HACK: We want to assert that the signature of the source fn is
+                        // well-formed, because we don't enforce that via the WF of FnDef
+                        // types normally. This should be removed when we improve the tracking
+                        // of implied bounds of fn signatures.
+                        self.prove_predicate(
+                            ty::ClauseKind::WellFormed(src_ty.into()),
+                            location.to_locations(),
+                            ConstraintCategory::Cast { unsize_to: None },
+                        );
 
                         // The type that we see in the fcx is like
                         // `foo::<'a, 'b>`, where `foo` is the path to a
                         // function definition. When we extract the
                         // signature, it comes from the `fn_sig` query,
                         // and hence may contain unnormalized results.
-                        let fn_sig = self.normalize(fn_sig, location);
-
-                        let ty_fn_ptr_from = Ty::new_fn_ptr(tcx, fn_sig);
-
+                        let src_ty = self.normalize(src_ty, location);
                         if let Err(terr) = self.sub_types(
-                            ty_fn_ptr_from,
+                            src_ty,
                             *ty,
                             location.to_locations(),
                             ConstraintCategory::Cast { unsize_to: None },
@@ -2000,7 +2057,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                                 self,
                                 rvalue,
                                 "equating {:?} with {:?} yields {:?}",
-                                ty_fn_ptr_from,
+                                src_ty,
                                 ty,
                                 terr
                             );
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index 9eabe817359..164be73f492 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -29,7 +29,8 @@ use rustc_macros::extension;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{
-    self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty, TyCtxt,
+    self, GenericArgs, GenericArgsRef, InlineConstArgs, InlineConstArgsParts, RegionVid, Ty,
+    TyCtxt, TypeVisitableExt,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_span::symbol::{kw, sym};
@@ -688,7 +689,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
         defining_ty: DefiningTy<'tcx>,
     ) -> ty::Binder<'tcx, &'tcx ty::List<Ty<'tcx>>> {
         let tcx = self.infcx.tcx;
-        match defining_ty {
+
+        let inputs_and_output = match defining_ty {
             DefiningTy::Closure(def_id, args) => {
                 assert_eq!(self.mir_def.to_def_id(), def_id);
                 let closure_sig = args.as_closure().sig();
@@ -798,6 +800,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 // "output" (the type of the constant).
                 assert_eq!(self.mir_def.to_def_id(), def_id);
                 let ty = tcx.type_of(self.mir_def).instantiate_identity();
+
                 let ty = indices.fold_to_region_vids(tcx, ty);
                 ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
@@ -807,7 +810,14 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
                 let ty = args.as_inline_const().ty();
                 ty::Binder::dummy(tcx.mk_type_list(&[ty]))
             }
+        };
+
+        // FIXME(#129952): We probably want a more principled approach here.
+        if let Err(terr) = inputs_and_output.skip_binder().error_reported() {
+            self.infcx.set_tainted_by_errors(terr);
         }
+
+        inputs_and_output
     }
 }
 
diff --git a/compiler/rustc_codegen_llvm/src/attributes.rs b/compiler/rustc_codegen_llvm/src/attributes.rs
index 92a857c2adc..9d4497d73a8 100644
--- a/compiler/rustc_codegen_llvm/src/attributes.rs
+++ b/compiler/rustc_codegen_llvm/src/attributes.rs
@@ -411,26 +411,31 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
             // the string "false". Now it is disabled by absence of the attribute.
             to_add.push(llvm::CreateAttrStringValue(cx.llcx, "branch-target-enforcement", "false"));
         }
-    } else if llvm_util::get_version() >= (19, 0, 0) {
-        // For non-naked functions, set branch protection attributes on aarch64.
-        if let Some(BranchProtection { bti, pac_ret }) =
-            cx.sess().opts.unstable_opts.branch_protection
-        {
-            assert!(cx.sess().target.arch == "aarch64");
-            if bti {
-                to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
-            }
-            if let Some(PacRet { leaf, key }) = pac_ret {
-                to_add.push(llvm::CreateAttrStringValue(
-                    cx.llcx,
-                    "sign-return-address",
-                    if leaf { "all" } else { "non-leaf" },
-                ));
-                to_add.push(llvm::CreateAttrStringValue(
-                    cx.llcx,
-                    "sign-return-address-key",
-                    if key == PAuthKey::A { "a_key" } else { "b_key" },
-                ));
+    } else {
+        // Do not set sanitizer attributes for naked functions.
+        to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
+
+        if llvm_util::get_version() >= (19, 0, 0) {
+            // For non-naked functions, set branch protection attributes on aarch64.
+            if let Some(BranchProtection { bti, pac_ret }) =
+                cx.sess().opts.unstable_opts.branch_protection
+            {
+                assert!(cx.sess().target.arch == "aarch64");
+                if bti {
+                    to_add.push(llvm::CreateAttrString(cx.llcx, "branch-target-enforcement"));
+                }
+                if let Some(PacRet { leaf, key }) = pac_ret {
+                    to_add.push(llvm::CreateAttrStringValue(
+                        cx.llcx,
+                        "sign-return-address",
+                        if leaf { "all" } else { "non-leaf" },
+                    ));
+                    to_add.push(llvm::CreateAttrStringValue(
+                        cx.llcx,
+                        "sign-return-address-key",
+                        if key == PAuthKey::A { "a_key" } else { "b_key" },
+                    ));
+                }
             }
         }
     }
@@ -485,7 +490,6 @@ pub(crate) fn llfn_attrs_from_instance<'ll, 'tcx>(
     if let Some(backchain) = backchain_attr(cx) {
         to_add.push(backchain);
     }
-    to_add.extend(sanitize_attrs(cx, codegen_fn_attrs.no_sanitize));
     to_add.extend(patchable_function_entry_attrs(cx, codegen_fn_attrs.patchable_function_entry));
 
     // Always annotate functions with the target-cpu they are compiled for.
diff --git a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
index 17a9630c655..d231b103964 100644
--- a/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
+++ b/compiler/rustc_codegen_llvm/src/debuginfo/metadata.rs
@@ -456,7 +456,7 @@ pub(crate) fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) ->
             if def.is_box()
                 && args.get(1).map_or(true, |arg| cx.layout_of(arg.expect_ty()).is_1zst()) =>
         {
-            build_pointer_or_reference_di_node(cx, t, t.boxed_ty(), unique_type_id)
+            build_pointer_or_reference_di_node(cx, t, t.expect_boxed_ty(), unique_type_id)
         }
         ty::FnDef(..) | ty::FnPtr(..) => build_subroutine_type_di_node(cx, unique_type_id),
         ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
diff --git a/compiler/rustc_codegen_llvm/src/intrinsic.rs b/compiler/rustc_codegen_llvm/src/intrinsic.rs
index a300f5f707a..05fb77a193a 100644
--- a/compiler/rustc_codegen_llvm/src/intrinsic.rs
+++ b/compiler/rustc_codegen_llvm/src/intrinsic.rs
@@ -187,9 +187,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     Some(instance),
                 )
             }
-            sym::likely => {
-                self.call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(true)])
-            }
+            sym::likely => self.expect(args[0].immediate(), true),
             sym::is_val_statically_known => {
                 let intrinsic_type = args[0].layout.immediate_llvm_type(self.cx);
                 let kind = self.type_kind(intrinsic_type);
@@ -210,8 +208,7 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
                     self.const_bool(false)
                 }
             }
-            sym::unlikely => self
-                .call_intrinsic("llvm.expect.i1", &[args[0].immediate(), self.const_bool(false)]),
+            sym::unlikely => self.expect(args[0].immediate(), false),
             sym::select_unpredictable => {
                 let cond = args[0].immediate();
                 assert_eq!(args[1].layout, args[2].layout);
@@ -604,11 +601,17 @@ impl<'ll, 'tcx> IntrinsicCallMethods<'tcx> for Builder<'_, 'll, 'tcx> {
     }
 
     fn assume(&mut self, val: Self::Value) {
-        self.call_intrinsic("llvm.assume", &[val]);
+        if self.cx.sess().opts.optimize != rustc_session::config::OptLevel::No {
+            self.call_intrinsic("llvm.assume", &[val]);
+        }
     }
 
     fn expect(&mut self, cond: Self::Value, expected: bool) -> Self::Value {
-        self.call_intrinsic("llvm.expect.i1", &[cond, self.const_bool(expected)])
+        if self.cx.sess().opts.optimize != rustc_session::config::OptLevel::No {
+            self.call_intrinsic("llvm.expect.i1", &[cond, self.const_bool(expected)])
+        } else {
+            cond
+        }
     }
 
     fn type_test(&mut self, pointer: Self::Value, typeid: Self::Value) -> Self::Value {
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index 618602ed70f..d55220ba5c3 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -353,9 +353,7 @@ pub fn target_features(sess: &Session, allow_unstable: bool) -> Vec<Symbol> {
                 None
             }
         })
-        .filter(|feature| {
-            RUSTC_SPECIAL_FEATURES.contains(feature) || features.contains(&Symbol::intern(feature))
-        })
+        .filter(|feature| features.contains(&Symbol::intern(feature)))
         .map(|feature| Symbol::intern(feature))
         .collect()
 }
diff --git a/compiler/rustc_codegen_ssa/src/back/metadata.rs b/compiler/rustc_codegen_ssa/src/back/metadata.rs
index 9b5a797ad51..0fd9d7fffe8 100644
--- a/compiler/rustc_codegen_ssa/src/back/metadata.rs
+++ b/compiler/rustc_codegen_ssa/src/back/metadata.rs
@@ -372,27 +372,42 @@ pub(crate) fn create_object_file(sess: &Session) -> Option<write::Object<'static
     Some(file)
 }
 
-/// Since Xcode 15 Apple's LD requires object files to contain information about what they were
-/// built for (LC_BUILD_VERSION): the platform (macOS/watchOS etc), minimum OS version, and SDK
-/// version. This returns a `MachOBuildVersion` for the target.
+/// Mach-O files contain information about:
+/// - The platform/OS they were built for (macOS/watchOS/Mac Catalyst/iOS simulator etc).
+/// - The minimum OS version / deployment target.
+/// - The version of the SDK they were targetting.
+///
+/// In the past, this was accomplished using the LC_VERSION_MIN_MACOSX, LC_VERSION_MIN_IPHONEOS,
+/// LC_VERSION_MIN_TVOS or LC_VERSION_MIN_WATCHOS load commands, which each contain information
+/// about the deployment target and SDK version, and implicitly, by their presence, which OS they
+/// target. Simulator targets were determined if the architecture was x86_64, but there was e.g. a
+/// LC_VERSION_MIN_IPHONEOS present.
+///
+/// This is of course brittle and limited, so modern tooling emit the LC_BUILD_VERSION load
+/// command (which contains all three pieces of information in one) when the deployment target is
+/// high enough, or the target is something that wouldn't be encodable with the old load commands
+/// (such as Mac Catalyst, or Aarch64 iOS simulator).
+///
+/// Since Xcode 15, Apple's LD apparently requires object files to use this load command, so this
+/// returns the `MachOBuildVersion` for the target to do so.
 fn macho_object_build_version_for_target(target: &Target) -> object::write::MachOBuildVersion {
     /// The `object` crate demands "X.Y.Z encoded in nibbles as xxxx.yy.zz"
     /// e.g. minOS 14.0 = 0x000E0000, or SDK 16.2 = 0x00100200
-    fn pack_version((major, minor): (u32, u32)) -> u32 {
-        (major << 16) | (minor << 8)
+    fn pack_version((major, minor, patch): (u16, u8, u8)) -> u32 {
+        let (major, minor, patch) = (major as u32, minor as u32, patch as u32);
+        (major << 16) | (minor << 8) | patch
     }
 
     let platform =
         rustc_target::spec::current_apple_platform(target).expect("unknown Apple target OS");
-    let min_os = rustc_target::spec::current_apple_deployment_target(target)
-        .expect("unknown Apple target OS");
-    let sdk =
+    let min_os = rustc_target::spec::current_apple_deployment_target(target);
+    let (sdk_major, sdk_minor) =
         rustc_target::spec::current_apple_sdk_version(platform).expect("unknown Apple target OS");
 
     let mut build_version = object::write::MachOBuildVersion::default();
     build_version.platform = platform;
     build_version.minos = pack_version(min_os);
-    build_version.sdk = pack_version(sdk);
+    build_version.sdk = pack_version((sdk_major, sdk_minor, 0));
     build_version
 }
 
diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index d94c6f8ddce..91fd9905f63 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -382,7 +382,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
         scalar: abi::Scalar,
         backend_ty: Bx::Type,
     ) {
-        if matches!(self.cx.sess().opts.optimize, OptLevel::No | OptLevel::Less)
+        if matches!(self.cx.sess().opts.optimize, OptLevel::No)
             // For now, the critical niches are all over `Int`eger values.
             // Should floating-point values or pointers ever get more complex
             // niches, then this code will probably want to handle them too.
diff --git a/compiler/rustc_codegen_ssa/src/mir/statement.rs b/compiler/rustc_codegen_ssa/src/mir/statement.rs
index 2ef860fc336..73283cafb49 100644
--- a/compiler/rustc_codegen_ssa/src/mir/statement.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/statement.rs
@@ -1,6 +1,5 @@
 use rustc_middle::mir::{self, NonDivergingIntrinsic};
 use rustc_middle::span_bug;
-use rustc_session::config::OptLevel;
 use tracing::instrument;
 
 use super::{FunctionCx, LocalRef};
@@ -68,10 +67,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 self.codegen_coverage(bx, kind, statement.source_info.scope);
             }
             mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::Assume(ref op)) => {
-                if !matches!(bx.tcx().sess.opts.optimize, OptLevel::No | OptLevel::Less) {
-                    let op_val = self.codegen_operand(bx, op);
-                    bx.assume(op_val.immediate());
-                }
+                let op_val = self.codegen_operand(bx, op);
+                bx.assume(op_val.immediate());
             }
             mir::StatementKind::Intrinsic(box NonDivergingIntrinsic::CopyNonOverlapping(
                 mir::CopyNonOverlapping { ref count, ref src, ref dst },
diff --git a/compiler/rustc_const_eval/src/interpret/call.rs b/compiler/rustc_const_eval/src/interpret/call.rs
index 82438eb5e78..568a9a3a637 100644
--- a/compiler/rustc_const_eval/src/interpret/call.rs
+++ b/compiler/rustc_const_eval/src/interpret/call.rs
@@ -189,7 +189,7 @@ impl<'tcx, M: Machine<'tcx>> InterpCx<'tcx, M> {
                 ty::Ref(_, ty, _) => *ty,
                 ty::RawPtr(ty, _) => *ty,
                 // We only accept `Box` with the default allocator.
-                _ if ty.is_box_global(*self.tcx) => ty.boxed_ty(),
+                _ if ty.is_box_global(*self.tcx) => ty.expect_boxed_ty(),
                 _ => return Ok(None),
             }))
         };
diff --git a/compiler/rustc_data_structures/src/steal.rs b/compiler/rustc_data_structures/src/steal.rs
index 0f2c0eee27d..aaa95f6b7f1 100644
--- a/compiler/rustc_data_structures/src/steal.rs
+++ b/compiler/rustc_data_structures/src/steal.rs
@@ -57,6 +57,7 @@ impl<T> Steal<T> {
     ///
     /// This should not be used within rustc as it leaks information not tracked
     /// by the query system, breaking incremental compilation.
+    #[cfg_attr(not(bootstrap), rustc_lint_untracked_query_information)]
     pub fn is_stolen(&self) -> bool {
         self.value.borrow().is_none()
     }
diff --git a/compiler/rustc_driver_impl/src/lib.rs b/compiler/rustc_driver_impl/src/lib.rs
index cb2fa6e9d74..e7d0fab3f0d 100644
--- a/compiler/rustc_driver_impl/src/lib.rs
+++ b/compiler/rustc_driver_impl/src/lib.rs
@@ -862,9 +862,9 @@ fn print_crate_info(
                 use rustc_target::spec::current_apple_deployment_target;
 
                 if sess.target.is_like_osx {
-                    let (major, minor) = current_apple_deployment_target(&sess.target)
-                        .expect("unknown Apple target OS");
-                    println_info!("deployment_target={}", format!("{major}.{minor}"))
+                    let (major, minor, patch) = current_apple_deployment_target(&sess.target);
+                    let patch = if patch != 0 { format!(".{patch}") } else { String::new() };
+                    println_info!("deployment_target={major}.{minor}{patch}")
                 } else {
                     #[allow(rustc::diagnostic_outside_of_impl)]
                     sess.dcx().fatal("only Apple targets currently support deployment version info")
diff --git a/compiler/rustc_expand/src/mbe/macro_parser.rs b/compiler/rustc_expand/src/mbe/macro_parser.rs
index 9011d02da33..501a2417fcf 100644
--- a/compiler/rustc_expand/src/mbe/macro_parser.rs
+++ b/compiler/rustc_expand/src/mbe/macro_parser.rs
@@ -398,8 +398,10 @@ pub(crate) enum NamedMatch {
 fn token_name_eq(t1: &Token, t2: &Token) -> bool {
     if let (Some((ident1, is_raw1)), Some((ident2, is_raw2))) = (t1.ident(), t2.ident()) {
         ident1.name == ident2.name && is_raw1 == is_raw2
-    } else if let (Some(ident1), Some(ident2)) = (t1.lifetime(), t2.lifetime()) {
-        ident1.name == ident2.name
+    } else if let (Some((ident1, is_raw1)), Some((ident2, is_raw2))) =
+        (t1.lifetime(), t2.lifetime())
+    {
+        ident1.name == ident2.name && is_raw1 == is_raw2
     } else {
         t1.kind == t2.kind
     }
diff --git a/compiler/rustc_expand/src/mbe/transcribe.rs b/compiler/rustc_expand/src/mbe/transcribe.rs
index b06910595bb..39489a8df1b 100644
--- a/compiler/rustc_expand/src/mbe/transcribe.rs
+++ b/compiler/rustc_expand/src/mbe/transcribe.rs
@@ -283,9 +283,9 @@ pub(super) fn transcribe<'a>(
                             let kind = token::NtIdent(*ident, *is_raw);
                             TokenTree::token_alone(kind, sp)
                         }
-                        MatchedSingle(ParseNtResult::Lifetime(ident)) => {
+                        MatchedSingle(ParseNtResult::Lifetime(ident, is_raw)) => {
                             marker.visit_span(&mut sp);
-                            let kind = token::NtLifetime(*ident);
+                            let kind = token::NtLifetime(*ident, *is_raw);
                             TokenTree::token_alone(kind, sp)
                         }
                         MatchedSingle(ParseNtResult::Nt(nt)) => {
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 4ff5da1a4bd..5798bcedc22 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -229,15 +229,16 @@ impl FromInternal<(TokenStream, &mut Rustc<'_, '_>)> for Vec<TokenTree<TokenStre
                     span: ident.span,
                 })),
 
-                Lifetime(name) => {
+                Lifetime(name, is_raw) => {
                     let ident = symbol::Ident::new(name, span).without_first_quote();
                     trees.extend([
                         TokenTree::Punct(Punct { ch: b'\'', joint: true, span }),
-                        TokenTree::Ident(Ident { sym: ident.name, is_raw: false, span }),
+                        TokenTree::Ident(Ident { sym: ident.name, is_raw: is_raw.into(), span }),
                     ]);
                 }
-                NtLifetime(ident) => {
-                    let stream = TokenStream::token_alone(token::Lifetime(ident.name), ident.span);
+                NtLifetime(ident, is_raw) => {
+                    let stream =
+                        TokenStream::token_alone(token::Lifetime(ident.name, is_raw), ident.span);
                     trees.push(TokenTree::Group(Group {
                         delimiter: pm::Delimiter::None,
                         stream: Some(stream),
diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index e2491922b8d..e86421f2150 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -793,6 +793,12 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         rustc_lint_query_instability, Normal, template!(Word),
         WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
     ),
+    // Used by the `rustc::untracked_query_information` lint to warn methods which
+    // might not be stable during incremental compilation.
+    rustc_attr!(
+        rustc_lint_untracked_query_information, Normal, template!(Word),
+        WarnFollowing, EncodeCrossCrate::Yes, INTERNAL_UNSTABLE
+    ),
     // Used by the `rustc::diagnostic_outside_of_impl` lints to assist in changes to diagnostic
     // APIs. Any function with this attribute will be checked by that lint.
     rustc_attr!(
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
index bd8b43e28e5..9fce927e2c7 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls.rs
@@ -93,7 +93,8 @@ impl<'tcx> InherentCollect<'tcx> {
                 }
             }
 
-            if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) {
+            if let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer)
+            {
                 self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
             } else {
                 bug!("unexpected self type: {:?}", self_ty);
@@ -132,7 +133,7 @@ impl<'tcx> InherentCollect<'tcx> {
             }
         }
 
-        if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::AsCandidateKey) {
+        if let Some(simp) = simplify_type(self.tcx, ty, TreatParams::InstantiateWithInfer) {
             self.impls_map.incoherent_impls.entry(simp).or_default().push(impl_def_id);
         } else {
             bug!("unexpected primitive type: {:?}", ty);
diff --git a/compiler/rustc_hir_analysis/src/collect/generics_of.rs b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
index be6c3f048dc..ba01ea3f512 100644
--- a/compiler/rustc_hir_analysis/src/collect/generics_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/generics_of.rs
@@ -59,6 +59,12 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
 
     let node = tcx.hir_node(hir_id);
+    if let Some(sig) = node.fn_sig()
+        && let Some(sig_id) = sig.decl.opt_delegation_sig_id()
+    {
+        return inherit_generics_for_delegation_item(tcx, def_id, sig_id);
+    }
+
     let parent_def_id = match node {
         Node::ImplItem(_)
         | Node::TraitItem(_)
@@ -229,16 +235,6 @@ pub(super) fn generics_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Generics {
                 // inherit the generics of the item.
                 Some(parent.to_def_id())
             }
-            ItemKind::Fn(sig, _, _) => {
-                // For a delegation item inherit generics from callee.
-                if let Some(sig_id) = sig.decl.opt_delegation_sig_id()
-                    && let Some(generics) =
-                        inherit_generics_for_delegation_item(tcx, def_id, sig_id)
-                {
-                    return generics;
-                }
-                None
-            }
             _ => None,
         },
         _ => None,
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index a47aaf25e95..7243e85ce98 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -138,6 +138,12 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
     let node = tcx.hir_node(hir_id);
 
+    if let Some(sig) = node.fn_sig()
+        && let Some(sig_id) = sig.decl.opt_delegation_sig_id()
+    {
+        return inherit_predicates_for_delegation_item(tcx, def_id, sig_id);
+    }
+
     let mut is_trait = None;
     let mut is_default_impl_trait = None;
 
@@ -164,16 +170,6 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
             ItemKind::Trait(_, _, _, self_bounds, ..) | ItemKind::TraitAlias(_, self_bounds) => {
                 is_trait = Some(self_bounds);
             }
-
-            ItemKind::Fn(sig, _, _) => {
-                // For a delegation item inherit predicates from callee.
-                if let Some(sig_id) = sig.decl.opt_delegation_sig_id()
-                    && let Some(predicates) =
-                        inherit_predicates_for_delegation_item(tcx, def_id, sig_id)
-                {
-                    return predicates;
-                }
-            }
             _ => {}
         }
     };
diff --git a/compiler/rustc_hir_analysis/src/delegation.rs b/compiler/rustc_hir_analysis/src/delegation.rs
index 20aaa43219f..2c9f20b7840 100644
--- a/compiler/rustc_hir_analysis/src/delegation.rs
+++ b/compiler/rustc_hir_analysis/src/delegation.rs
@@ -1,3 +1,7 @@
+//! Support inheriting generic parameters and predicates for function delegation.
+//!
+//! For more information about delegation design, see the tracking issue #118212.
+
 use std::assert_matches::debug_assert_matches;
 
 use rustc_data_structures::fx::FxHashMap;
@@ -5,7 +9,7 @@ use rustc_hir::def::DefKind;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_middle::ty::fold::{TypeFoldable, TypeFolder, TypeSuperFoldable};
 use rustc_middle::ty::{self, Ty, TyCtxt};
-use rustc_span::ErrorGuaranteed;
+use rustc_span::{ErrorGuaranteed, Span};
 use rustc_type_ir::visit::TypeVisitableExt;
 
 type RemapTable = FxHashMap<u32, u32>;
@@ -76,127 +80,381 @@ fn fn_kind<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> FnKind {
     }
 }
 
+/// Given the current context(caller and callee `FnKind`), it specifies
+/// the policy of predicates and generic parameters inheritance.
+#[derive(Clone, Copy, Debug, PartialEq)]
+enum InheritanceKind {
+    /// Copying all predicates and parameters, including those of the parent
+    /// container.
+    ///
+    /// Boolean value defines whether the `Self` parameter or `Self: Trait`
+    /// predicate are copied. It's always equal to `false` except when
+    /// delegating from a free function to a trait method.
+    ///
+    /// FIXME(fn_delegation): This often leads to type inference
+    /// errors. Support providing generic arguments or restrict use sites.
+    WithParent(bool),
+    /// The trait implementation should be compatible with the original trait.
+    /// Therefore, for trait implementations only the method's own parameters
+    /// and predicates are copied.
+    Own,
+}
+
+struct GenericsBuilder<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    sig_id: DefId,
+    parent: Option<DefId>,
+    inh_kind: InheritanceKind,
+}
+
+impl<'tcx> GenericsBuilder<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, sig_id: DefId) -> GenericsBuilder<'tcx> {
+        GenericsBuilder { tcx, sig_id, parent: None, inh_kind: InheritanceKind::WithParent(false) }
+    }
+
+    fn with_parent(mut self, parent: DefId) -> Self {
+        self.parent = Some(parent);
+        self
+    }
+
+    fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self {
+        self.inh_kind = inh_kind;
+        self
+    }
+
+    fn build(self) -> ty::Generics {
+        let mut own_params = vec![];
+
+        let sig_generics = self.tcx.generics_of(self.sig_id);
+        if let InheritanceKind::WithParent(has_self) = self.inh_kind
+            && let Some(parent_def_id) = sig_generics.parent
+        {
+            let sig_parent_generics = self.tcx.generics_of(parent_def_id);
+            own_params.append(&mut sig_parent_generics.own_params.clone());
+            if !has_self {
+                own_params.remove(0);
+            }
+        }
+        own_params.append(&mut sig_generics.own_params.clone());
+
+        // Lifetime parameters must be declared before type and const parameters.
+        // Therefore, When delegating from a free function to a associated function,
+        // generic parameters need to be reordered:
+        //
+        // trait Trait<'a, A> {
+        //     fn foo<'b, B>(...) {...}
+        // }
+        //
+        // reuse Trait::foo;
+        // desugaring:
+        // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) {
+        //     Trait::foo(...)
+        // }
+        own_params.sort_by_key(|key| key.kind.is_ty_or_const());
+
+        let param_def_id_to_index =
+            own_params.iter().map(|param| (param.def_id, param.index)).collect();
+
+        let (parent_count, has_self) = if let Some(def_id) = self.parent {
+            let parent_generics = self.tcx.generics_of(def_id);
+            let parent_kind = self.tcx.def_kind(def_id);
+            (parent_generics.count(), parent_kind == DefKind::Trait)
+        } else {
+            (0, false)
+        };
+
+        for (idx, param) in own_params.iter_mut().enumerate() {
+            param.index = (idx + parent_count) as u32;
+            // FIXME(fn_delegation): Default parameters are not inherited, because they are
+            // not permitted in functions. Therefore, there are 2 options here:
+            //
+            // - We can create non-default generic parameters.
+            // - We can substitute default parameters into the signature.
+            //
+            // At the moment, first option has been selected as the most general.
+            if let ty::GenericParamDefKind::Type { has_default, .. }
+            | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind
+            {
+                *has_default = false;
+            }
+        }
+
+        ty::Generics {
+            parent: self.parent,
+            parent_count,
+            own_params,
+            param_def_id_to_index,
+            has_self,
+            has_late_bound_regions: sig_generics.has_late_bound_regions,
+            host_effect_index: sig_generics.host_effect_index,
+        }
+    }
+}
+
+struct PredicatesBuilder<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    sig_id: DefId,
+    parent: Option<DefId>,
+    inh_kind: InheritanceKind,
+    args: ty::GenericArgsRef<'tcx>,
+}
+
+impl<'tcx> PredicatesBuilder<'tcx> {
+    fn new(
+        tcx: TyCtxt<'tcx>,
+        args: ty::GenericArgsRef<'tcx>,
+        sig_id: DefId,
+    ) -> PredicatesBuilder<'tcx> {
+        PredicatesBuilder {
+            tcx,
+            sig_id,
+            parent: None,
+            inh_kind: InheritanceKind::WithParent(false),
+            args,
+        }
+    }
+
+    fn with_parent(mut self, parent: DefId) -> Self {
+        self.parent = Some(parent);
+        self
+    }
+
+    fn with_inheritance_kind(mut self, inh_kind: InheritanceKind) -> Self {
+        self.inh_kind = inh_kind;
+        self
+    }
+
+    fn build(self) -> ty::GenericPredicates<'tcx> {
+        struct PredicatesCollector<'tcx> {
+            tcx: TyCtxt<'tcx>,
+            preds: Vec<(ty::Clause<'tcx>, Span)>,
+            args: ty::GenericArgsRef<'tcx>,
+        }
+
+        impl<'tcx> PredicatesCollector<'tcx> {
+            fn new(tcx: TyCtxt<'tcx>, args: ty::GenericArgsRef<'tcx>) -> PredicatesCollector<'tcx> {
+                PredicatesCollector { tcx, preds: vec![], args }
+            }
+
+            fn with_own_preds(
+                mut self,
+                f: impl Fn(DefId) -> ty::GenericPredicates<'tcx>,
+                def_id: DefId,
+            ) -> Self {
+                let preds = f(def_id).instantiate_own(self.tcx, self.args);
+                self.preds.extend(preds);
+                self
+            }
+
+            fn with_preds(
+                mut self,
+                f: impl Fn(DefId) -> ty::GenericPredicates<'tcx> + Copy,
+                def_id: DefId,
+            ) -> Self {
+                let preds = f(def_id);
+                if let Some(parent_def_id) = preds.parent {
+                    self = self.with_own_preds(f, parent_def_id);
+                }
+                self.with_own_preds(f, def_id)
+            }
+        }
+        let collector = PredicatesCollector::new(self.tcx, self.args);
+
+        // `explicit_predicates_of` is used here to avoid copying `Self: Trait` predicate.
+        // Note: `predicates_of` query can also add inferred outlives predicates, but that
+        // is not the case here as `sig_id` is either a trait or a function.
+        let preds = match self.inh_kind {
+            InheritanceKind::WithParent(false) => {
+                collector.with_preds(|def_id| self.tcx.explicit_predicates_of(def_id), self.sig_id)
+            }
+            InheritanceKind::WithParent(true) => {
+                collector.with_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id)
+            }
+            InheritanceKind::Own => {
+                collector.with_own_preds(|def_id| self.tcx.predicates_of(def_id), self.sig_id)
+            }
+        }
+        .preds;
+
+        ty::GenericPredicates {
+            parent: self.parent,
+            predicates: self.tcx.arena.alloc_from_iter(preds),
+            // FIXME(fn_delegation): Support effects.
+            effects_min_tys: ty::List::empty(),
+        }
+    }
+}
+
+struct GenericArgsBuilder<'tcx> {
+    tcx: TyCtxt<'tcx>,
+    remap_table: RemapTable,
+    sig_id: DefId,
+    def_id: LocalDefId,
+}
+
+impl<'tcx> GenericArgsBuilder<'tcx> {
+    fn new(tcx: TyCtxt<'tcx>, sig_id: DefId, def_id: LocalDefId) -> GenericArgsBuilder<'tcx> {
+        GenericArgsBuilder { tcx, remap_table: FxHashMap::default(), sig_id, def_id }
+    }
+
+    fn build_from_args(mut self, args: ty::GenericArgsRef<'tcx>) -> ty::GenericArgsRef<'tcx> {
+        let caller_generics = self.tcx.generics_of(self.def_id);
+        let callee_generics = self.tcx.generics_of(self.sig_id);
+
+        for caller_param in &caller_generics.own_params {
+            let callee_index =
+                callee_generics.param_def_id_to_index(self.tcx, caller_param.def_id).unwrap();
+            self.remap_table.insert(callee_index, caller_param.index);
+        }
+
+        let mut folder = ParamIndexRemapper { tcx: self.tcx, remap_table: self.remap_table };
+        args.fold_with(&mut folder)
+    }
+}
+
 fn create_generic_args<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
     sig_id: DefId,
 ) -> ty::GenericArgsRef<'tcx> {
-    let caller_generics = tcx.generics_of(def_id);
-    let callee_generics = tcx.generics_of(sig_id);
+    let builder = GenericArgsBuilder::new(tcx, sig_id, def_id);
 
     let caller_kind = fn_kind(tcx, def_id.into());
     let callee_kind = fn_kind(tcx, sig_id);
-    // FIXME(fn_delegation): Support generics on associated delegation items.
-    // Error will be reported in `check_constraints`.
     match (caller_kind, callee_kind) {
-        (FnKind::Free, _) => {
-            // Lifetime parameters must be declared before type and const parameters.
-            // Therefore, When delegating from a free function to a associated function,
-            // generic parameters need to be reordered:
-            //
-            // trait Trait<'a, A> {
-            //     fn foo<'b, B>(...) {...}
-            // }
-            //
-            // reuse Trait::foo;
-            // desugaring:
-            // fn foo<'a, 'b, This: Trait<'a, A>, A, B>(...) {
-            //     Trait::foo(...)
-            // }
-            let mut remap_table = RemapTable::default();
-            for caller_param in &caller_generics.own_params {
-                let callee_index =
-                    callee_generics.param_def_id_to_index(tcx, caller_param.def_id).unwrap();
-                remap_table.insert(callee_index, caller_param.index);
-            }
-            let mut folder = ParamIndexRemapper { tcx, remap_table };
-            ty::GenericArgs::identity_for_item(tcx, sig_id).fold_with(&mut folder)
+        (FnKind::Free, FnKind::Free)
+        | (FnKind::Free, FnKind::AssocTrait)
+        | (FnKind::AssocInherentImpl, FnKind::Free)
+        | (FnKind::AssocTrait, FnKind::Free)
+        | (FnKind::AssocTrait, FnKind::AssocTrait) => {
+            let args = ty::GenericArgs::identity_for_item(tcx, sig_id);
+            builder.build_from_args(args)
         }
-        // FIXME(fn_delegation): Only `Self` param supported here.
-        (FnKind::AssocTraitImpl, FnKind::AssocTrait)
-        | (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
+
+        (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
+            let callee_generics = tcx.generics_of(sig_id);
+            let parent = tcx.parent(def_id.into());
+            let parent_args =
+                tcx.impl_trait_header(parent).unwrap().trait_ref.instantiate_identity().args;
+
+            let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
+            let method_args = tcx.mk_args_from_iter(trait_args.iter().skip(callee_generics.parent_count));
+            let method_args = builder.build_from_args(method_args);
+
+            tcx.mk_args_from_iter(parent_args.iter().chain(method_args))
+        }
+
+        (FnKind::AssocInherentImpl, FnKind::AssocTrait) => {
             let parent = tcx.parent(def_id.into());
             let self_ty = tcx.type_of(parent).instantiate_identity();
             let generic_self_ty = ty::GenericArg::from(self_ty);
-            tcx.mk_args_from_iter(std::iter::once(generic_self_ty))
+
+            let trait_args = ty::GenericArgs::identity_for_item(tcx, sig_id);
+            let trait_args = builder.build_from_args(trait_args);
+
+            let args = std::iter::once(generic_self_ty).chain(trait_args.iter().skip(1));
+            tcx.mk_args_from_iter(args)
         }
-        _ => ty::GenericArgs::identity_for_item(tcx, sig_id),
+
+        // For trait impl's `sig_id` is always equal to the corresponding trait method.
+        (FnKind::AssocTraitImpl, _)
+        | (_, FnKind::AssocTraitImpl)
+        // Delegation to inherent methods is not yet supported.
+        | (_, FnKind::AssocInherentImpl) => unreachable!(),
     }
 }
 
+// FIXME(fn_delegation): Move generics inheritance to the AST->HIR lowering.
+// For now, generic parameters are not propagated to the generated call,
+// which leads to inference errors:
+//
+// fn foo<T>(x: i32) {}
+//
+// reuse foo as bar;
+// desugaring:
+// fn bar<T>() {
+//   foo::<_>() // ERROR: type annotations needed
+// }
 pub(crate) fn inherit_generics_for_delegation_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
     sig_id: DefId,
-) -> Option<ty::Generics> {
-    // FIXME(fn_delegation): Support generics on associated delegation items.
-    // Error will be reported in `check_constraints`.
-    if fn_kind(tcx, def_id.into()) != FnKind::Free {
-        return None;
-    }
+) -> ty::Generics {
+    let builder = GenericsBuilder::new(tcx, sig_id);
 
-    let mut own_params = vec![];
-
-    let callee_generics = tcx.generics_of(sig_id);
-    if let Some(parent_sig_id) = callee_generics.parent {
-        let parent_sig_generics = tcx.generics_of(parent_sig_id);
-        own_params.append(&mut parent_sig_generics.own_params.clone());
-    }
-    own_params.append(&mut callee_generics.own_params.clone());
+    let caller_kind = fn_kind(tcx, def_id.into());
+    let callee_kind = fn_kind(tcx, sig_id);
+    match (caller_kind, callee_kind) {
+        (FnKind::Free, FnKind::Free)
+        | (FnKind::Free, FnKind::AssocTrait) => builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build(),
+
+        (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
+            builder
+            .with_parent(tcx.parent(def_id.into()))
+            .with_inheritance_kind(InheritanceKind::Own)
+            .build()
+        }
 
-    // Lifetimes go first.
-    own_params.sort_by_key(|key| key.kind.is_ty_or_const());
+        (FnKind::AssocInherentImpl, FnKind::AssocTrait)
+        | (FnKind::AssocTrait, FnKind::AssocTrait) => {
+            builder
+            .with_parent(tcx.parent(def_id.into()))
+            .build()
+        }
 
-    for (idx, param) in own_params.iter_mut().enumerate() {
-        param.index = idx as u32;
-        // Default parameters are not inherited: they are not allowed
-        // in fn's.
-        if let ty::GenericParamDefKind::Type { has_default, .. }
-        | ty::GenericParamDefKind::Const { has_default, .. } = &mut param.kind
-        {
-            *has_default = false;
+        (FnKind::AssocInherentImpl, FnKind::Free)
+        | (FnKind::AssocTrait, FnKind::Free) => {
+            builder
+            .with_parent(tcx.parent(def_id.into()))
+            .build()
         }
-    }
 
-    let param_def_id_to_index =
-        own_params.iter().map(|param| (param.def_id, param.index)).collect();
-
-    Some(ty::Generics {
-        parent: None,
-        parent_count: 0,
-        own_params,
-        param_def_id_to_index,
-        has_self: false,
-        has_late_bound_regions: callee_generics.has_late_bound_regions,
-        host_effect_index: callee_generics.host_effect_index,
-    })
+        // For trait impl's `sig_id` is always equal to the corresponding trait method.
+        (FnKind::AssocTraitImpl, _)
+        | (_, FnKind::AssocTraitImpl)
+        // Delegation to inherent methods is not yet supported.
+        | (_, FnKind::AssocInherentImpl) => unreachable!(),
+    }
 }
 
 pub(crate) fn inherit_predicates_for_delegation_item<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: LocalDefId,
     sig_id: DefId,
-) -> Option<ty::GenericPredicates<'tcx>> {
-    // FIXME(fn_delegation): Support generics on associated delegation items.
-    // Error will be reported in `check_constraints`.
-    if fn_kind(tcx, def_id.into()) != FnKind::Free {
-        return None;
-    }
-
-    let callee_predicates = tcx.predicates_of(sig_id);
+) -> ty::GenericPredicates<'tcx> {
     let args = create_generic_args(tcx, def_id, sig_id);
+    let builder = PredicatesBuilder::new(tcx, args, sig_id);
 
-    let mut preds = vec![];
-    if let Some(parent_id) = callee_predicates.parent {
-        preds.extend(tcx.predicates_of(parent_id).instantiate_own(tcx, args));
-    }
-    preds.extend(callee_predicates.instantiate_own(tcx, args));
+    let caller_kind = fn_kind(tcx, def_id.into());
+    let callee_kind = fn_kind(tcx, sig_id);
+    match (caller_kind, callee_kind) {
+        (FnKind::Free, FnKind::Free)
+        | (FnKind::Free, FnKind::AssocTrait) => {
+            builder.with_inheritance_kind(InheritanceKind::WithParent(true)).build()
+        }
+
+        (FnKind::AssocTraitImpl, FnKind::AssocTrait) => {
+            builder
+            .with_parent(tcx.parent(def_id.into()))
+            .with_inheritance_kind(InheritanceKind::Own)
+            .build()
+        }
+
+        (FnKind::AssocInherentImpl, FnKind::AssocTrait)
+        | (FnKind::AssocTrait, FnKind::AssocTrait)
+        | (FnKind::AssocInherentImpl, FnKind::Free)
+        | (FnKind::AssocTrait, FnKind::Free) => {
+            builder
+                .with_parent(tcx.parent(def_id.into()))
+                .build()
+        }
 
-    Some(ty::GenericPredicates {
-        parent: None,
-        predicates: tcx.arena.alloc_from_iter(preds),
-        effects_min_tys: ty::List::empty(),
-    })
+        // For trait impl's `sig_id` is always equal to the corresponding trait method.
+        (FnKind::AssocTraitImpl, _)
+        | (_, FnKind::AssocTraitImpl)
+        // Delegation to inherent methods is not yet supported.
+        | (_, FnKind::AssocInherentImpl) => unreachable!(),
+    }
 }
 
 fn check_constraints<'tcx>(
@@ -224,19 +482,6 @@ fn check_constraints<'tcx>(
         emit("recursive delegation is not supported yet");
     }
 
-    if fn_kind(tcx, def_id.into()) != FnKind::Free {
-        let sig_generics = tcx.generics_of(sig_id);
-        let parent = tcx.parent(def_id.into());
-        let parent_generics = tcx.generics_of(parent);
-
-        let parent_has_self = parent_generics.has_self as usize;
-        let sig_has_self = sig_generics.has_self as usize;
-
-        if sig_generics.count() > sig_has_self || parent_generics.count() > parent_has_self {
-            emit("early bound generics are not supported for associated delegation items");
-        }
-    }
-
     ret
 }
 
diff --git a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
index 0790c6f9a59..ac5e1040803 100644
--- a/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
+++ b/compiler/rustc_hir_typeck/src/method/prelude_edition_lints.rs
@@ -63,8 +63,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     // Instead, the problem is that the array-into_iter hack will no longer
                     // apply in Rust 2021.
                     (ARRAY_INTO_ITER, "2021")
-                } else if self_ty.is_box()
-                    && self_ty.boxed_ty().is_slice()
+                } else if self_ty.boxed_ty().is_some_and(Ty::is_slice)
                     && !span.at_least_rust_2024()
                 {
                     // In this case, it wasn't really a prelude addition that was the problem.
diff --git a/compiler/rustc_hir_typeck/src/method/probe.rs b/compiler/rustc_hir_typeck/src/method/probe.rs
index 2fdba8446bd..3ba3429cbb3 100644
--- a/compiler/rustc_hir_typeck/src/method/probe.rs
+++ b/compiler/rustc_hir_typeck/src/method/probe.rs
@@ -715,7 +715,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
     }
 
     fn assemble_inherent_candidates_for_incoherent_ty(&mut self, self_ty: Ty<'tcx>) {
-        let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::AsCandidateKey) else {
+        let Some(simp) = simplify_type(self.tcx, self_ty, TreatParams::InstantiateWithInfer) else {
             bug!("unexpected incoherent type: {:?}", self_ty)
         };
         for &impl_def_id in self.tcx.incoherent_impls(simp).into_iter().flatten() {
@@ -1485,8 +1485,7 @@ impl<'a, 'tcx> ProbeContext<'a, 'tcx> {
 
                         // Some trait methods are excluded for boxed slices before 2024.
                         // (`boxed_slice.into_iter()` wants a slice iterator for compatibility.)
-                        if self_ty.is_box()
-                            && self_ty.boxed_ty().is_slice()
+                        if self_ty.boxed_ty().is_some_and(Ty::is_slice)
                             && !method_name.span.at_least_rust_2024()
                         {
                             let trait_def = self.tcx.trait_def(poly_trait_ref.def_id());
diff --git a/compiler/rustc_hir_typeck/src/method/suggest.rs b/compiler/rustc_hir_typeck/src/method/suggest.rs
index 9ea57e4aa61..14ad5830111 100644
--- a/compiler/rustc_hir_typeck/src/method/suggest.rs
+++ b/compiler/rustc_hir_typeck/src/method/suggest.rs
@@ -2235,8 +2235,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let target_ty = self
                 .autoderef(sugg_span, rcvr_ty)
                 .find(|(rcvr_ty, _)| {
-                    DeepRejectCtxt::new(self.tcx, TreatParams::ForLookup)
-                        .types_may_unify(*rcvr_ty, impl_ty)
+                    DeepRejectCtxt::relate_rigid_infer(self.tcx).types_may_unify(*rcvr_ty, impl_ty)
                 })
                 .map_or(impl_ty, |(ty, _)| ty)
                 .peel_refs();
@@ -2498,7 +2497,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .into_iter()
             .any(|info| self.associated_value(info.def_id, item_name).is_some());
         let found_assoc = |ty: Ty<'tcx>| {
-            simplify_type(tcx, ty, TreatParams::AsCandidateKey)
+            simplify_type(tcx, ty, TreatParams::InstantiateWithInfer)
                 .and_then(|simp| {
                     tcx.incoherent_impls(simp)
                         .into_iter()
@@ -3963,7 +3962,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // cases where a positive bound implies a negative impl.
                 (candidates, Vec::new())
             } else if let Some(simp_rcvr_ty) =
-                simplify_type(self.tcx, rcvr_ty, TreatParams::ForLookup)
+                simplify_type(self.tcx, rcvr_ty, TreatParams::AsRigid)
             {
                 let mut potential_candidates = Vec::new();
                 let mut explicitly_negative = Vec::new();
@@ -3981,7 +3980,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                         .any(|header| {
                             let imp = header.trait_ref.instantiate_identity();
                             let imp_simp =
-                                simplify_type(self.tcx, imp.self_ty(), TreatParams::ForLookup);
+                                simplify_type(self.tcx, imp.self_ty(), TreatParams::AsRigid);
                             imp_simp.is_some_and(|s| s == simp_rcvr_ty)
                         })
                     {
diff --git a/compiler/rustc_hir_typeck/src/upvar.rs b/compiler/rustc_hir_typeck/src/upvar.rs
index 5789e60ebbe..7688a63a30a 100644
--- a/compiler/rustc_hir_typeck/src/upvar.rs
+++ b/compiler/rustc_hir_typeck/src/upvar.rs
@@ -39,7 +39,6 @@ use rustc_hir as hir;
 use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::HirId;
-use rustc_infer::infer::UpvarRegion;
 use rustc_middle::hir::place::{Place, PlaceBase, PlaceWithHirId, Projection, ProjectionKind};
 use rustc_middle::mir::FakeReadCause;
 use rustc_middle::traits::ObligationCauseCode;
@@ -425,7 +424,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                             self.tcx,
                             upvar_ty,
                             capture,
-                            if needs_ref { Some(closure_env_region) } else { child_capture.region },
+                            if needs_ref {
+                                closure_env_region
+                            } else {
+                                self.tcx.lifetimes.re_erased
+                            },
                         );
                     },
                 ),
@@ -587,7 +590,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
                 debug!(?captured_place.place, ?upvar_ty, ?capture, ?captured_place.mutability);
 
-                apply_capture_kind_on_capture_ty(self.tcx, upvar_ty, capture, captured_place.region)
+                apply_capture_kind_on_capture_ty(
+                    self.tcx,
+                    upvar_ty,
+                    capture,
+                    self.tcx.lifetimes.re_erased,
+                )
             })
             .collect()
     }
@@ -775,13 +783,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
             let Some(min_cap_list) = root_var_min_capture_list.get_mut(&var_hir_id) else {
                 let mutability = self.determine_capture_mutability(&typeck_results, &place);
-                let min_cap_list = vec![ty::CapturedPlace {
-                    var_ident,
-                    place,
-                    info: capture_info,
-                    mutability,
-                    region: None,
-                }];
+                let min_cap_list =
+                    vec![ty::CapturedPlace { var_ident, place, info: capture_info, mutability }];
                 root_var_min_capture_list.insert(var_hir_id, min_cap_list);
                 continue;
             };
@@ -874,34 +877,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             // Only need to insert when we don't have an ancestor in the existing min capture list
             if !ancestor_found {
                 let mutability = self.determine_capture_mutability(&typeck_results, &place);
-                let captured_place = ty::CapturedPlace {
-                    var_ident,
-                    place,
-                    info: updated_capture_info,
-                    mutability,
-                    region: None,
-                };
+                let captured_place =
+                    ty::CapturedPlace { var_ident, place, info: updated_capture_info, mutability };
                 min_cap_list.push(captured_place);
             }
         }
 
-        // For each capture that is determined to be captured by ref, add region info.
-        for (_, captures) in &mut root_var_min_capture_list {
-            for capture in captures {
-                match capture.info.capture_kind {
-                    ty::UpvarCapture::ByRef(_) => {
-                        let PlaceBase::Upvar(upvar_id) = capture.place.base else {
-                            bug!("expected upvar")
-                        };
-                        let origin = UpvarRegion(upvar_id, closure_span);
-                        let upvar_region = self.next_region_var(origin);
-                        capture.region = Some(upvar_region);
-                    }
-                    _ => (),
-                }
-            }
-        }
-
         debug!(
             "For closure={:?}, min_captures before sorting={:?}",
             closure_def_id, root_var_min_capture_list
@@ -1195,7 +1176,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                     self.tcx,
                     ty,
                     max_capture_info.capture_kind,
-                    Some(self.tcx.lifetimes.re_erased),
+                    self.tcx.lifetimes.re_erased,
                 )
             }
         };
@@ -1217,7 +1198,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 self.tcx,
                 capture.place.ty(),
                 capture.info.capture_kind,
-                Some(self.tcx.lifetimes.re_erased),
+                self.tcx.lifetimes.re_erased,
             );
 
             // Checks if a capture implements any of the auto traits
@@ -1935,13 +1916,11 @@ fn apply_capture_kind_on_capture_ty<'tcx>(
     tcx: TyCtxt<'tcx>,
     ty: Ty<'tcx>,
     capture_kind: UpvarCapture,
-    region: Option<ty::Region<'tcx>>,
+    region: ty::Region<'tcx>,
 ) -> Ty<'tcx> {
     match capture_kind {
         ty::UpvarCapture::ByValue => ty,
-        ty::UpvarCapture::ByRef(kind) => {
-            Ty::new_ref(tcx, region.unwrap(), ty, kind.to_mutbl_lossy())
-        }
+        ty::UpvarCapture::ByRef(kind) => Ty::new_ref(tcx, region, ty, kind.to_mutbl_lossy()),
     }
 }
 
diff --git a/compiler/rustc_interface/src/tests.rs b/compiler/rustc_interface/src/tests.rs
index 42fed98df01..50422df8ee6 100644
--- a/compiler/rustc_interface/src/tests.rs
+++ b/compiler/rustc_interface/src/tests.rs
@@ -808,7 +808,7 @@ fn test_unstable_options_tracking_hash() {
     tracked!(mir_opt_level, Some(4));
     tracked!(move_size_limit, Some(4096));
     tracked!(mutable_noalias, false);
-    tracked!(next_solver, Some(NextSolverConfig { coherence: true, globally: false }));
+    tracked!(next_solver, NextSolverConfig { coherence: true, globally: true });
     tracked!(no_generate_arange_section, true);
     tracked!(no_jump_tables, true);
     tracked!(no_link, true);
diff --git a/compiler/rustc_lexer/src/lib.rs b/compiler/rustc_lexer/src/lib.rs
index 31fdd2d7cec..60aab668cba 100644
--- a/compiler/rustc_lexer/src/lib.rs
+++ b/compiler/rustc_lexer/src/lib.rs
@@ -91,6 +91,15 @@ pub enum TokenKind {
     /// tokens.
     UnknownPrefix,
 
+    /// An unknown prefix in a lifetime, like `'foo#`.
+    ///
+    /// Note that like above, only the `'` and prefix are included in the token
+    /// and not the separator.
+    UnknownPrefixLifetime,
+
+    /// `'r#lt`, which in edition < 2021 is split into several tokens: `'r # lt`.
+    RawLifetime,
+
     /// Similar to the above, but *always* an error on every edition. This is used
     /// for emoji identifier recovery, as those are not meant to be ever accepted.
     InvalidPrefix,
@@ -677,9 +686,17 @@ impl Cursor<'_> {
             return Literal { kind, suffix_start };
         }
 
+        if self.first() == 'r' && self.second() == '#' && is_id_start(self.third()) {
+            // Eat "r" and `#`, and identifier start characters.
+            self.bump();
+            self.bump();
+            self.bump();
+            self.eat_while(is_id_continue);
+            return RawLifetime;
+        }
+
         // Either a lifetime or a character literal with
         // length greater than 1.
-
         let starts_with_number = self.first().is_ascii_digit();
 
         // Skip the literal contents.
@@ -688,15 +705,17 @@ impl Cursor<'_> {
         self.bump();
         self.eat_while(is_id_continue);
 
-        // Check if after skipping literal contents we've met a closing
-        // single quote (which means that user attempted to create a
-        // string with single quotes).
-        if self.first() == '\'' {
-            self.bump();
-            let kind = Char { terminated: true };
-            Literal { kind, suffix_start: self.pos_within_token() }
-        } else {
-            Lifetime { starts_with_number }
+        match self.first() {
+            // Check if after skipping literal contents we've met a closing
+            // single quote (which means that user attempted to create a
+            // string with single quotes).
+            '\'' => {
+                self.bump();
+                let kind = Char { terminated: true };
+                Literal { kind, suffix_start: self.pos_within_token() }
+            }
+            '#' if !starts_with_number => UnknownPrefixLifetime,
+            _ => Lifetime { starts_with_number },
         }
     }
 
diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl
index 35334595833..7d4dee45c26 100644
--- a/compiler/rustc_lint/messages.ftl
+++ b/compiler/rustc_lint/messages.ftl
@@ -255,6 +255,7 @@ lint_duplicate_matcher_binding = duplicate matcher binding
 lint_elided_named_lifetime = elided lifetime has a name
     .label_elided = this elided lifetime gets resolved as `{$name}`
     .label_named = lifetime `{$name}` declared here
+    .suggestion = consider specifying it explicitly
 
 lint_enum_intrinsics_mem_discriminant =
     the return value of `mem::discriminant` is unspecified when called with a non-enum type
@@ -699,11 +700,18 @@ lint_ptr_null_checks_ref = references are not nullable, so checking them for nul
 lint_query_instability = using `{$query}` can result in unstable query results
     .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
 
+lint_query_untracked = `{$method}` accesses information that is not tracked by the query system
+    .note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+
 lint_range_endpoint_out_of_range = range endpoint is out of range for `{$ty}`
 
 lint_range_use_inclusive_range = use an inclusive range instead
 
 
+lint_raw_prefix = prefix `'r` is reserved
+    .label = reserved prefix
+    .suggestion = insert whitespace here to avoid this being parsed as a prefix in Rust 2021
+
 lint_reason_must_be_string_literal = reason must be a string literal
 
 lint_reason_must_come_last = reason in lint attribute must come last
diff --git a/compiler/rustc_lint/src/builtin.rs b/compiler/rustc_lint/src/builtin.rs
index d8482567bbe..824a1868c55 100644
--- a/compiler/rustc_lint/src/builtin.rs
+++ b/compiler/rustc_lint/src/builtin.rs
@@ -1851,9 +1851,16 @@ impl KeywordIdents {
                 TokenTree::Token(token, _) => {
                     if let Some((ident, token::IdentIsRaw::No)) = token.ident() {
                         if !prev_dollar {
-                            self.check_ident_token(cx, UnderMacro(true), ident);
+                            self.check_ident_token(cx, UnderMacro(true), ident, "");
                         }
-                    } else if *token == TokenKind::Dollar {
+                    } else if let Some((ident, token::IdentIsRaw::No)) = token.lifetime() {
+                        self.check_ident_token(
+                            cx,
+                            UnderMacro(true),
+                            ident.without_first_quote(),
+                            "'",
+                        );
+                    } else if token.kind == TokenKind::Dollar {
                         prev_dollar = true;
                         continue;
                     }
@@ -1869,6 +1876,7 @@ impl KeywordIdents {
         cx: &EarlyContext<'_>,
         UnderMacro(under_macro): UnderMacro,
         ident: Ident,
+        prefix: &'static str,
     ) {
         let (lint, edition) = match ident.name {
             kw::Async | kw::Await | kw::Try => (KEYWORD_IDENTS_2018, Edition::Edition2018),
@@ -1902,7 +1910,7 @@ impl KeywordIdents {
         cx.emit_span_lint(
             lint,
             ident.span,
-            BuiltinKeywordIdents { kw: ident, next: edition, suggestion: ident.span },
+            BuiltinKeywordIdents { kw: ident, next: edition, suggestion: ident.span, prefix },
         );
     }
 }
@@ -1915,7 +1923,11 @@ impl EarlyLintPass for KeywordIdents {
         self.check_tokens(cx, &mac.args.tokens);
     }
     fn check_ident(&mut self, cx: &EarlyContext<'_>, ident: Ident) {
-        self.check_ident_token(cx, UnderMacro(false), ident);
+        if ident.name.as_str().starts_with('\'') {
+            self.check_ident_token(cx, UnderMacro(false), ident.without_first_quote(), "'");
+        } else {
+            self.check_ident_token(cx, UnderMacro(false), ident, "");
+        }
     }
 }
 
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs
index fd43afa1743..fd13c418c09 100644
--- a/compiler/rustc_lint/src/context/diagnostics.rs
+++ b/compiler/rustc_lint/src/context/diagnostics.rs
@@ -8,13 +8,13 @@ use rustc_errors::{
     elided_lifetime_in_path_suggestion, Applicability, Diag, DiagArgValue, LintDiagnostic,
 };
 use rustc_middle::middle::stability;
-use rustc_session::lint::BuiltinLintDiag;
+use rustc_session::lint::{BuiltinLintDiag, ElidedLifetimeResolution};
 use rustc_session::Session;
 use rustc_span::symbol::kw;
 use rustc_span::BytePos;
 use tracing::debug;
 
-use crate::lints;
+use crate::lints::{self, ElidedNamedLifetime};
 
 mod check_cfg;
 
@@ -172,6 +172,10 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
             }
             .decorate_lint(diag);
         }
+        BuiltinLintDiag::RawPrefix(label_span) => {
+            lints::RawPrefix { label: label_span, suggestion: label_span.shrink_to_hi() }
+                .decorate_lint(diag);
+        }
         BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => {
             lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }.decorate_lint(diag);
         }
@@ -442,15 +446,14 @@ pub(super) fn decorate_lint(sess: &Session, diagnostic: BuiltinLintDiag, diag: &
         BuiltinLintDiag::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by } => {
             lints::UnexpectedBuiltinCfg { cfg, cfg_name, controlled_by }.decorate_lint(diag)
         }
-        BuiltinLintDiag::ElidedIsStatic { elided } => {
-            lints::ElidedNamedLifetime { elided, name: kw::StaticLifetime, named_declaration: None }
-                .decorate_lint(diag)
-        }
-        BuiltinLintDiag::ElidedIsParam { elided, param: (param_name, param_span) } => {
-            lints::ElidedNamedLifetime {
-                elided,
-                name: param_name,
-                named_declaration: Some(param_span),
+        BuiltinLintDiag::ElidedNamedLifetimes { elided: (span, kind), resolution } => {
+            match resolution {
+                ElidedLifetimeResolution::Static => {
+                    ElidedNamedLifetime { span, kind, name: kw::StaticLifetime, declaration: None }
+                }
+                ElidedLifetimeResolution::Param(name, declaration) => {
+                    ElidedNamedLifetime { span, kind, name, declaration: Some(declaration) }
+                }
             }
             .decorate_lint(diag)
         }
diff --git a/compiler/rustc_lint/src/internal.rs b/compiler/rustc_lint/src/internal.rs
index 2e8116b8ba8..9d637c1eb7f 100644
--- a/compiler/rustc_lint/src/internal.rs
+++ b/compiler/rustc_lint/src/internal.rs
@@ -17,8 +17,8 @@ use tracing::debug;
 
 use crate::lints::{
     BadOptAccessDiag, DefaultHashTypesDiag, DiagOutOfImpl, LintPassByHand, NonExistentDocKeyword,
-    NonGlobImportTypeIrInherent, QueryInstability, SpanUseEqCtxtDiag, TyQualified, TykindDiag,
-    TykindKind, TypeIrInherentUsage, UntranslatableDiag,
+    NonGlobImportTypeIrInherent, QueryInstability, QueryUntracked, SpanUseEqCtxtDiag, TyQualified,
+    TykindDiag, TykindKind, TypeIrInherentUsage, UntranslatableDiag,
 };
 use crate::{EarlyContext, EarlyLintPass, LateContext, LateLintPass, LintContext};
 
@@ -88,7 +88,18 @@ declare_tool_lint! {
     report_in_external_macro: true
 }
 
-declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY]);
+declare_tool_lint! {
+    /// The `untracked_query_information` lint detects use of methods which leak information not
+    /// tracked by the query system, such as whether a `Steal<T>` value has already been stolen. In
+    /// order not to break incremental compilation, such methods must be used very carefully or not
+    /// at all.
+    pub rustc::UNTRACKED_QUERY_INFORMATION,
+    Allow,
+    "require explicit opt-in when accessing information not tracked by the query system",
+    report_in_external_macro: true
+}
+
+declare_lint_pass!(QueryStability => [POTENTIAL_QUERY_INSTABILITY, UNTRACKED_QUERY_INFORMATION]);
 
 impl LateLintPass<'_> for QueryStability {
     fn check_expr(&mut self, cx: &LateContext<'_>, expr: &Expr<'_>) {
@@ -102,6 +113,13 @@ impl LateLintPass<'_> for QueryStability {
                     QueryInstability { query: cx.tcx.item_name(def_id) },
                 );
             }
+            if cx.tcx.has_attr(def_id, sym::rustc_lint_untracked_query_information) {
+                cx.emit_span_lint(
+                    UNTRACKED_QUERY_INFORMATION,
+                    span,
+                    QueryUntracked { method: cx.tcx.item_name(def_id) },
+                );
+            }
         }
     }
 }
diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs
index bb7de4739fb..a9627e9b789 100644
--- a/compiler/rustc_lint/src/lib.rs
+++ b/compiler/rustc_lint/src/lib.rs
@@ -610,6 +610,7 @@ fn register_internals(store: &mut LintStore) {
         vec![
             LintId::of(DEFAULT_HASH_TYPES),
             LintId::of(POTENTIAL_QUERY_INSTABILITY),
+            LintId::of(UNTRACKED_QUERY_INFORMATION),
             LintId::of(USAGE_OF_TY_TYKIND),
             LintId::of(PASS_BY_VALUE),
             LintId::of(LINT_PASS_IMPL_WITHOUT_MACRO),
diff --git a/compiler/rustc_lint/src/lints.rs b/compiler/rustc_lint/src/lints.rs
index 7ca282b7c85..e49b102cb39 100644
--- a/compiler/rustc_lint/src/lints.rs
+++ b/compiler/rustc_lint/src/lints.rs
@@ -9,7 +9,7 @@ use rustc_errors::{
 };
 use rustc_hir::def::Namespace;
 use rustc_hir::def_id::DefId;
-use rustc_hir::{self as hir};
+use rustc_hir::{self as hir, MissingLifetimeKind};
 use rustc_macros::{LintDiagnostic, Subdiagnostic};
 use rustc_middle::ty::inhabitedness::InhabitedPredicate;
 use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
@@ -363,8 +363,9 @@ pub(crate) enum BuiltinEllipsisInclusiveRangePatternsLint {
 pub(crate) struct BuiltinKeywordIdents {
     pub kw: Ident,
     pub next: Edition,
-    #[suggestion(code = "r#{kw}", applicability = "machine-applicable")]
+    #[suggestion(code = "{prefix}r#{kw}", applicability = "machine-applicable")]
     pub suggestion: Span,
+    pub prefix: &'static str,
 }
 
 #[derive(LintDiagnostic)]
@@ -895,6 +896,13 @@ pub(crate) struct QueryInstability {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_query_untracked)]
+#[note]
+pub(crate) struct QueryUntracked {
+    pub method: Symbol,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(lint_span_use_eq_ctxt)]
 pub(crate) struct SpanUseEqCtxtDiag;
 
@@ -2616,14 +2624,56 @@ pub(crate) struct ElidedLifetimesInPaths {
     pub subdiag: ElidedLifetimeInPathSubdiag,
 }
 
-#[derive(LintDiagnostic)]
-#[diag(lint_elided_named_lifetime)]
 pub(crate) struct ElidedNamedLifetime {
-    #[label(lint_label_elided)]
-    pub elided: Span,
+    pub span: Span,
+    pub kind: MissingLifetimeKind,
     pub name: Symbol,
-    #[label(lint_label_named)]
-    pub named_declaration: Option<Span>,
+    pub declaration: Option<Span>,
+}
+
+impl<G: EmissionGuarantee> LintDiagnostic<'_, G> for ElidedNamedLifetime {
+    fn decorate_lint(self, diag: &mut rustc_errors::Diag<'_, G>) {
+        let Self { span, kind, name, declaration } = self;
+        diag.primary_message(fluent::lint_elided_named_lifetime);
+        diag.arg("name", name);
+        diag.span_label(span, fluent::lint_label_elided);
+        if let Some(declaration) = declaration {
+            diag.span_label(declaration, fluent::lint_label_named);
+        }
+        // FIXME(GrigorenkoPV): this `if` and `return` should be removed,
+        //  but currently this lint's suggestions can conflict with those of `clippy::needless_lifetimes`:
+        //  https://github.com/rust-lang/rust/pull/129840#issuecomment-2323349119
+        // HACK: `'static` suggestions will never sonflict, emit only those for now.
+        if name != rustc_span::symbol::kw::StaticLifetime {
+            return;
+        }
+        match kind {
+            MissingLifetimeKind::Underscore => diag.span_suggestion_verbose(
+                span,
+                fluent::lint_suggestion,
+                format!("{name}"),
+                Applicability::MachineApplicable,
+            ),
+            MissingLifetimeKind::Ampersand => diag.span_suggestion_verbose(
+                span.shrink_to_hi(),
+                fluent::lint_suggestion,
+                format!("{name} "),
+                Applicability::MachineApplicable,
+            ),
+            MissingLifetimeKind::Comma => diag.span_suggestion_verbose(
+                span.shrink_to_hi(),
+                fluent::lint_suggestion,
+                format!("{name}, "),
+                Applicability::MachineApplicable,
+            ),
+            MissingLifetimeKind::Brackets => diag.span_suggestion_verbose(
+                span.shrink_to_hi(),
+                fluent::lint_suggestion,
+                format!("<{name}>"),
+                Applicability::MachineApplicable,
+            ),
+        };
+    }
 }
 
 #[derive(LintDiagnostic)]
@@ -2766,6 +2816,15 @@ pub(crate) struct ReservedPrefix {
 }
 
 #[derive(LintDiagnostic)]
+#[diag(lint_raw_prefix)]
+pub(crate) struct RawPrefix {
+    #[label]
+    pub label: Span,
+    #[suggestion(code = " ", applicability = "machine-applicable")]
+    pub suggestion: Span,
+}
+
+#[derive(LintDiagnostic)]
 #[diag(lint_unused_builtin_attribute)]
 pub(crate) struct UnusedBuiltinAttribute {
     #[note]
diff --git a/compiler/rustc_lint/src/shadowed_into_iter.rs b/compiler/rustc_lint/src/shadowed_into_iter.rs
index bb9c7d85c2e..bb122509d0a 100644
--- a/compiler/rustc_lint/src/shadowed_into_iter.rs
+++ b/compiler/rustc_lint/src/shadowed_into_iter.rs
@@ -94,12 +94,9 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter {
         fn is_ref_to_array(ty: Ty<'_>) -> bool {
             if let ty::Ref(_, pointee_ty, _) = *ty.kind() { pointee_ty.is_array() } else { false }
         }
-        fn is_boxed_slice(ty: Ty<'_>) -> bool {
-            ty.is_box() && ty.boxed_ty().is_slice()
-        }
         fn is_ref_to_boxed_slice(ty: Ty<'_>) -> bool {
             if let ty::Ref(_, pointee_ty, _) = *ty.kind() {
-                is_boxed_slice(pointee_ty)
+                pointee_ty.boxed_ty().is_some_and(Ty::is_slice)
             } else {
                 false
             }
@@ -119,7 +116,7 @@ impl<'tcx> LateLintPass<'tcx> for ShadowedIntoIter {
                     .iter()
                     .copied()
                     .take_while(|ty| !is_ref_to_boxed_slice(*ty))
-                    .position(|ty| is_boxed_slice(ty))
+                    .position(|ty| ty.boxed_ty().is_some_and(Ty::is_slice))
             {
                 (BOXED_SLICE_INTO_ITER, "Box<[T]>", "2024", idx == 0)
             } else {
diff --git a/compiler/rustc_lint/src/types.rs b/compiler/rustc_lint/src/types.rs
index f2f7c0eaa4d..b5e501b92f0 100644
--- a/compiler/rustc_lint/src/types.rs
+++ b/compiler/rustc_lint/src/types.rs
@@ -1304,8 +1304,10 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
 
         match *ty.kind() {
             ty::Adt(def, args) => {
-                if def.is_box() && matches!(self.mode, CItemKind::Definition) {
-                    if ty.boxed_ty().is_sized(tcx, self.cx.param_env) {
+                if let Some(boxed) = ty.boxed_ty()
+                    && matches!(self.mode, CItemKind::Definition)
+                {
+                    if boxed.is_sized(tcx, self.cx.param_env) {
                         return FfiSafe;
                     } else {
                         return FfiUnsafe {
diff --git a/compiler/rustc_lint/src/unused.rs b/compiler/rustc_lint/src/unused.rs
index 761d30bac71..b7f7b782c77 100644
--- a/compiler/rustc_lint/src/unused.rs
+++ b/compiler/rustc_lint/src/unused.rs
@@ -283,9 +283,8 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
             }
 
             match *ty.kind() {
-                ty::Adt(..) if ty.is_box() => {
-                    let boxed_ty = ty.boxed_ty();
-                    is_ty_must_use(cx, boxed_ty, expr, span)
+                ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => {
+                    is_ty_must_use(cx, boxed, expr, span)
                         .map(|inner| MustUsePath::Boxed(Box::new(inner)))
                 }
                 ty::Adt(def, args) if cx.tcx.is_lang_item(def.did(), LangItem::Pin) => {
diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs
index 6ee33041623..5c4b7e5664d 100644
--- a/compiler/rustc_lint_defs/src/lib.rs
+++ b/compiler/rustc_lint_defs/src/lib.rs
@@ -10,7 +10,7 @@ use rustc_data_structures::stable_hasher::{
 };
 use rustc_error_messages::{DiagMessage, MultiSpan};
 use rustc_hir::def::Namespace;
-use rustc_hir::{HashStableContext, HirId};
+use rustc_hir::{HashStableContext, HirId, MissingLifetimeKind};
 use rustc_macros::{Decodable, Encodable, HashStable_Generic};
 use rustc_span::edition::Edition;
 use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent};
@@ -556,6 +556,12 @@ pub enum DeprecatedSinceKind {
     InVersion(String),
 }
 
+#[derive(Debug)]
+pub enum ElidedLifetimeResolution {
+    Static,
+    Param(Symbol, Span),
+}
+
 // This could be a closure, but then implementing derive trait
 // becomes hacky (and it gets allocated).
 #[derive(Debug)]
@@ -568,12 +574,9 @@ pub enum BuiltinLintDiag {
     },
     MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
     ElidedLifetimesInPaths(usize, Span, bool, Span),
-    ElidedIsStatic {
-        elided: Span,
-    },
-    ElidedIsParam {
-        elided: Span,
-        param: (Symbol, Span),
+    ElidedNamedLifetimes {
+        elided: (Span, MissingLifetimeKind),
+        resolution: ElidedLifetimeResolution,
     },
     UnknownCrateTypes {
         span: Span,
@@ -609,6 +612,8 @@ pub enum BuiltinLintDiag {
     LegacyDeriveHelpers(Span),
     OrPatternsBackCompat(Span, String),
     ReservedPrefix(Span, String),
+    /// `'r#` in edition < 2021.
+    RawPrefix(Span),
     TrailingMacro(bool, Ident),
     BreakWithLabelAndLoop(Span),
     UnicodeTextFlow(Span, String),
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index c55583b39a6..83bad59825c 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -2033,7 +2033,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                 let simplified_self_ty = fast_reject::simplify_type(
                     self.tcx,
                     trait_ref.self_ty(),
-                    TreatParams::AsCandidateKey,
+                    TreatParams::InstantiateWithInfer,
                 );
                 trait_impls
                     .entry(trait_ref.def_id)
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 748ca047754..22a4b688c51 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1307,6 +1307,9 @@ pub enum Rvalue<'tcx> {
     /// If the type of the place is an array, this is the array length. For slices (`[T]`, not
     /// `&[T]`) this accesses the place's metadata to determine the length. This rvalue is
     /// ill-formed for places of other types.
+    ///
+    /// This cannot be a `UnOp(PtrMetadata, _)` because that expects a value, and we only
+    /// have a place, and `UnOp(PtrMetadata, RawPtr(place))` is not a thing.
     Len(Place<'tcx>),
 
     /// Performs essentially all of the casts that can be performed via `as`.
diff --git a/compiler/rustc_middle/src/ty/closure.rs b/compiler/rustc_middle/src/ty/closure.rs
index 8eb3c015679..809801c33e1 100644
--- a/compiler/rustc_middle/src/ty/closure.rs
+++ b/compiler/rustc_middle/src/ty/closure.rs
@@ -88,9 +88,6 @@ pub struct CapturedPlace<'tcx> {
 
     /// Represents if `place` can be mutated or not.
     pub mutability: hir::Mutability,
-
-    /// Region of the resulting reference if the upvar is captured by ref.
-    pub region: Option<ty::Region<'tcx>>,
 }
 
 impl<'tcx> CapturedPlace<'tcx> {
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 20828067c46..2a3008897c6 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -426,7 +426,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
                 let simp = ty::fast_reject::simplify_type(
                     tcx,
                     self_ty,
-                    ty::fast_reject::TreatParams::ForLookup,
+                    ty::fast_reject::TreatParams::AsRigid,
                 )
                 .unwrap();
                 consider_impls_for_simplified_type(simp);
@@ -3128,11 +3128,11 @@ impl<'tcx> TyCtxt<'tcx> {
     }
 
     pub fn next_trait_solver_globally(self) -> bool {
-        self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally)
+        self.sess.opts.unstable_opts.next_solver.globally
     }
 
     pub fn next_trait_solver_in_coherence(self) -> bool {
-        self.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.coherence)
+        self.sess.opts.unstable_opts.next_solver.coherence
     }
 
     pub fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
diff --git a/compiler/rustc_middle/src/ty/fast_reject.rs b/compiler/rustc_middle/src/ty/fast_reject.rs
index 91344c4e39c..2945a0be424 100644
--- a/compiler/rustc_middle/src/ty/fast_reject.rs
+++ b/compiler/rustc_middle/src/ty/fast_reject.rs
@@ -3,6 +3,14 @@ pub use rustc_type_ir::fast_reject::*;
 
 use super::TyCtxt;
 
-pub type DeepRejectCtxt<'tcx> = rustc_type_ir::fast_reject::DeepRejectCtxt<TyCtxt<'tcx>>;
+pub type DeepRejectCtxt<
+    'tcx,
+    const INSTANTIATE_LHS_WITH_INFER: bool,
+    const INSTANTIATE_RHS_WITH_INFER: bool,
+> = rustc_type_ir::fast_reject::DeepRejectCtxt<
+    TyCtxt<'tcx>,
+    INSTANTIATE_LHS_WITH_INFER,
+    INSTANTIATE_RHS_WITH_INFER,
+>;
 
 pub type SimplifiedType = rustc_type_ir::fast_reject::SimplifiedType<DefId>;
diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs
index d0a9039441d..8cec8eac189 100644
--- a/compiler/rustc_middle/src/ty/layout.rs
+++ b/compiler/rustc_middle/src/ty/layout.rs
@@ -1075,11 +1075,13 @@ where
                 // the raw pointer, so size and align are set to the boxed type, but `pointee.safe`
                 // will still be `None`.
                 if let Some(ref mut pointee) = result {
-                    if offset.bytes() == 0 && this.ty.is_box() {
+                    if offset.bytes() == 0
+                        && let Some(boxed_ty) = this.ty.boxed_ty()
+                    {
                         debug_assert!(pointee.safe.is_none());
                         let optimize = tcx.sess.opts.optimize != OptLevel::No;
                         pointee.safe = Some(PointerKind::Box {
-                            unpin: optimize && this.ty.boxed_ty().is_unpin(tcx, cx.param_env()),
+                            unpin: optimize && boxed_ty.is_unpin(tcx, cx.param_env()),
                             global: this.ty.is_box_global(tcx),
                         });
                     }
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 89ef30fa768..1f4f2c62d70 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -1170,14 +1170,19 @@ impl<'tcx> Ty<'tcx> {
         }
     }
 
-    /// Panics if called on any type other than `Box<T>`.
-    pub fn boxed_ty(self) -> Ty<'tcx> {
+    pub fn boxed_ty(self) -> Option<Ty<'tcx>> {
         match self.kind() {
-            Adt(def, args) if def.is_box() => args.type_at(0),
-            _ => bug!("`boxed_ty` is called on non-box type {:?}", self),
+            Adt(def, args) if def.is_box() => Some(args.type_at(0)),
+            _ => None,
         }
     }
 
+    /// Panics if called on any type other than `Box<T>`.
+    pub fn expect_boxed_ty(self) -> Ty<'tcx> {
+        self.boxed_ty()
+            .unwrap_or_else(|| bug!("`expect_boxed_ty` is called on non-box type {:?}", self))
+    }
+
     /// A scalar type is one that denotes an atomic datum, with no sub-components.
     /// (A RawPtr is scalar because it represents a non-managed pointer, so its
     /// contents are abstract to rustc.)
@@ -1323,7 +1328,7 @@ impl<'tcx> Ty<'tcx> {
     /// Some types -- notably unsafe ptrs -- can only be dereferenced explicitly.
     pub fn builtin_deref(self, explicit: bool) -> Option<Ty<'tcx>> {
         match *self.kind() {
-            Adt(def, _) if def.is_box() => Some(self.boxed_ty()),
+            _ if let Some(boxed) = self.boxed_ty() => Some(boxed),
             Ref(_, ty, _) => Some(ty),
             RawPtr(ty, _) if explicit => Some(ty),
             _ => None,
diff --git a/compiler/rustc_middle/src/ty/trait_def.rs b/compiler/rustc_middle/src/ty/trait_def.rs
index dfb137f738f..82690f70e5f 100644
--- a/compiler/rustc_middle/src/ty/trait_def.rs
+++ b/compiler/rustc_middle/src/ty/trait_def.rs
@@ -168,9 +168,9 @@ impl<'tcx> TyCtxt<'tcx> {
         // whose outer level is not a parameter or projection. Especially for things like
         // `T: Clone` this is incredibly useful as we would otherwise look at all the impls
         // of `Clone` for `Option<T>`, `Vec<T>`, `ConcreteType` and so on.
-        // Note that we're using `TreatParams::ForLookup` to query `non_blanket_impls` while using
-        // `TreatParams::AsCandidateKey` while actually adding them.
-        if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::ForLookup) {
+        // Note that we're using `TreatParams::AsRigid` to query `non_blanket_impls` while using
+        // `TreatParams::InstantiateWithInfer` while actually adding them.
+        if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsRigid) {
             if let Some(impls) = impls.non_blanket_impls.get(&simp) {
                 for &impl_def_id in impls {
                     f(impl_def_id);
@@ -190,7 +190,9 @@ impl<'tcx> TyCtxt<'tcx> {
         self_ty: Ty<'tcx>,
     ) -> impl Iterator<Item = DefId> + 'tcx {
         let impls = self.trait_impls_of(trait_def_id);
-        if let Some(simp) = fast_reject::simplify_type(self, self_ty, TreatParams::AsCandidateKey) {
+        if let Some(simp) =
+            fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer)
+        {
             if let Some(impls) = impls.non_blanket_impls.get(&simp) {
                 return impls.iter().copied();
             }
@@ -239,7 +241,7 @@ pub(super) fn trait_impls_of_provider(tcx: TyCtxt<'_>, trait_id: DefId) -> Trait
         let impl_self_ty = tcx.type_of(impl_def_id).instantiate_identity();
 
         if let Some(simplified_self_ty) =
-            fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::AsCandidateKey)
+            fast_reject::simplify_type(tcx, impl_self_ty, TreatParams::InstantiateWithInfer)
         {
             impls.non_blanket_impls.entry(simplified_self_ty).or_default().push(impl_def_id);
         } else {
diff --git a/compiler/rustc_middle/src/ty/util.rs b/compiler/rustc_middle/src/ty/util.rs
index efbccca77c1..d70ff8258d0 100644
--- a/compiler/rustc_middle/src/ty/util.rs
+++ b/compiler/rustc_middle/src/ty/util.rs
@@ -1628,7 +1628,7 @@ impl<'tcx> ExplicitSelf<'tcx> {
             _ if is_self_ty(self_arg_ty) => ByValue,
             ty::Ref(region, ty, mutbl) if is_self_ty(ty) => ByReference(region, mutbl),
             ty::RawPtr(ty, mutbl) if is_self_ty(ty) => ByRawPointer(mutbl),
-            ty::Adt(def, _) if def.is_box() && is_self_ty(self_arg_ty.boxed_ty()) => ByBox,
+            _ if self_arg_ty.boxed_ty().is_some_and(is_self_ty) => ByBox,
             _ => Other,
         }
     }
diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
index cf39c136b01..9e35dfed0ee 100644
--- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
+++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs
@@ -88,6 +88,11 @@ pub fn coroutine_by_move_body_def_id<'tcx>(
 ) -> DefId {
     let body = tcx.mir_built(coroutine_def_id).borrow();
 
+    // If the typeck results are tainted, no need to make a by-ref body.
+    if body.tainted_by_errors.is_some() {
+        return coroutine_def_id.to_def_id();
+    }
+
     let Some(hir::CoroutineKind::Desugared(_, hir::CoroutineSource::Closure)) =
         tcx.coroutine_kind(coroutine_def_id)
     else {
@@ -98,7 +103,9 @@ pub fn coroutine_by_move_body_def_id<'tcx>(
     // the MIR body will be constructed well.
     let coroutine_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty;
 
-    let ty::Coroutine(_, args) = *coroutine_ty.kind() else { bug!("{body:#?}") };
+    let ty::Coroutine(_, args) = *coroutine_ty.kind() else {
+        bug!("tried to create by-move body of non-coroutine receiver");
+    };
     let args = args.as_coroutine();
 
     let coroutine_kind = args.kind_ty().to_opt_closure_kind().unwrap();
@@ -107,7 +114,7 @@ pub fn coroutine_by_move_body_def_id<'tcx>(
     let ty::CoroutineClosure(_, parent_args) =
         *tcx.type_of(parent_def_id).instantiate_identity().kind()
     else {
-        bug!();
+        bug!("coroutine's parent was not a coroutine-closure");
     };
     if parent_args.references_error() {
         return coroutine_def_id.to_def_id();
diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs
index fcc774503f4..b904b0d2599 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans.rs
@@ -3,7 +3,7 @@ use std::collections::VecDeque;
 use rustc_data_structures::captures::Captures;
 use rustc_data_structures::fx::FxHashSet;
 use rustc_middle::mir;
-use rustc_span::Span;
+use rustc_span::{DesugaringKind, ExpnKind, MacroKind, Span};
 use tracing::{debug, debug_span, instrument};
 
 use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph};
@@ -25,7 +25,7 @@ pub(super) fn extract_refined_covspans(
 
     // First, perform the passes that need macro information.
     covspans.sort_by(|a, b| basic_coverage_blocks.cmp_in_dominator_order(a.bcb, b.bcb));
-    remove_unwanted_macro_spans(&mut covspans);
+    remove_unwanted_expansion_spans(&mut covspans);
     split_visible_macro_spans(&mut covspans);
 
     // We no longer need the extra information in `SpanFromMir`, so convert to `Covspan`.
@@ -76,18 +76,24 @@ pub(super) fn extract_refined_covspans(
 /// invocation, which is unhelpful. Keeping only the first such span seems to
 /// give better mappings, so remove the others.
 ///
+/// Similarly, `await` expands to a branch on the discriminant of `Poll`, which
+/// leads to incorrect coverage if the `Future` is immediately ready (#98712).
+///
 /// (The input spans should be sorted in BCB dominator order, so that the
 /// retained "first" span is likely to dominate the others.)
-fn remove_unwanted_macro_spans(covspans: &mut Vec<SpanFromMir>) {
-    let mut seen_macro_spans = FxHashSet::default();
+fn remove_unwanted_expansion_spans(covspans: &mut Vec<SpanFromMir>) {
+    let mut deduplicated_spans = FxHashSet::default();
+
     covspans.retain(|covspan| {
-        // Ignore (retain) non-macro-expansion spans.
-        if covspan.visible_macro.is_none() {
-            return true;
+        match covspan.expn_kind {
+            // Retain only the first await-related or macro-expanded covspan with this span.
+            Some(ExpnKind::Desugaring(kind)) if kind == DesugaringKind::Await => {
+                deduplicated_spans.insert(covspan.span)
+            }
+            Some(ExpnKind::Macro(MacroKind::Bang, _)) => deduplicated_spans.insert(covspan.span),
+            // Ignore (retain) other spans.
+            _ => true,
         }
-
-        // Retain only the first macro-expanded covspan with this span.
-        seen_macro_spans.insert(covspan.span)
     });
 }
 
@@ -99,7 +105,9 @@ fn split_visible_macro_spans(covspans: &mut Vec<SpanFromMir>) {
     let mut extra_spans = vec![];
 
     covspans.retain(|covspan| {
-        let Some(visible_macro) = covspan.visible_macro else { return true };
+        let Some(ExpnKind::Macro(MacroKind::Bang, visible_macro)) = covspan.expn_kind else {
+            return true;
+        };
 
         let split_len = visible_macro.as_str().len() as u32 + 1;
         let (before, after) = covspan.span.split_at(split_len);
@@ -111,8 +119,8 @@ fn split_visible_macro_spans(covspans: &mut Vec<SpanFromMir>) {
             return true;
         }
 
-        extra_spans.push(SpanFromMir::new(before, covspan.visible_macro, covspan.bcb));
-        extra_spans.push(SpanFromMir::new(after, covspan.visible_macro, covspan.bcb));
+        extra_spans.push(SpanFromMir::new(before, covspan.expn_kind.clone(), covspan.bcb));
+        extra_spans.push(SpanFromMir::new(after, covspan.expn_kind.clone(), covspan.bcb));
         false // Discard the original covspan that we just split.
     });
 
diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
index 32bd25bf4b9..7f5765c9462 100644
--- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
+++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs
@@ -3,13 +3,13 @@ use rustc_middle::mir::coverage::CoverageKind;
 use rustc_middle::mir::{
     self, FakeReadCause, Statement, StatementKind, Terminator, TerminatorKind,
 };
-use rustc_span::{Span, Symbol};
+use rustc_span::{ExpnKind, Span};
 
 use crate::coverage::graph::{
     BasicCoverageBlock, BasicCoverageBlockData, CoverageGraph, START_BCB,
 };
 use crate::coverage::spans::Covspan;
-use crate::coverage::unexpand::unexpand_into_body_span_with_visible_macro;
+use crate::coverage::unexpand::unexpand_into_body_span_with_expn_kind;
 use crate::coverage::ExtractedHirInfo;
 
 pub(crate) struct ExtractedCovspans {
@@ -60,7 +60,7 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
         let data = &mir_body[bb];
 
         let unexpand = move |expn_span| {
-            unexpand_into_body_span_with_visible_macro(expn_span, body_span)
+            unexpand_into_body_span_with_expn_kind(expn_span, body_span)
                 // Discard any spans that fill the entire body, because they tend
                 // to represent compiler-inserted code, e.g. implicitly returning `()`.
                 .filter(|(span, _)| !span.source_equal(body_span))
@@ -68,9 +68,9 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
 
         let mut extract_statement_span = |statement| {
             let expn_span = filtered_statement_span(statement)?;
-            let (span, visible_macro) = unexpand(expn_span)?;
+            let (span, expn_kind) = unexpand(expn_span)?;
 
-            initial_covspans.push(SpanFromMir::new(span, visible_macro, bcb));
+            initial_covspans.push(SpanFromMir::new(span, expn_kind, bcb));
             Some(())
         };
         for statement in data.statements.iter() {
@@ -79,9 +79,9 @@ fn bcb_to_initial_coverage_spans<'a, 'tcx>(
 
         let mut extract_terminator_span = |terminator| {
             let expn_span = filtered_terminator_span(terminator)?;
-            let (span, visible_macro) = unexpand(expn_span)?;
+            let (span, expn_kind) = unexpand(expn_span)?;
 
-            initial_covspans.push(SpanFromMir::new(span, visible_macro, bcb));
+            initial_covspans.push(SpanFromMir::new(span, expn_kind, bcb));
             Some(())
         };
         extract_terminator_span(data.terminator());
@@ -214,7 +214,7 @@ pub(crate) struct SpanFromMir {
     /// With the exception of `fn_sig_span`, this should always be contained
     /// within `body_span`.
     pub(crate) span: Span,
-    pub(crate) visible_macro: Option<Symbol>,
+    pub(crate) expn_kind: Option<ExpnKind>,
     pub(crate) bcb: BasicCoverageBlock,
 }
 
@@ -223,12 +223,12 @@ impl SpanFromMir {
         Self::new(fn_sig_span, None, START_BCB)
     }
 
-    pub(crate) fn new(span: Span, visible_macro: Option<Symbol>, bcb: BasicCoverageBlock) -> Self {
-        Self { span, visible_macro, bcb }
+    pub(crate) fn new(span: Span, expn_kind: Option<ExpnKind>, bcb: BasicCoverageBlock) -> Self {
+        Self { span, expn_kind, bcb }
     }
 
     pub(crate) fn into_covspan(self) -> Covspan {
-        let Self { span, visible_macro: _, bcb } = self;
+        let Self { span, expn_kind: _, bcb } = self;
         Covspan { span, bcb }
     }
 }
diff --git a/compiler/rustc_mir_transform/src/coverage/unexpand.rs b/compiler/rustc_mir_transform/src/coverage/unexpand.rs
index 8cde291b907..cb861544736 100644
--- a/compiler/rustc_mir_transform/src/coverage/unexpand.rs
+++ b/compiler/rustc_mir_transform/src/coverage/unexpand.rs
@@ -1,4 +1,4 @@
-use rustc_span::{ExpnKind, MacroKind, Span, Symbol};
+use rustc_span::{ExpnKind, Span};
 
 /// Walks through the expansion ancestors of `original_span` to find a span that
 /// is contained in `body_span` and has the same [syntax context] as `body_span`.
@@ -13,20 +13,15 @@ pub(crate) fn unexpand_into_body_span(original_span: Span, body_span: Span) -> O
 ///
 /// If the returned span represents a bang-macro invocation (e.g. `foo!(..)`),
 /// the returned symbol will be the name of that macro (e.g. `foo`).
-pub(crate) fn unexpand_into_body_span_with_visible_macro(
+pub(crate) fn unexpand_into_body_span_with_expn_kind(
     original_span: Span,
     body_span: Span,
-) -> Option<(Span, Option<Symbol>)> {
+) -> Option<(Span, Option<ExpnKind>)> {
     let (span, prev) = unexpand_into_body_span_with_prev(original_span, body_span)?;
 
-    let visible_macro = prev
-        .map(|prev| match prev.ctxt().outer_expn_data().kind {
-            ExpnKind::Macro(MacroKind::Bang, name) => Some(name),
-            _ => None,
-        })
-        .flatten();
+    let expn_kind = prev.map(|prev| prev.ctxt().outer_expn_data().kind);
 
-    Some((span, visible_macro))
+    Some((span, expn_kind))
 }
 
 /// Walks through the expansion ancestors of `original_span` to find a span that
diff --git a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
index 5dd82f40163..66e49d556e2 100644
--- a/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
+++ b/compiler/rustc_mir_transform/src/elaborate_box_derefs.rs
@@ -62,11 +62,13 @@ impl<'tcx, 'a> MutVisitor<'tcx> for ElaborateBoxDerefVisitor<'tcx, 'a> {
         let base_ty = self.local_decls[place.local].ty;
 
         // Derefer ensures that derefs are always the first projection
-        if place.projection.first() == Some(&PlaceElem::Deref) && base_ty.is_box() {
+        if let Some(PlaceElem::Deref) = place.projection.first()
+            && let Some(boxed_ty) = base_ty.boxed_ty()
+        {
             let source_info = self.local_decls[place.local].source_info;
 
             let (unique_ty, nonnull_ty, ptr_ty) =
-                build_ptr_tys(tcx, base_ty.boxed_ty(), self.unique_did, self.nonnull_did);
+                build_ptr_tys(tcx, boxed_ty, self.unique_did, self.nonnull_did);
 
             let ptr_local = self.patch.new_temp(ptr_ty, source_info.span);
 
@@ -120,13 +122,15 @@ impl<'tcx> crate::MirPass<'tcx> for ElaborateBoxDerefs {
                     for (base, elem) in place.iter_projections() {
                         let base_ty = base.ty(&body.local_decls, tcx).ty;
 
-                        if elem == PlaceElem::Deref && base_ty.is_box() {
+                        if let PlaceElem::Deref = elem
+                            && let Some(boxed_ty) = base_ty.boxed_ty()
+                        {
                             // Clone the projections before us, since now we need to mutate them.
                             let new_projections =
                                 new_projections.get_or_insert_with(|| base.projection.to_vec());
 
                             let (unique_ty, nonnull_ty, ptr_ty) =
-                                build_ptr_tys(tcx, base_ty.boxed_ty(), unique_did, nonnull_did);
+                                build_ptr_tys(tcx, boxed_ty, unique_did, nonnull_did);
 
                             new_projections.extend_from_slice(&build_projection(
                                 unique_ty, nonnull_ty, ptr_ty,
diff --git a/compiler/rustc_mir_transform/src/validate.rs b/compiler/rustc_mir_transform/src/validate.rs
index 69e2592e82c..e515dfc5ea5 100644
--- a/compiler/rustc_mir_transform/src/validate.rs
+++ b/compiler/rustc_mir_transform/src/validate.rs
@@ -1,6 +1,7 @@
 //! Validates the MIR to ensure that invariants are upheld.
 
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_hir as hir;
 use rustc_hir::LangItem;
 use rustc_index::bit_set::BitSet;
 use rustc_index::IndexVec;
@@ -714,7 +715,17 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                             // since we may be in the process of computing this MIR in the
                             // first place.
                             let layout = if def_id == self.caller_body.source.def_id() {
-                                // FIXME: This is not right for async closures.
+                                self.caller_body.coroutine_layout_raw()
+                            } else if let Some(hir::CoroutineKind::Desugared(
+                                _,
+                                hir::CoroutineSource::Closure,
+                            )) = self.tcx.coroutine_kind(def_id)
+                                && let ty::ClosureKind::FnOnce =
+                                    args.as_coroutine().kind_ty().to_opt_closure_kind().unwrap()
+                                && self.caller_body.source.def_id()
+                                    == self.tcx.coroutine_by_move_body_def_id(def_id)
+                            {
+                                // Same if this is the by-move body of a coroutine-closure.
                                 self.caller_body.coroutine_layout_raw()
                             } else {
                                 self.tcx.coroutine_layout(def_id, args.as_coroutine().kind_ty())
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index 8515ab45de2..093697a290c 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -1041,8 +1041,11 @@ fn find_vtable_types_for_unsizing<'tcx>(
     match (source_ty.kind(), target_ty.kind()) {
         (&ty::Ref(_, a, _), &ty::Ref(_, b, _) | &ty::RawPtr(b, _))
         | (&ty::RawPtr(a, _), &ty::RawPtr(b, _)) => ptr_vtable(a, b),
-        (&ty::Adt(def_a, _), &ty::Adt(def_b, _)) if def_a.is_box() && def_b.is_box() => {
-            ptr_vtable(source_ty.boxed_ty(), target_ty.boxed_ty())
+        (_, _)
+            if let Some(source_boxed) = source_ty.boxed_ty()
+                && let Some(target_boxed) = target_ty.boxed_ty() =>
+        {
+            ptr_vtable(source_boxed, target_boxed)
         }
 
         // T as dyn* Trait
diff --git a/compiler/rustc_monomorphize/src/lib.rs b/compiler/rustc_monomorphize/src/lib.rs
index b22e8e30465..91101ddd590 100644
--- a/compiler/rustc_monomorphize/src/lib.rs
+++ b/compiler/rustc_monomorphize/src/lib.rs
@@ -1,5 +1,7 @@
 // tidy-alphabetical-start
 #![feature(array_windows)]
+#![feature(if_let_guard)]
+#![feature(let_chains)]
 #![warn(unreachable_pub)]
 // tidy-alphabetical-end
 
diff --git a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
index c7a9846cd97..17b6ec7e2bb 100644
--- a/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/normalizes_to/mod.rs
@@ -3,7 +3,7 @@ mod inherent;
 mod opaque_types;
 mod weak_types;
 
-use rustc_type_ir::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_type_ir::fast_reject::DeepRejectCtxt;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
 use rustc_type_ir::{self as ty, Interner, NormalizesTo, Upcast as _};
@@ -106,6 +106,12 @@ where
         if let Some(projection_pred) = assumption.as_projection_clause() {
             if projection_pred.projection_def_id() == goal.predicate.def_id() {
                 let cx = ecx.cx();
+                if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                    goal.predicate.alias.args,
+                    projection_pred.skip_binder().projection_term.args,
+                ) {
+                    return Err(NoSolution);
+                }
                 ecx.probe_trait_candidate(source).enter(|ecx| {
                     let assumption_projection_pred =
                         ecx.instantiate_binder_with_infer(projection_pred);
@@ -144,7 +150,7 @@ where
 
         let goal_trait_ref = goal.predicate.alias.trait_ref(cx);
         let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
-        if !DeepRejectCtxt::new(ecx.cx(), TreatParams::ForLookup).args_may_unify(
+        if !DeepRejectCtxt::relate_rigid_infer(ecx.cx()).args_may_unify(
             goal.predicate.alias.trait_ref(cx).args,
             impl_trait_ref.skip_binder().args,
         ) {
diff --git a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
index 67b001d0cce..683d8dab3b2 100644
--- a/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
+++ b/compiler/rustc_next_trait_solver/src/solve/trait_goals.rs
@@ -2,7 +2,7 @@
 
 use rustc_ast_ir::Movability;
 use rustc_type_ir::data_structures::IndexSet;
-use rustc_type_ir::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_type_ir::fast_reject::DeepRejectCtxt;
 use rustc_type_ir::inherent::*;
 use rustc_type_ir::lang_items::TraitSolverLangItem;
 use rustc_type_ir::visit::TypeVisitableExt as _;
@@ -47,7 +47,7 @@ where
         let cx = ecx.cx();
 
         let impl_trait_ref = cx.impl_trait_ref(impl_def_id);
-        if !DeepRejectCtxt::new(ecx.cx(), TreatParams::ForLookup)
+        if !DeepRejectCtxt::relate_rigid_infer(ecx.cx())
             .args_may_unify(goal.predicate.trait_ref.args, impl_trait_ref.skip_binder().args)
         {
             return Err(NoSolution);
@@ -124,6 +124,13 @@ where
             if trait_clause.def_id() == goal.predicate.def_id()
                 && trait_clause.polarity() == goal.predicate.polarity
             {
+                if !DeepRejectCtxt::relate_rigid_rigid(ecx.cx()).args_may_unify(
+                    goal.predicate.trait_ref.args,
+                    trait_clause.skip_binder().trait_ref.args,
+                ) {
+                    return Err(NoSolution);
+                }
+
                 ecx.probe_trait_candidate(source).enter(|ecx| {
                     let assumption_trait_pred = ecx.instantiate_binder_with_infer(trait_clause);
                     ecx.eq(
diff --git a/compiler/rustc_parse/messages.ftl b/compiler/rustc_parse/messages.ftl
index 8e8d91ce4d0..ec9a676ea31 100644
--- a/compiler/rustc_parse/messages.ftl
+++ b/compiler/rustc_parse/messages.ftl
@@ -381,6 +381,7 @@ parse_invalid_char_in_escape_msg = invalid character in {$is_hex ->
     *[false] unicode
     } escape
 
+
 parse_invalid_comparison_operator = invalid comparison operator `{$invalid}`
     .use_instead = `{$invalid}` is not a valid comparison operator, use `{$correct}`
     .spaceship_operator_invalid = `<=>` is not a valid comparison operator, use `std::cmp::Ordering`
@@ -581,6 +582,11 @@ parse_missing_trait_in_trait_impl = missing trait in a trait impl
     .suggestion_add_trait = add a trait here
     .suggestion_remove_for = for an inherent impl, drop this `for`
 
+parse_misspelled_kw = {$is_incorrect_case ->
+                    [true] write keyword `{$similar_kw}` in lowercase
+                    *[false] there is a keyword `{$similar_kw}` with a similar name
+}
+
 parse_modifier_lifetime = `{$modifier}` may only modify trait bounds, not lifetime bounds
     .suggestion = remove the `{$modifier}`
 
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index f30939093c2..b7232ff21ca 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -13,7 +13,6 @@ use rustc_session::lint::builtin::{
 };
 use rustc_session::lint::BuiltinLintDiag;
 use rustc_session::parse::ParseSess;
-use rustc_span::edition::Edition;
 use rustc_span::symbol::Symbol;
 use rustc_span::{BytePos, Pos, Span};
 use tracing::debug;
@@ -188,9 +187,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                     preceded_by_whitespace = true;
                     continue;
                 }
-                rustc_lexer::TokenKind::Ident => {
-                    self.ident(start)
-                }
+                rustc_lexer::TokenKind::Ident => self.ident(start),
                 rustc_lexer::TokenKind::RawIdent => {
                     let sym = nfc_normalize(self.str_from(start + BytePos(2)));
                     let span = self.mk_sp(start, self.pos);
@@ -205,20 +202,31 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                     self.report_unknown_prefix(start);
                     self.ident(start)
                 }
-                rustc_lexer::TokenKind::InvalidIdent
-                | rustc_lexer::TokenKind::InvalidPrefix
+                rustc_lexer::TokenKind::UnknownPrefixLifetime => {
+                    self.report_unknown_prefix(start);
+                    // Include the leading `'` in the real identifier, for macro
+                    // expansion purposes. See #12512 for the gory details of why
+                    // this is necessary.
+                    let lifetime_name = self.str_from(start);
+                    self.last_lifetime = Some(self.mk_sp(start, start + BytePos(1)));
+                    let ident = Symbol::intern(lifetime_name);
+                    token::Lifetime(ident, IdentIsRaw::No)
+                }
+                rustc_lexer::TokenKind::InvalidIdent | rustc_lexer::TokenKind::InvalidPrefix
                     // Do not recover an identifier with emoji if the codepoint is a confusable
                     // with a recoverable substitution token, like `âž–`.
-                    if !UNICODE_ARRAY
-                        .iter()
-                        .any(|&(c, _, _)| {
-                            let sym = self.str_from(start);
-                            sym.chars().count() == 1 && c == sym.chars().next().unwrap()
-                        }) =>
+                    if !UNICODE_ARRAY.iter().any(|&(c, _, _)| {
+                        let sym = self.str_from(start);
+                        sym.chars().count() == 1 && c == sym.chars().next().unwrap()
+                    }) =>
                 {
                     let sym = nfc_normalize(self.str_from(start));
                     let span = self.mk_sp(start, self.pos);
-                    self.psess.bad_unicode_identifiers.borrow_mut().entry(sym).or_default()
+                    self.psess
+                        .bad_unicode_identifiers
+                        .borrow_mut()
+                        .entry(sym)
+                        .or_default()
                         .push(span);
                     token::Ident(sym, IdentIsRaw::No)
                 }
@@ -249,9 +257,9 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                     let suffix = if suffix_start < self.pos {
                         let string = self.str_from(suffix_start);
                         if string == "_" {
-                            self
-                                .dcx()
-                                .emit_err(errors::UnderscoreLiteralSuffix { span: self.mk_sp(suffix_start, self.pos) });
+                            self.dcx().emit_err(errors::UnderscoreLiteralSuffix {
+                                span: self.mk_sp(suffix_start, self.pos),
+                            });
                             None
                         } else {
                             Some(Symbol::intern(string))
@@ -269,12 +277,47 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                     self.last_lifetime = Some(self.mk_sp(start, start + BytePos(1)));
                     if starts_with_number {
                         let span = self.mk_sp(start, self.pos);
-                        self.dcx().struct_err("lifetimes cannot start with a number")
+                        self.dcx()
+                            .struct_err("lifetimes cannot start with a number")
                             .with_span(span)
                             .stash(span, StashKey::LifetimeIsChar);
                     }
                     let ident = Symbol::intern(lifetime_name);
-                    token::Lifetime(ident)
+                    token::Lifetime(ident, IdentIsRaw::No)
+                }
+                rustc_lexer::TokenKind::RawLifetime => {
+                    self.last_lifetime = Some(self.mk_sp(start, start + BytePos(1)));
+
+                    let ident_start = start + BytePos(3);
+                    let prefix_span = self.mk_sp(start, ident_start);
+
+                    if prefix_span.at_least_rust_2021() {
+                        let lifetime_name_without_tick = self.str_from(ident_start);
+                        // Put the `'` back onto the lifetime name.
+                        let mut lifetime_name = String::with_capacity(lifetime_name_without_tick.len() + 1);
+                        lifetime_name.push('\'');
+                        lifetime_name += lifetime_name_without_tick;
+                        let sym = Symbol::intern(&lifetime_name);
+
+                        token::Lifetime(sym, IdentIsRaw::Yes)
+                    } else {
+                        // Otherwise, this should be parsed like `'r`. Warn about it though.
+                        self.psess.buffer_lint(
+                            RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX,
+                            prefix_span,
+                            ast::CRATE_NODE_ID,
+                            BuiltinLintDiag::RawPrefix(prefix_span),
+                        );
+
+                        // Reset the state so we just lex the `'r`.
+                        let lt_start = start + BytePos(2);
+                        self.pos = lt_start;
+                        self.cursor = Cursor::new(&str_before[2 as usize..]);
+
+                        let lifetime_name = self.str_from(start);
+                        let ident = Symbol::intern(lifetime_name);
+                        token::Lifetime(ident, IdentIsRaw::No)
+                    }
                 }
                 rustc_lexer::TokenKind::Semi => token::Semi,
                 rustc_lexer::TokenKind::Comma => token::Comma,
@@ -331,16 +374,19 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
                     // first remove compound tokens like `<<` from `rustc_lexer`, and then add
                     // fancier error recovery to it, as there will be less overall work to do this
                     // way.
-                    let (token, sugg) = unicode_chars::check_for_substitution(self, start, c, repeats+1);
+                    let (token, sugg) =
+                        unicode_chars::check_for_substitution(self, start, c, repeats + 1);
                     self.dcx().emit_err(errors::UnknownTokenStart {
                         span: self.mk_sp(start, self.pos + Pos::from_usize(repeats * c.len_utf8())),
                         escaped: escaped_char(c),
                         sugg,
-                        null: if c == '\x00' {Some(errors::UnknownTokenNull)} else {None},
+                        null: if c == '\x00' { Some(errors::UnknownTokenNull) } else { None },
                         repeat: if repeats > 0 {
                             swallow_next_invalid = repeats;
                             Some(errors::UnknownTokenRepeat { repeats })
-                        } else {None}
+                        } else {
+                            None
+                        },
                     });
 
                     if let Some(token) = token {
@@ -699,7 +745,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> {
 
         let expn_data = prefix_span.ctxt().outer_expn_data();
 
-        if expn_data.edition >= Edition::Edition2021 {
+        if expn_data.edition.at_least_rust_2021() {
             // In Rust 2021, this is a hard error.
             let sugg = if prefix == "rb" {
                 Some(errors::UnknownPrefixSugg::UseBr(prefix_span))
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index fcdc10c0837..f6f66821df7 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -19,8 +19,9 @@ use rustc_errors::{
     Subdiagnostic,
 };
 use rustc_session::errors::ExprParenthesesNeeded;
+use rustc_span::edit_distance::find_best_match_for_name;
 use rustc_span::source_map::Spanned;
-use rustc_span::symbol::{kw, sym, Ident};
+use rustc_span::symbol::{kw, sym, AllKeywords, Ident};
 use rustc_span::{BytePos, Span, SpanSnippetError, Symbol, DUMMY_SP};
 use thin_vec::{thin_vec, ThinVec};
 use tracing::{debug, trace};
@@ -203,6 +204,37 @@ impl std::fmt::Display for UnaryFixity {
     }
 }
 
+#[derive(Debug, rustc_macros::Subdiagnostic)]
+#[suggestion(
+    parse_misspelled_kw,
+    applicability = "machine-applicable",
+    code = "{similar_kw}",
+    style = "verbose"
+)]
+struct MisspelledKw {
+    similar_kw: String,
+    #[primary_span]
+    span: Span,
+    is_incorrect_case: bool,
+}
+
+/// Checks if the given `lookup` identifier is similar to any keyword symbol in `candidates`.
+fn find_similar_kw(lookup: Ident, candidates: &[Symbol]) -> Option<MisspelledKw> {
+    let lowercase = lookup.name.as_str().to_lowercase();
+    let lowercase_sym = Symbol::intern(&lowercase);
+    if candidates.contains(&lowercase_sym) {
+        Some(MisspelledKw { similar_kw: lowercase, span: lookup.span, is_incorrect_case: true })
+    } else if let Some(similar_sym) = find_best_match_for_name(candidates, lookup.name, None) {
+        Some(MisspelledKw {
+            similar_kw: similar_sym.to_string(),
+            span: lookup.span,
+            is_incorrect_case: false,
+        })
+    } else {
+        None
+    }
+}
+
 struct MultiSugg {
     msg: String,
     patches: Vec<(Span, String)>,
@@ -638,9 +670,9 @@ impl<'a> Parser<'a> {
             let concat = Symbol::intern(&format!("{prev}{cur}"));
             let ident = Ident::new(concat, DUMMY_SP);
             if ident.is_used_keyword() || ident.is_reserved() || ident.is_raw_guess() {
-                let span = self.prev_token.span.to(self.token.span);
+                let concat_span = self.prev_token.span.to(self.token.span);
                 err.span_suggestion_verbose(
-                    span,
+                    concat_span,
                     format!("consider removing the space to spell keyword `{concat}`"),
                     concat,
                     Applicability::MachineApplicable,
@@ -741,9 +773,55 @@ impl<'a> Parser<'a> {
             err.span_label(sp, label_exp);
             err.span_label(self.token.span, "unexpected token");
         }
+
+        // Check for misspelled keywords if there are no suggestions added to the diagnostic.
+        if err.suggestions.as_ref().is_ok_and(|code_suggestions| code_suggestions.is_empty()) {
+            self.check_for_misspelled_kw(&mut err, &expected);
+        }
         Err(err)
     }
 
+    /// Checks if the current token or the previous token are misspelled keywords
+    /// and adds a helpful suggestion.
+    fn check_for_misspelled_kw(&self, err: &mut Diag<'_>, expected: &[TokenType]) {
+        let Some((curr_ident, _)) = self.token.ident() else {
+            return;
+        };
+        let expected_tokens: &[TokenType] =
+            expected.len().checked_sub(10).map_or(&expected, |index| &expected[index..]);
+        let expected_keywords: Vec<Symbol> = expected_tokens
+            .iter()
+            .filter_map(|token| if let TokenType::Keyword(kw) = token { Some(*kw) } else { None })
+            .collect();
+
+        // When there are a few keywords in the last ten elements of `self.expected_tokens` and the current
+        // token is an identifier, it's probably a misspelled keyword.
+        // This handles code like `async Move {}`, misspelled `if` in match guard, misspelled `else` in `if`-`else`
+        // and mispelled `where` in a where clause.
+        if !expected_keywords.is_empty()
+            && !curr_ident.is_used_keyword()
+            && let Some(misspelled_kw) = find_similar_kw(curr_ident, &expected_keywords)
+        {
+            err.subdiagnostic(misspelled_kw);
+        } else if let Some((prev_ident, _)) = self.prev_token.ident()
+            && !prev_ident.is_used_keyword()
+        {
+            // We generate a list of all keywords at runtime rather than at compile time
+            // so that it gets generated only when the diagnostic needs it.
+            // Also, it is unlikely that this list is generated multiple times because the
+            // parser halts after execution hits this path.
+            let all_keywords = AllKeywords::new().collect_used(|| prev_ident.span.edition());
+
+            // Otherwise, check the previous token with all the keywords as possible candidates.
+            // This handles code like `Struct Human;` and `While a < b {}`.
+            // We check the previous token only when the current token is an identifier to avoid false
+            // positives like suggesting keyword `for` for `extern crate foo {}`.
+            if let Some(misspelled_kw) = find_similar_kw(prev_ident, &all_keywords) {
+                err.subdiagnostic(misspelled_kw);
+            }
+        }
+    }
+
     /// 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.
@@ -846,6 +924,7 @@ impl<'a> Parser<'a> {
                 );
             }
         }
+
         err.emit()
     }
 
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 84684e808d9..ecc4cd96faf 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2050,7 +2050,7 @@ impl<'a> Parser<'a> {
         };
         // On an error path, eagerly consider a lifetime to be an unclosed character lit, if that
         // makes sense.
-        if let Some(ident) = self.token.lifetime()
+        if let Some((ident, IdentIsRaw::No)) = self.token.lifetime()
             && could_be_unclosed_char_literal(ident)
         {
             let lt = self.expect_lifetime();
@@ -2925,9 +2925,9 @@ impl<'a> Parser<'a> {
     }
 
     pub(crate) fn eat_label(&mut self) -> Option<Label> {
-        if let Some(ident) = self.token.lifetime() {
+        if let Some((ident, is_raw)) = self.token.lifetime() {
             // Disallow `'fn`, but with a better error message than `expect_lifetime`.
-            if ident.without_first_quote().is_reserved() {
+            if matches!(is_raw, IdentIsRaw::No) && ident.without_first_quote().is_reserved() {
                 self.dcx().emit_err(errors::InvalidLabel { span: ident.span, name: ident.name });
             }
 
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 61e3fa2e6c5..b90c41d9163 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1666,7 +1666,7 @@ enum FlatToken {
 pub enum ParseNtResult {
     Tt(TokenTree),
     Ident(Ident, IdentIsRaw),
-    Lifetime(Ident),
+    Lifetime(Ident, IdentIsRaw),
 
     /// This case will eventually be removed, along with `Token::Interpolate`.
     Nt(Lrc<Nonterminal>),
diff --git a/compiler/rustc_parse/src/parser/nonterminal.rs b/compiler/rustc_parse/src/parser/nonterminal.rs
index e66d0df012b..44b169c881e 100644
--- a/compiler/rustc_parse/src/parser/nonterminal.rs
+++ b/compiler/rustc_parse/src/parser/nonterminal.rs
@@ -88,7 +88,7 @@ impl<'a> Parser<'a> {
             },
             NonterminalKind::Pat(pat_kind) => token.can_begin_pattern(pat_kind),
             NonterminalKind::Lifetime => match &token.kind {
-                token::Lifetime(_) | token::NtLifetime(..) => true,
+                token::Lifetime(..) | token::NtLifetime(..) => true,
                 _ => false,
             },
             NonterminalKind::TT | NonterminalKind::Item | NonterminalKind::Stmt => {
@@ -171,9 +171,9 @@ impl<'a> Parser<'a> {
             NonterminalKind::Lifetime => {
                 // We want to keep `'keyword` parsing, just like `keyword` is still
                 // an ident for nonterminal purposes.
-                return if let Some(ident) = self.token.lifetime() {
+                return if let Some((ident, is_raw)) = self.token.lifetime() {
                     self.bump();
-                    Ok(ParseNtResult::Lifetime(ident))
+                    Ok(ParseNtResult::Lifetime(ident, is_raw))
                 } else {
                     Err(self.dcx().create_err(UnexpectedNonterminal::Lifetime {
                         span: self.token.span,
diff --git a/compiler/rustc_parse/src/parser/pat.rs b/compiler/rustc_parse/src/parser/pat.rs
index f87b5649654..cbd35ffdfa9 100644
--- a/compiler/rustc_parse/src/parser/pat.rs
+++ b/compiler/rustc_parse/src/parser/pat.rs
@@ -1,6 +1,6 @@
 use rustc_ast::mut_visit::{walk_pat, MutVisitor};
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, BinOpToken, Delimiter, Token};
+use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token};
 use rustc_ast::{
     self as ast, AttrVec, BindingMode, ByRef, Expr, ExprKind, MacCall, Mutability, Pat, PatField,
     PatFieldsRest, PatKind, Path, QSelf, RangeEnd, RangeSyntax,
@@ -548,7 +548,7 @@ impl<'a> Parser<'a> {
                     None => PatKind::Path(qself, path),
                 }
             }
-        } else if let Some(lt) = self.token.lifetime()
+        } else if let Some((lt, IdentIsRaw::No)) = self.token.lifetime()
             // In pattern position, we're totally fine with using "next token isn't colon"
             // as a heuristic. We could probably just always try to recover if it's a lifetime,
             // because we never have `'a: label {}` in a pattern position anyways, but it does
@@ -689,7 +689,7 @@ impl<'a> Parser<'a> {
     /// Parse `&pat` / `&mut pat`.
     fn parse_pat_deref(&mut self, expected: Option<Expected>) -> PResult<'a, PatKind> {
         self.expect_and()?;
-        if let Some(lifetime) = self.token.lifetime() {
+        if let Some((lifetime, _)) = self.token.lifetime() {
             self.bump(); // `'a`
 
             self.dcx().emit_err(UnexpectedLifetimeInPattern {
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 52f0b1c1b04..dd1cc75c7ff 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -1,5 +1,5 @@
 use rustc_ast::ptr::P;
-use rustc_ast::token::{self, BinOpToken, Delimiter, Token, TokenKind};
+use rustc_ast::token::{self, BinOpToken, Delimiter, IdentIsRaw, Token, TokenKind};
 use rustc_ast::util::case::Case;
 use rustc_ast::{
     self as ast, BareFnTy, BoundAsyncness, BoundConstness, BoundPolarity, FnRetTy, GenericBound,
@@ -1285,8 +1285,9 @@ impl<'a> Parser<'a> {
 
     /// Parses a single lifetime `'a` or panics.
     pub(super) fn expect_lifetime(&mut self) -> Lifetime {
-        if let Some(ident) = self.token.lifetime() {
-            if ident.without_first_quote().is_reserved()
+        if let Some((ident, is_raw)) = self.token.lifetime() {
+            if matches!(is_raw, IdentIsRaw::No)
+                && ident.without_first_quote().is_reserved()
                 && ![kw::UnderscoreLifetime, kw::StaticLifetime].contains(&ident.name)
             {
                 self.dcx().emit_err(errors::KeywordLifetime { span: ident.span });
diff --git a/compiler/rustc_passes/src/check_attr.rs b/compiler/rustc_passes/src/check_attr.rs
index 21478a44b0e..e41f89a3c9d 100644
--- a/compiler/rustc_passes/src/check_attr.rs
+++ b/compiler/rustc_passes/src/check_attr.rs
@@ -125,7 +125,9 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                 [sym::inline, ..] => self.check_inline(hir_id, attr, span, target),
                 [sym::coverage, ..] => self.check_coverage(attr, span, target),
                 [sym::optimize, ..] => self.check_optimize(hir_id, attr, target),
-                [sym::no_sanitize, ..] => self.check_no_sanitize(hir_id, attr, span, target),
+                [sym::no_sanitize, ..] => {
+                    self.check_applied_to_fn_or_method(hir_id, attr, span, target)
+                }
                 [sym::non_exhaustive, ..] => self.check_non_exhaustive(hir_id, attr, span, target),
                 [sym::marker, ..] => self.check_marker(hir_id, attr, span, target),
                 [sym::target_feature, ..] => {
@@ -166,10 +168,13 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
                     self.check_rustc_legacy_const_generics(hir_id, attr, span, target, item)
                 }
                 [sym::rustc_lint_query_instability, ..] => {
-                    self.check_rustc_lint_query_instability(hir_id, attr, span, target)
+                    self.check_applied_to_fn_or_method(hir_id, attr, span, target)
+                }
+                [sym::rustc_lint_untracked_query_information, ..] => {
+                    self.check_applied_to_fn_or_method(hir_id, attr, span, target)
                 }
                 [sym::rustc_lint_diagnostics, ..] => {
-                    self.check_rustc_lint_diagnostics(hir_id, attr, span, target)
+                    self.check_applied_to_fn_or_method(hir_id, attr, span, target)
                 }
                 [sym::rustc_lint_opt_ty, ..] => self.check_rustc_lint_opt_ty(attr, span, target),
                 [sym::rustc_lint_opt_deny_field_access, ..] => {
@@ -452,11 +457,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Checks that `#[no_sanitize(..)]` is applied to a function or method.
-    fn check_no_sanitize(&self, hir_id: HirId, attr: &Attribute, span: Span, target: Target) {
-        self.check_applied_to_fn_or_method(hir_id, attr, span, target)
-    }
-
     fn check_generic_attr(
         &self,
         hir_id: HirId,
@@ -1635,30 +1635,6 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
         }
     }
 
-    /// Checks that the `#[rustc_lint_query_instability]` attribute is only applied to a function
-    /// or method.
-    fn check_rustc_lint_query_instability(
-        &self,
-        hir_id: HirId,
-        attr: &Attribute,
-        span: Span,
-        target: Target,
-    ) {
-        self.check_applied_to_fn_or_method(hir_id, attr, span, target)
-    }
-
-    /// Checks that the `#[rustc_lint_diagnostics]` attribute is only applied to a function or
-    /// method.
-    fn check_rustc_lint_diagnostics(
-        &self,
-        hir_id: HirId,
-        attr: &Attribute,
-        span: Span,
-        target: Target,
-    ) {
-        self.check_applied_to_fn_or_method(hir_id, attr, span, target)
-    }
-
     /// Checks that the `#[rustc_lint_opt_ty]` attribute is only applied to a struct.
     fn check_rustc_lint_opt_ty(&self, attr: &Attribute, span: Span, target: Target) {
         match target {
diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs
index 79c42456cf8..917cb81aa51 100644
--- a/compiler/rustc_resolve/src/late.rs
+++ b/compiler/rustc_resolve/src/late.rs
@@ -2062,7 +2062,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                                 lint::builtin::ELIDED_NAMED_LIFETIMES,
                                 missing.id_for_lint,
                                 missing.span,
-                                BuiltinLintDiag::ElidedIsStatic { elided: missing.span },
+                                BuiltinLintDiag::ElidedNamedLifetimes {
+                                    elided: (missing.span, missing.kind),
+                                    resolution: lint::ElidedLifetimeResolution::Static,
+                                },
                             );
                         }
                     }
@@ -2072,9 +2075,12 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> {
                             lint::builtin::ELIDED_NAMED_LIFETIMES,
                             missing.id_for_lint,
                             missing.span,
-                            BuiltinLintDiag::ElidedIsParam {
-                                elided: missing.span,
-                                param: (tcx.item_name(param.into()), tcx.source_span(param)),
+                            BuiltinLintDiag::ElidedNamedLifetimes {
+                                elided: (missing.span, missing.kind),
+                                resolution: lint::ElidedLifetimeResolution::Param(
+                                    tcx.item_name(param.into()),
+                                    tcx.source_span(param),
+                                ),
                             },
                         );
                     }
diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs
index 908d50a041e..f3e3b36111c 100644
--- a/compiler/rustc_session/src/config.rs
+++ b/compiler/rustc_session/src/config.rs
@@ -842,6 +842,11 @@ pub struct NextSolverConfig {
     /// This is only `true` if `coherence` is also enabled.
     pub globally: bool,
 }
+impl Default for NextSolverConfig {
+    fn default() -> Self {
+        NextSolverConfig { coherence: true, globally: false }
+    }
+}
 
 #[derive(Clone)]
 pub enum Input {
diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs
index 45339c23ea3..a57dc80b316 100644
--- a/compiler/rustc_session/src/options.rs
+++ b/compiler/rustc_session/src/options.rs
@@ -403,7 +403,7 @@ mod desc {
     pub(crate) const parse_unpretty: &str = "`string` or `string=string`";
     pub(crate) const parse_treat_err_as_bug: &str = "either no value or a non-negative number";
     pub(crate) const parse_next_solver_config: &str =
-        "a comma separated list of solver configurations: `globally` (default), and `coherence`";
+        "either `globally` (when used without an argument), `coherence` (default) or `no`";
     pub(crate) const parse_lto: &str =
         "either a boolean (`yes`, `no`, `on`, `off`, etc), `thin`, `fat`, or omitted";
     pub(crate) const parse_linker_plugin_lto: &str =
@@ -1105,27 +1105,16 @@ mod parse {
         }
     }
 
-    pub(crate) fn parse_next_solver_config(
-        slot: &mut Option<NextSolverConfig>,
-        v: Option<&str>,
-    ) -> bool {
+    pub(crate) fn parse_next_solver_config(slot: &mut NextSolverConfig, v: Option<&str>) -> bool {
         if let Some(config) = v {
-            let mut coherence = false;
-            let mut globally = true;
-            for c in config.split(',') {
-                match c {
-                    "globally" => globally = true,
-                    "coherence" => {
-                        globally = false;
-                        coherence = true;
-                    }
-                    _ => return false,
-                }
-            }
-
-            *slot = Some(NextSolverConfig { coherence: coherence || globally, globally });
+            *slot = match config {
+                "no" => NextSolverConfig { coherence: false, globally: false },
+                "coherence" => NextSolverConfig { coherence: true, globally: false },
+                "globally" => NextSolverConfig { coherence: true, globally: true },
+                _ => return false,
+            };
         } else {
-            *slot = Some(NextSolverConfig { coherence: true, globally: true });
+            *slot = NextSolverConfig { coherence: true, globally: true };
         }
 
         true
@@ -1878,7 +1867,7 @@ options! {
         "the size at which the `large_assignments` lint starts to be emitted"),
     mutable_noalias: bool = (true, parse_bool, [TRACKED],
         "emit noalias metadata for mutable references (default: yes)"),
-    next_solver: Option<NextSolverConfig> = (None, parse_next_solver_config, [TRACKED],
+    next_solver: NextSolverConfig = (NextSolverConfig::default(), parse_next_solver_config, [TRACKED],
         "enable and configure the next generation trait solver used by rustc"),
     nll_facts: bool = (false, parse_bool, [UNTRACKED],
         "dump facts from NLL analysis into side files (default: no)"),
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 36b31d10c4d..7572d57309c 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -20,7 +20,8 @@ mod tests;
 
 // The proc macro code for this is in `compiler/rustc_macros/src/symbols.rs`.
 symbols! {
-    // If you modify this list, adjust `is_special` and `is_used_keyword`/`is_unused_keyword`.
+    // If you modify this list, adjust `is_special`, `is_used_keyword`/`is_unused_keyword`
+    // and `AllKeywords`.
     // But this should rarely be necessary if the keywords are kept in alphabetic order.
     Keywords {
         // Special reserved identifiers used internally for elided lifetimes,
@@ -1654,6 +1655,7 @@ symbols! {
         rustc_lint_opt_deny_field_access,
         rustc_lint_opt_ty,
         rustc_lint_query_instability,
+        rustc_lint_untracked_query_information,
         rustc_macro_transparency,
         rustc_main,
         rustc_mir,
@@ -2578,3 +2580,42 @@ impl Ident {
         self.name.can_be_raw() && self.is_reserved()
     }
 }
+
+/// An iterator over all the keywords in Rust.
+#[derive(Copy, Clone)]
+pub struct AllKeywords {
+    curr_idx: u32,
+    end_idx: u32,
+}
+
+impl AllKeywords {
+    /// Initialize a new iterator over all the keywords.
+    ///
+    /// *Note:* Please update this if a new keyword is added beyond the current
+    /// range.
+    pub fn new() -> Self {
+        AllKeywords { curr_idx: kw::Empty.as_u32(), end_idx: kw::Yeet.as_u32() }
+    }
+
+    /// Collect all the keywords in a given edition into a vector.
+    pub fn collect_used(&self, edition: impl Copy + FnOnce() -> Edition) -> Vec<Symbol> {
+        self.filter(|&keyword| {
+            keyword.is_used_keyword_always() || keyword.is_used_keyword_conditional(edition)
+        })
+        .collect()
+    }
+}
+
+impl Iterator for AllKeywords {
+    type Item = Symbol;
+
+    fn next(&mut self) -> Option<Self::Item> {
+        if self.curr_idx <= self.end_idx {
+            let keyword = Symbol::new(self.curr_idx);
+            self.curr_idx += 1;
+            Some(keyword)
+        } else {
+            None
+        }
+    }
+}
diff --git a/compiler/rustc_target/src/spec/base/apple/mod.rs b/compiler/rustc_target/src/spec/base/apple/mod.rs
index b752a344395..b1fe49f76ca 100644
--- a/compiler/rustc_target/src/spec/base/apple/mod.rs
+++ b/compiler/rustc_target/src/spec/base/apple/mod.rs
@@ -1,5 +1,6 @@
 use std::borrow::Cow;
 use std::env;
+use std::num::ParseIntError;
 
 use crate::spec::{
     add_link_args, add_link_args_iter, cvs, Cc, DebuginfoKind, FramePointer, LinkArgs,
@@ -39,6 +40,25 @@ impl Arch {
         }
     }
 
+    /// The architecture name to forward to the linker.
+    fn ld_arch(self) -> &'static str {
+        // Supported architecture names can be found in the source:
+        // https://github.com/apple-oss-distributions/ld64/blob/ld64-951.9/src/abstraction/MachOFileAbstraction.hpp#L578-L648
+        match self {
+            Armv7k => "armv7k",
+            Armv7s => "armv7s",
+            Arm64 => "arm64",
+            Arm64e => "arm64e",
+            Arm64_32 => "arm64_32",
+            // ld64 doesn't understand i686, so fall back to i386 instead
+            //
+            // Same story when linking with cc, since that ends up invoking ld64.
+            I386 | I686 => "i386",
+            X86_64 => "x86_64",
+            X86_64h => "x86_64h",
+        }
+    }
+
     pub(crate) fn target_arch(self) -> Cow<'static, str> {
         Cow::Borrowed(match self {
             Armv7k | Armv7s => "arm",
@@ -97,53 +117,85 @@ impl TargetAbi {
 }
 
 fn pre_link_args(os: &'static str, arch: Arch, abi: TargetAbi) -> LinkArgs {
+    // From the man page for ld64 (`man ld`):
+    // > The linker accepts universal (multiple-architecture) input files,
+    // > but always creates a "thin" (single-architecture), standard Mach-O
+    // > output file. The architecture for the output file is specified using
+    // > the -arch option.
+    //
+    // The linker has heuristics to determine the desired architecture, but to
+    // be safe, and to avoid a warning, we set the architecture explicitly.
+    let mut args =
+        TargetOptions::link_args(LinkerFlavor::Darwin(Cc::No, Lld::No), &["-arch", arch.ld_arch()]);
+
+    // From the man page for ld64 (`man ld`):
+    // > This is set to indicate the platform, oldest supported version of
+    // > that platform that output is to be used on, and the SDK that the
+    // > output was built against. platform [...] may be one of the following
+    // > strings:
+    // > - macos
+    // > - ios
+    // > - tvos
+    // > - watchos
+    // > - bridgeos
+    // > - visionos
+    // > - xros
+    // > - mac-catalyst
+    // > - ios-simulator
+    // > - tvos-simulator
+    // > - watchos-simulator
+    // > - visionos-simulator
+    // > - xros-simulator
+    // > - driverkit
+    //
+    // Like with `-arch`, the linker can figure out the platform versions
+    // itself from the binaries being linked, but to be safe, we specify the
+    // desired versions here explicitly.
     let platform_name: StaticCow<str> = match abi {
         TargetAbi::Normal => os.into(),
         TargetAbi::Simulator => format!("{os}-simulator").into(),
         TargetAbi::MacCatalyst => "mac-catalyst".into(),
     };
-
     let min_version: StaticCow<str> = {
-        let (major, minor) = match os {
-            "ios" => ios_deployment_target(arch, abi.target_abi()),
-            "tvos" => tvos_deployment_target(),
-            "watchos" => watchos_deployment_target(),
-            "visionos" => visionos_deployment_target(),
-            "macos" => macos_deployment_target(arch),
-            _ => unreachable!(),
-        };
-        format!("{major}.{minor}").into()
+        let (major, minor, patch) = deployment_target(os, arch, abi);
+        format!("{major}.{minor}.{patch}").into()
     };
+    // Lie about the SDK version, we don't know it here
     let sdk_version = min_version.clone();
-
-    let mut args = TargetOptions::link_args(
-        LinkerFlavor::Darwin(Cc::No, Lld::No),
-        &["-arch", arch.target_name(), "-platform_version"],
-    );
     add_link_args_iter(
         &mut args,
         LinkerFlavor::Darwin(Cc::No, Lld::No),
-        [platform_name, min_version, sdk_version].into_iter(),
+        ["-platform_version".into(), platform_name, min_version, sdk_version].into_iter(),
     );
+
     if abi != TargetAbi::MacCatalyst {
+        // CC forwards the `-arch` to the linker, so we use the same value
+        // here intentionally.
         add_link_args(
             &mut args,
             LinkerFlavor::Darwin(Cc::Yes, Lld::No),
-            &["-arch", arch.target_name()],
+            &["-arch", arch.ld_arch()],
         );
     } else {
         add_link_args_iter(
             &mut args,
             LinkerFlavor::Darwin(Cc::Yes, Lld::No),
-            ["-target".into(), mac_catalyst_llvm_target(arch).into()].into_iter(),
+            ["-target".into(), llvm_target(os, arch, abi)].into_iter(),
         );
     }
 
     args
 }
 
-pub(crate) fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOptions {
-    TargetOptions {
+/// Get the base target options, LLVM target and `target_arch` from the three
+/// things that uniquely identify Rust's Apple targets: The OS, the
+/// architecture, and the ABI.
+pub(crate) fn base(
+    os: &'static str,
+    arch: Arch,
+    abi: TargetAbi,
+) -> (TargetOptions, StaticCow<str>, StaticCow<str>) {
+    let opts = TargetOptions {
         abi: abi.target_abi().into(),
         os: os.into(),
         cpu: arch.target_cpu(abi).into(),
@@ -193,10 +245,11 @@ pub(crate) fn opts(os: &'static str, arch: Arch, abi: TargetAbi) -> TargetOption
         link_env: Cow::Borrowed(&[(Cow::Borrowed("ZERO_AR_DATE"), Cow::Borrowed("1"))]),
 
         ..Default::default()
-    }
+    };
+    (opts, llvm_target(os, arch, abi), arch.target_arch())
 }
 
-pub fn sdk_version(platform: u32) -> Option<(u32, u32)> {
+pub fn sdk_version(platform: u32) -> Option<(u16, u8)> {
     // NOTE: These values are from an arbitrary point in time but shouldn't make it into the final
     // binary since the final link command will have the current SDK version passed to it.
     match platform {
@@ -230,58 +283,108 @@ pub fn platform(target: &Target) -> Option<u32> {
     })
 }
 
-pub fn deployment_target(target: &Target) -> Option<(u32, u32)> {
-    let (major, minor) = match &*target.os {
-        "macos" => {
-            // This does not need to be specific. It just needs to handle x86 vs M1.
-            let arch = match target.arch.as_ref() {
-                "x86" | "x86_64" => X86_64,
-                "arm64e" => Arm64e,
-                _ => Arm64,
-            };
-            macos_deployment_target(arch)
-        }
-        "ios" => {
-            let arch = match target.arch.as_ref() {
-                "arm64e" => Arm64e,
-                _ => Arm64,
-            };
-            ios_deployment_target(arch, &target.abi)
-        }
-        "watchos" => watchos_deployment_target(),
-        "tvos" => tvos_deployment_target(),
-        "visionos" => visionos_deployment_target(),
-        _ => return None,
+/// Hack for calling `deployment_target` outside of this module.
+pub fn deployment_target_for_target(target: &Target) -> (u16, u8, u8) {
+    let arch = if target.llvm_target.starts_with("arm64e") {
+        Arch::Arm64e
+    } else if target.arch == "aarch64" {
+        Arch::Arm64
+    } else {
+        // Dummy architecture, only used by `deployment_target` anyhow
+        Arch::X86_64
     };
-
-    Some((major, minor))
+    let abi = match &*target.abi {
+        "macabi" => TargetAbi::MacCatalyst,
+        "sim" => TargetAbi::Simulator,
+        "" => TargetAbi::Normal,
+        abi => unreachable!("invalid abi '{abi}' for Apple target"),
+    };
+    deployment_target(&target.os, arch, abi)
 }
 
-fn from_set_deployment_target(var_name: &str) -> Option<(u32, u32)> {
-    let deployment_target = env::var(var_name).ok()?;
-    let (unparsed_major, unparsed_minor) = deployment_target.split_once('.')?;
-    let (major, minor) = (unparsed_major.parse().ok()?, unparsed_minor.parse().ok()?);
+/// Get the deployment target based on the standard environment variables, or
+/// fall back to a sane default.
+fn deployment_target(os: &str, arch: Arch, abi: TargetAbi) -> (u16, u8, u8) {
+    // When bumping a version in here, remember to update the platform-support
+    // docs too.
+    //
+    // NOTE: If you are looking for the default deployment target, prefer
+    // `rustc --print deployment-target`, as the default here may change in
+    // future `rustc` versions.
+
+    // Minimum operating system versions currently supported by `rustc`.
+    let os_min = match os {
+        "macos" => (10, 12, 0),
+        "ios" => (10, 0, 0),
+        "tvos" => (10, 0, 0),
+        "watchos" => (5, 0, 0),
+        "visionos" => (1, 0, 0),
+        _ => unreachable!("tried to get deployment target for non-Apple platform"),
+    };
 
-    Some((major, minor))
-}
+    // On certain targets it makes sense to raise the minimum OS version.
+    let min = match (os, arch, abi) {
+        // Use 11.0 on Aarch64 as that's the earliest version with M1 support.
+        ("macos", Arch::Arm64 | Arch::Arm64e, _) => (11, 0, 0),
+        ("ios", Arch::Arm64e, _) => (14, 0, 0),
+        // Mac Catalyst defaults to 13.1 in Clang.
+        ("ios", _, TargetAbi::MacCatalyst) => (13, 1, 0),
+        _ => os_min,
+    };
 
-fn macos_default_deployment_target(arch: Arch) -> (u32, u32) {
-    match arch {
-        Arm64 | Arm64e => (11, 0),
-        _ => (10, 12),
-    }
-}
+    // The environment variable used to fetch the deployment target.
+    let env_var = match os {
+        "macos" => "MACOSX_DEPLOYMENT_TARGET",
+        "ios" => "IPHONEOS_DEPLOYMENT_TARGET",
+        "watchos" => "WATCHOS_DEPLOYMENT_TARGET",
+        "tvos" => "TVOS_DEPLOYMENT_TARGET",
+        "visionos" => "XROS_DEPLOYMENT_TARGET",
+        _ => unreachable!("tried to get deployment target env var for non-Apple platform"),
+    };
 
-fn macos_deployment_target(arch: Arch) -> (u32, u32) {
-    // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    // Note: If bumping this version, remember to update it in the rustc/platform-support docs.
-    from_set_deployment_target("MACOSX_DEPLOYMENT_TARGET")
-        .unwrap_or_else(|| macos_default_deployment_target(arch))
+    if let Ok(deployment_target) = env::var(env_var) {
+        match parse_version(&deployment_target) {
+            // It is common that the deployment target is set too low, e.g. on
+            // macOS Aarch64 to also target older x86_64, the user may set a
+            // lower deployment target than supported.
+            //
+            // To avoid such issues, we silently raise the deployment target
+            // here.
+            // FIXME: We want to show a warning when `version < os_min`.
+            Ok(version) => version.max(min),
+            // FIXME: Report erroneous environment variable to user.
+            Err(_) => min,
+        }
+    } else {
+        min
+    }
 }
 
-pub(crate) fn macos_llvm_target(arch: Arch) -> String {
-    let (major, minor) = macos_deployment_target(arch);
-    format!("{}-apple-macosx{}.{}.0", arch.target_name(), major, minor)
+/// Generate the target triple that we need to pass to LLVM and/or Clang.
+fn llvm_target(os: &str, arch: Arch, abi: TargetAbi) -> StaticCow<str> {
+    // The target triple depends on the deployment target, and is required to
+    // enable features such as cross-language LTO, and for picking the right
+    // Mach-O commands.
+    //
+    // Certain optimizations also depend on the deployment target.
+    let (major, minor, patch) = deployment_target(os, arch, abi);
+    let arch = arch.target_name();
+    // Convert to the "canonical" OS name used by LLVM:
+    // https://github.com/llvm/llvm-project/blob/llvmorg-18.1.8/llvm/lib/TargetParser/Triple.cpp#L236-L282
+    let os = match os {
+        "macos" => "macosx",
+        "ios" => "ios",
+        "watchos" => "watchos",
+        "tvos" => "tvos",
+        "visionos" => "xros",
+        _ => unreachable!("tried to get LLVM target OS for non-Apple platform"),
+    };
+    let environment = match abi {
+        TargetAbi::Normal => "",
+        TargetAbi::MacCatalyst => "-macabi",
+        TargetAbi::Simulator => "-simulator",
+    };
+    format!("{arch}-apple-{os}{major}.{minor}.{patch}{environment}").into()
 }
 
 fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
@@ -321,83 +424,19 @@ fn link_env_remove(os: &'static str) -> StaticCow<[StaticCow<str>]> {
     }
 }
 
-fn ios_deployment_target(arch: Arch, abi: &str) -> (u32, u32) {
-    // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    // Note: If bumping this version, remember to update it in the rustc/platform-support docs.
-    let (major, minor) = match (arch, abi) {
-        (Arm64e, _) => (14, 0),
-        // Mac Catalyst defaults to 13.1 in Clang.
-        (_, "macabi") => (13, 1),
-        _ => (10, 0),
-    };
-    from_set_deployment_target("IPHONEOS_DEPLOYMENT_TARGET").unwrap_or((major, minor))
-}
-
-pub(crate) fn ios_llvm_target(arch: Arch) -> String {
-    // Modern iOS tooling extracts information about deployment target
-    // from LC_BUILD_VERSION. This load command will only be emitted when
-    // we build with a version specific `llvm_target`, with the version
-    // set high enough. Luckily one LC_BUILD_VERSION is enough, for Xcode
-    // to pick it up (since std and core are still built with the fallback
-    // of version 7.0 and hence emit the old LC_IPHONE_MIN_VERSION).
-    let (major, minor) = ios_deployment_target(arch, "");
-    format!("{}-apple-ios{}.{}.0", arch.target_name(), major, minor)
-}
-
-pub(crate) fn mac_catalyst_llvm_target(arch: Arch) -> String {
-    let (major, minor) = ios_deployment_target(arch, "macabi");
-    format!("{}-apple-ios{}.{}.0-macabi", arch.target_name(), major, minor)
-}
-
-pub(crate) fn ios_sim_llvm_target(arch: Arch) -> String {
-    let (major, minor) = ios_deployment_target(arch, "sim");
-    format!("{}-apple-ios{}.{}.0-simulator", arch.target_name(), major, minor)
-}
-
-fn tvos_deployment_target() -> (u32, u32) {
-    // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    // Note: If bumping this version, remember to update it in the rustc platform-support docs.
-    from_set_deployment_target("TVOS_DEPLOYMENT_TARGET").unwrap_or((10, 0))
-}
-
-pub(crate) fn tvos_llvm_target(arch: Arch) -> String {
-    let (major, minor) = tvos_deployment_target();
-    format!("{}-apple-tvos{}.{}.0", arch.target_name(), major, minor)
-}
-
-pub(crate) fn tvos_sim_llvm_target(arch: Arch) -> String {
-    let (major, minor) = tvos_deployment_target();
-    format!("{}-apple-tvos{}.{}.0-simulator", arch.target_name(), major, minor)
-}
-
-fn watchos_deployment_target() -> (u32, u32) {
-    // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    // Note: If bumping this version, remember to update it in the rustc platform-support docs.
-    from_set_deployment_target("WATCHOS_DEPLOYMENT_TARGET").unwrap_or((5, 0))
-}
-
-pub(crate) fn watchos_llvm_target(arch: Arch) -> String {
-    let (major, minor) = watchos_deployment_target();
-    format!("{}-apple-watchos{}.{}.0", arch.target_name(), major, minor)
-}
-
-pub(crate) fn watchos_sim_llvm_target(arch: Arch) -> String {
-    let (major, minor) = watchos_deployment_target();
-    format!("{}-apple-watchos{}.{}.0-simulator", arch.target_name(), major, minor)
-}
-
-fn visionos_deployment_target() -> (u32, u32) {
-    // If you are looking for the default deployment target, prefer `rustc --print deployment-target`.
-    // Note: If bumping this version, remember to update it in the rustc platform-support docs.
-    from_set_deployment_target("XROS_DEPLOYMENT_TARGET").unwrap_or((1, 0))
-}
-
-pub(crate) fn visionos_llvm_target(arch: Arch) -> String {
-    let (major, minor) = visionos_deployment_target();
-    format!("{}-apple-visionos{}.{}.0", arch.target_name(), major, minor)
-}
-
-pub(crate) fn visionos_sim_llvm_target(arch: Arch) -> String {
-    let (major, minor) = visionos_deployment_target();
-    format!("{}-apple-visionos{}.{}.0-simulator", arch.target_name(), major, minor)
+/// Parse an OS version triple (SDK version or deployment target).
+///
+/// The size of the returned numbers here are limited by Mach-O's
+/// `LC_BUILD_VERSION`.
+fn parse_version(version: &str) -> Result<(u16, u8, u8), ParseIntError> {
+    if let Some((major, minor)) = version.split_once('.') {
+        let major = major.parse()?;
+        if let Some((minor, patch)) = minor.split_once('.') {
+            Ok((major, minor.parse()?, patch.parse()?))
+        } else {
+            Ok((major, minor.parse()?, 0))
+        }
+    } else {
+        Ok((version.parse()?, 0, 0))
+    }
 }
diff --git a/compiler/rustc_target/src/spec/base/apple/tests.rs b/compiler/rustc_target/src/spec/base/apple/tests.rs
index 7a985ad4dc0..d55b44e3c9e 100644
--- a/compiler/rustc_target/src/spec/base/apple/tests.rs
+++ b/compiler/rustc_target/src/spec/base/apple/tests.rs
@@ -1,3 +1,4 @@
+use super::parse_version;
 use crate::spec::targets::{
     aarch64_apple_darwin, aarch64_apple_ios_sim, aarch64_apple_visionos_sim,
     aarch64_apple_watchos_sim, i686_apple_darwin, x86_64_apple_darwin, x86_64_apple_ios,
@@ -42,3 +43,11 @@ fn macos_link_environment_unmodified() {
         );
     }
 }
+
+#[test]
+fn test_parse_version() {
+    assert_eq!(parse_version("10"), Ok((10, 0, 0)));
+    assert_eq!(parse_version("10.12"), Ok((10, 12, 0)));
+    assert_eq!(parse_version("10.12.6"), Ok((10, 12, 6)));
+    assert_eq!(parse_version("9999.99.99"), Ok((9999, 99, 99)));
+}
diff --git a/compiler/rustc_target/src/spec/mod.rs b/compiler/rustc_target/src/spec/mod.rs
index 6abd8a0d6b7..58d47c201f0 100644
--- a/compiler/rustc_target/src/spec/mod.rs
+++ b/compiler/rustc_target/src/spec/mod.rs
@@ -60,8 +60,8 @@ pub mod crt_objects;
 
 mod base;
 pub use base::apple::{
-    deployment_target as current_apple_deployment_target, platform as current_apple_platform,
-    sdk_version as current_apple_sdk_version,
+    deployment_target_for_target as current_apple_deployment_target,
+    platform as current_apple_platform, sdk_version as current_apple_sdk_version,
 };
 pub use base::avr_gnu::ef_avr_arch;
 
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
index 912392c9fef..1061633be17 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_darwin.rs
@@ -1,20 +1,10 @@
-use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
-    let mut base = opts("macos", arch, TargetAbi::Normal);
-    base.cpu = "apple-m1".into();
-    base.max_atomic_width = Some(128);
-
-    // FIXME: The leak sanitizer currently fails the tests, see #88132.
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("macos", Arch::Arm64, TargetAbi::Normal);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
-        // correctly, we do too.
-        llvm_target: macos_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 macOS (11.0+, Big Sur+)".into()),
             tier: Some(1),
@@ -23,11 +13,15 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             mcount: "\u{1}mcount".into(),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            cpu: "apple-m1".into(),
+            max_atomic_width: Some(128),
+            // FIXME: The leak sanitizer currently fails the tests, see #88132.
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
index 7f3a86f3256..caeb9a121e4 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios.rs
@@ -1,17 +1,10 @@
-use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
-    let mut base = opts("ios", arch, TargetAbi::Normal);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::Normal);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // IPHONEOS_DEPLOYMENT_TARGET.
-        // This is required for the target to pick the right
-        // MACH-O commands, so we do too.
-        llvm_target: ios_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 iOS".into()),
             tier: Some(2),
@@ -20,12 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
index e60eeda4295..eee9eca3bcb 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_macabi.rs
@@ -1,13 +1,10 @@
-use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
-    let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::MacCatalyst);
     Target {
-        llvm_target: mac_catalyst_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("Apple Catalyst on ARM64".into()),
             tier: Some(2),
@@ -16,12 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a12".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
index d605e22701a..ee58038301d 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_ios_sim.rs
@@ -1,17 +1,10 @@
-use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
-    let mut base = opts("ios", arch, TargetAbi::Simulator);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("ios", Arch::Arm64, TargetAbi::Simulator);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // IPHONEOS_DEPLOYMENT_TARGET.
-        // This is required for the simulator target to pick the right
-        // MACH-O commands, so we do too.
-        llvm_target: ios_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("Apple iOS Simulator on ARM64".into()),
             tier: Some(2),
@@ -20,12 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
index fc774ab94c8..baca863d442 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos.rs
@@ -1,10 +1,10 @@
-use crate::spec::base::apple::{opts, tvos_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
+    let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetAbi::Normal);
     Target {
-        llvm_target: tvos_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 tvOS".into()),
             tier: Some(3),
@@ -13,12 +13,12 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..opts("tvos", arch, TargetAbi::Normal)
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
index 8e8bb1efc9d..1a48f8c5acf 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_tvos_sim.rs
@@ -1,10 +1,10 @@
-use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
+    let (opts, llvm_target, arch) = base("tvos", Arch::Arm64, TargetAbi::Simulator);
     Target {
-        llvm_target: tvos_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 tvOS Simulator".into()),
             tier: Some(3),
@@ -13,12 +13,12 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..opts("tvos", arch, TargetAbi::Simulator)
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
index 16c7d72daed..1424126134d 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos.rs
@@ -1,13 +1,10 @@
-use crate::spec::base::apple::{opts, visionos_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
-    let mut base = opts("visionos", arch, TargetAbi::Normal);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetAbi::Normal);
     Target {
-        llvm_target: visionos_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 Apple visionOS".into()),
             tier: Some(3),
@@ -16,12 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a16".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
index 42973e0268e..d7226e02ecb 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_visionos_sim.rs
@@ -1,13 +1,10 @@
-use crate::spec::base::apple::{opts, visionos_sim_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
-    let mut base = opts("visionos", arch, TargetAbi::Simulator);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("visionos", Arch::Arm64, TargetAbi::Simulator);
     Target {
-        llvm_target: visionos_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 Apple visionOS simulator".into()),
             tier: Some(3),
@@ -16,12 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a16".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs
index 03fc2518d1d..1940a568b39 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos.rs
@@ -1,10 +1,10 @@
-use crate::spec::base::apple::{opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let base = opts("watchos", Arch::Arm64, TargetAbi::Normal);
+    let (opts, llvm_target, arch) = base("watchos", Arch::Arm64, TargetAbi::Normal);
     Target {
-        llvm_target: "aarch64-apple-watchos".into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 Apple WatchOS".into()),
             tier: Some(3),
@@ -13,13 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: "aarch64".into(),
+        arch,
         options: TargetOptions {
             features: "+v8a,+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             dynamic_linking: false,
             position_independent_executables: true,
-            ..base
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
index 13e2b961794..6beef11c504 100644
--- a/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/aarch64_apple_watchos_sim.rs
@@ -1,14 +1,10 @@
-use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64;
+    let (opts, llvm_target, arch) = base("watchos", Arch::Arm64, TargetAbi::Simulator);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // WATCHOS_DEPLOYMENT_TARGET.
-        // This is required for the simulator target to pick the right
-        // MACH-O commands, so we do too.
-        llvm_target: watchos_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64 Apple WatchOS Simulator".into()),
             tier: Some(3),
@@ -17,12 +13,12 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..opts("watchos", arch, TargetAbi::Simulator)
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs
index f292ee7f563..e9f4d9330d5 100644
--- a/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64_32_apple_watchos.rs
@@ -1,11 +1,10 @@
-use crate::spec::base::apple::{opts, watchos_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64_32;
-    let base = opts("watchos", arch, TargetAbi::Normal);
+    let (opts, llvm_target, arch) = base("watchos", Arch::Arm64_32, TargetAbi::Normal);
     Target {
-        llvm_target: watchos_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("Arm Apple WatchOS 64-bit with 32-bit pointers".into()),
             tier: Some(3),
@@ -14,13 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 32,
         data_layout: "e-m:o-p:32:32-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: "aarch64".into(),
+        arch,
         options: TargetOptions {
             features: "+v8a,+neon,+fp-armv8,+apple-a7".into(),
             max_atomic_width: Some(128),
             dynamic_linking: false,
             position_independent_executables: true,
-            ..base
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
index e86b8358a9c..4f7c945b9fe 100644
--- a/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_darwin.rs
@@ -1,20 +1,10 @@
-use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64e;
-    let mut base = opts("macos", arch, TargetAbi::Normal);
-    base.cpu = "apple-m1".into();
-    base.max_atomic_width = Some(128);
-
-    // FIXME: The leak sanitizer currently fails the tests, see #88132.
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("macos", Arch::Arm64e, TargetAbi::Normal);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
-        // correctly, we do too.
-        llvm_target: macos_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64e Apple Darwin".into()),
             tier: Some(3),
@@ -23,11 +13,15 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             mcount: "\u{1}mcount".into(),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            cpu: "apple-m1".into(),
+            max_atomic_width: Some(128),
+            // FIXME: The leak sanitizer currently fails the tests, see #88132.
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
index fcb850f44bc..8f192fe2886 100644
--- a/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/arm64e_apple_ios.rs
@@ -1,17 +1,10 @@
-use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{FramePointer, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Arm64e;
-    let mut base = opts("ios", arch, TargetAbi::Normal);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("ios", Arch::Arm64e, TargetAbi::Normal);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // IPHONEOS_DEPLOYMENT_TARGET.
-        // This is required for the target to pick the right
-        // MACH-O commands, so we do too.
-        llvm_target: ios_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("ARM64e Apple iOS".into()),
             tier: Some(3),
@@ -20,12 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 64,
         data_layout: "e-m:o-i64:64-i128:128-n32:64-S128-Fn32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+neon,+fp-armv8,+apple-a12,+v8.3a,+pauth".into(),
             max_atomic_width: Some(128),
             frame_pointer: FramePointer::NonLeaf,
-            ..base
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs
index 35de6b35eaf..8fe27f60e0a 100644
--- a/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7k_apple_watchos.rs
@@ -1,10 +1,10 @@
-use crate::spec::base::apple::{opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Armv7k;
+    let (opts, llvm_target, arch) = base("watchos", Arch::Armv7k, TargetAbi::Normal);
     Target {
-        llvm_target: "armv7k-apple-watchos".into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("Armv7-A Apple WatchOS".into()),
             tier: Some(3),
@@ -13,13 +13,13 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 32,
         data_layout: "e-m:o-p:32:32-Fi8-i64:64-a:0:32-n32-S128".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+v7,+vfp4,+neon".into(),
             max_atomic_width: Some(64),
             dynamic_linking: false,
             position_independent_executables: true,
-            ..opts("watchos", arch, TargetAbi::Normal)
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs
index 41eaa79d3eb..deee6985f1a 100644
--- a/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/armv7s_apple_ios.rs
@@ -1,10 +1,10 @@
-use crate::spec::base::apple::{ios_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::Armv7s;
+    let (opts, llvm_target, arch) = base("ios", Arch::Armv7s, TargetAbi::Normal);
     Target {
-        llvm_target: ios_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("Armv7-A Apple-A6 Apple iOS".into()),
             tier: Some(3),
@@ -13,11 +13,11 @@ pub(crate) fn target() -> Target {
         },
         pointer_width: 32,
         data_layout: "e-m:o-p:32:32-Fi8-f64:32:64-v64:32:64-v128:32:128-a:0:32-n32-S32".into(),
-        arch: arch.target_arch(),
+        arch,
         options: TargetOptions {
             features: "+v7,+vfp4,+neon".into(),
             max_atomic_width: Some(64),
-            ..opts("ios", arch, TargetAbi::Normal)
+            ..opts
         },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
index 263393fd536..dc14cb3ec76 100644
--- a/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/i386_apple_ios.rs
@@ -1,17 +1,12 @@
-use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::I386;
     // i386-apple-ios is a simulator target, even though it isn't declared
     // that way in the target name like the other ones...
-    let abi = TargetAbi::Simulator;
+    let (opts, llvm_target, arch) = base("ios", Arch::I386, TargetAbi::Simulator);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // IPHONEOS_DEPLOYMENT_TARGET.
-        // This is required for the target to pick the right
-        // MACH-O commands, so we do too.
-        llvm_target: ios_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("32-bit x86 iOS".into()),
             tier: Some(3),
@@ -22,7 +17,7 @@ pub(crate) fn target() -> Target {
         data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
             i128:128-f64:32:64-f80:128-n8:16:32-S128"
             .into(),
-        arch: arch.target_arch(),
-        options: TargetOptions { max_atomic_width: Some(64), ..opts("ios", arch, abi) },
+        arch,
+        options: TargetOptions { max_atomic_width: Some(64), ..opts },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
index f173e8b7e4a..67afe35bee4 100644
--- a/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/i686_apple_darwin.rs
@@ -1,21 +1,12 @@
-use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    // ld64 only understands i386 and not i686
-    let arch = Arch::I386;
-    let mut base = opts("macos", arch, TargetAbi::Normal);
-    base.max_atomic_width = Some(64);
-    base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);
-    base.frame_pointer = FramePointer::Always;
+    let (mut opts, llvm_target, arch) = base("macos", Arch::I686, TargetAbi::Normal);
+    opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m32"]);
 
     Target {
-        // Clang automatically chooses a more specific target based on
-        // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
-        // correctly, we do too.
-        //
-        // While ld64 doesn't understand i686, LLVM does.
-        llvm_target: macos_llvm_target(Arch::I686).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("32-bit macOS (10.12+, Sierra+)".into()),
             tier: Some(3),
@@ -26,7 +17,12 @@ pub(crate) fn target() -> Target {
         data_layout: "e-m:o-p:32:32-p270:32:32-p271:32:32-p272:64:64-\
             i128:128-f64:32:64-f80:128-n8:16:32-S128"
             .into(),
-        arch: arch.target_arch(),
-        options: TargetOptions { mcount: "\u{1}mcount".into(), ..base },
+        arch,
+        options: TargetOptions {
+            mcount: "\u{1}mcount".into(),
+            max_atomic_width: Some(64),
+            frame_pointer: FramePointer::Always,
+            ..opts
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
index 7bf18026735..e7f14aa9209 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_darwin.rs
@@ -1,20 +1,11 @@
-use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::X86_64;
-    let mut base = opts("macos", arch, TargetAbi::Normal);
-    base.max_atomic_width = Some(128); // penryn+ supports cmpxchg16b
-    base.frame_pointer = FramePointer::Always;
-    base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
-    base.supported_sanitizers =
-        SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
-
+    let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64, TargetAbi::Normal);
+    opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
     Target {
-        // Clang automatically chooses a more specific target based on
-        // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
-        // correctly, we do too.
-        llvm_target: macos_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("64-bit macOS (10.12+, Sierra+)".into()),
             tier: Some(1),
@@ -24,7 +15,16 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout:
             "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions { mcount: "\u{1}mcount".into(), ..base },
+        arch,
+        options: TargetOptions {
+            mcount: "\u{1}mcount".into(),
+            max_atomic_width: Some(128), // penryn+ supports cmpxchg16b
+            frame_pointer: FramePointer::Always,
+            supported_sanitizers: SanitizerSet::ADDRESS
+                | SanitizerSet::CFI
+                | SanitizerSet::LEAK
+                | SanitizerSet::THREAD,
+            ..opts
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
index 76a0bb1d91e..847c4f011f9 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios.rs
@@ -1,15 +1,12 @@
-use crate::spec::base::apple::{ios_sim_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::X86_64;
     // x86_64-apple-ios is a simulator target, even though it isn't declared
     // that way in the target name like the other ones...
-    let mut base = opts("ios", arch, TargetAbi::Simulator);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("ios", Arch::X86_64, TargetAbi::Simulator);
     Target {
-        llvm_target: ios_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("64-bit x86 iOS".into()),
             tier: Some(2),
@@ -19,7 +16,11 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout:
             "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions { max_atomic_width: Some(128), ..base },
+        arch,
+        options: TargetOptions {
+            max_atomic_width: Some(128),
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::THREAD,
+            ..opts
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
index f66efbbf709..042079f800b 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_ios_macabi.rs
@@ -1,13 +1,10 @@
-use crate::spec::base::apple::{mac_catalyst_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::X86_64;
-    let mut base = opts("ios", arch, TargetAbi::MacCatalyst);
-    base.supported_sanitizers = SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD;
-
+    let (opts, llvm_target, arch) = base("ios", Arch::X86_64, TargetAbi::MacCatalyst);
     Target {
-        llvm_target: mac_catalyst_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("Apple Catalyst on x86_64".into()),
             tier: Some(2),
@@ -17,7 +14,11 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout:
             "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions { max_atomic_width: Some(128), ..base },
+        arch,
+        options: TargetOptions {
+            max_atomic_width: Some(128),
+            supported_sanitizers: SanitizerSet::ADDRESS | SanitizerSet::LEAK | SanitizerSet::THREAD,
+            ..opts
+        },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
index f9d5f6e77d9..94708609790 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_tvos.rs
@@ -1,13 +1,12 @@
-use crate::spec::base::apple::{opts, tvos_sim_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::X86_64;
     // x86_64-apple-tvos is a simulator target, even though it isn't declared
     // that way in the target name like the other ones...
-    let abi = TargetAbi::Simulator;
+    let (opts, llvm_target, arch) = base("tvos", Arch::X86_64, TargetAbi::Simulator);
     Target {
-        llvm_target: tvos_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("x86 64-bit tvOS".into()),
             tier: Some(3),
@@ -17,7 +16,7 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout:
             "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions { max_atomic_width: Some(128), ..opts("tvos", arch, abi) },
+        arch,
+        options: TargetOptions { max_atomic_width: Some(128), ..opts },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
index 1fced10c895..1dab9598860 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64_apple_watchos_sim.rs
@@ -1,10 +1,10 @@
-use crate::spec::base::apple::{opts, watchos_sim_llvm_target, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::X86_64;
+    let (opts, llvm_target, arch) = base("watchos", Arch::X86_64, TargetAbi::Simulator);
     Target {
-        llvm_target: watchos_sim_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("x86 64-bit Apple WatchOS simulator".into()),
             tier: Some(3),
@@ -14,10 +14,7 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout:
             "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions {
-            max_atomic_width: Some(128),
-            ..opts("watchos", arch, TargetAbi::Simulator)
-        },
+        arch,
+        options: TargetOptions { max_atomic_width: Some(128), ..opts },
     }
 }
diff --git a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
index 9b9ffe4e536..f44bc660a62 100644
--- a/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
+++ b/compiler/rustc_target/src/spec/targets/x86_64h_apple_darwin.rs
@@ -1,13 +1,12 @@
-use crate::spec::base::apple::{macos_llvm_target, opts, Arch, TargetAbi};
+use crate::spec::base::apple::{base, Arch, TargetAbi};
 use crate::spec::{Cc, FramePointer, LinkerFlavor, Lld, SanitizerSet, Target, TargetOptions};
 
 pub(crate) fn target() -> Target {
-    let arch = Arch::X86_64h;
-    let mut base = opts("macos", arch, TargetAbi::Normal);
-    base.max_atomic_width = Some(128);
-    base.frame_pointer = FramePointer::Always;
-    base.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
-    base.supported_sanitizers =
+    let (mut opts, llvm_target, arch) = base("macos", Arch::X86_64h, TargetAbi::Normal);
+    opts.max_atomic_width = Some(128);
+    opts.frame_pointer = FramePointer::Always;
+    opts.add_pre_link_args(LinkerFlavor::Darwin(Cc::Yes, Lld::No), &["-m64"]);
+    opts.supported_sanitizers =
         SanitizerSet::ADDRESS | SanitizerSet::CFI | SanitizerSet::LEAK | SanitizerSet::THREAD;
 
     // x86_64h is core2-avx without a few of the features which would otherwise
@@ -20,19 +19,16 @@ pub(crate) fn target() -> Target {
     // It would be nice if this were not the case, but fixing it seems tricky
     // (and given that the main use-case for this target is for use in universal
     // binaries, probably not that important).
-    base.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into();
+    opts.features = "-rdrnd,-aes,-pclmul,-rtm,-fsgsbase".into();
     // Double-check that the `cpu` is what we expect (if it's not the list above
     // may need updating).
     assert_eq!(
-        base.cpu, "core-avx2",
+        opts.cpu, "core-avx2",
         "you need to adjust the feature list in x86_64h-apple-darwin if you change this",
     );
 
     Target {
-        // Clang automatically chooses a more specific target based on
-        // MACOSX_DEPLOYMENT_TARGET. To enable cross-language LTO to work
-        // correctly, we do too.
-        llvm_target: macos_llvm_target(arch).into(),
+        llvm_target,
         metadata: crate::spec::TargetMetadata {
             description: Some("macOS with late-gen Intel (at least Haswell)".into()),
             tier: Some(3),
@@ -42,7 +38,7 @@ pub(crate) fn target() -> Target {
         pointer_width: 64,
         data_layout:
             "e-m:o-p270:32:32-p271:32:32-p272:64:64-i64:64-i128:128-f80:128-n8:16:32:64-S128".into(),
-        arch: arch.target_arch(),
-        options: TargetOptions { mcount: "\u{1}mcount".into(), ..base },
+        arch,
+        options: TargetOptions { mcount: "\u{1}mcount".into(), ..opts },
     }
 }
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
index bff2a184b19..65d21518491 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/mod.rs
@@ -348,8 +348,7 @@ impl<'a, 'tcx> TypeErrCtxt<'a, 'tcx> {
                     }
                 }
                 if let Some(ty::error::ExpectedFound { found, .. }) = exp_found
-                    && ty.is_box()
-                    && ty.boxed_ty() == found
+                    && ty.boxed_ty() == Some(found)
                     && let Ok(snippet) = self.tcx.sess.source_map().span_to_snippet(span)
                 {
                     err.span_suggestion(
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
index a93b633ce1a..cf9891f15ad 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/need_type_info.rs
@@ -1296,6 +1296,9 @@ impl<'a, 'tcx> Visitor<'tcx> for FindInferSourceVisitor<'a, 'tcx> {
             && let Some(def_id) = self.typeck_results.type_dependent_def_id(expr.hir_id)
             && self.tecx.tcx.trait_of_item(def_id).is_some()
             && !has_impl_trait(def_id)
+            // FIXME(fn_delegation): In delegation item argument spans are equal to last path
+            // segment. This leads to ICE's when emitting `multipart_suggestion`.
+            && tcx.hir().opt_delegation_sig_id(expr.hir_id.owner.def_id).is_none()
         {
             let successor =
                 method_args.get(0).map_or_else(|| (")", span.hi()), |arg| (", ", arg.span.lo()));
diff --git a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
index db71331d07f..7bfc6471dc8 100644
--- a/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
+++ b/compiler/rustc_trait_selection/src/error_reporting/infer/note_and_explain.rs
@@ -4,7 +4,7 @@ use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_middle::traits::{ObligationCause, ObligationCauseCode};
 use rustc_middle::ty::error::{ExpectedFound, TypeError};
-use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::print::{FmtPrinter, Printer};
 use rustc_middle::ty::{self, suggest_constraining_type_param, Ty};
 use rustc_span::def_id::DefId;
@@ -317,7 +317,7 @@ impl<T> Trait<T> for X {
                     {
                         let mut has_matching_impl = false;
                         tcx.for_each_relevant_impl(def_id, values.found, |did| {
-                            if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
+                            if DeepRejectCtxt::relate_rigid_infer(tcx)
                                 .types_may_unify(values.found, tcx.type_of(did).skip_binder())
                             {
                                 has_matching_impl = true;
@@ -338,7 +338,7 @@ impl<T> Trait<T> for X {
                     {
                         let mut has_matching_impl = false;
                         tcx.for_each_relevant_impl(def_id, values.expected, |did| {
-                            if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
+                            if DeepRejectCtxt::relate_rigid_infer(tcx)
                                 .types_may_unify(values.expected, tcx.type_of(did).skip_binder())
                             {
                                 has_matching_impl = true;
@@ -358,7 +358,7 @@ impl<T> Trait<T> for X {
                     {
                         let mut has_matching_impl = false;
                         tcx.for_each_relevant_impl(def_id, values.found, |did| {
-                            if DeepRejectCtxt::new(tcx, TreatParams::ForLookup)
+                            if DeepRejectCtxt::relate_rigid_infer(tcx)
                                 .types_may_unify(values.found, tcx.type_of(did).skip_binder())
                             {
                                 has_matching_impl = true;
diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs
index 8b55f84bccc..bafe1ffae44 100644
--- a/compiler/rustc_trait_selection/src/traits/coherence.rs
+++ b/compiler/rustc_trait_selection/src/traits/coherence.rs
@@ -15,7 +15,7 @@ use rustc_middle::bug;
 use rustc_middle::traits::query::NoSolution;
 use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
 use rustc_middle::traits::specialization_graph::OverlapMode;
-use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor};
 use rustc_middle::ty::{self, Ty, TyCtxt};
 pub use rustc_next_trait_solver::coherence::*;
@@ -96,7 +96,7 @@ pub fn overlapping_impls(
     // Before doing expensive operations like entering an inference context, do
     // a quick check via fast_reject to tell if the impl headers could possibly
     // unify.
-    let drcx = DeepRejectCtxt::new(tcx, TreatParams::AsCandidateKey);
+    let drcx = DeepRejectCtxt::relate_infer_infer(tcx);
     let impl1_ref = tcx.impl_trait_ref(impl1_def_id);
     let impl2_ref = tcx.impl_trait_ref(impl2_def_id);
     let may_overlap = match (impl1_ref, impl2_ref) {
diff --git a/compiler/rustc_trait_selection/src/traits/engine.rs b/compiler/rustc_trait_selection/src/traits/engine.rs
index de1d4ef15ac..c8811bc37b3 100644
--- a/compiler/rustc_trait_selection/src/traits/engine.rs
+++ b/compiler/rustc_trait_selection/src/traits/engine.rs
@@ -35,10 +35,8 @@ where
         if infcx.next_trait_solver() {
             Box::new(NextFulfillmentCtxt::new(infcx))
         } else {
-            let new_solver_globally =
-                infcx.tcx.sess.opts.unstable_opts.next_solver.map_or(false, |c| c.globally);
             assert!(
-                !new_solver_globally,
+                !infcx.tcx.next_trait_solver_globally(),
                 "using old solver even though new solver is enabled globally"
             );
             Box::new(FulfillmentContext::new(infcx))
diff --git a/compiler/rustc_trait_selection/src/traits/project.rs b/compiler/rustc_trait_selection/src/traits/project.rs
index 4702fd866c1..630acc91fbe 100644
--- a/compiler/rustc_trait_selection/src/traits/project.rs
+++ b/compiler/rustc_trait_selection/src/traits/project.rs
@@ -13,6 +13,7 @@ use rustc_infer::traits::ObligationCauseCode;
 use rustc_middle::traits::select::OverflowError;
 pub use rustc_middle::traits::Reveal;
 use rustc_middle::traits::{BuiltinImplSource, ImplSource, ImplSourceUserDefinedData};
+use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::fold::TypeFoldable;
 use rustc_middle::ty::visit::{MaxUniverse, TypeVisitable, TypeVisitableExt};
 use rustc_middle::ty::{self, Term, Ty, TyCtxt, Upcast};
@@ -886,6 +887,7 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
     potentially_unnormalized_candidates: bool,
 ) {
     let infcx = selcx.infcx;
+    let drcx = DeepRejectCtxt::relate_rigid_rigid(selcx.tcx());
     for predicate in env_predicates {
         let bound_predicate = predicate.kind();
         if let ty::ClauseKind::Projection(data) = predicate.kind().skip_binder() {
@@ -894,6 +896,12 @@ fn assemble_candidates_from_predicates<'cx, 'tcx>(
                 continue;
             }
 
+            if !drcx
+                .args_may_unify(obligation.predicate.args, data.skip_binder().projection_term.args)
+            {
+                continue;
+            }
+
             let is_match = infcx.probe(|_| {
                 selcx.match_projection_projections(
                     obligation,
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 96faa5236b1..77efc2fc2db 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -13,7 +13,7 @@ use hir::LangItem;
 use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_hir as hir;
 use rustc_infer::traits::{Obligation, ObligationCause, PolyTraitObligation, SelectionError};
-use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::{self, ToPolyTraitRef, Ty, TypeVisitableExt};
 use rustc_middle::{bug, span_bug};
 use tracing::{debug, instrument, trace};
@@ -248,11 +248,17 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             .filter(|p| p.def_id() == stack.obligation.predicate.def_id())
             .filter(|p| p.polarity() == stack.obligation.predicate.polarity());
 
+        let drcx = DeepRejectCtxt::relate_rigid_rigid(self.tcx());
+        let obligation_args = stack.obligation.predicate.skip_binder().trait_ref.args;
         // Keep only those bounds which may apply, and propagate overflow if it occurs.
         for bound in bounds {
+            let bound_trait_ref = bound.map_bound(|t| t.trait_ref);
+            if !drcx.args_may_unify(obligation_args, bound_trait_ref.skip_binder().args) {
+                continue;
+            }
             // FIXME(oli-obk): it is suspicious that we are dropping the constness and
             // polarity here.
-            let wc = self.where_clause_may_apply(stack, bound.map_bound(|t| t.trait_ref))?;
+            let wc = self.where_clause_may_apply(stack, bound_trait_ref)?;
             if wc.may_apply() {
                 candidates.vec.push(ParamCandidate(bound));
             }
@@ -581,7 +587,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
             return;
         }
 
-        let drcx = DeepRejectCtxt::new(self.tcx(), TreatParams::ForLookup);
+        let drcx = DeepRejectCtxt::relate_rigid_infer(self.tcx());
         let obligation_args = obligation.predicate.skip_binder().trait_ref.args;
         self.tcx().for_each_relevant_impl(
             obligation.predicate.def_id(),
diff --git a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
index 0fdaf40b136..13620f4b8d9 100644
--- a/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
+++ b/compiler/rustc_trait_selection/src/traits/specialize/specialization_graph.rs
@@ -41,7 +41,7 @@ impl<'tcx> Children {
     fn insert_blindly(&mut self, tcx: TyCtxt<'tcx>, impl_def_id: DefId) {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
         if let Some(st) =
-            fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
+            fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
         {
             debug!("insert_blindly: impl_def_id={:?} st={:?}", impl_def_id, st);
             self.non_blanket_impls.entry(st).or_default().push(impl_def_id)
@@ -58,7 +58,7 @@ impl<'tcx> Children {
         let trait_ref = tcx.impl_trait_ref(impl_def_id).unwrap().skip_binder();
         let vec: &mut Vec<DefId>;
         if let Some(st) =
-            fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey)
+            fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer)
         {
             debug!("remove_existing: impl_def_id={:?} st={:?}", impl_def_id, st);
             vec = self.non_blanket_impls.get_mut(&st).unwrap();
@@ -279,7 +279,7 @@ impl<'tcx> Graph {
         let mut parent = trait_def_id;
         let mut last_lint = None;
         let simplified =
-            fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::AsCandidateKey);
+            fast_reject::simplify_type(tcx, trait_ref.self_ty(), TreatParams::InstantiateWithInfer);
 
         // Descend the specialization tree, where `parent` is the current parent node.
         loop {
diff --git a/compiler/rustc_type_ir/src/fast_reject.rs b/compiler/rustc_type_ir/src/fast_reject.rs
index fab4a099117..2c8e47bcbca 100644
--- a/compiler/rustc_type_ir/src/fast_reject.rs
+++ b/compiler/rustc_type_ir/src/fast_reject.rs
@@ -74,13 +74,13 @@ impl<HCX: Clone, DefId: HashStable<HCX>> ToStableHashKey<HCX> for SimplifiedType
 pub enum TreatParams {
     /// Treat parameters as infer vars. This is the correct mode for caching
     /// an impl's type for lookup.
-    AsCandidateKey,
+    InstantiateWithInfer,
     /// Treat parameters as placeholders in the given environment. This is the
     /// correct mode for *lookup*, as during candidate selection.
     ///
     /// This also treats projections with inference variables as infer vars
     /// since they could be further normalized.
-    ForLookup,
+    AsRigid,
 }
 
 /// Tries to simplify a type by only returning the outermost injective¹ layer, if one exists.
@@ -140,18 +140,16 @@ pub fn simplify_type<I: Interner>(
         }
         ty::Placeholder(..) => Some(SimplifiedType::Placeholder),
         ty::Param(_) => match treat_params {
-            TreatParams::ForLookup => Some(SimplifiedType::Placeholder),
-            TreatParams::AsCandidateKey => None,
+            TreatParams::AsRigid => Some(SimplifiedType::Placeholder),
+            TreatParams::InstantiateWithInfer => None,
         },
         ty::Alias(..) => match treat_params {
             // When treating `ty::Param` as a placeholder, projections also
             // don't unify with anything else as long as they are fully normalized.
             // FIXME(-Znext-solver): Can remove this `if` and always simplify to `Placeholder`
             // when the new solver is enabled by default.
-            TreatParams::ForLookup if !ty.has_non_region_infer() => {
-                Some(SimplifiedType::Placeholder)
-            }
-            TreatParams::ForLookup | TreatParams::AsCandidateKey => None,
+            TreatParams::AsRigid if !ty.has_non_region_infer() => Some(SimplifiedType::Placeholder),
+            TreatParams::AsRigid | TreatParams::InstantiateWithInfer => None,
         },
         ty::Foreign(def_id) => Some(SimplifiedType::Foreign(def_id)),
         ty::Error(_) => Some(SimplifiedType::Error),
@@ -173,29 +171,49 @@ impl<DefId> SimplifiedType<DefId> {
     }
 }
 
-/// Given generic arguments from an obligation and an impl,
-/// could these two be unified after replacing parameters in the
-/// the impl with inference variables.
+/// Given generic arguments, could they be unified after
+/// replacing parameters with inference variables or placeholders.
+/// This behavior is toggled using the const generics.
 ///
-/// For obligations, parameters won't be replaced by inference
-/// variables and only unify with themselves. We treat them
-/// the same way we treat placeholders.
+/// We use this to quickly reject impl/wc candidates without needing
+/// to instantiate generic arguments/having to enter a probe.
 ///
 /// We also use this function during coherence. For coherence the
 /// impls only have to overlap for some value, so we treat parameters
-/// on both sides like inference variables. This behavior is toggled
-/// using the `treat_obligation_params` field.
+/// on both sides like inference variables.
 #[derive(Debug, Clone, Copy)]
-pub struct DeepRejectCtxt<I: Interner> {
-    treat_obligation_params: TreatParams,
+pub struct DeepRejectCtxt<
+    I: Interner,
+    const INSTANTIATE_LHS_WITH_INFER: bool,
+    const INSTANTIATE_RHS_WITH_INFER: bool,
+> {
     _interner: PhantomData<I>,
 }
 
-impl<I: Interner> DeepRejectCtxt<I> {
-    pub fn new(_interner: I, treat_obligation_params: TreatParams) -> Self {
-        DeepRejectCtxt { treat_obligation_params, _interner: PhantomData }
+impl<I: Interner> DeepRejectCtxt<I, false, false> {
+    /// Treat parameters in both the lhs and the rhs as rigid.
+    pub fn relate_rigid_rigid(_interner: I) -> DeepRejectCtxt<I, false, false> {
+        DeepRejectCtxt { _interner: PhantomData }
+    }
+}
+
+impl<I: Interner> DeepRejectCtxt<I, true, true> {
+    /// Treat parameters in both the lhs and the rhs as infer vars.
+    pub fn relate_infer_infer(_interner: I) -> DeepRejectCtxt<I, true, true> {
+        DeepRejectCtxt { _interner: PhantomData }
     }
+}
 
+impl<I: Interner> DeepRejectCtxt<I, false, true> {
+    /// Treat parameters in the lhs as rigid, and in rhs as infer vars.
+    pub fn relate_rigid_infer(_interner: I) -> DeepRejectCtxt<I, false, true> {
+        DeepRejectCtxt { _interner: PhantomData }
+    }
+}
+
+impl<I: Interner, const INSTANTIATE_LHS_WITH_INFER: bool, const INSTANTIATE_RHS_WITH_INFER: bool>
+    DeepRejectCtxt<I, INSTANTIATE_LHS_WITH_INFER, INSTANTIATE_RHS_WITH_INFER>
+{
     pub fn args_may_unify(
         self,
         obligation_args: I::GenericArgs,
@@ -216,11 +234,18 @@ impl<I: Interner> DeepRejectCtxt<I> {
         })
     }
 
-    pub fn types_may_unify(self, obligation_ty: I::Ty, impl_ty: I::Ty) -> bool {
-        match impl_ty.kind() {
-            // Start by checking whether the type in the impl may unify with
+    pub fn types_may_unify(self, lhs: I::Ty, rhs: I::Ty) -> bool {
+        match rhs.kind() {
+            // Start by checking whether the `rhs` type may unify with
             // pretty much everything. Just return `true` in that case.
-            ty::Param(_) | ty::Error(_) | ty::Alias(..) => return true,
+            ty::Param(_) => {
+                if INSTANTIATE_RHS_WITH_INFER {
+                    return true;
+                }
+            }
+            ty::Error(_) | ty::Alias(..) | ty::Bound(..) => return true,
+            ty::Infer(var) => return self.var_and_ty_may_unify(var, lhs),
+
             // These types only unify with inference variables or their own
             // variant.
             ty::Bool
@@ -238,159 +263,217 @@ impl<I: Interner> DeepRejectCtxt<I> {
             | ty::Ref(..)
             | ty::Never
             | ty::Tuple(..)
+            | ty::FnDef(..)
             | ty::FnPtr(..)
-            | ty::Foreign(..) => debug_assert!(impl_ty.is_known_rigid()),
-            ty::FnDef(..)
             | ty::Closure(..)
             | ty::CoroutineClosure(..)
             | ty::Coroutine(..)
             | ty::CoroutineWitness(..)
-            | ty::Placeholder(..)
-            | ty::Bound(..)
-            | ty::Infer(_) => panic!("unexpected impl_ty: {impl_ty:?}"),
-        }
+            | ty::Foreign(_)
+            | ty::Placeholder(_) => {}
+        };
 
-        let k = impl_ty.kind();
-        match obligation_ty.kind() {
-            // Purely rigid types, use structural equivalence.
-            ty::Bool
-            | ty::Char
-            | ty::Int(_)
-            | ty::Uint(_)
-            | ty::Float(_)
-            | ty::Str
-            | ty::Never
-            | ty::Foreign(_) => obligation_ty == impl_ty,
-            ty::Ref(_, obl_ty, obl_mutbl) => match k {
-                ty::Ref(_, impl_ty, impl_mutbl) => {
-                    obl_mutbl == impl_mutbl && self.types_may_unify(obl_ty, impl_ty)
+        // For purely rigid types, use structural equivalence.
+        match lhs.kind() {
+            ty::Ref(_, lhs_ty, lhs_mutbl) => match rhs.kind() {
+                ty::Ref(_, rhs_ty, rhs_mutbl) => {
+                    lhs_mutbl == rhs_mutbl && self.types_may_unify(lhs_ty, rhs_ty)
                 }
                 _ => false,
             },
-            ty::Adt(obl_def, obl_args) => match k {
-                ty::Adt(impl_def, impl_args) => {
-                    obl_def == impl_def && self.args_may_unify(obl_args, impl_args)
+
+            ty::Adt(lhs_def, lhs_args) => match rhs.kind() {
+                ty::Adt(rhs_def, rhs_args) => {
+                    lhs_def == rhs_def && self.args_may_unify(lhs_args, rhs_args)
                 }
                 _ => false,
             },
-            ty::Pat(obl_ty, _) => {
-                // FIXME(pattern_types): take pattern into account
-                matches!(k, ty::Pat(impl_ty, _) if self.types_may_unify(obl_ty, impl_ty))
+
+            // Depending on the value of const generics, we either treat generic parameters
+            // like placeholders or like inference variables.
+            ty::Param(lhs) => {
+                INSTANTIATE_LHS_WITH_INFER
+                    || match rhs.kind() {
+                        ty::Param(rhs) => lhs == rhs,
+                        _ => false,
+                    }
             }
-            ty::Slice(obl_ty) => {
-                matches!(k, ty::Slice(impl_ty) if self.types_may_unify(obl_ty, impl_ty))
+
+            // Placeholder types don't unify with anything on their own.
+            ty::Placeholder(lhs) => {
+                matches!(rhs.kind(), ty::Placeholder(rhs) if lhs == rhs)
             }
-            ty::Array(obl_ty, obl_len) => match k {
-                ty::Array(impl_ty, impl_len) => {
-                    self.types_may_unify(obl_ty, impl_ty)
-                        && self.consts_may_unify(obl_len, impl_len)
+
+            ty::Infer(var) => self.var_and_ty_may_unify(var, rhs),
+
+            // As we're walking the whole type, it may encounter projections
+            // inside of binders and what not, so we're just going to assume that
+            // projections can unify with other stuff.
+            //
+            // Looking forward to lazy normalization this is the safer strategy anyways.
+            ty::Alias(..) => true,
+
+            ty::Int(_)
+            | ty::Uint(_)
+            | ty::Float(_)
+            | ty::Str
+            | ty::Bool
+            | ty::Char
+            | ty::Never
+            | ty::Foreign(_) => lhs == rhs,
+
+            ty::Tuple(lhs) => match rhs.kind() {
+                ty::Tuple(rhs) => {
+                    lhs.len() == rhs.len()
+                        && iter::zip(lhs.iter(), rhs.iter())
+                            .all(|(lhs, rhs)| self.types_may_unify(lhs, rhs))
                 }
                 _ => false,
             },
-            ty::Tuple(obl) => match k {
-                ty::Tuple(imp) => {
-                    obl.len() == imp.len()
-                        && iter::zip(obl.iter(), imp.iter())
-                            .all(|(obl, imp)| self.types_may_unify(obl, imp))
+
+            ty::Array(lhs_ty, lhs_len) => match rhs.kind() {
+                ty::Array(rhs_ty, rhs_len) => {
+                    self.types_may_unify(lhs_ty, rhs_ty) && self.consts_may_unify(lhs_len, rhs_len)
                 }
                 _ => false,
             },
-            ty::RawPtr(obl_ty, obl_mutbl) => match k {
-                ty::RawPtr(imp_ty, imp_mutbl) => {
-                    obl_mutbl == imp_mutbl && self.types_may_unify(obl_ty, imp_ty)
+
+            ty::RawPtr(lhs_ty, lhs_mutbl) => match rhs.kind() {
+                ty::RawPtr(rhs_ty, rhs_mutbl) => {
+                    lhs_mutbl == rhs_mutbl && self.types_may_unify(lhs_ty, rhs_ty)
                 }
                 _ => false,
             },
-            ty::Dynamic(obl_preds, ..) => {
+
+            ty::Slice(lhs_ty) => {
+                matches!(rhs.kind(), ty::Slice(rhs_ty) if self.types_may_unify(lhs_ty, rhs_ty))
+            }
+
+            ty::Dynamic(lhs_preds, ..) => {
                 // Ideally we would walk the existential predicates here or at least
                 // compare their length. But considering that the relevant `Relate` impl
                 // actually sorts and deduplicates these, that doesn't work.
-                matches!(k, ty::Dynamic(impl_preds, ..) if
-                    obl_preds.principal_def_id() == impl_preds.principal_def_id()
+                matches!(rhs.kind(), ty::Dynamic(rhs_preds, ..) if
+                    lhs_preds.principal_def_id() == rhs_preds.principal_def_id()
                 )
             }
-            ty::FnPtr(obl_sig_tys, obl_hdr) => match k {
-                ty::FnPtr(impl_sig_tys, impl_hdr) => {
-                    let obl_sig_tys = obl_sig_tys.skip_binder().inputs_and_output;
-                    let impl_sig_tys = impl_sig_tys.skip_binder().inputs_and_output;
-
-                    obl_hdr == impl_hdr
-                        && obl_sig_tys.len() == impl_sig_tys.len()
-                        && iter::zip(obl_sig_tys.iter(), impl_sig_tys.iter())
-                            .all(|(obl, imp)| self.types_may_unify(obl, imp))
+
+            ty::FnPtr(lhs_sig_tys, lhs_hdr) => match rhs.kind() {
+                ty::FnPtr(rhs_sig_tys, rhs_hdr) => {
+                    let lhs_sig_tys = lhs_sig_tys.skip_binder().inputs_and_output;
+                    let rhs_sig_tys = rhs_sig_tys.skip_binder().inputs_and_output;
+
+                    lhs_hdr == rhs_hdr
+                        && lhs_sig_tys.len() == rhs_sig_tys.len()
+                        && iter::zip(lhs_sig_tys.iter(), rhs_sig_tys.iter())
+                            .all(|(lhs, rhs)| self.types_may_unify(lhs, rhs))
                 }
                 _ => false,
             },
 
-            // Impls cannot contain these types as these cannot be named directly.
-            ty::FnDef(..) | ty::Closure(..) | ty::CoroutineClosure(..) | ty::Coroutine(..) => false,
-
-            // Placeholder types don't unify with anything on their own
-            ty::Placeholder(..) | ty::Bound(..) => false,
+            ty::Bound(..) => true,
 
-            // Depending on the value of `treat_obligation_params`, we either
-            // treat generic parameters like placeholders or like inference variables.
-            ty::Param(_) => match self.treat_obligation_params {
-                TreatParams::ForLookup => false,
-                TreatParams::AsCandidateKey => true,
+            ty::FnDef(lhs_def_id, lhs_args) => match rhs.kind() {
+                ty::FnDef(rhs_def_id, rhs_args) => {
+                    lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
+                }
+                _ => false,
             },
 
-            ty::Infer(ty::IntVar(_)) => impl_ty.is_integral(),
-
-            ty::Infer(ty::FloatVar(_)) => impl_ty.is_floating_point(),
+            ty::Closure(lhs_def_id, lhs_args) => match rhs.kind() {
+                ty::Closure(rhs_def_id, rhs_args) => {
+                    lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
+                }
+                _ => false,
+            },
 
-            ty::Infer(_) => true,
+            ty::CoroutineClosure(lhs_def_id, lhs_args) => match rhs.kind() {
+                ty::CoroutineClosure(rhs_def_id, rhs_args) => {
+                    lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
+                }
+                _ => false,
+            },
 
-            // As we're walking the whole type, it may encounter projections
-            // inside of binders and what not, so we're just going to assume that
-            // projections can unify with other stuff.
-            //
-            // Looking forward to lazy normalization this is the safer strategy anyways.
-            ty::Alias(..) => true,
+            ty::Coroutine(lhs_def_id, lhs_args) => match rhs.kind() {
+                ty::Coroutine(rhs_def_id, rhs_args) => {
+                    lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
+                }
+                _ => false,
+            },
 
-            ty::Error(_) => true,
+            ty::CoroutineWitness(lhs_def_id, lhs_args) => match rhs.kind() {
+                ty::CoroutineWitness(rhs_def_id, rhs_args) => {
+                    lhs_def_id == rhs_def_id && self.args_may_unify(lhs_args, rhs_args)
+                }
+                _ => false,
+            },
 
-            ty::CoroutineWitness(..) => {
-                panic!("unexpected obligation type: {:?}", obligation_ty)
+            ty::Pat(lhs_ty, _) => {
+                // FIXME(pattern_types): take pattern into account
+                matches!(rhs.kind(), ty::Pat(rhs_ty, _) if self.types_may_unify(lhs_ty, rhs_ty))
             }
+
+            ty::Error(..) => true,
         }
     }
 
-    pub fn consts_may_unify(self, obligation_ct: I::Const, impl_ct: I::Const) -> bool {
-        let impl_val = match impl_ct.kind() {
+    pub fn consts_may_unify(self, lhs: I::Const, rhs: I::Const) -> bool {
+        match rhs.kind() {
+            ty::ConstKind::Param(_) => {
+                if INSTANTIATE_RHS_WITH_INFER {
+                    return true;
+                }
+            }
+
             ty::ConstKind::Expr(_)
-            | ty::ConstKind::Param(_)
             | ty::ConstKind::Unevaluated(_)
-            | ty::ConstKind::Error(_) => {
+            | ty::ConstKind::Error(_)
+            | ty::ConstKind::Infer(_)
+            | ty::ConstKind::Bound(..) => {
                 return true;
             }
-            ty::ConstKind::Value(_, impl_val) => impl_val,
-            ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) | ty::ConstKind::Placeholder(_) => {
-                panic!("unexpected impl arg: {:?}", impl_ct)
-            }
+
+            ty::ConstKind::Value(..) | ty::ConstKind::Placeholder(_) => {}
         };
 
-        match obligation_ct.kind() {
-            ty::ConstKind::Param(_) => match self.treat_obligation_params {
-                TreatParams::ForLookup => false,
-                TreatParams::AsCandidateKey => true,
+        match lhs.kind() {
+            ty::ConstKind::Value(_, lhs_val) => match rhs.kind() {
+                ty::ConstKind::Value(_, rhs_val) => lhs_val == rhs_val,
+                _ => false,
             },
 
+            ty::ConstKind::Param(lhs) => {
+                INSTANTIATE_LHS_WITH_INFER
+                    || match rhs.kind() {
+                        ty::ConstKind::Param(rhs) => lhs == rhs,
+                        _ => false,
+                    }
+            }
+
             // Placeholder consts don't unify with anything on their own
-            ty::ConstKind::Placeholder(_) => false,
+            ty::ConstKind::Placeholder(lhs) => {
+                matches!(rhs.kind(), ty::ConstKind::Placeholder(rhs) if lhs == rhs)
+            }
 
             // As we don't necessarily eagerly evaluate constants,
             // they might unify with any value.
             ty::ConstKind::Expr(_) | ty::ConstKind::Unevaluated(_) | ty::ConstKind::Error(_) => {
                 true
             }
-            ty::ConstKind::Value(_, obl_val) => obl_val == impl_val,
 
-            ty::ConstKind::Infer(_) => true,
+            ty::ConstKind::Infer(_) | ty::ConstKind::Bound(..) => true,
+        }
+    }
 
-            ty::ConstKind::Bound(..) => {
-                panic!("unexpected obl const: {:?}", obligation_ct)
-            }
+    fn var_and_ty_may_unify(self, var: ty::InferTy, ty: I::Ty) -> bool {
+        if !ty.is_known_rigid() {
+            return true;
+        }
+
+        match var {
+            ty::IntVar(_) => ty.is_integral(),
+            ty::FloatVar(_) => ty.is_floating_point(),
+            _ => true,
         }
     }
 }
diff --git a/config.example.toml b/config.example.toml
index 13f76933b16..e9433c9c9bd 100644
--- a/config.example.toml
+++ b/config.example.toml
@@ -78,6 +78,9 @@
 # Indicates whether the LLVM plugin is enabled or not
 #plugins = false
 
+# Wheter to build Enzyme as AutoDiff backend.
+#enzyme = false
+
 # Indicates whether ccache is used when building LLVM. Set to `true` to use the first `ccache` in
 # PATH, or set an absolute path to use a specific version.
 #ccache = false
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index e60bcf3aa5d..81b21f02159 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -122,7 +122,6 @@
 #![feature(const_cell_into_inner)]
 #![feature(const_eval_select)]
 #![feature(const_exact_div)]
-#![feature(const_float_bits_conv)]
 #![feature(const_float_classify)]
 #![feature(const_fmt_arguments_new)]
 #![feature(const_hash)]
@@ -166,6 +165,8 @@
 #![feature(coverage_attribute)]
 #![feature(do_not_recommend)]
 #![feature(duration_consts_float)]
+#![feature(f128_const)]
+#![feature(f16_const)]
 #![feature(internal_impls_macro)]
 #![feature(ip)]
 #![feature(is_ascii_octdigit)]
diff --git a/library/core/src/num/f128.rs b/library/core/src/num/f128.rs
index d4236e47bfe..1959628bd8f 100644
--- a/library/core/src/num/f128.rs
+++ b/library/core/src/num/f128.rs
@@ -914,7 +914,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_bits(self) -> u128 {
         // SAFETY: `u128` is a plain old datatype so we can always transmute to it.
@@ -963,7 +963,7 @@ impl f128 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     pub const fn from_bits(v: u128) -> Self {
         // It turns out the safety issues with sNaN were overblown! Hooray!
         // SAFETY: `u128` is a plain old datatype so we can always transmute from it.
@@ -990,7 +990,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_be_bytes(self) -> [u8; 16] {
         self.to_bits().to_be_bytes()
@@ -1016,7 +1016,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_le_bytes(self) -> [u8; 16] {
         self.to_bits().to_le_bytes()
@@ -1053,7 +1053,7 @@ impl f128 {
     /// ```
     #[inline]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_ne_bytes(self) -> [u8; 16] {
         self.to_bits().to_ne_bytes()
@@ -1081,7 +1081,7 @@ impl f128 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     pub const fn from_be_bytes(bytes: [u8; 16]) -> Self {
         Self::from_bits(u128::from_be_bytes(bytes))
     }
@@ -1108,7 +1108,7 @@ impl f128 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     pub const fn from_le_bytes(bytes: [u8; 16]) -> Self {
         Self::from_bits(u128::from_le_bytes(bytes))
     }
@@ -1145,7 +1145,7 @@ impl f128 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f128", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f128_const", issue = "116909")]
     pub const fn from_ne_bytes(bytes: [u8; 16]) -> Self {
         Self::from_bits(u128::from_ne_bytes(bytes))
     }
diff --git a/library/core/src/num/f16.rs b/library/core/src/num/f16.rs
index 1e2f841aca7..9252e8c6015 100644
--- a/library/core/src/num/f16.rs
+++ b/library/core/src/num/f16.rs
@@ -925,7 +925,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_bits(self) -> u16 {
         // SAFETY: `u16` is a plain old datatype so we can always transmute to it.
@@ -973,7 +973,7 @@ impl f16 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     pub const fn from_bits(v: u16) -> Self {
         // It turns out the safety issues with sNaN were overblown! Hooray!
         // SAFETY: `u16` is a plain old datatype so we can always transmute from it.
@@ -999,7 +999,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_be_bytes(self) -> [u8; 2] {
         self.to_bits().to_be_bytes()
@@ -1024,7 +1024,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_le_bytes(self) -> [u8; 2] {
         self.to_bits().to_le_bytes()
@@ -1062,7 +1062,7 @@ impl f16 {
     /// ```
     #[inline]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     #[must_use = "this returns the result of the operation, without modifying the original"]
     pub const fn to_ne_bytes(self) -> [u8; 2] {
         self.to_bits().to_ne_bytes()
@@ -1086,7 +1086,7 @@ impl f16 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     pub const fn from_be_bytes(bytes: [u8; 2]) -> Self {
         Self::from_bits(u16::from_be_bytes(bytes))
     }
@@ -1109,7 +1109,7 @@ impl f16 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     pub const fn from_le_bytes(bytes: [u8; 2]) -> Self {
         Self::from_bits(u16::from_le_bytes(bytes))
     }
@@ -1143,7 +1143,7 @@ impl f16 {
     #[inline]
     #[must_use]
     #[unstable(feature = "f16", issue = "116909")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_unstable(feature = "f16_const", issue = "116909")]
     pub const fn from_ne_bytes(bytes: [u8; 2]) -> Self {
         Self::from_bits(u16::from_ne_bytes(bytes))
     }
diff --git a/library/core/src/num/f32.rs b/library/core/src/num/f32.rs
index c1adcc753f2..2bc89722497 100644
--- a/library/core/src/num/f32.rs
+++ b/library/core/src/num/f32.rs
@@ -1115,7 +1115,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_bits(self) -> u32 {
         // SAFETY: `u32` is a plain old datatype so we can always transmute to it.
@@ -1159,7 +1159,7 @@ impl f32 {
     /// assert_eq!(v, 12.5);
     /// ```
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_bits(v: u32) -> Self {
@@ -1183,7 +1183,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_be_bytes(self) -> [u8; 4] {
         self.to_bits().to_be_bytes()
@@ -1204,7 +1204,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_le_bytes(self) -> [u8; 4] {
         self.to_bits().to_le_bytes()
@@ -1238,7 +1238,7 @@ impl f32 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_ne_bytes(self) -> [u8; 4] {
         self.to_bits().to_ne_bytes()
@@ -1256,7 +1256,7 @@ impl f32 {
     /// assert_eq!(value, 12.5);
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_be_bytes(bytes: [u8; 4]) -> Self {
@@ -1275,7 +1275,7 @@ impl f32 {
     /// assert_eq!(value, 12.5);
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_le_bytes(bytes: [u8; 4]) -> Self {
@@ -1305,7 +1305,7 @@ impl f32 {
     /// assert_eq!(value, 12.5);
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_ne_bytes(bytes: [u8; 4]) -> Self {
diff --git a/library/core/src/num/f64.rs b/library/core/src/num/f64.rs
index e6406771ad3..b3f5be9fc8a 100644
--- a/library/core/src/num/f64.rs
+++ b/library/core/src/num/f64.rs
@@ -1111,7 +1111,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_bits(self) -> u64 {
         // SAFETY: `u64` is a plain old datatype so we can always transmute to it.
@@ -1155,7 +1155,7 @@ impl f64 {
     /// assert_eq!(v, 12.5);
     /// ```
     #[stable(feature = "float_bits_conv", since = "1.20.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_bits(v: u64) -> Self {
@@ -1179,7 +1179,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_be_bytes(self) -> [u8; 8] {
         self.to_bits().to_be_bytes()
@@ -1200,7 +1200,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_le_bytes(self) -> [u8; 8] {
         self.to_bits().to_le_bytes()
@@ -1234,7 +1234,7 @@ impl f64 {
     #[must_use = "this returns the result of the operation, \
                   without modifying the original"]
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[inline]
     pub const fn to_ne_bytes(self) -> [u8; 8] {
         self.to_bits().to_ne_bytes()
@@ -1252,7 +1252,7 @@ impl f64 {
     /// assert_eq!(value, 12.5);
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_be_bytes(bytes: [u8; 8]) -> Self {
@@ -1271,7 +1271,7 @@ impl f64 {
     /// assert_eq!(value, 12.5);
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_le_bytes(bytes: [u8; 8]) -> Self {
@@ -1301,7 +1301,7 @@ impl f64 {
     /// assert_eq!(value, 12.5);
     /// ```
     #[stable(feature = "float_to_from_bytes", since = "1.40.0")]
-    #[rustc_const_unstable(feature = "const_float_bits_conv", issue = "72447")]
+    #[rustc_const_stable(feature = "const_float_bits_conv", since = "CURRENT_RUSTC_VERSION")]
     #[must_use]
     #[inline]
     pub const fn from_ne_bytes(bytes: [u8; 8]) -> Self {
diff --git a/library/core/src/ptr/mod.rs b/library/core/src/ptr/mod.rs
index d7ed4edcc00..08d06cad55d 100644
--- a/library/core/src/ptr/mod.rs
+++ b/library/core/src/ptr/mod.rs
@@ -2277,6 +2277,14 @@ impl<F: FnPtr> fmt::Debug for F {
 /// `addr_of!(expr)` is equivalent to `&raw const expr`. The macro is *soft-deprecated*;
 /// use `&raw const` instead.
 ///
+/// It is still an open question under which conditions writing through an `addr_of!`-created
+/// pointer is permitted. If the place `expr` evaluates to is based on a raw pointer, then the
+/// result of `addr_of!` inherits all permissions from that raw pointer. However, if the place is
+/// based on a reference, local variable, or `static`, then until all details are decided, the same
+/// rules as for shared references apply: it is UB to write through a pointer created with this
+/// operation, except for bytes located inside an `UnsafeCell`. Use `&raw mut` (or [`addr_of_mut`])
+/// to create a raw pointer that definitely permits mutation.
+///
 /// Creating a reference with `&`/`&mut` is only allowed if the pointer is properly aligned
 /// and points to initialized data. For cases where those requirements do not hold,
 /// raw pointers should be used instead. However, `&expr as *const _` creates a reference
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index 0390bb59a89..c19eeedb354 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -250,7 +250,7 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let duration = Duration::from_millis(2569);
+    /// let duration = Duration::from_millis(2_569);
     ///
     /// assert_eq!(2, duration.as_secs());
     /// assert_eq!(569_000_000, duration.subsec_nanos());
@@ -279,7 +279,7 @@ impl Duration {
     /// let duration = Duration::from_micros(1_000_002);
     ///
     /// assert_eq!(1, duration.as_secs());
-    /// assert_eq!(2000, duration.subsec_nanos());
+    /// assert_eq!(2_000, duration.subsec_nanos());
     /// ```
     #[stable(feature = "duration_from_micros", since = "1.27.0")]
     #[must_use]
@@ -472,7 +472,7 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let duration = Duration::new(5, 730023852);
+    /// let duration = Duration::new(5, 730_023_852);
     /// assert_eq!(duration.as_secs(), 5);
     /// ```
     ///
@@ -501,7 +501,7 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let duration = Duration::from_millis(5432);
+    /// let duration = Duration::from_millis(5_432);
     /// assert_eq!(duration.as_secs(), 5);
     /// assert_eq!(duration.subsec_millis(), 432);
     /// ```
@@ -547,7 +547,7 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let duration = Duration::from_millis(5010);
+    /// let duration = Duration::from_millis(5_010);
     /// assert_eq!(duration.as_secs(), 5);
     /// assert_eq!(duration.subsec_nanos(), 10_000_000);
     /// ```
@@ -566,8 +566,8 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let duration = Duration::new(5, 730023852);
-    /// assert_eq!(duration.as_millis(), 5730);
+    /// let duration = Duration::new(5, 730_023_852);
+    /// assert_eq!(duration.as_millis(), 5_730);
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
@@ -584,8 +584,8 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let duration = Duration::new(5, 730023852);
-    /// assert_eq!(duration.as_micros(), 5730023);
+    /// let duration = Duration::new(5, 730_023_852);
+    /// assert_eq!(duration.as_micros(), 5_730_023);
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
@@ -602,8 +602,8 @@ impl Duration {
     /// ```
     /// use std::time::Duration;
     ///
-    /// let duration = Duration::new(5, 730023852);
-    /// assert_eq!(duration.as_nanos(), 5730023852);
+    /// let duration = Duration::new(5, 730_023_852);
+    /// assert_eq!(duration.as_nanos(), 5_730_023_852);
     /// ```
     #[stable(feature = "duration_as_u128", since = "1.33.0")]
     #[rustc_const_stable(feature = "duration_as_u128", since = "1.33.0")]
@@ -879,7 +879,7 @@ impl Duration {
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 345_678_000);
-    /// assert_eq!(dur.as_millis_f64(), 2345.678);
+    /// assert_eq!(dur.as_millis_f64(), 2_345.678);
     /// ```
     #[unstable(feature = "duration_millis_float", issue = "122451")]
     #[must_use]
@@ -900,7 +900,7 @@ impl Duration {
     /// use std::time::Duration;
     ///
     /// let dur = Duration::new(2, 345_678_000);
-    /// assert_eq!(dur.as_millis_f32(), 2345.678);
+    /// assert_eq!(dur.as_millis_f32(), 2_345.678);
     /// ```
     #[unstable(feature = "duration_millis_float", issue = "122451")]
     #[must_use]
@@ -1017,7 +1017,7 @@ impl Duration {
     ///
     /// let dur = Duration::new(2, 700_000_000);
     /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_641));
-    /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847800, 0));
+    /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0));
     /// ```
     #[stable(feature = "duration_float", since = "1.38.0")]
     #[must_use = "this returns the result of the operation, \
diff --git a/library/std/src/ffi/os_str.rs b/library/std/src/ffi/os_str.rs
index 918eec2d0d8..99bea676e12 100644
--- a/library/std/src/ffi/os_str.rs
+++ b/library/std/src/ffi/os_str.rs
@@ -852,7 +852,7 @@ impl OsStr {
 
     /// Converts an `OsStr` to a <code>[Cow]<[str]></code>.
     ///
-    /// Any non-Unicode sequences are replaced with
+    /// Any non-UTF-8 sequences are replaced with
     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
     ///
     /// [U+FFFD]: crate::char::REPLACEMENT_CHARACTER
diff --git a/library/std/src/path.rs b/library/std/src/path.rs
index 9eaa0e01c2c..506ad445b6b 100644
--- a/library/std/src/path.rs
+++ b/library/std/src/path.rs
@@ -2200,7 +2200,7 @@ impl Path {
 
     /// Converts a `Path` to a [`Cow<str>`].
     ///
-    /// Any non-Unicode sequences are replaced with
+    /// Any non-UTF-8 sequences are replaced with
     /// [`U+FFFD REPLACEMENT CHARACTER`][U+FFFD].
     ///
     /// [U+FFFD]: super::char::REPLACEMENT_CHARACTER
diff --git a/library/std/src/sync/condvar.rs b/library/std/src/sync/condvar.rs
index 08d46f356d9..e41cbc1a65c 100644
--- a/library/std/src/sync/condvar.rs
+++ b/library/std/src/sync/condvar.rs
@@ -195,8 +195,11 @@ impl Condvar {
         if poisoned { Err(PoisonError::new(guard)) } else { Ok(guard) }
     }
 
-    /// Blocks the current thread until this condition variable receives a
-    /// notification and the provided condition is false.
+    /// Blocks the current thread until the provided condition becomes false.
+    ///
+    /// `condition` is checked immediately; if not met (returns `true`), this
+    /// will [`wait`] for the next notification then check again. This repeats
+    /// until `condition` returns `false`, in which case this function returns.
     ///
     /// This function will atomically unlock the mutex specified (represented by
     /// `guard`) and block the current thread. This means that any calls
@@ -210,6 +213,7 @@ impl Condvar {
     /// poisoned when this thread re-acquires the lock. For more information,
     /// see information about [poisoning] on the [`Mutex`] type.
     ///
+    /// [`wait`]: Self::wait
     /// [`notify_one`]: Self::notify_one
     /// [`notify_all`]: Self::notify_all
     /// [poisoning]: super::Mutex#poisoning
diff --git a/src/bootstrap/bootstrap.py b/src/bootstrap/bootstrap.py
index 71f69e03a9f..666df49012c 100644
--- a/src/bootstrap/bootstrap.py
+++ b/src/bootstrap/bootstrap.py
@@ -106,22 +106,29 @@ def _download(path, url, probably_big, verbose, exception):
 
     try:
         if (probably_big or verbose) and "GITHUB_ACTIONS" not in os.environ:
-            option = "-#"
+            option = "--progress-bar"
         else:
-            option = "-s"
+            option = "--silent"
         # If curl is not present on Win32, we should not sys.exit
         #   but raise `CalledProcessError` or `OSError` instead
         require(["curl", "--version"], exception=platform_is_win32())
         extra_flags = []
         if curl_version() > (7, 70):
             extra_flags = [ "--retry-all-errors" ]
+        # options should be kept in sync with
+        # src/bootstrap/src/core/download.rs
+        # for consistency.
+        # they are also more compreprensivly explained in that file.
         run(["curl", option] + extra_flags + [
-            "-L", # Follow redirect.
-            "-y", "30", "-Y", "10",    # timeout if speed is < 10 bytes/sec for > 30 seconds
-            "--connect-timeout", "30",  # timeout if cannot connect within 30 seconds
-            "-o", path,
+            # Follow redirect.
+            "--location",
+            # timeout if speed is < 10 bytes/sec for > 30 seconds
+            "--speed-time", "30", "--speed-limit", "10",
+            # timeout if cannot connect within 30 seconds
+            "--connect-timeout", "30",
+            "--output", path,
             "--continue-at", "-",
-            "--retry", "3", "-SRf", url],
+            "--retry", "3", "--show-error", "--remote-time", "--fail", url],
             verbose=verbose,
             exception=True, # Will raise RuntimeError on failure
         )
diff --git a/src/bootstrap/configure.py b/src/bootstrap/configure.py
index 768aac912ce..49d564642bd 100755
--- a/src/bootstrap/configure.py
+++ b/src/bootstrap/configure.py
@@ -71,6 +71,7 @@ v("llvm-libunwind", "rust.llvm-libunwind", "use LLVM libunwind")
 # channel, etc.
 o("optimize-llvm", "llvm.optimize", "build optimized LLVM")
 o("llvm-assertions", "llvm.assertions", "build LLVM with assertions")
+o("llvm-enzyme", "llvm.enzyme", "build LLVM with enzyme")
 o("llvm-plugins", "llvm.plugins", "build LLVM with plugin interface")
 o("debug-assertions", "rust.debug-assertions", "build with debugging assertions")
 o("debug-assertions-std", "rust.debug-assertions-std", "build the standard library with debugging assertions")
diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs
index 7f7faf077d0..ba12e64c4a2 100644
--- a/src/bootstrap/src/core/build_steps/check.rs
+++ b/src/bootstrap/src/core/build_steps/check.rs
@@ -228,7 +228,7 @@ impl Step for Rustc {
             self.override_build_kind.unwrap_or(builder.kind),
         );
 
-        rustc_cargo(builder, &mut cargo, target, &compiler);
+        rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
 
         // For ./x.py clippy, don't run with --all-targets because
         // linting tests and benchmarks can produce very noisy results
diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs
index a2bb03cd5ac..a0992350722 100644
--- a/src/bootstrap/src/core/build_steps/clippy.rs
+++ b/src/bootstrap/src/core/build_steps/clippy.rs
@@ -197,7 +197,7 @@ impl Step for Rustc {
             Kind::Clippy,
         );
 
-        rustc_cargo(builder, &mut cargo, target, &compiler);
+        rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
 
         // Explicitly pass -p for all compiler crates -- this will force cargo
         // to also lint the tests/benches/examples for these crates, rather
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs
index eef548033f1..1936c91ef83 100644
--- a/src/bootstrap/src/core/build_steps/compile.rs
+++ b/src/bootstrap/src/core/build_steps/compile.rs
@@ -931,7 +931,12 @@ impl Step for Rustc {
         // NOTE: the ABI of the beta compiler is different from the ABI of the downloaded compiler,
         // so its artifacts can't be reused.
         if builder.download_rustc() && compiler.stage != 0 {
-            builder.ensure(Sysroot { compiler, force_recompile: false });
+            let sysroot = builder.ensure(Sysroot { compiler, force_recompile: false });
+            cp_rustc_component_to_ci_sysroot(
+                builder,
+                &sysroot,
+                builder.config.ci_rustc_dev_contents(),
+            );
             return compiler.stage;
         }
 
@@ -983,7 +988,7 @@ impl Step for Rustc {
             Kind::Build,
         );
 
-        rustc_cargo(builder, &mut cargo, target, &compiler);
+        rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
 
         // NB: all RUSTFLAGS should be added to `rustc_cargo()` so they will be
         // consistently applied by check/doc/test modes too.
@@ -1042,10 +1047,11 @@ pub fn rustc_cargo(
     cargo: &mut Cargo,
     target: TargetSelection,
     compiler: &Compiler,
+    crates: &[String],
 ) {
     cargo
         .arg("--features")
-        .arg(builder.rustc_features(builder.kind, target))
+        .arg(builder.rustc_features(builder.kind, target, crates))
         .arg("--manifest-path")
         .arg(builder.src.join("compiler/rustc/Cargo.toml"));
 
@@ -1189,6 +1195,10 @@ pub fn rustc_cargo_env(
         cargo.env("RUSTC_VERIFY_LLVM_IR", "1");
     }
 
+    if builder.config.llvm_enzyme {
+        cargo.rustflag("--cfg=llvm_enzyme");
+    }
+
     // Note that this is disabled if LLVM itself is disabled or we're in a check
     // build. If we are in a check build we still go ahead here presuming we've
     // detected that LLVM is already built and good to go which helps prevent
@@ -1784,6 +1794,24 @@ impl Step for Assemble {
         //        use that to bootstrap this compiler forward.
         let mut build_compiler = builder.compiler(target_compiler.stage - 1, builder.config.build);
 
+        // Build enzyme
+        let enzyme_install = if builder.config.llvm_enzyme {
+            Some(builder.ensure(llvm::Enzyme { target: build_compiler.host }))
+        } else {
+            None
+        };
+
+        if let Some(enzyme_install) = enzyme_install {
+            let lib_ext = std::env::consts::DLL_EXTENSION;
+            let src_lib = enzyme_install.join("build/Enzyme/libEnzyme-19").with_extension(lib_ext);
+            let libdir = builder.sysroot_libdir(build_compiler, build_compiler.host);
+            let target_libdir = builder.sysroot_libdir(target_compiler, target_compiler.host);
+            let dst_lib = libdir.join("libEnzyme-19").with_extension(lib_ext);
+            let target_dst_lib = target_libdir.join("libEnzyme-19").with_extension(lib_ext);
+            builder.copy_link(&src_lib, &dst_lib);
+            builder.copy_link(&src_lib, &target_dst_lib);
+        }
+
         // Build the libraries for this compiler to link to (i.e., the libraries
         // it uses at runtime). NOTE: Crates the target compiler compiles don't
         // link to these. (FIXME: Is that correct? It seems to be correct most
diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs
index ffb617c642b..73d9e3f6793 100644
--- a/src/bootstrap/src/core/build_steps/doc.rs
+++ b/src/bootstrap/src/core/build_steps/doc.rs
@@ -826,7 +826,7 @@ impl Step for Rustc {
         // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222
         // cargo.rustdocflag("--generate-link-to-definition");
 
-        compile::rustc_cargo(builder, &mut cargo, target, &compiler);
+        compile::rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
         cargo.arg("-Zskip-rustdoc-fingerprint");
 
         // Only include compiler crates, no dependencies of those, such as `libc`.
@@ -1186,6 +1186,9 @@ impl Step for RustcBook {
         cmd.arg("--rustc");
         cmd.arg(&rustc);
         cmd.arg("--rustc-target").arg(self.target.rustc_target_arg());
+        if let Some(target_linker) = builder.linker(self.target) {
+            cmd.arg("--rustc-linker").arg(target_linker);
+        }
         if builder.is_verbose() {
             cmd.arg("--verbose");
         }
diff --git a/src/bootstrap/src/core/build_steps/llvm.rs b/src/bootstrap/src/core/build_steps/llvm.rs
index e1eea31b3bb..442638d3203 100644
--- a/src/bootstrap/src/core/build_steps/llvm.rs
+++ b/src/bootstrap/src/core/build_steps/llvm.rs
@@ -529,6 +529,7 @@ impl Step for Llvm {
             }
         };
 
+        // FIXME(ZuseZ4): Do we need that for Enzyme too?
         // When building LLVM with LLVM_LINK_LLVM_DYLIB for macOS, an unversioned
         // libLLVM.dylib will be built. However, llvm-config will still look
         // for a versioned path like libLLVM-14.dylib. Manually create a symbolic
@@ -849,6 +850,100 @@ fn get_var(var_base: &str, host: &str, target: &str) -> Option<OsString> {
         .or_else(|| env::var_os(var_base))
 }
 
+#[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)]
+pub struct Enzyme {
+    pub target: TargetSelection,
+}
+
+impl Step for Enzyme {
+    type Output = PathBuf;
+    const ONLY_HOSTS: bool = true;
+
+    fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
+        run.path("src/tools/enzyme/enzyme")
+    }
+
+    fn make_run(run: RunConfig<'_>) {
+        run.builder.ensure(Enzyme { target: run.target });
+    }
+
+    /// Compile Enzyme for `target`.
+    fn run(self, builder: &Builder<'_>) -> PathBuf {
+        builder.require_submodule(
+            "src/tools/enzyme",
+            Some("The Enzyme sources are required for autodiff."),
+        );
+        if builder.config.dry_run() {
+            let out_dir = builder.enzyme_out(self.target);
+            return out_dir;
+        }
+        let target = self.target;
+
+        let LlvmResult { llvm_config, .. } = builder.ensure(Llvm { target: self.target });
+
+        static STAMP_HASH_MEMO: OnceLock<String> = OnceLock::new();
+        let smart_stamp_hash = STAMP_HASH_MEMO.get_or_init(|| {
+            generate_smart_stamp_hash(
+                builder,
+                &builder.config.src.join("src/tools/enzyme"),
+                builder.enzyme_info.sha().unwrap_or_default(),
+            )
+        });
+
+        let out_dir = builder.enzyme_out(target);
+        let stamp = out_dir.join("enzyme-finished-building");
+        let stamp = HashStamp::new(stamp, Some(smart_stamp_hash));
+
+        if stamp.is_done() {
+            if stamp.hash.is_none() {
+                builder.info(
+                    "Could not determine the Enzyme submodule commit hash. \
+                     Assuming that an Enzyme rebuild is not necessary.",
+                );
+                builder.info(&format!(
+                    "To force Enzyme to rebuild, remove the file `{}`",
+                    stamp.path.display()
+                ));
+            }
+            return out_dir;
+        }
+
+        builder.info(&format!("Building Enzyme for {}", target));
+        t!(stamp.remove());
+        let _time = helpers::timeit(builder);
+        t!(fs::create_dir_all(&out_dir));
+
+        builder
+            .config
+            .update_submodule(Path::new("src").join("tools").join("enzyme").to_str().unwrap());
+        let mut cfg = cmake::Config::new(builder.src.join("src/tools/enzyme/enzyme/"));
+        // FIXME(ZuseZ4): Find a nicer way to use Enzyme Debug builds
+        //cfg.profile("Debug");
+        //cfg.define("CMAKE_BUILD_TYPE", "Debug");
+        configure_cmake(builder, target, &mut cfg, true, LdFlags::default(), &[]);
+
+        // Re-use the same flags as llvm to control the level of debug information
+        // generated for lld.
+        let profile = match (builder.config.llvm_optimize, builder.config.llvm_release_debuginfo) {
+            (false, _) => "Debug",
+            (true, false) => "Release",
+            (true, true) => "RelWithDebInfo",
+        };
+
+        cfg.out_dir(&out_dir)
+            .profile(profile)
+            .env("LLVM_CONFIG_REAL", &llvm_config)
+            .define("LLVM_ENABLE_ASSERTIONS", "ON")
+            .define("ENZYME_EXTERNAL_SHARED_LIB", "ON")
+            .define("LLVM_DIR", builder.llvm_out(target));
+
+        cfg.build();
+
+        t!(stamp.write());
+        out_dir
+    }
+}
+
 #[derive(Debug, Clone, Hash, PartialEq, Eq)]
 pub struct Lld {
     pub target: TargetSelection,
diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs
index a8e12540473..83f65615c8d 100644
--- a/src/bootstrap/src/core/build_steps/test.rs
+++ b/src/bootstrap/src/core/build_steps/test.rs
@@ -2690,7 +2690,7 @@ impl Step for Crate {
                 }
             }
             Mode::Rustc => {
-                compile::rustc_cargo(builder, &mut cargo, target, &compiler);
+                compile::rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
             }
             _ => panic!("can only test libraries"),
         };
@@ -3529,11 +3529,13 @@ impl Step for TestFloatParse {
 
     fn run(self, builder: &Builder<'_>) {
         let bootstrap_host = builder.config.build;
-        let compiler = builder.compiler(0, bootstrap_host);
+        let compiler = builder.compiler(builder.top_stage, bootstrap_host);
         let path = self.path.to_str().unwrap();
         let crate_name = self.path.components().last().unwrap().as_os_str().to_str().unwrap();
 
-        builder.ensure(compile::Std::new(compiler, self.host));
+        if !builder.download_rustc() {
+            builder.ensure(compile::Std::new(compiler, self.host));
+        }
 
         // Run any unit tests in the crate
         let cargo_test = tool::prepare_tool_cargo(
diff --git a/src/bootstrap/src/core/builder.rs b/src/bootstrap/src/core/builder.rs
index 304fe8da2bf..8f7ade79403 100644
--- a/src/bootstrap/src/core/builder.rs
+++ b/src/bootstrap/src/core/builder.rs
@@ -798,6 +798,7 @@ impl<'a> Builder<'a> {
                 tool::Miri,
                 tool::CargoMiri,
                 llvm::Lld,
+                llvm::Enzyme,
                 llvm::CrtBeginEnd,
                 tool::RustdocGUITest,
                 tool::OptimizedDist,
@@ -1588,6 +1589,12 @@ impl<'a> Builder<'a> {
             rustflags.arg(sysroot_str);
         }
 
+        // https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/.E2.9C.94.20link.20new.20library.20into.20stage1.2Frustc
+        if self.config.llvm_enzyme {
+            rustflags.arg("-l");
+            rustflags.arg("Enzyme-19");
+        }
+
         let use_new_symbol_mangling = match self.config.rust_new_symbol_mangling {
             Some(setting) => {
                 // If an explicit setting is given, use that
@@ -2456,7 +2463,15 @@ impl Cargo {
         cmd_kind: Kind,
     ) -> Cargo {
         let mut cargo = builder.cargo(compiler, mode, source_type, target, cmd_kind);
-        cargo.configure_linker(builder);
+
+        match cmd_kind {
+            // No need to configure the target linker for these command types.
+            Kind::Clean | Kind::Check | Kind::Suggest | Kind::Format | Kind::Setup => {}
+            _ => {
+                cargo.configure_linker(builder);
+            }
+        }
+
         cargo
     }
 
diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs
index f7cc9ee7219..52c1c462788 100644
--- a/src/bootstrap/src/core/config/config.rs
+++ b/src/bootstrap/src/core/config/config.rs
@@ -221,6 +221,7 @@ pub struct Config {
     // llvm codegen options
     pub llvm_assertions: bool,
     pub llvm_tests: bool,
+    pub llvm_enzyme: bool,
     pub llvm_plugins: bool,
     pub llvm_optimize: bool,
     pub llvm_thin_lto: bool,
@@ -898,6 +899,7 @@ define_config! {
         release_debuginfo: Option<bool> = "release-debuginfo",
         assertions: Option<bool> = "assertions",
         tests: Option<bool> = "tests",
+        enzyme: Option<bool> = "enzyme",
         plugins: Option<bool> = "plugins",
         ccache: Option<StringOrBool> = "ccache",
         static_libstdcpp: Option<bool> = "static-libstdcpp",
@@ -1603,6 +1605,7 @@ impl Config {
         // we'll infer default values for them later
         let mut llvm_assertions = None;
         let mut llvm_tests = None;
+        let mut llvm_enzyme = None;
         let mut llvm_plugins = None;
         let mut debug = None;
         let mut debug_assertions = None;
@@ -1722,6 +1725,8 @@ impl Config {
             config.llvm_tools_enabled = llvm_tools.unwrap_or(true);
             config.rustc_parallel =
                 parallel_compiler.unwrap_or(config.channel == "dev" || config.channel == "nightly");
+            config.llvm_enzyme =
+                llvm_enzyme.unwrap_or(config.channel == "dev" || config.channel == "nightly");
             config.rustc_default_linker = default_linker;
             config.musl_root = musl_root.map(PathBuf::from);
             config.save_toolstates = save_toolstates.map(PathBuf::from);
@@ -1806,6 +1811,7 @@ impl Config {
                 release_debuginfo,
                 assertions,
                 tests,
+                enzyme,
                 plugins,
                 ccache,
                 static_libstdcpp,
@@ -1839,6 +1845,7 @@ impl Config {
             set(&mut config.ninja_in_file, ninja);
             llvm_assertions = assertions;
             llvm_tests = tests;
+            llvm_enzyme = enzyme;
             llvm_plugins = plugins;
             set(&mut config.llvm_optimize, optimize_toml);
             set(&mut config.llvm_thin_lto, thin_lto);
@@ -2055,6 +2062,7 @@ impl Config {
 
         config.llvm_assertions = llvm_assertions.unwrap_or(false);
         config.llvm_tests = llvm_tests.unwrap_or(false);
+        config.llvm_enzyme = llvm_enzyme.unwrap_or(false);
         config.llvm_plugins = llvm_plugins.unwrap_or(false);
         config.rust_optimize = optimize.unwrap_or(RustOptimize::Bool(true));
 
diff --git a/src/bootstrap/src/core/download.rs b/src/bootstrap/src/core/download.rs
index 1e3f8da5258..3f5ec70b9ab 100644
--- a/src/bootstrap/src/core/download.rs
+++ b/src/bootstrap/src/core/download.rs
@@ -228,25 +228,42 @@ impl Config {
     fn download_http_with_retries(&self, tempfile: &Path, url: &str, help_on_error: &str) {
         println!("downloading {url}");
         // Try curl. If that fails and we are on windows, fallback to PowerShell.
+        // options should be kept in sync with
+        // src/bootstrap/src/core/download.rs
+        // for consistency
         let mut curl = command("curl");
         curl.args([
-            "-y",
+            // follow redirect
+            "--location",
+            // timeout if speed is < 10 bytes/sec for > 30 seconds
+            "--speed-time",
             "30",
-            "-Y",
-            "10", // timeout if speed is < 10 bytes/sec for > 30 seconds
+            "--speed-limit",
+            "10",
+            // timeout if cannot connect within 30 seconds
             "--connect-timeout",
-            "30", // timeout if cannot connect within 30 seconds
-            "-o",
+            "30",
+            // output file
+            "--output",
             tempfile.to_str().unwrap(),
+            // if there is an error, don't restart the download,
+            // instead continue where it left off.
             "--continue-at",
             "-",
+            // retry up to 3 times.  note that this means a maximum of 4
+            // attempts will be made, since the first attempt isn't a *re*try.
             "--retry",
             "3",
-            "-SRf",
+            // show errors, even if --silent is specified
+            "--show-error",
+            // set timestamp of downloaded file to that of the server
+            "--remote-time",
+            // fail on non-ok http status
+            "--fail",
         ]);
         // Don't print progress in CI; the \r wrapping looks bad and downloads don't take long enough for progress to be useful.
         if CiEnv::is_ci() {
-            curl.arg("-s");
+            curl.arg("--silent");
         } else {
             curl.arg("--progress-bar");
         }
diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs
index 1016607fc83..d665544f593 100644
--- a/src/bootstrap/src/core/metadata.rs
+++ b/src/bootstrap/src/core/metadata.rs
@@ -1,3 +1,4 @@
+use std::collections::BTreeMap;
 use std::path::PathBuf;
 
 use serde_derive::Deserialize;
@@ -21,6 +22,7 @@ struct Package {
     manifest_path: String,
     dependencies: Vec<Dependency>,
     targets: Vec<Target>,
+    features: BTreeMap<String, Vec<String>>,
 }
 
 /// For more information, see the output of
@@ -51,7 +53,13 @@ pub fn build(build: &mut Build) {
                 .map(|dep| dep.name)
                 .collect();
             let has_lib = package.targets.iter().any(|t| t.kind.iter().any(|k| k == "lib"));
-            let krate = Crate { name: name.clone(), deps, path, has_lib };
+            let krate = Crate {
+                name: name.clone(),
+                deps,
+                path,
+                has_lib,
+                features: package.features.keys().cloned().collect(),
+            };
             let relative_path = krate.local_path(build);
             build.crates.insert(name.clone(), krate);
             let existing_path = build.crate_paths.insert(relative_path, name);
diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs
index 5751c398f30..c76ce340956 100644
--- a/src/bootstrap/src/lib.rs
+++ b/src/bootstrap/src/lib.rs
@@ -77,6 +77,9 @@ const LLD_FILE_NAMES: &[&str] = &["ld.lld", "ld64.lld", "lld-link", "wasm-ld"];
 #[allow(clippy::type_complexity)] // It's fine for hard-coded list and type is explained above.
 const EXTRA_CHECK_CFGS: &[(Option<Mode>, &str, Option<&[&'static str]>)] = &[
     (None, "bootstrap", None),
+    (Some(Mode::Rustc), "llvm_enzyme", None),
+    (Some(Mode::Codegen), "llvm_enzyme", None),
+    (Some(Mode::ToolRustc), "llvm_enzyme", None),
     (Some(Mode::Rustc), "parallel_compiler", None),
     (Some(Mode::ToolRustc), "parallel_compiler", None),
     (Some(Mode::ToolRustc), "rust_analyzer", None),
@@ -140,6 +143,7 @@ pub struct Build {
     clippy_info: GitInfo,
     miri_info: GitInfo,
     rustfmt_info: GitInfo,
+    enzyme_info: GitInfo,
     in_tree_llvm_info: GitInfo,
     local_rebuild: bool,
     fail_fast: bool,
@@ -183,6 +187,7 @@ struct Crate {
     deps: HashSet<String>,
     path: PathBuf,
     has_lib: bool,
+    features: Vec<String>,
 }
 
 impl Crate {
@@ -306,6 +311,7 @@ impl Build {
         let clippy_info = GitInfo::new(omit_git_hash, &src.join("src/tools/clippy"));
         let miri_info = GitInfo::new(omit_git_hash, &src.join("src/tools/miri"));
         let rustfmt_info = GitInfo::new(omit_git_hash, &src.join("src/tools/rustfmt"));
+        let enzyme_info = GitInfo::new(omit_git_hash, &src.join("src/tools/enzyme"));
 
         // we always try to use git for LLVM builds
         let in_tree_llvm_info = GitInfo::new(false, &src.join("src/llvm-project"));
@@ -332,14 +338,20 @@ impl Build {
         .trim()
         .to_string();
 
-        let initial_libdir = initial_target_dir
-            .parent()
-            .unwrap()
-            .parent()
-            .unwrap()
-            .strip_prefix(&initial_sysroot)
-            .unwrap()
-            .to_path_buf();
+        // FIXME(Zalathar): Determining this path occasionally fails locally for
+        // unknown reasons, so we print some extra context to help track down why.
+        let find_initial_libdir = || {
+            let initial_libdir =
+                initial_target_dir.parent()?.parent()?.strip_prefix(&initial_sysroot).ok()?;
+            Some(initial_libdir.to_path_buf())
+        };
+        let Some(initial_libdir) = find_initial_libdir() else {
+            panic!(
+                "couldn't determine `initial_libdir` \
+                from target dir {initial_target_dir:?} \
+                and sysroot {initial_sysroot:?}"
+            )
+        };
 
         let version = std::fs::read_to_string(src.join("src").join("version"))
             .expect("failed to read src/version");
@@ -393,6 +405,7 @@ impl Build {
             clippy_info,
             miri_info,
             rustfmt_info,
+            enzyme_info,
             in_tree_llvm_info,
             cc: RefCell::new(HashMap::new()),
             cxx: RefCell::new(HashMap::new()),
@@ -666,16 +679,24 @@ impl Build {
     }
 
     /// Gets the space-separated set of activated features for the compiler.
-    fn rustc_features(&self, kind: Kind, target: TargetSelection) -> String {
+    fn rustc_features(&self, kind: Kind, target: TargetSelection, crates: &[String]) -> String {
+        let possible_features_by_crates: HashSet<_> = crates
+            .iter()
+            .flat_map(|krate| &self.crates[krate].features)
+            .map(std::ops::Deref::deref)
+            .collect();
+        let check = |feature: &str| -> bool {
+            crates.is_empty() || possible_features_by_crates.contains(feature)
+        };
         let mut features = vec![];
-        if self.config.jemalloc {
+        if self.config.jemalloc && check("jemalloc") {
             features.push("jemalloc");
         }
-        if self.config.llvm_enabled(target) || kind == Kind::Check {
+        if (self.config.llvm_enabled(target) || kind == Kind::Check) && check("llvm") {
             features.push("llvm");
         }
         // keep in sync with `bootstrap/compile.rs:rustc_cargo_env`
-        if self.config.rustc_parallel {
+        if self.config.rustc_parallel && check("rustc_use_parallel_compiler") {
             features.push("rustc_use_parallel_compiler");
         }
         if self.config.rust_randomize_layout {
@@ -687,7 +708,7 @@ impl Build {
         // which is everything (including debug/trace/etc.)
         // if its unset, if debug_assertions is on, then debug_logging will also be on
         // as well as tracing *ignoring* this feature when debug_assertions is on
-        if !self.config.rust_debug_logging {
+        if !self.config.rust_debug_logging && check("max_level_info") {
             features.push("max_level_info");
         }
 
@@ -740,6 +761,10 @@ impl Build {
         }
     }
 
+    fn enzyme_out(&self, target: TargetSelection) -> PathBuf {
+        self.out.join(&*target.triple).join("enzyme")
+    }
+
     fn lld_out(&self, target: TargetSelection) -> PathBuf {
         self.out.join(target).join("lld")
     }
diff --git a/src/bootstrap/src/utils/cc_detect.rs b/src/bootstrap/src/utils/cc_detect.rs
index 29e6b74aace..a2c7ab31df8 100644
--- a/src/bootstrap/src/utils/cc_detect.rs
+++ b/src/bootstrap/src/utils/cc_detect.rs
@@ -87,15 +87,29 @@ fn new_cc_build(build: &Build, target: TargetSelection) -> cc::Build {
 }
 
 pub fn find(build: &Build) {
-    // For all targets we're going to need a C compiler for building some shims
-    // and such as well as for being a linker for Rust code.
-    let targets = build
-        .targets
-        .iter()
-        .chain(&build.hosts)
-        .cloned()
-        .chain(iter::once(build.build))
-        .collect::<HashSet<_>>();
+    let targets: HashSet<_> = match build.config.cmd {
+        // We don't need to check cross targets for these commands.
+        crate::Subcommand::Clean { .. }
+        | crate::Subcommand::Check { .. }
+        | crate::Subcommand::Suggest { .. }
+        | crate::Subcommand::Format { .. }
+        | crate::Subcommand::Setup { .. } => {
+            build.hosts.iter().cloned().chain(iter::once(build.build)).collect()
+        }
+
+        _ => {
+            // For all targets we're going to need a C compiler for building some shims
+            // and such as well as for being a linker for Rust code.
+            build
+                .targets
+                .iter()
+                .chain(&build.hosts)
+                .cloned()
+                .chain(iter::once(build.build))
+                .collect()
+        }
+    };
+
     for target in targets.into_iter() {
         find_target(build, target);
     }
diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs
index 3fec2d953d9..80ab09881fe 100644
--- a/src/bootstrap/src/utils/change_tracker.rs
+++ b/src/bootstrap/src/utils/change_tracker.rs
@@ -245,4 +245,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[
         severity: ChangeSeverity::Warning,
         summary: "Removed `rust.split-debuginfo` as it was deprecated long time ago.",
     },
+    ChangeInfo {
+        change_id: 129176,
+        severity: ChangeSeverity::Info,
+        summary: "New option `llvm.enzyme` to control whether the llvm based autodiff tool (Enzyme) is built.",
+    },
 ];
diff --git a/src/librustdoc/html/highlight.rs b/src/librustdoc/html/highlight.rs
index 29b4889a6ab..e728da67dc2 100644
--- a/src/librustdoc/html/highlight.rs
+++ b/src/librustdoc/html/highlight.rs
@@ -879,7 +879,9 @@ impl<'src> Classifier<'src> {
             | TokenKind::UnknownPrefix
             | TokenKind::InvalidPrefix
             | TokenKind::InvalidIdent => Class::Ident(self.new_span(before, text)),
-            TokenKind::Lifetime { .. } => Class::Lifetime,
+            TokenKind::Lifetime { .. }
+            | TokenKind::RawLifetime
+            | TokenKind::UnknownPrefixLifetime => Class::Lifetime,
             TokenKind::Eof => panic!("Eof in advance"),
         };
         // Anything that didn't return above is the simple case where we the
diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs
index 60dc142b9ff..b0af8d8c23e 100644
--- a/src/librustdoc/html/render/write_shared.rs
+++ b/src/librustdoc/html/render/write_shared.rs
@@ -29,7 +29,7 @@ use itertools::Itertools;
 use regex::Regex;
 use rustc_data_structures::flock;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
-use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams};
+use rustc_middle::ty::fast_reject::DeepRejectCtxt;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::def_id::DefId;
 use rustc_span::Symbol;
@@ -832,7 +832,7 @@ impl<'cx, 'cache> DocVisitor for TypeImplCollector<'cx, 'cache> {
             // Be aware of `tests/rustdoc/type-alias/deeply-nested-112515.rs` which might regress.
             let Some(impl_did) = impl_item_id.as_def_id() else { continue };
             let for_ty = self.cx.tcx().type_of(impl_did).skip_binder();
-            let reject_cx = DeepRejectCtxt::new(self.cx.tcx(), TreatParams::AsCandidateKey);
+            let reject_cx = DeepRejectCtxt::relate_infer_infer(self.cx.tcx());
             if !reject_cx.types_may_unify(aliased_ty, for_ty) {
                 continue;
             }
diff --git a/src/tools/clippy/clippy_lints/src/escape.rs b/src/tools/clippy/clippy_lints/src/escape.rs
index a5da52b0be5..80360697941 100644
--- a/src/tools/clippy/clippy_lints/src/escape.rs
+++ b/src/tools/clippy/clippy_lints/src/escape.rs
@@ -50,7 +50,7 @@ declare_clippy_lint! {
 }
 
 fn is_non_trait_box(ty: Ty<'_>) -> bool {
-    ty.is_box() && !ty.boxed_ty().is_trait()
+    ty.boxed_ty().is_some_and(|boxed| !boxed.is_trait())
 }
 
 struct EscapeDelegate<'a, 'tcx> {
@@ -191,8 +191,8 @@ impl<'a, 'tcx> Delegate<'tcx> for EscapeDelegate<'a, 'tcx> {
 impl<'a, 'tcx> EscapeDelegate<'a, 'tcx> {
     fn is_large_box(&self, ty: Ty<'tcx>) -> bool {
         // Large types need to be boxed to avoid stack overflows.
-        if ty.is_box() {
-            self.cx.layout_of(ty.boxed_ty()).map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
+        if let Some(boxed_ty) = ty.boxed_ty() {
+            self.cx.layout_of(boxed_ty).map_or(0, |l| l.size.bytes()) > self.too_large_for_stack
         } else {
             false
         }
diff --git a/src/tools/clippy/clippy_lints/src/methods/mod.rs b/src/tools/clippy/clippy_lints/src/methods/mod.rs
index d7126990edb..f61bb3a6bf4 100644
--- a/src/tools/clippy/clippy_lints/src/methods/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/mod.rs
@@ -5187,8 +5187,8 @@ impl SelfKind {
         fn matches_value<'a>(cx: &LateContext<'a>, parent_ty: Ty<'a>, ty: Ty<'a>) -> bool {
             if ty == parent_ty {
                 true
-            } else if ty.is_box() {
-                ty.boxed_ty() == parent_ty
+            } else if let Some(boxed_ty) = ty.boxed_ty() {
+                boxed_ty == parent_ty
             } else if is_type_diagnostic_item(cx, ty, sym::Rc) || is_type_diagnostic_item(cx, ty, sym::Arc) {
                 if let ty::Adt(_, args) = ty.kind() {
                     args.types().next().map_or(false, |t| t == parent_ty)
diff --git a/src/tools/clippy/clippy_lints/src/methods/utils.rs b/src/tools/clippy/clippy_lints/src/methods/utils.rs
index 0d2b0a31317..fe860e5ae26 100644
--- a/src/tools/clippy/clippy_lints/src/methods/utils.rs
+++ b/src/tools/clippy/clippy_lints/src/methods/utils.rs
@@ -16,7 +16,7 @@ pub(super) fn derefs_to_slice<'tcx>(
     fn may_slice<'a>(cx: &LateContext<'a>, ty: Ty<'a>) -> bool {
         match ty.kind() {
             ty::Slice(_) => true,
-            ty::Adt(def, _) if def.is_box() => may_slice(cx, ty.boxed_ty()),
+            ty::Adt(..) if let Some(boxed) = ty.boxed_ty() => may_slice(cx, boxed),
             ty::Adt(..) => is_type_diagnostic_item(cx, ty, sym::Vec),
             ty::Array(_, size) => size.try_eval_target_usize(cx.tcx, cx.param_env).is_some(),
             ty::Ref(_, inner, _) => may_slice(cx, *inner),
@@ -33,7 +33,7 @@ pub(super) fn derefs_to_slice<'tcx>(
     } else {
         match ty.kind() {
             ty::Slice(_) => Some(expr),
-            ty::Adt(def, _) if def.is_box() && may_slice(cx, ty.boxed_ty()) => Some(expr),
+            _ if ty.boxed_ty().is_some_and(|boxed| may_slice(cx, boxed)) => Some(expr),
             ty::Ref(_, inner, _) => {
                 if may_slice(cx, *inner) {
                     Some(expr)
diff --git a/src/tools/clippy/clippy_lints/src/transmute/mod.rs b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
index 373bf61d8ff..a2ae36cc484 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/mod.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/mod.rs
@@ -619,10 +619,10 @@ impl<'tcx> LateLintPass<'tcx> for Transmute {
                 | transmute_ref_to_ref::check(cx, e, from_ty, to_ty, arg, const_context)
                 | transmute_ptr_to_ptr::check(cx, e, from_ty, to_ty, arg, &self.msrv)
                 | transmute_int_to_bool::check(cx, e, from_ty, to_ty, arg)
-                | transmute_int_to_float::check(cx, e, from_ty, to_ty, arg, const_context)
+                | transmute_int_to_float::check(cx, e, from_ty, to_ty, arg)
                 | transmute_int_to_non_zero::check(cx, e, from_ty, to_ty, arg)
-                | transmute_float_to_int::check(cx, e, from_ty, to_ty, arg, const_context)
-                | transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg, const_context)
+                | transmute_float_to_int::check(cx, e, from_ty, to_ty, arg)
+                | transmute_num_to_bytes::check(cx, e, from_ty, to_ty, arg)
                 | (unsound_collection_transmute::check(cx, e, from_ty, to_ty)
                     || transmute_undefined_repr::check(cx, e, from_ty, to_ty))
                 | (eager_transmute::check(cx, e, arg, from_ty, to_ty));
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
index ab3bb5e1062..cb46109c27e 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_float_to_int.rs
@@ -15,10 +15,9 @@ pub(super) fn check<'tcx>(
     from_ty: Ty<'tcx>,
     to_ty: Ty<'tcx>,
     mut arg: &'tcx Expr<'_>,
-    const_context: bool,
 ) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) if !const_context => {
+        (ty::Float(float_ty), ty::Int(_) | ty::Uint(_)) => {
             span_lint_and_then(
                 cx,
                 TRANSMUTE_FLOAT_TO_INT,
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
index d51888e3097..e00fb90c307 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_int_to_float.rs
@@ -14,10 +14,9 @@ pub(super) fn check<'tcx>(
     from_ty: Ty<'tcx>,
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
-    const_context: bool,
 ) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
-        (ty::Int(_) | ty::Uint(_), ty::Float(_)) if !const_context => {
+        (ty::Int(_) | ty::Uint(_), ty::Float(_)) => {
             span_lint_and_then(
                 cx,
                 TRANSMUTE_INT_TO_FLOAT,
diff --git a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
index 88b0ac5a368..362f2bb6960 100644
--- a/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
+++ b/src/tools/clippy/clippy_lints/src/transmute/transmute_num_to_bytes.rs
@@ -14,18 +14,12 @@ pub(super) fn check<'tcx>(
     from_ty: Ty<'tcx>,
     to_ty: Ty<'tcx>,
     arg: &'tcx Expr<'_>,
-    const_context: bool,
 ) -> bool {
     match (&from_ty.kind(), &to_ty.kind()) {
         (ty::Int(_) | ty::Uint(_) | ty::Float(_), ty::Array(arr_ty, _)) => {
             if !matches!(arr_ty.kind(), ty::Uint(UintTy::U8)) {
                 return false;
             }
-            if matches!(from_ty.kind(), ty::Float(_)) && const_context {
-                // TODO: Remove when const_float_bits_conv is stabilized
-                // rust#72447
-                return false;
-            }
 
             span_lint_and_then(
                 cx,
diff --git a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
index 3f130bf5a67..14f4aa6676b 100644
--- a/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
+++ b/src/tools/clippy/clippy_lints/src/unnecessary_box_returns.rs
@@ -75,11 +75,9 @@ impl UnnecessaryBoxReturns {
             .instantiate_bound_regions_with_erased(cx.tcx.fn_sig(def_id).skip_binder())
             .output();
 
-        if !return_ty.is_box() {
+        let Some(boxed_ty) = return_ty.boxed_ty() else {
             return;
-        }
-
-        let boxed_ty = return_ty.boxed_ty();
+        };
 
         // It's sometimes useful to return Box<T> if T is unsized, so don't lint those.
         // Also, don't lint if we know that T is very large, in which case returning
diff --git a/src/tools/clippy/clippy_utils/src/ty.rs b/src/tools/clippy/clippy_utils/src/ty.rs
index f80981c11af..585134209ca 100644
--- a/src/tools/clippy/clippy_utils/src/ty.rs
+++ b/src/tools/clippy/clippy_utils/src/ty.rs
@@ -704,8 +704,8 @@ pub fn expr_sig<'tcx>(cx: &LateContext<'tcx>, expr: &Expr<'_>) -> Option<ExprFnS
 
 /// If the type is function like, get the signature for it.
 pub fn ty_sig<'tcx>(cx: &LateContext<'tcx>, ty: Ty<'tcx>) -> Option<ExprFnSig<'tcx>> {
-    if ty.is_box() {
-        return ty_sig(cx, ty.boxed_ty());
+    if let Some(boxed_ty) = ty.boxed_ty() {
+        return ty_sig(cx, boxed_ty);
     }
     match *ty.kind() {
         ty::Closure(id, subs) => {
diff --git a/src/tools/clippy/tests/ui/transmute.rs b/src/tools/clippy/tests/ui/transmute.rs
index 46629526367..eeea3f080b1 100644
--- a/src/tools/clippy/tests/ui/transmute.rs
+++ b/src/tools/clippy/tests/ui/transmute.rs
@@ -140,24 +140,32 @@ mod int_to_float {
 
     mod issue_5747 {
         const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) };
+        //~^ ERROR: transmute from a `u16` to a `f16`
         const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
+        //~^ ERROR: transmute from a `u32` to a `f32`
         const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
+        //~^ ERROR: transmute from a `i64` to a `f64`
         const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) };
+        //~^ ERROR: transmute from a `i128` to a `f128`
 
         const fn from_bits_16(v: i16) -> f16 {
             unsafe { std::mem::transmute(v) }
+            //~^ ERROR: transmute from a `i16` to a `f16`
         }
 
         const fn from_bits_32(v: i32) -> f32 {
             unsafe { std::mem::transmute(v) }
+            //~^ ERROR: transmute from a `i32` to a `f32`
         }
 
         const fn from_bits_64(v: u64) -> f64 {
             unsafe { std::mem::transmute(v) }
+            //~^ ERROR: transmute from a `u64` to a `f64`
         }
 
         const fn from_bits_128(v: u128) -> f128 {
             unsafe { std::mem::transmute(v) }
+            //~^ ERROR: transmute from a `u128` to a `f128`
         }
     }
 }
@@ -205,9 +213,13 @@ mod num_to_bytes {
             //~^ ERROR: transmute from a `i128` to a `[u8; 16]`
 
             let _: [u8; 2] = std::mem::transmute(0.0f16);
+            //~^ ERROR: transmute from a `f16` to a `[u8; 2]`
             let _: [u8; 4] = std::mem::transmute(0.0f32);
+            //~^ ERROR: transmute from a `f32` to a `[u8; 4]`
             let _: [u8; 8] = std::mem::transmute(0.0f64);
+            //~^ ERROR: transmute from a `f64` to a `[u8; 8]`
             let _: [u8; 16] = std::mem::transmute(0.0f128);
+            //~^ ERROR: transmute from a `f128` to a `[u8; 16]`
         }
     }
 }
diff --git a/src/tools/clippy/tests/ui/transmute.stderr b/src/tools/clippy/tests/ui/transmute.stderr
index 0072f62962a..41a10f381dc 100644
--- a/src/tools/clippy/tests/ui/transmute.stderr
+++ b/src/tools/clippy/tests/ui/transmute.stderr
@@ -148,8 +148,56 @@ error: transmute from a `i128` to a `f128`
 LL |         let _: f128 = unsafe { std::mem::transmute(0_i128) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
 
+error: transmute from a `u16` to a `f16`
+  --> tests/ui/transmute.rs:142:39
+   |
+LL |         const VALUE16: f16 = unsafe { std::mem::transmute(0_u16) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(0_u16)`
+
+error: transmute from a `u32` to a `f32`
+  --> tests/ui/transmute.rs:144:39
+   |
+LL |         const VALUE32: f32 = unsafe { std::mem::transmute(0_u32) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(0_u32)`
+
+error: transmute from a `i64` to a `f64`
+  --> tests/ui/transmute.rs:146:39
+   |
+LL |         const VALUE64: f64 = unsafe { std::mem::transmute(0_i64) };
+   |                                       ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(0_i64 as u64)`
+
+error: transmute from a `i128` to a `f128`
+  --> tests/ui/transmute.rs:148:41
+   |
+LL |         const VALUE128: f128 = unsafe { std::mem::transmute(0_i128) };
+   |                                         ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(0_i128 as u128)`
+
+error: transmute from a `i16` to a `f16`
+  --> tests/ui/transmute.rs:152:22
+   |
+LL |             unsafe { std::mem::transmute(v) }
+   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f16::from_bits(v as u16)`
+
+error: transmute from a `i32` to a `f32`
+  --> tests/ui/transmute.rs:157:22
+   |
+LL |             unsafe { std::mem::transmute(v) }
+   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f32::from_bits(v as u32)`
+
+error: transmute from a `u64` to a `f64`
+  --> tests/ui/transmute.rs:162:22
+   |
+LL |             unsafe { std::mem::transmute(v) }
+   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f64::from_bits(v)`
+
+error: transmute from a `u128` to a `f128`
+  --> tests/ui/transmute.rs:167:22
+   |
+LL |             unsafe { std::mem::transmute(v) }
+   |                      ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `f128::from_bits(v)`
+
 error: transmute from a `u8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:168:30
+  --> tests/ui/transmute.rs:176:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
@@ -158,97 +206,121 @@ LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    = help: to override `-D warnings` add `#[allow(clippy::transmute_num_to_bytes)]`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:171:30
+  --> tests/ui/transmute.rs:179:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:173:31
+  --> tests/ui/transmute.rs:181:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:175:30
+  --> tests/ui/transmute.rs:183:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:177:30
+  --> tests/ui/transmute.rs:185:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:179:31
+  --> tests/ui/transmute.rs:187:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
 error: transmute from a `f16` to a `[u8; 2]`
-  --> tests/ui/transmute.rs:182:30
+  --> tests/ui/transmute.rs:190:30
    |
 LL |             let _: [u8; 2] = std::mem::transmute(0.0f16);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
 
 error: transmute from a `f32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:184:30
+  --> tests/ui/transmute.rs:192:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0.0f32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
 
 error: transmute from a `f64` to a `[u8; 8]`
-  --> tests/ui/transmute.rs:186:30
+  --> tests/ui/transmute.rs:194:30
    |
 LL |             let _: [u8; 8] = std::mem::transmute(0.0f64);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
 
 error: transmute from a `f128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:188:31
+  --> tests/ui/transmute.rs:196:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0.0f128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
 
 error: transmute from a `u8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:194:30
+  --> tests/ui/transmute.rs:202:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0u8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u8.to_ne_bytes()`
 
 error: transmute from a `u32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:196:30
+  --> tests/ui/transmute.rs:204:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0u32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u32.to_ne_bytes()`
 
 error: transmute from a `u128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:198:31
+  --> tests/ui/transmute.rs:206:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0u128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0u128.to_ne_bytes()`
 
 error: transmute from a `i8` to a `[u8; 1]`
-  --> tests/ui/transmute.rs:200:30
+  --> tests/ui/transmute.rs:208:30
    |
 LL |             let _: [u8; 1] = std::mem::transmute(0i8);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i8.to_ne_bytes()`
 
 error: transmute from a `i32` to a `[u8; 4]`
-  --> tests/ui/transmute.rs:202:30
+  --> tests/ui/transmute.rs:210:30
    |
 LL |             let _: [u8; 4] = std::mem::transmute(0i32);
    |                              ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i32.to_ne_bytes()`
 
 error: transmute from a `i128` to a `[u8; 16]`
-  --> tests/ui/transmute.rs:204:31
+  --> tests/ui/transmute.rs:212:31
    |
 LL |             let _: [u8; 16] = std::mem::transmute(0i128);
    |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0i128.to_ne_bytes()`
 
+error: transmute from a `f16` to a `[u8; 2]`
+  --> tests/ui/transmute.rs:215:30
+   |
+LL |             let _: [u8; 2] = std::mem::transmute(0.0f16);
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f16.to_ne_bytes()`
+
+error: transmute from a `f32` to a `[u8; 4]`
+  --> tests/ui/transmute.rs:217:30
+   |
+LL |             let _: [u8; 4] = std::mem::transmute(0.0f32);
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f32.to_ne_bytes()`
+
+error: transmute from a `f64` to a `[u8; 8]`
+  --> tests/ui/transmute.rs:219:30
+   |
+LL |             let _: [u8; 8] = std::mem::transmute(0.0f64);
+   |                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f64.to_ne_bytes()`
+
+error: transmute from a `f128` to a `[u8; 16]`
+  --> tests/ui/transmute.rs:221:31
+   |
+LL |             let _: [u8; 16] = std::mem::transmute(0.0f128);
+   |                               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `to_ne_bytes()`: `0.0f128.to_ne_bytes()`
+
 error: transmute from a `&[u8]` to a `&str`
-  --> tests/ui/transmute.rs:218:28
+  --> tests/ui/transmute.rs:230:28
    |
 LL |     let _: &str = unsafe { std::mem::transmute(B) };
    |                            ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8(B).unwrap()`
@@ -257,16 +329,16 @@ LL |     let _: &str = unsafe { std::mem::transmute(B) };
    = help: to override `-D warnings` add `#[allow(clippy::transmute_bytes_to_str)]`
 
 error: transmute from a `&mut [u8]` to a `&mut str`
-  --> tests/ui/transmute.rs:221:32
+  --> tests/ui/transmute.rs:233:32
    |
 LL |     let _: &mut str = unsafe { std::mem::transmute(mb) };
    |                                ^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_mut(mb).unwrap()`
 
 error: transmute from a `&[u8]` to a `&str`
-  --> tests/ui/transmute.rs:223:30
+  --> tests/ui/transmute.rs:235:30
    |
 LL |     const _: &str = unsafe { std::mem::transmute(B) };
    |                              ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `std::str::from_utf8_unchecked(B)`
 
-error: aborting due to 42 previous errors
+error: aborting due to 54 previous errors
 
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
index 4361a7407d1..83814ca43b9 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.fixed
@@ -1,7 +1,7 @@
 #![warn(clippy::transmute_float_to_int)]
 #![allow(clippy::missing_transmute_annotations)]
-#![feature(f128)]
-#![feature(f16)]
+#![feature(f128, f128_const)]
+#![feature(f16, f16_const)]
 
 fn float_to_int() {
     let _: u32 = unsafe { 1f32.to_bits() };
@@ -20,25 +20,33 @@ fn float_to_int() {
 }
 
 mod issue_5747 {
-    const VALUE16: i16 = unsafe { std::mem::transmute(1f16) };
-    const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
-    const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
-    const VALUE128: u128 = unsafe { std::mem::transmute(1f128) };
+    const VALUE16: i16 = unsafe { 1f16.to_bits() as i16 };
+    //~^ ERROR: transmute from a `f16` to a `i16`
+    const VALUE32: i32 = unsafe { 1f32.to_bits() as i32 };
+    //~^ ERROR: transmute from a `f32` to a `i32`
+    const VALUE64: u64 = unsafe { 1f64.to_bits() };
+    //~^ ERROR: transmute from a `f64` to a `u64`
+    const VALUE128: u128 = unsafe { 1f128.to_bits() };
+    //~^ ERROR: transmute from a `f128` to a `u128`
 
     const fn to_bits_16(v: f16) -> u16 {
-        unsafe { std::mem::transmute(v) }
+        unsafe { v.to_bits() }
+        //~^ ERROR: transmute from a `f16` to a `u16`
     }
 
     const fn to_bits_32(v: f32) -> u32 {
-        unsafe { std::mem::transmute(v) }
+        unsafe { v.to_bits() }
+        //~^ ERROR: transmute from a `f32` to a `u32`
     }
 
     const fn to_bits_64(v: f64) -> i64 {
-        unsafe { std::mem::transmute(v) }
+        unsafe { v.to_bits() as i64 }
+        //~^ ERROR: transmute from a `f64` to a `i64`
     }
 
     const fn to_bits_128(v: f128) -> i128 {
-        unsafe { std::mem::transmute(v) }
+        unsafe { v.to_bits() as i128 }
+        //~^ ERROR: transmute from a `f128` to a `i128`
     }
 }
 
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.rs b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
index 363ce0bcb16..64d6e917203 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.rs
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.rs
@@ -1,7 +1,7 @@
 #![warn(clippy::transmute_float_to_int)]
 #![allow(clippy::missing_transmute_annotations)]
-#![feature(f128)]
-#![feature(f16)]
+#![feature(f128, f128_const)]
+#![feature(f16, f16_const)]
 
 fn float_to_int() {
     let _: u32 = unsafe { std::mem::transmute(1f32) };
@@ -21,24 +21,32 @@ fn float_to_int() {
 
 mod issue_5747 {
     const VALUE16: i16 = unsafe { std::mem::transmute(1f16) };
+    //~^ ERROR: transmute from a `f16` to a `i16`
     const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
+    //~^ ERROR: transmute from a `f32` to a `i32`
     const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
+    //~^ ERROR: transmute from a `f64` to a `u64`
     const VALUE128: u128 = unsafe { std::mem::transmute(1f128) };
+    //~^ ERROR: transmute from a `f128` to a `u128`
 
     const fn to_bits_16(v: f16) -> u16 {
         unsafe { std::mem::transmute(v) }
+        //~^ ERROR: transmute from a `f16` to a `u16`
     }
 
     const fn to_bits_32(v: f32) -> u32 {
         unsafe { std::mem::transmute(v) }
+        //~^ ERROR: transmute from a `f32` to a `u32`
     }
 
     const fn to_bits_64(v: f64) -> i64 {
         unsafe { std::mem::transmute(v) }
+        //~^ ERROR: transmute from a `f64` to a `i64`
     }
 
     const fn to_bits_128(v: f128) -> i128 {
         unsafe { std::mem::transmute(v) }
+        //~^ ERROR: transmute from a `f128` to a `i128`
     }
 }
 
diff --git a/src/tools/clippy/tests/ui/transmute_float_to_int.stderr b/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
index 9cac75f72cd..0cabab58ab0 100644
--- a/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
+++ b/src/tools/clippy/tests/ui/transmute_float_to_int.stderr
@@ -37,5 +37,53 @@ error: transmute from a `f64` to a `u64`
 LL |     let _: u64 = unsafe { std::mem::transmute(-1.0) };
    |                           ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `(-1.0f64).to_bits()`
 
-error: aborting due to 6 previous errors
+error: transmute from a `f16` to a `i16`
+  --> tests/ui/transmute_float_to_int.rs:23:35
+   |
+LL |     const VALUE16: i16 = unsafe { std::mem::transmute(1f16) };
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f16.to_bits() as i16`
+
+error: transmute from a `f32` to a `i32`
+  --> tests/ui/transmute_float_to_int.rs:25:35
+   |
+LL |     const VALUE32: i32 = unsafe { std::mem::transmute(1f32) };
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f32.to_bits() as i32`
+
+error: transmute from a `f64` to a `u64`
+  --> tests/ui/transmute_float_to_int.rs:27:35
+   |
+LL |     const VALUE64: u64 = unsafe { std::mem::transmute(1f64) };
+   |                                   ^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f64.to_bits()`
+
+error: transmute from a `f128` to a `u128`
+  --> tests/ui/transmute_float_to_int.rs:29:37
+   |
+LL |     const VALUE128: u128 = unsafe { std::mem::transmute(1f128) };
+   |                                     ^^^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `1f128.to_bits()`
+
+error: transmute from a `f16` to a `u16`
+  --> tests/ui/transmute_float_to_int.rs:33:18
+   |
+LL |         unsafe { std::mem::transmute(v) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()`
+
+error: transmute from a `f32` to a `u32`
+  --> tests/ui/transmute_float_to_int.rs:38:18
+   |
+LL |         unsafe { std::mem::transmute(v) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits()`
+
+error: transmute from a `f64` to a `i64`
+  --> tests/ui/transmute_float_to_int.rs:43:18
+   |
+LL |         unsafe { std::mem::transmute(v) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i64`
+
+error: transmute from a `f128` to a `i128`
+  --> tests/ui/transmute_float_to_int.rs:48:18
+   |
+LL |         unsafe { std::mem::transmute(v) }
+   |                  ^^^^^^^^^^^^^^^^^^^^^^ help: consider using: `v.to_bits() as i128`
+
+error: aborting due to 14 previous errors
 
diff --git a/src/tools/enzyme b/src/tools/enzyme
new file mode 160000
+Subproject 2fe5164a2423dd67ef25e2c4fb204fd06362494
diff --git a/src/tools/lint-docs/src/lib.rs b/src/tools/lint-docs/src/lib.rs
index 72bb9db7e74..532a27b22aa 100644
--- a/src/tools/lint-docs/src/lib.rs
+++ b/src/tools/lint-docs/src/lib.rs
@@ -56,6 +56,8 @@ pub struct LintExtractor<'a> {
     pub rustc_path: &'a Path,
     /// The target arch to build the docs for.
     pub rustc_target: &'a str,
+    /// The target linker overriding `rustc`'s default
+    pub rustc_linker: Option<&'a str>,
     /// Verbose output.
     pub verbose: bool,
     /// Validate the style and the code example.
@@ -459,6 +461,9 @@ impl<'a> LintExtractor<'a> {
         }
         cmd.arg("--error-format=json");
         cmd.arg("--target").arg(self.rustc_target);
+        if let Some(target_linker) = self.rustc_linker {
+            cmd.arg(format!("-Clinker={target_linker}"));
+        }
         if options.contains(&"test") {
             cmd.arg("--test");
         }
diff --git a/src/tools/lint-docs/src/main.rs b/src/tools/lint-docs/src/main.rs
index 2055fed2b48..e377283b1a4 100644
--- a/src/tools/lint-docs/src/main.rs
+++ b/src/tools/lint-docs/src/main.rs
@@ -27,6 +27,7 @@ fn doit() -> Result<(), Box<dyn Error>> {
     let mut out_path = None;
     let mut rustc_path = None;
     let mut rustc_target = None;
+    let mut rustc_linker = None;
     let mut verbose = false;
     let mut validate = false;
     while let Some(arg) = args.next() {
@@ -55,6 +56,12 @@ fn doit() -> Result<(), Box<dyn Error>> {
                     None => return Err("--rustc-target requires a value".into()),
                 };
             }
+            "--rustc-linker" => {
+                rustc_linker = match args.next() {
+                    Some(s) => Some(s),
+                    None => return Err("--rustc-linker requires a value".into()),
+                };
+            }
             "-v" | "--verbose" => verbose = true,
             "--validate" => validate = true,
             s => return Err(format!("unexpected argument `{}`", s).into()),
@@ -77,6 +84,7 @@ fn doit() -> Result<(), Box<dyn Error>> {
         out_path: &out_path.unwrap(),
         rustc_path: &rustc_path.unwrap(),
         rustc_target: &rustc_target.unwrap(),
+        rustc_linker: rustc_linker.as_deref(),
         verbose,
         validate,
     };
diff --git a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
index ee15b1b5ce9..5c25a55362e 100644
--- a/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
+++ b/src/tools/rust-analyzer/crates/hir-expand/src/inert_attr_macro.rs
@@ -464,6 +464,9 @@ pub const INERT_ATTRIBUTES: &[BuiltinAttribute] = &[
     // Used by the `rustc::potential_query_instability` lint to warn methods which
     // might not be stable during incremental compilation.
     rustc_attr!(rustc_lint_query_instability, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
+    // Used by the `rustc::untracked_query_information` lint to warn methods which
+    // might break incremental compilation.
+    rustc_attr!(rustc_lint_untracked_query_information, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
     // Used by the `rustc::untranslatable_diagnostic` and `rustc::diagnostic_outside_of_impl` lints
     // to assist in changes to diagnostic APIs.
     rustc_attr!(rustc_lint_diagnostics, Normal, template!(Word), WarnFollowing, INTERNAL_UNSTABLE),
diff --git a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
index ff924830ae0..3590486bd29 100644
--- a/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
+++ b/src/tools/rust-analyzer/crates/parser/src/lexed_str.rs
@@ -198,6 +198,13 @@ impl<'a> Converter<'a> {
                     }
                     LIFETIME_IDENT
                 }
+                rustc_lexer::TokenKind::UnknownPrefixLifetime => {
+                    err = "Unknown lifetime prefix";
+                    LIFETIME_IDENT
+                }
+                rustc_lexer::TokenKind::RawLifetime => {
+                    LIFETIME_IDENT
+                }
 
                 rustc_lexer::TokenKind::Semi => T![;],
                 rustc_lexer::TokenKind::Comma => T![,],
diff --git a/src/tools/rustfmt/src/expr.rs b/src/tools/rustfmt/src/expr.rs
index 6ba5217bc92..75c75c523b0 100644
--- a/src/tools/rustfmt/src/expr.rs
+++ b/src/tools/rustfmt/src/expr.rs
@@ -462,7 +462,7 @@ fn rewrite_empty_block(
         return None;
     }
 
-    let label_str = rewrite_label(label);
+    let label_str = rewrite_label(context, label);
     if attrs.map_or(false, |a| !inner_attributes(a).is_empty()) {
         return None;
     }
@@ -527,7 +527,7 @@ fn rewrite_single_line_block(
     if let Some(block_expr) = stmt::Stmt::from_simple_block(context, block, attrs) {
         let expr_shape = shape.offset_left(last_line_width(prefix))?;
         let expr_str = block_expr.rewrite(context, expr_shape)?;
-        let label_str = rewrite_label(label);
+        let label_str = rewrite_label(context, label);
         let result = format!("{prefix}{label_str}{{ {expr_str} }}");
         if result.len() <= shape.width && !result.contains('\n') {
             return Some(result);
@@ -562,7 +562,7 @@ pub(crate) fn rewrite_block_with_visitor(
     }
 
     let inner_attrs = attrs.map(inner_attributes);
-    let label_str = rewrite_label(label);
+    let label_str = rewrite_label(context, label);
     visitor.visit_block(block, inner_attrs.as_deref(), has_braces);
     let visitor_context = visitor.get_context();
     context
@@ -939,7 +939,7 @@ impl<'a> ControlFlow<'a> {
             fresh_shape
         };
 
-        let label_string = rewrite_label(self.label);
+        let label_string = rewrite_label(context, self.label);
         // 1 = space after keyword.
         let offset = self.keyword.len() + label_string.len() + 1;
 
@@ -1168,9 +1168,9 @@ impl<'a> Rewrite for ControlFlow<'a> {
     }
 }
 
-fn rewrite_label(opt_label: Option<ast::Label>) -> Cow<'static, str> {
+fn rewrite_label(context: &RewriteContext<'_>, opt_label: Option<ast::Label>) -> Cow<'static, str> {
     match opt_label {
-        Some(label) => Cow::from(format!("{}: ", label.ident)),
+        Some(label) => Cow::from(format!("{}: ", context.snippet(label.ident.span))),
         None => Cow::from(""),
     }
 }
diff --git a/src/tools/rustfmt/src/macros.rs b/src/tools/rustfmt/src/macros.rs
index b14b74a4938..524fc666fae 100644
--- a/src/tools/rustfmt/src/macros.rs
+++ b/src/tools/rustfmt/src/macros.rs
@@ -1074,7 +1074,7 @@ fn force_space_before(tok: &TokenKind) -> bool {
 fn ident_like(tok: &Token) -> bool {
     matches!(
         tok.kind,
-        TokenKind::Ident(..) | TokenKind::Literal(..) | TokenKind::Lifetime(_)
+        TokenKind::Ident(..) | TokenKind::Literal(..) | TokenKind::Lifetime(..)
     )
 }
 
@@ -1099,7 +1099,9 @@ fn next_space(tok: &TokenKind) -> SpaceState {
         | TokenKind::OpenDelim(_)
         | TokenKind::CloseDelim(_) => SpaceState::Never,
 
-        TokenKind::Literal(..) | TokenKind::Ident(..) | TokenKind::Lifetime(_) => SpaceState::Ident,
+        TokenKind::Literal(..) | TokenKind::Ident(..) | TokenKind::Lifetime(..) => {
+            SpaceState::Ident
+        }
 
         _ => SpaceState::Always,
     }
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 875c61113c5..7730aa467ce 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -548,7 +548,7 @@ impl Rewrite for ast::AnonConst {
 
 impl Rewrite for ast::Lifetime {
     fn rewrite(&self, context: &RewriteContext<'_>, _: Shape) -> Option<String> {
-        Some(rewrite_ident(context, self.ident).to_owned())
+        Some(context.snippet(self.ident.span).to_owned())
     }
 }
 
diff --git a/src/tools/rustfmt/tests/target/raw-lifetimes.rs b/src/tools/rustfmt/tests/target/raw-lifetimes.rs
new file mode 100644
index 00000000000..62fb9be6882
--- /dev/null
+++ b/src/tools/rustfmt/tests/target/raw-lifetimes.rs
@@ -0,0 +1,15 @@
+// rustfmt-edition: 2021
+
+// Simple idempotence test for raw lifetimes.
+
+fn test<'r#gen>() -> &'r#gen () {
+    // Test raw lifetimes...
+}
+
+fn label() {
+    'r#label: {
+        // Test raw labels.
+    }
+}
+
+fn main() {}
diff --git a/src/tools/tidy/config/black.toml b/src/tools/tidy/config/black.toml
index e73847a93ba..a1e1eef987a 100644
--- a/src/tools/tidy/config/black.toml
+++ b/src/tools/tidy/config/black.toml
@@ -12,5 +12,6 @@ extend-exclude = """(\
     src/llvm-project/|\
     src/doc/embedded-book/|\
     src/tools/rustc-perf/|\
+    src/tools/enzyme/|\
     library/backtrace/
     )"""
diff --git a/src/tools/tidy/config/ruff.toml b/src/tools/tidy/config/ruff.toml
index c87c17f7833..2be109010a0 100644
--- a/src/tools/tidy/config/ruff.toml
+++ b/src/tools/tidy/config/ruff.toml
@@ -16,6 +16,7 @@ extend-exclude = [
     "src/llvm-project/",
     "src/doc/embedded-book/",
     "library/backtrace/",
+    "src/tools/enzyme/",
     "src/tools/rustc-perf/",
     # Hack: CI runs from a subdirectory under the main checkout
     "../src/doc/nomicon/",
@@ -29,6 +30,7 @@ extend-exclude = [
     "../src/llvm-project/",
     "../src/doc/embedded-book/",
     "../library/backtrace/",
+    "../src/tools/enzyme/",
     "../src/tools/rustc-perf/",
 ]
 
diff --git a/src/tools/tidy/src/walk.rs b/src/tools/tidy/src/walk.rs
index d4721b5a5fd..4a69022ebdc 100644
--- a/src/tools/tidy/src/walk.rs
+++ b/src/tools/tidy/src/walk.rs
@@ -24,6 +24,7 @@ pub fn filter_dirs(path: &Path) -> bool {
         "src/tools/rust-analyzer",
         "src/tools/rustc-perf",
         "src/tools/rustfmt",
+        "src/tools/enzyme",
         "src/doc/book",
         "src/doc/edition-guide",
         "src/doc/embedded-book",
diff --git a/tests/assembly/asm/aarch64-modifiers.rs b/tests/assembly/asm/aarch64-modifiers.rs
index b7ef1d77ea0..a4a41dd96c1 100644
--- a/tests/assembly/asm/aarch64-modifiers.rs
+++ b/tests/assembly/asm/aarch64-modifiers.rs
@@ -1,6 +1,7 @@
 //@ assembly-output: emit-asm
 //@ compile-flags: -O -C panic=abort
 //@ compile-flags: --target aarch64-unknown-linux-gnu
+//@ compile-flags: -Zmerge-functions=disabled
 //@ needs-llvm-components: aarch64
 
 #![feature(no_core, lang_items, rustc_attrs)]
@@ -29,12 +30,6 @@ macro_rules! check {
         // -O and extern "C" guarantee that the selected register is always r0/s0/d0/q0
         #[no_mangle]
         pub unsafe extern "C" fn $func() -> i32 {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!($code, out($reg) y);
             y
diff --git a/tests/assembly/asm/aarch64-types.rs b/tests/assembly/asm/aarch64-types.rs
index f36345670e3..cf1882ba1a2 100644
--- a/tests/assembly/asm/aarch64-types.rs
+++ b/tests/assembly/asm/aarch64-types.rs
@@ -4,6 +4,7 @@
 //@ [aarch64] needs-llvm-components: aarch64
 //@ [arm64ec] compile-flags: --target arm64ec-pc-windows-msvc
 //@ [arm64ec] needs-llvm-components: aarch64
+//@ compile-flags: -Zmerge-functions=disabled
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch, f16, f128)]
 #![crate_type = "rlib"]
@@ -132,12 +133,6 @@ macro_rules! check {
         // LLVM issue: <https://github.com/llvm/llvm-project/issues/94434>
         #[no_mangle]
         pub unsafe fn $func(inp: &$ty, out: &mut $ty) {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let x = *inp;
             let y;
             asm!(
@@ -155,12 +150,6 @@ macro_rules! check_reg {
         // FIXME(f16_f128): See FIXME in `check!`
         #[no_mangle]
         pub unsafe fn $func(inp: &$ty, out: &mut $ty) {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let x = *inp;
             let y;
             asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
diff --git a/tests/assembly/asm/arm-modifiers.rs b/tests/assembly/asm/arm-modifiers.rs
index 0674e169d72..d421e0e6954 100644
--- a/tests/assembly/asm/arm-modifiers.rs
+++ b/tests/assembly/asm/arm-modifiers.rs
@@ -2,6 +2,7 @@
 //@ compile-flags: -O -C panic=abort
 //@ compile-flags: --target armv7-unknown-linux-gnueabihf
 //@ compile-flags: -C target-feature=+neon
+//@ compile-flags: -Zmerge-functions=disabled
 //@ needs-llvm-components: arm
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd)]
@@ -40,12 +41,6 @@ macro_rules! check {
         // -O and extern "C" guarantee that the selected register is always r0/s0/d0/q0
         #[no_mangle]
         pub unsafe extern "C" fn $func() -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
             y
diff --git a/tests/assembly/asm/arm-types.rs b/tests/assembly/asm/arm-types.rs
index eeff1a070b4..448b92aa839 100644
--- a/tests/assembly/asm/arm-types.rs
+++ b/tests/assembly/asm/arm-types.rs
@@ -2,6 +2,7 @@
 //@ assembly-output: emit-asm
 //@ compile-flags: --target armv7-unknown-linux-gnueabihf
 //@ compile-flags: -C opt-level=0
+//@ compile-flags: -Zmerge-functions=disabled
 //@[d32] compile-flags: -C target-feature=+d32
 //@[neon] compile-flags: -C target-feature=+neon --cfg d32
 //@[neon] filecheck-flags: --check-prefix d32
@@ -114,12 +115,6 @@ macro_rules! check {
     ($func:ident $ty:ident $class:ident $mov:literal) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
             y
@@ -131,12 +126,6 @@ macro_rules! check_reg {
     ($func:ident $ty:ident $reg:tt $mov:literal) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
             y
diff --git a/tests/assembly/asm/hexagon-types.rs b/tests/assembly/asm/hexagon-types.rs
index 269c7582a1c..9389fcf9cba 100644
--- a/tests/assembly/asm/hexagon-types.rs
+++ b/tests/assembly/asm/hexagon-types.rs
@@ -1,5 +1,6 @@
 //@ assembly-output: emit-asm
 //@ compile-flags: --target hexagon-unknown-linux-musl
+//@ compile-flags: -Zmerge-functions=disabled
 //@ needs-llvm-components: hexagon
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
@@ -41,12 +42,6 @@ macro_rules! check {
     ($func:ident $ty:ident $class:ident) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!("{} = {}", out($class) y, in($class) x);
             y
@@ -58,12 +53,6 @@ macro_rules! check_reg {
     ($func:ident $ty:ident $reg:tt) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($reg, " = ", $reg), lateout($reg) y, in($reg) x);
             y
@@ -77,12 +66,6 @@ macro_rules! check_reg {
 // CHECK: InlineAsm End
 #[no_mangle]
 pub unsafe fn sym_static() {
-    // Hack to avoid function merging
-    extern "Rust" {
-        fn dont_merge(s: &str);
-    }
-    dont_merge(stringify!($func));
-
     asm!("r0 = #{}", sym extern_static);
 }
 
@@ -92,12 +75,6 @@ pub unsafe fn sym_static() {
 // CHECK: InlineAsm End
 #[no_mangle]
 pub unsafe fn sym_fn() {
-    // Hack to avoid function merging
-    extern "Rust" {
-        fn dont_merge(s: &str);
-    }
-    dont_merge(stringify!($func));
-
     asm!("r0 = #{}", sym extern_func);
 }
 
diff --git a/tests/assembly/asm/loongarch-type.rs b/tests/assembly/asm/loongarch-type.rs
index e4c46cfcf81..1b097f41105 100644
--- a/tests/assembly/asm/loongarch-type.rs
+++ b/tests/assembly/asm/loongarch-type.rs
@@ -1,5 +1,6 @@
 //@ assembly-output: emit-asm
 //@ compile-flags: --target loongarch64-unknown-linux-gnu
+//@ compile-flags: -Zmerge-functions=disabled
 //@ needs-llvm-components: loongarch
 
 #![feature(no_core, lang_items, rustc_attrs, asm_experimental_arch)]
@@ -39,11 +40,6 @@ extern "C" {
     static extern_static: u8;
 }
 
-// Hack to avoid function merging
-extern "Rust" {
-    fn dont_merge(s: &str);
-}
-
 // CHECK-LABEL: sym_fn:
 // CHECK: #APP
 // CHECK: pcalau12i $t0, %got_pc_hi20(extern_func)
@@ -67,8 +63,6 @@ pub unsafe fn sym_static() {
 macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
         y
@@ -78,8 +72,6 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
 macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
         y
diff --git a/tests/assembly/asm/mips-types.rs b/tests/assembly/asm/mips-types.rs
index bd62f4a5236..f40a28be4a7 100644
--- a/tests/assembly/asm/mips-types.rs
+++ b/tests/assembly/asm/mips-types.rs
@@ -4,6 +4,7 @@
 //@[mips32] needs-llvm-components: mips
 //@[mips64] compile-flags: --target mips64-unknown-linux-gnuabi64
 //@[mips64] needs-llvm-components: mips
+//@ compile-flags: -Zmerge-functions=disabled
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
 #![crate_type = "rlib"]
@@ -43,16 +44,9 @@ extern "C" {
     static extern_static: u8;
 }
 
-// Hack to avoid function merging
-extern "Rust" {
-    fn dont_merge(s: &str);
-}
-
 macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
         y
@@ -62,8 +56,6 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
 macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
         y
diff --git a/tests/assembly/asm/powerpc-types.rs b/tests/assembly/asm/powerpc-types.rs
index bc8af08ad11..85321e5f345 100644
--- a/tests/assembly/asm/powerpc-types.rs
+++ b/tests/assembly/asm/powerpc-types.rs
@@ -4,6 +4,7 @@
 //@[powerpc] needs-llvm-components: powerpc
 //@[powerpc64] compile-flags: --target powerpc64-unknown-linux-gnu
 //@[powerpc64] needs-llvm-components: powerpc
+//@ compile-flags: -Zmerge-functions=disabled
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
 #![crate_type = "rlib"]
@@ -43,16 +44,9 @@ extern "C" {
     static extern_static: u8;
 }
 
-// Hack to avoid function merging
-extern "Rust" {
-    fn dont_merge(s: &str);
-}
-
 macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
         y
@@ -62,8 +56,6 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
 macro_rules! check_reg { ($func:ident, $ty:ty, $rego:tt, $regc:tt, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov, " ", $rego, ", ", $rego), lateout($regc) y, in($regc) x);
         y
diff --git a/tests/assembly/asm/riscv-types.rs b/tests/assembly/asm/riscv-types.rs
index 51b3aaf99d9..1f5d7d85b0a 100644
--- a/tests/assembly/asm/riscv-types.rs
+++ b/tests/assembly/asm/riscv-types.rs
@@ -27,6 +27,7 @@
 //@[riscv32-zfh] filecheck-flags: --check-prefix zfhmin
 
 //@ compile-flags: -C target-feature=+d
+//@ compile-flags: -Zmerge-functions=disabled
 
 #![feature(no_core, lang_items, rustc_attrs, f16)]
 #![crate_type = "rlib"]
@@ -90,12 +91,6 @@ macro_rules! check {
     ($func:ident $ty:ident $class:ident $mov:literal) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " {}, {}"), out($class) y, in($class) x);
             y
@@ -107,12 +102,6 @@ macro_rules! check_reg {
     ($func:ident $ty:ident $reg:tt $mov:literal) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
             y
diff --git a/tests/assembly/asm/s390x-types.rs b/tests/assembly/asm/s390x-types.rs
index 661907360bd..e68b18d7aa6 100644
--- a/tests/assembly/asm/s390x-types.rs
+++ b/tests/assembly/asm/s390x-types.rs
@@ -2,6 +2,7 @@
 //@ assembly-output: emit-asm
 //@[s390x] compile-flags: --target s390x-unknown-linux-gnu
 //@[s390x] needs-llvm-components: systemz
+//@ compile-flags: -Zmerge-functions=disabled
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd, asm_experimental_arch)]
 #![crate_type = "rlib"]
@@ -42,16 +43,9 @@ extern "C" {
     static extern_static: u8;
 }
 
-// Hack to avoid function merging
-extern "Rust" {
-    fn dont_merge(s: &str);
-}
-
 macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov," {}, {}"), out($class) y, in($class) x);
         y
@@ -61,8 +55,6 @@ macro_rules! check { ($func:ident, $ty:ty, $class:ident, $mov:literal) => {
 macro_rules! check_reg { ($func:ident, $ty:ty, $reg:tt, $mov:literal) => {
     #[no_mangle]
     pub unsafe fn $func(x: $ty) -> $ty {
-        dont_merge(stringify!($func));
-
         let y;
         asm!(concat!($mov, " %", $reg, ", %", $reg), lateout($reg) y, in($reg) x);
         y
diff --git a/tests/assembly/asm/x86-modifiers.rs b/tests/assembly/asm/x86-modifiers.rs
index c5e393b1056..5a48af9205f 100644
--- a/tests/assembly/asm/x86-modifiers.rs
+++ b/tests/assembly/asm/x86-modifiers.rs
@@ -7,6 +7,7 @@
 //@[i686] needs-llvm-components: x86
 //@ compile-flags: -C llvm-args=--x86-asm-syntax=intel
 //@ compile-flags: -C target-feature=+avx512bw
+//@ compile-flags: -Zmerge-functions=disabled
 
 #![feature(no_core, lang_items, rustc_attrs)]
 #![crate_type = "rlib"]
@@ -38,12 +39,6 @@ macro_rules! check {
         // -O and extern "C" guarantee that the selected register is always ax/xmm0
         #[no_mangle]
         pub unsafe extern "C" fn $func() -> i32 {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " {0:", $modifier, "}, {0:", $modifier, "}"), out($reg) y);
             y
diff --git a/tests/assembly/asm/x86-types.rs b/tests/assembly/asm/x86-types.rs
index 8e229614420..a40bc10d991 100644
--- a/tests/assembly/asm/x86-types.rs
+++ b/tests/assembly/asm/x86-types.rs
@@ -6,6 +6,7 @@
 //@[i686] needs-llvm-components: x86
 //@ compile-flags: -C llvm-args=--x86-asm-syntax=intel
 //@ compile-flags: -C target-feature=+avx512bw
+//@ compile-flags: -Zmerge-functions=disabled
 
 #![feature(no_core, lang_items, rustc_attrs, repr_simd, f16, f128)]
 #![crate_type = "rlib"]
@@ -283,12 +284,6 @@ macro_rules! check {
     ($func:ident $ty:ident $class:ident $mov:literal) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " {}, {}"), lateout($class) y, in($class) x);
             y
@@ -300,12 +295,6 @@ macro_rules! check_reg {
     ($func:ident $ty:ident $reg:tt $mov:literal) => {
         #[no_mangle]
         pub unsafe fn $func(x: $ty) -> $ty {
-            // Hack to avoid function merging
-            extern "Rust" {
-                fn dont_merge(s: &str);
-            }
-            dont_merge(stringify!($func));
-
             let y;
             asm!(concat!($mov, " ", $reg, ", ", $reg), lateout($reg) y, in($reg) x);
             y
diff --git a/tests/assembly/s390x-backchain-toggle.rs b/tests/assembly/s390x-backchain-toggle.rs
new file mode 100644
index 00000000000..8b6d0cf2123
--- /dev/null
+++ b/tests/assembly/s390x-backchain-toggle.rs
@@ -0,0 +1,46 @@
+//@ revisions: enable-backchain disable-backchain
+//@ assembly-output: emit-asm
+//@ compile-flags: -O --crate-type=lib --target=s390x-unknown-linux-gnu
+//@ needs-llvm-components: systemz
+//@[enable-backchain] compile-flags: -Ctarget-feature=+backchain
+//@[disable-backchain] compile-flags: -Ctarget-feature=-backchain
+#![feature(no_core, lang_items)]
+#![no_std]
+#![no_core]
+
+#[lang = "sized"]
+trait Sized {}
+
+extern "C" {
+    fn extern_func();
+}
+
+// CHECK-LABEL: test_backchain
+#[no_mangle]
+extern "C" fn test_backchain() -> i32 {
+    // Here we try to match if backchain register is saved to the parameter area (stored in r15/sp)
+    // And also if a new parameter area (160 bytes) is allocated for the upcoming function call
+    // enable-backchain: lgr [[REG1:.*]], %r15
+    // enable-backchain-NEXT: aghi %r15, -160
+    // enable-backchain: stg [[REG1]], 0(%r15)
+    // disable-backchain: aghi %r15, -160
+    // disable-backchain-NOT: stg %r{{.*}}, 0(%r15)
+    unsafe {
+        extern_func();
+    }
+    // enable-backchain-NEXT: brasl %r{{.*}}, extern_func@PLT
+    // disable-backchain: brasl %r{{.*}}, extern_func@PLT
+
+    // Make sure that the expected return value is written into %r2 (return register):
+    // enable-backchain-NEXT: lghi %r2, 1
+    // disable-backchain: lghi %r2, 0
+    #[cfg(target_feature = "backchain")]
+    {
+        1
+    }
+    #[cfg(not(target_feature = "backchain"))]
+    {
+        0
+    }
+    // CHECK: br %r{{.*}}
+}
diff --git a/tests/codegen/intrinsics/likely.rs b/tests/codegen/intrinsics/likely.rs
index 098fd9936ce..9dc31d21045 100644
--- a/tests/codegen/intrinsics/likely.rs
+++ b/tests/codegen/intrinsics/likely.rs
@@ -1,4 +1,4 @@
-//@ compile-flags: -C no-prepopulate-passes
+//@ compile-flags: -C no-prepopulate-passes -Copt-level=1
 
 #![crate_type = "lib"]
 #![feature(core_intrinsics)]
diff --git a/tests/codegen/naked-asan.rs b/tests/codegen/naked-asan.rs
new file mode 100644
index 00000000000..a45b95780f7
--- /dev/null
+++ b/tests/codegen/naked-asan.rs
@@ -0,0 +1,22 @@
+// Make sure we do not request sanitizers for naked functions.
+
+//@ only-x86_64
+//@ needs-sanitizer-address
+//@ compile-flags: -Zsanitizer=address -Ctarget-feature=-crt-static
+
+#![crate_type = "lib"]
+#![no_std]
+#![feature(abi_x86_interrupt, naked_functions)]
+
+// CHECK: define x86_intrcc void @page_fault_handler(ptr {{.*}}%0, i64 {{.*}}%1){{.*}}#[[ATTRS:[0-9]+]] {
+// CHECK-NOT: memcpy
+#[naked]
+#[no_mangle]
+pub extern "x86-interrupt" fn page_fault_handler(_: u64, _: u64) {
+    unsafe {
+        core::arch::asm!("ud2", options(noreturn));
+    }
+}
+
+// CHECK: #[[ATTRS]] =
+// CHECK-NOT: sanitize_address
diff --git a/tests/coverage/async.cov-map b/tests/coverage/async.cov-map
index 9e5a4bdc60f..1ba165f1e49 100644
--- a/tests/coverage/async.cov-map
+++ b/tests/coverage/async.cov-map
@@ -92,20 +92,18 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 25, 1) to (start + 0, 23)
 
 Function name: async::g::{closure#0} (unused)
-Raw bytes (69): 0x[01, 01, 00, 0d, 00, 19, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 11, 00, 00, 12, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (59): 0x[01, 01, 00, 0b, 00, 19, 17, 01, 0c, 00, 02, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 09, 00, 0a, 00, 00, 0e, 00, 17, 00, 00, 1b, 00, 1c, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
-Number of file 0 mappings: 13
+Number of file 0 mappings: 11
 - Code(Zero) at (prev + 25, 23) to (start + 1, 12)
 - Code(Zero) at (prev + 2, 9) to (start + 0, 10)
-- Code(Zero) at (prev + 0, 14) to (start + 0, 17)
-- Code(Zero) at (prev + 0, 18) to (start + 0, 23)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 23)
 - Code(Zero) at (prev + 0, 27) to (start + 0, 28)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
 - Code(Zero) at (prev + 1, 9) to (start + 0, 10)
-- Code(Zero) at (prev + 0, 14) to (start + 0, 17)
-- Code(Zero) at (prev + 0, 18) to (start + 0, 23)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 23)
 - Code(Zero) at (prev + 0, 27) to (start + 0, 28)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
@@ -120,15 +118,14 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 33, 1) to (start + 0, 22)
 
 Function name: async::h::{closure#0} (unused)
-Raw bytes (44): 0x[01, 01, 00, 08, 00, 21, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 13, 00, 00, 14, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
+Raw bytes (39): 0x[01, 01, 00, 07, 00, 21, 16, 03, 0c, 00, 04, 09, 00, 0a, 00, 00, 0e, 00, 19, 00, 00, 1a, 00, 1b, 00, 00, 20, 00, 22, 00, 01, 0e, 00, 10, 00, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 0
-Number of file 0 mappings: 8
+Number of file 0 mappings: 7
 - Code(Zero) at (prev + 33, 22) to (start + 3, 12)
 - Code(Zero) at (prev + 4, 9) to (start + 0, 10)
-- Code(Zero) at (prev + 0, 14) to (start + 0, 19)
-- Code(Zero) at (prev + 0, 20) to (start + 0, 25)
+- Code(Zero) at (prev + 0, 14) to (start + 0, 25)
 - Code(Zero) at (prev + 0, 26) to (start + 0, 27)
 - Code(Zero) at (prev + 0, 32) to (start + 0, 34)
 - Code(Zero) at (prev + 1, 14) to (start + 0, 16)
@@ -143,28 +140,25 @@ Number of file 0 mappings: 1
 - Code(Counter(0)) at (prev + 42, 1) to (start + 0, 19)
 
 Function name: async::i::{closure#0}
-Raw bytes (78): 0x[01, 01, 02, 07, 21, 19, 1d, 0e, 01, 2a, 13, 04, 0c, 0d, 05, 09, 00, 0a, 01, 00, 0e, 00, 12, 05, 00, 13, 00, 18, 09, 00, 1c, 00, 21, 0d, 00, 27, 00, 2a, 15, 00, 2b, 00, 30, 1d, 01, 09, 00, 0a, 11, 00, 0e, 00, 11, 25, 00, 12, 00, 17, 29, 00, 1b, 00, 20, 1d, 00, 24, 00, 26, 21, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
+Raw bytes (63): 0x[01, 01, 02, 07, 19, 11, 15, 0b, 01, 2a, 13, 04, 0c, 09, 05, 09, 00, 0a, 01, 00, 0e, 00, 18, 05, 00, 1c, 00, 21, 09, 00, 27, 00, 30, 15, 01, 09, 00, 0a, 0d, 00, 0e, 00, 17, 1d, 00, 1b, 00, 20, 15, 00, 24, 00, 26, 19, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
 Number of files: 1
 - file 0 => global file 1
 Number of expressions: 2
-- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(8)
-- expression 1 operands: lhs = Counter(6), rhs = Counter(7)
-Number of file 0 mappings: 14
+- expression 0 operands: lhs = Expression(1, Add), rhs = Counter(6)
+- expression 1 operands: lhs = Counter(4), rhs = Counter(5)
+Number of file 0 mappings: 11
 - Code(Counter(0)) at (prev + 42, 19) to (start + 4, 12)
-- Code(Counter(3)) at (prev + 5, 9) to (start + 0, 10)
-- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 18)
-- Code(Counter(1)) at (prev + 0, 19) to (start + 0, 24)
-- Code(Counter(2)) at (prev + 0, 28) to (start + 0, 33)
-- Code(Counter(3)) at (prev + 0, 39) to (start + 0, 42)
-- Code(Counter(5)) at (prev + 0, 43) to (start + 0, 48)
-- Code(Counter(7)) at (prev + 1, 9) to (start + 0, 10)
-- Code(Counter(4)) at (prev + 0, 14) to (start + 0, 17)
-- Code(Counter(9)) at (prev + 0, 18) to (start + 0, 23)
-- Code(Counter(10)) at (prev + 0, 27) to (start + 0, 32)
-- Code(Counter(7)) at (prev + 0, 36) to (start + 0, 38)
-- Code(Counter(8)) at (prev + 1, 14) to (start + 0, 16)
+- Code(Counter(2)) at (prev + 5, 9) to (start + 0, 10)
+- Code(Counter(0)) at (prev + 0, 14) to (start + 0, 24)
+- Code(Counter(1)) at (prev + 0, 28) to (start + 0, 33)
+- Code(Counter(2)) at (prev + 0, 39) to (start + 0, 48)
+- Code(Counter(5)) at (prev + 1, 9) to (start + 0, 10)
+- Code(Counter(3)) at (prev + 0, 14) to (start + 0, 23)
+- Code(Counter(7)) at (prev + 0, 27) to (start + 0, 32)
+- Code(Counter(5)) at (prev + 0, 36) to (start + 0, 38)
+- Code(Counter(6)) at (prev + 1, 14) to (start + 0, 16)
 - Code(Expression(0, Add)) at (prev + 2, 1) to (start + 0, 2)
-    = ((c6 + c7) + c8)
+    = ((c4 + c5) + c6)
 
 Function name: async::j
 Raw bytes (58): 0x[01, 01, 02, 07, 0d, 05, 09, 0a, 01, 35, 01, 00, 0d, 01, 0b, 0b, 00, 0c, 05, 01, 09, 00, 0a, 01, 00, 0e, 00, 1b, 05, 00, 1f, 00, 27, 09, 01, 09, 00, 0a, 11, 00, 0e, 00, 1a, 09, 00, 1e, 00, 20, 0d, 01, 0e, 00, 10, 03, 02, 01, 00, 02]
diff --git a/tests/coverage/async.coverage b/tests/coverage/async.coverage
index f5473829b02..995674257c4 100644
--- a/tests/coverage/async.coverage
+++ b/tests/coverage/async.coverage
@@ -45,9 +45,9 @@
    LL|      1|                    // executed asynchronously.
    LL|      1|    match x {
    LL|      1|        y if c(x).await == y + 1 => { d().await; }
-                      ^0        ^0                  ^0  ^0
+                      ^0                            ^0
    LL|      1|        y if f().await == y + 1 => (),
-                      ^0       ^0                ^0
+                      ^0                         ^0
    LL|      1|        _ => (),
    LL|       |    }
    LL|      1|}
diff --git a/tests/coverage/await_ready.cov-map b/tests/coverage/await_ready.cov-map
new file mode 100644
index 00000000000..0c9f2ae29a8
--- /dev/null
+++ b/tests/coverage/await_ready.cov-map
@@ -0,0 +1,25 @@
+Function name: await_ready::await_ready
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 0a, 01, 00, 1e]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 10, 1) to (start + 0, 30)
+
+Function name: await_ready::await_ready::{closure#0}
+Raw bytes (14): 0x[01, 01, 00, 02, 01, 0a, 1e, 03, 0f, 05, 04, 01, 00, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 2
+- Code(Counter(0)) at (prev + 10, 30) to (start + 3, 15)
+- Code(Counter(1)) at (prev + 4, 1) to (start + 0, 2)
+
+Function name: await_ready::main
+Raw bytes (9): 0x[01, 01, 00, 01, 01, 10, 01, 03, 02]
+Number of files: 1
+- file 0 => global file 1
+Number of expressions: 0
+Number of file 0 mappings: 1
+- Code(Counter(0)) at (prev + 16, 1) to (start + 3, 2)
+
diff --git a/tests/coverage/await_ready.coverage b/tests/coverage/await_ready.coverage
new file mode 100644
index 00000000000..0075f09426e
--- /dev/null
+++ b/tests/coverage/await_ready.coverage
@@ -0,0 +1,38 @@
+   LL|       |#![feature(coverage_attribute)]
+   LL|       |#![feature(custom_inner_attributes)] // for #![rustfmt::skip]
+   LL|       |#![feature(noop_waker)]
+   LL|       |#![rustfmt::skip]
+   LL|       |//@ edition: 2021
+   LL|       |
+   LL|       |#[coverage(off)]
+   LL|       |async fn ready() -> u8 { 1 }
+   LL|       |
+   LL|      1|async fn await_ready() -> u8 {
+   LL|      1|    // await should be covered even if the function never yields
+   LL|      1|    ready()
+   LL|      1|        .await
+   LL|      1|}
+   LL|       |
+   LL|      1|fn main() {
+   LL|      1|    let mut future = Box::pin(await_ready());
+   LL|      1|    executor::block_on(future.as_mut());
+   LL|      1|}
+   LL|       |
+   LL|       |mod executor {
+   LL|       |    use core::future::Future;
+   LL|       |    use core::pin::pin;
+   LL|       |    use core::task::{Context, Poll, Waker};
+   LL|       |
+   LL|       |    #[coverage(off)]
+   LL|       |    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+   LL|       |        let mut future = pin!(future);
+   LL|       |        let mut context = Context::from_waker(Waker::noop());
+   LL|       |
+   LL|       |        loop {
+   LL|       |            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+   LL|       |                break val;
+   LL|       |            }
+   LL|       |        }
+   LL|       |    }
+   LL|       |}
+
diff --git a/tests/coverage/await_ready.rs b/tests/coverage/await_ready.rs
new file mode 100644
index 00000000000..9212a4ba705
--- /dev/null
+++ b/tests/coverage/await_ready.rs
@@ -0,0 +1,37 @@
+#![feature(coverage_attribute)]
+#![feature(custom_inner_attributes)] // for #![rustfmt::skip]
+#![feature(noop_waker)]
+#![rustfmt::skip]
+//@ edition: 2021
+
+#[coverage(off)]
+async fn ready() -> u8 { 1 }
+
+async fn await_ready() -> u8 {
+    // await should be covered even if the function never yields
+    ready()
+        .await
+}
+
+fn main() {
+    let mut future = Box::pin(await_ready());
+    executor::block_on(future.as_mut());
+}
+
+mod executor {
+    use core::future::Future;
+    use core::pin::pin;
+    use core::task::{Context, Poll, Waker};
+
+    #[coverage(off)]
+    pub fn block_on<F: Future>(mut future: F) -> F::Output {
+        let mut future = pin!(future);
+        let mut context = Context::from_waker(Waker::noop());
+
+        loop {
+            if let Poll::Ready(val) = future.as_mut().poll(&mut context) {
+                break val;
+            }
+        }
+    }
+}
diff --git a/tests/crashes/118987.rs b/tests/crashes/118987.rs
deleted file mode 100644
index 4382a7bcb63..00000000000
--- a/tests/crashes/118987.rs
+++ /dev/null
@@ -1,17 +0,0 @@
-//@ known-bug: #118987
-#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
-
-trait Assoc {
-    type Output;
-}
-
-default impl<T: Clone> Assoc for T {
-    type Output = bool;
-}
-
-impl Assoc for u8 {}
-
-trait Foo {}
-
-impl Foo for <u8 as Assoc>::Output {}
-impl Foo for <u16 as Assoc>::Output {}
diff --git a/tests/crashes/123629.rs b/tests/crashes/123629.rs
new file mode 100644
index 00000000000..61532321806
--- /dev/null
+++ b/tests/crashes/123629.rs
@@ -0,0 +1,10 @@
+//@ known-bug: #123629
+#![feature(generic_assert)]
+
+fn foo()
+where
+    for<const N: usize = { assert!(u) }> ():,
+{
+}
+
+fn main() {}
diff --git a/tests/crashes/127033.rs b/tests/crashes/127033.rs
new file mode 100644
index 00000000000..919c9dfd30e
--- /dev/null
+++ b/tests/crashes/127033.rs
@@ -0,0 +1,18 @@
+//@ known-bug: #127033
+//@ compile-flags: --edition=2021
+
+pub trait RaftLogStorage {
+    fn save_vote(vote: ()) -> impl std::future::Future + Send;
+}
+
+struct X;
+impl RaftLogStorage for X {
+    fn save_vote(vote: ()) -> impl std::future::Future {
+        loop {}
+        async {
+            vote
+        }
+    }
+}
+
+fn main() {}
diff --git a/tests/crashes/129372.rs b/tests/crashes/129372.rs
new file mode 100644
index 00000000000..43be01b35df
--- /dev/null
+++ b/tests/crashes/129372.rs
@@ -0,0 +1,52 @@
+//@ known-bug: #129372
+//@ compile-flags: -Cdebuginfo=2 -Copt-level=0
+
+pub struct Wrapper<T>(T);
+struct Struct;
+
+pub trait TraitA {
+    type AssocA<'t>;
+}
+pub trait TraitB {
+    type AssocB;
+}
+
+pub fn helper(v: impl MethodTrait) {
+    let _local_that_causes_ice = v.method();
+}
+
+pub fn main() {
+    helper(Wrapper(Struct));
+}
+
+pub trait MethodTrait {
+    type Assoc<'a>;
+
+    fn method(self) -> impl for<'a> FnMut(&'a ()) -> Self::Assoc<'a>;
+}
+
+impl<T: TraitB> MethodTrait for T
+where
+    <T as TraitB>::AssocB: TraitA,
+{
+    type Assoc<'a> = <T::AssocB as TraitA>::AssocA<'a>;
+
+    fn method(self) -> impl for<'a> FnMut(&'a ()) -> Self::Assoc<'a> {
+        move |_| loop {}
+    }
+}
+
+impl<T, B> TraitB for Wrapper<B>
+where
+    B: TraitB<AssocB = T>,
+{
+    type AssocB = T;
+}
+
+impl TraitB for Struct {
+    type AssocB = Struct;
+}
+
+impl TraitA for Struct {
+    type AssocA<'t> = Self;
+}
diff --git a/tests/ui-fulldeps/internal-lints/query_completeness.rs b/tests/ui-fulldeps/internal-lints/query_completeness.rs
new file mode 100644
index 00000000000..50b0fb4c3fc
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/query_completeness.rs
@@ -0,0 +1,16 @@
+//@ compile-flags: -Z unstable-options
+// #[cfg(bootstrap)]: We can stop ignoring next beta bump; afterward this ALWAYS should run.
+//@ ignore-stage1 (requires matching sysroot built with in-tree compiler)
+#![feature(rustc_private)]
+#![deny(rustc::untracked_query_information)]
+
+extern crate rustc_data_structures;
+
+use rustc_data_structures::steal::Steal;
+
+fn use_steal(x: Steal<()>) {
+    let _ = x.is_stolen();
+    //~^ ERROR `is_stolen` accesses information that is not tracked by the query system
+}
+
+fn main() {}
diff --git a/tests/ui-fulldeps/internal-lints/query_completeness.stderr b/tests/ui-fulldeps/internal-lints/query_completeness.stderr
new file mode 100644
index 00000000000..35bb867f40e
--- /dev/null
+++ b/tests/ui-fulldeps/internal-lints/query_completeness.stderr
@@ -0,0 +1,15 @@
+error: `is_stolen` accesses information that is not tracked by the query system
+  --> $DIR/query_completeness.rs:12:15
+   |
+LL |     let _ = x.is_stolen();
+   |               ^^^^^^^^^
+   |
+   = note: if you believe this case to be fine, allow this lint and add a comment explaining your rationale
+note: the lint level is defined here
+  --> $DIR/query_completeness.rs:5:9
+   |
+LL | #![deny(rustc::untracked_query_information)]
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/asm/const-refs-to-static.rs b/tests/ui/asm/const-refs-to-static.rs
new file mode 100644
index 00000000000..9fc010b5763
--- /dev/null
+++ b/tests/ui/asm/const-refs-to-static.rs
@@ -0,0 +1,21 @@
+//@ needs-asm-support
+//@ ignore-nvptx64
+//@ ignore-spirv
+
+#![feature(const_refs_to_static)]
+
+use std::arch::{asm, global_asm};
+use std::ptr::addr_of;
+
+static FOO: u8 = 42;
+
+global_asm!("{}", const addr_of!(FOO));
+//~^ ERROR invalid type for `const` operand
+
+#[no_mangle]
+fn inline() {
+    unsafe { asm!("{}", const addr_of!(FOO)) };
+    //~^ ERROR invalid type for `const` operand
+}
+
+fn main() {}
diff --git a/tests/ui/asm/const-refs-to-static.stderr b/tests/ui/asm/const-refs-to-static.stderr
new file mode 100644
index 00000000000..8fd69da0d1e
--- /dev/null
+++ b/tests/ui/asm/const-refs-to-static.stderr
@@ -0,0 +1,22 @@
+error: invalid type for `const` operand
+  --> $DIR/const-refs-to-static.rs:12:19
+   |
+LL | global_asm!("{}", const addr_of!(FOO));
+   |                   ^^^^^^-------------
+   |                         |
+   |                         is a `*const u8`
+   |
+   = help: `const` operands must be of an integer type
+
+error: invalid type for `const` operand
+  --> $DIR/const-refs-to-static.rs:17:25
+   |
+LL |     unsafe { asm!("{}", const addr_of!(FOO)) };
+   |                         ^^^^^^-------------
+   |                               |
+   |                               is a `*const u8`
+   |
+   = help: `const` operands must be of an integer type
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/associated-types/associated-types-coherence-failure.stderr b/tests/ui/associated-types/associated-types-coherence-failure.stderr
index 211613b3714..25c22e5f82a 100644
--- a/tests/ui/associated-types/associated-types-coherence-failure.stderr
+++ b/tests/ui/associated-types/associated-types-coherence-failure.stderr
@@ -1,20 +1,20 @@
-error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `Cow<'_, _>`
+error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `<_ as ToOwned>::Owned`
   --> $DIR/associated-types-coherence-failure.rs:21:1
    |
 LL | impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
    | ----------------------------------------------------------------------------- first implementation here
 ...
 LL | impl<'a, B: ?Sized> IntoCow<'a, B> for Cow<'a, B> where B: ToOwned {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Cow<'_, _>`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<_ as ToOwned>::Owned`
 
-error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `&_`
+error[E0119]: conflicting implementations of trait `IntoCow<'_, _>` for type `<_ as ToOwned>::Owned`
   --> $DIR/associated-types-coherence-failure.rs:28:1
    |
 LL | impl<'a, B: ?Sized> IntoCow<'a, B> for <B as ToOwned>::Owned where B: ToOwned {
    | ----------------------------------------------------------------------------- first implementation here
 ...
 LL | impl<'a, B: ?Sized> IntoCow<'a, B> for &'a B where B: ToOwned {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<_ as ToOwned>::Owned`
 
 error: aborting due to 2 previous errors
 
diff --git a/tests/ui/async-await/async-closures/tainted-body-2.rs b/tests/ui/async-await/async-closures/tainted-body-2.rs
new file mode 100644
index 00000000000..73c6bdc30a0
--- /dev/null
+++ b/tests/ui/async-await/async-closures/tainted-body-2.rs
@@ -0,0 +1,18 @@
+//@ edition: 2021
+
+#![feature(async_closure)]
+
+// Ensure that building a by-ref async closure body doesn't ICE when the parent
+// body is tainted.
+
+fn main() {
+    missing;
+    //~^ ERROR cannot find value `missing` in this scope
+
+    // We don't do numerical inference fallback when the body is tainted.
+    // This leads to writeback folding the type of the coroutine-closure
+    // into an error type, since its signature contains that numerical
+    // infer var.
+    let c = async |_| {};
+    c(1);
+}
diff --git a/tests/ui/async-await/async-closures/tainted-body-2.stderr b/tests/ui/async-await/async-closures/tainted-body-2.stderr
new file mode 100644
index 00000000000..798d47064d9
--- /dev/null
+++ b/tests/ui/async-await/async-closures/tainted-body-2.stderr
@@ -0,0 +1,9 @@
+error[E0425]: cannot find value `missing` in this scope
+  --> $DIR/tainted-body-2.rs:9:5
+   |
+LL |     missing;
+   |     ^^^^^^^ not found in this scope
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0425`.
diff --git a/tests/ui/async-await/async-closures/validate-synthetic-body.rs b/tests/ui/async-await/async-closures/validate-synthetic-body.rs
new file mode 100644
index 00000000000..67e683ac08a
--- /dev/null
+++ b/tests/ui/async-await/async-closures/validate-synthetic-body.rs
@@ -0,0 +1,19 @@
+//@ check-pass
+//@ edition: 2021
+
+#![feature(async_closure)]
+
+// Make sure that we don't hit a query cycle when validating
+// the by-move coroutine body for an async closure.
+
+use std::future::Future;
+
+async fn test<Fut: Future>(operation: impl Fn() -> Fut) {
+    operation().await;
+}
+
+pub async fn orchestrate_simple_crud() {
+    test(async || async {}.await).await;
+}
+
+fn main() {}
diff --git a/tests/ui/auto-traits/opaque_type_candidate_selection.rs b/tests/ui/auto-traits/opaque_type_candidate_selection.rs
deleted file mode 100644
index d6973b76a6e..00000000000
--- a/tests/ui/auto-traits/opaque_type_candidate_selection.rs
+++ /dev/null
@@ -1,30 +0,0 @@
-//! used to ICE: #119272
-
-//@ check-pass
-
-#![feature(type_alias_impl_trait)]
-mod defining_scope {
-    use super::*;
-    pub type Alias<T> = impl Sized;
-
-    pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
-        x
-    }
-}
-
-struct Container<T: Trait<U>, U> {
-    x: <T as Trait<U>>::Assoc,
-}
-
-trait Trait<T> {
-    type Assoc;
-}
-
-impl<T> Trait<T> for T {
-    type Assoc = Box<u32>;
-}
-impl<T> Trait<T> for defining_scope::Alias<T> {
-    type Assoc = usize;
-}
-
-fn main() {}
diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
index dbb22d8937d..1d28bb46812 100644
--- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
+++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.stock.stderr
@@ -5,6 +5,8 @@ LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
    | ---------------------------------------------- first implementation here
 LL | impl<'a, T> MyTrait<'a> for &'a T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+   |
+   = note: downstream crates may implement trait `MyPredicate<'_>` for type `&_`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
index dbb22d8937d..1d28bb46812 100644
--- a/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
+++ b/tests/ui/coherence/coherence-negative-outlives-lifetimes.with_negative_coherence.stderr
@@ -5,6 +5,8 @@ LL | impl<'a, T: MyPredicate<'a>> MyTrait<'a> for T {}
    | ---------------------------------------------- first implementation here
 LL | impl<'a, T> MyTrait<'a> for &'a T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+   |
+   = note: downstream crates may implement trait `MyPredicate<'_>` for type `&_`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr b/tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr
deleted file mode 100644
index 2938bc629b2..00000000000
--- a/tests/ui/coherence/coherence-overlap-downstream-inherent.old.stderr
+++ /dev/null
@@ -1,23 +0,0 @@
-error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:10:26
-   |
-LL | impl<T:Sugar> Sweet<T> { fn dummy(&self) { } }
-   |                          ^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-LL |
-LL | impl<T:Fruit> Sweet<T> { fn dummy(&self) { } }
-   |                          --------------- other definition for `dummy`
-
-error[E0592]: duplicate definitions with name `f`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:16:38
-   |
-LL | impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} }
-   |                                      ^^^^^^^^^^^ duplicate definitions for `f`
-LL |
-LL | impl<X> A<i32, X> { fn f(&self) {} }
-   |                     ----------- other definition for `f`
-   |
-   = note: downstream crates may implement trait `Bar<_>` for type `i32`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0592`.
diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs
index 3e90b7c7fdd..5dea33e330b 100644
--- a/tests/ui/coherence/coherence-overlap-downstream-inherent.rs
+++ b/tests/ui/coherence/coherence-overlap-downstream-inherent.rs
@@ -1,6 +1,3 @@
-//@ revisions: old next
-//@[next] compile-flags: -Znext-solver
-
 // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even
 // though no impls are found.
 
diff --git a/tests/ui/coherence/coherence-overlap-downstream-inherent.next.stderr b/tests/ui/coherence/coherence-overlap-downstream-inherent.stderr
index 2938bc629b2..bbce4b530b4 100644
--- a/tests/ui/coherence/coherence-overlap-downstream-inherent.next.stderr
+++ b/tests/ui/coherence/coherence-overlap-downstream-inherent.stderr
@@ -1,5 +1,5 @@
 error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:10:26
+  --> $DIR/coherence-overlap-downstream-inherent.rs:7:26
    |
 LL | impl<T:Sugar> Sweet<T> { fn dummy(&self) { } }
    |                          ^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
@@ -8,7 +8,7 @@ LL | impl<T:Fruit> Sweet<T> { fn dummy(&self) { } }
    |                          --------------- other definition for `dummy`
 
 error[E0592]: duplicate definitions with name `f`
-  --> $DIR/coherence-overlap-downstream-inherent.rs:16:38
+  --> $DIR/coherence-overlap-downstream-inherent.rs:13:38
    |
 LL | impl<X, T> A<T, X> where T: Bar<X> { fn f(&self) {} }
    |                                      ^^^^^^^^^^^ duplicate definitions for `f`
diff --git a/tests/ui/coherence/coherence-overlap-downstream.next.stderr b/tests/ui/coherence/coherence-overlap-downstream.next.stderr
deleted file mode 100644
index 6c2e9466b4b..00000000000
--- a/tests/ui/coherence/coherence-overlap-downstream.next.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0119]: conflicting implementations of trait `Sweet`
-  --> $DIR/coherence-overlap-downstream.rs:11:1
-   |
-LL | impl<T:Sugar> Sweet for T { }
-   | ------------------------- first implementation here
-LL | impl<T:Fruit> Sweet for T { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
-
-error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32`
-  --> $DIR/coherence-overlap-downstream.rs:17:1
-   |
-LL | impl<X, T> Foo<X> for T where T: Bar<X> {}
-   | --------------------------------------- first implementation here
-LL | impl<X> Foo<X> for i32 {}
-   | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `i32`
-   |
-   = note: downstream crates may implement trait `Bar<_>` for type `i32`
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-downstream.rs b/tests/ui/coherence/coherence-overlap-downstream.rs
index 8b99296d12a..738ec0e3d45 100644
--- a/tests/ui/coherence/coherence-overlap-downstream.rs
+++ b/tests/ui/coherence/coherence-overlap-downstream.rs
@@ -1,6 +1,3 @@
-//@ revisions: old next
-//@[next] compile-flags: -Znext-solver
-
 // Tests that we consider `T: Sugar + Fruit` to be ambiguous, even
 // though no impls are found.
 
diff --git a/tests/ui/coherence/coherence-overlap-downstream.old.stderr b/tests/ui/coherence/coherence-overlap-downstream.stderr
index 6c2e9466b4b..9ab099489d9 100644
--- a/tests/ui/coherence/coherence-overlap-downstream.old.stderr
+++ b/tests/ui/coherence/coherence-overlap-downstream.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Sweet`
-  --> $DIR/coherence-overlap-downstream.rs:11:1
+  --> $DIR/coherence-overlap-downstream.rs:8:1
    |
 LL | impl<T:Sugar> Sweet for T { }
    | ------------------------- first implementation here
@@ -7,7 +7,7 @@ LL | impl<T:Fruit> Sweet for T { }
    | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0119]: conflicting implementations of trait `Foo<_>` for type `i32`
-  --> $DIR/coherence-overlap-downstream.rs:17:1
+  --> $DIR/coherence-overlap-downstream.rs:14:1
    |
 LL | impl<X, T> Foo<X> for T where T: Bar<X> {}
    | --------------------------------------- first implementation here
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr
deleted file mode 100644
index 2f3ad627808..00000000000
--- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.old.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-issue-23516-inherent.rs:12:25
-   |
-LL | impl<T:Sugar> Cake<T> { fn dummy(&self) { } }
-   |                         ^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
-LL |
-LL | impl<U:Sugar> Cake<Box<U>> { fn dummy(&self) { } }
-   |                              --------------- other definition for `dummy`
-   |
-   = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0592`.
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs
index 53b0a40fa66..a272e620fca 100644
--- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs
+++ b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.rs
@@ -1,6 +1,3 @@
-//@ revisions: old next
-//@[next] compile-flags: -Znext-solver
-
 // Tests that we consider `Box<U>: !Sugar` to be ambiguous, even
 // though we see no impl of `Sugar` for `Box`. Therefore, an overlap
 // error is reported for the following pair of impls (#23516).
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.next.stderr b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr
index 2f3ad627808..aacdeb5b0f9 100644
--- a/tests/ui/coherence/coherence-overlap-issue-23516-inherent.next.stderr
+++ b/tests/ui/coherence/coherence-overlap-issue-23516-inherent.stderr
@@ -1,5 +1,5 @@
 error[E0592]: duplicate definitions with name `dummy`
-  --> $DIR/coherence-overlap-issue-23516-inherent.rs:12:25
+  --> $DIR/coherence-overlap-issue-23516-inherent.rs:9:25
    |
 LL | impl<T:Sugar> Cake<T> { fn dummy(&self) { } }
    |                         ^^^^^^^^^^^^^^^ duplicate definitions for `dummy`
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.old.stderr b/tests/ui/coherence/coherence-overlap-issue-23516.old.stderr
deleted file mode 100644
index b9494774025..00000000000
--- a/tests/ui/coherence/coherence-overlap-issue-23516.old.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `Sweet` for type `Box<_>`
-  --> $DIR/coherence-overlap-issue-23516.rs:11:1
-   |
-LL | impl<T:Sugar> Sweet for T { }
-   | ------------------------- first implementation here
-LL | impl<U:Sugar> Sweet for Box<U> { }
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
-   |
-   = note: downstream crates may implement trait `Sugar` for type `std::boxed::Box<_>`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.rs b/tests/ui/coherence/coherence-overlap-issue-23516.rs
index 620e00cd057..63e42e8f412 100644
--- a/tests/ui/coherence/coherence-overlap-issue-23516.rs
+++ b/tests/ui/coherence/coherence-overlap-issue-23516.rs
@@ -1,6 +1,3 @@
-//@ revisions: old next
-//@[next] compile-flags: -Znext-solver
-
 // Tests that we consider `Box<U>: !Sugar` to be ambiguous, even
 // though we see no impl of `Sugar` for `Box`. Therefore, an overlap
 // error is reported for the following pair of impls (#23516).
diff --git a/tests/ui/coherence/coherence-overlap-issue-23516.next.stderr b/tests/ui/coherence/coherence-overlap-issue-23516.stderr
index b9494774025..7b1b240291a 100644
--- a/tests/ui/coherence/coherence-overlap-issue-23516.next.stderr
+++ b/tests/ui/coherence/coherence-overlap-issue-23516.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Sweet` for type `Box<_>`
-  --> $DIR/coherence-overlap-issue-23516.rs:11:1
+  --> $DIR/coherence-overlap-issue-23516.rs:8:1
    |
 LL | impl<T:Sugar> Sweet for T { }
    | ------------------------- first implementation here
diff --git a/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr
index 21c82eedd5d..c5bb695eb18 100644
--- a/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr
+++ b/tests/ui/coherence/coherence-overlap-negate-not-use-feature-gate.stderr
@@ -5,6 +5,8 @@ LL | impl<T: DerefMut> Foo for T {}
    | --------------------------- first implementation here
 LL | impl<U> Foo for &U {}
    | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+   |
+   = note: downstream crates may implement trait `std::ops::DerefMut` for type `&_`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr
deleted file mode 100644
index 2ffb6000ec8..00000000000
--- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.classic.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
-  --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1
-   |
-LL | / impl<T> Trait for T
-LL | | where
-LL | |     T: 'static,
-LL | |     for<'a> T: WithAssoc<'a>,
-LL | |     for<'a> <T as WithAssoc<'a>>::Assoc: WhereBound,
-   | |____________________________________________________- first implementation here
-...
-LL |   impl<T> Trait for Box<T> {}
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
-   |
-   = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
-   = note: downstream crates may implement trait `WhereBound` for type `<std::boxed::Box<_> as WithAssoc<'a>>::Assoc`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs
index b8b6d8846ef..0695076e221 100644
--- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.rs
@@ -2,9 +2,6 @@
 // "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could"
 #![crate_type = "lib"]
 
-//@ revisions: classic next
-//@[next] compile-flags: -Znext-solver
-
 trait WhereBound {}
 impl WhereBound for () {}
 
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.stderr
index 99abdf65abd..57befbe6e68 100644
--- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.next.stderr
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-0.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
-  --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:27:1
+  --> $DIR/coherence-overlap-unnormalizable-projection-0.rs:24:1
    |
 LL | / impl<T> Trait for T
 LL | | where
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr
deleted file mode 100644
index 49b236f9d2a..00000000000
--- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.classic.stderr
+++ /dev/null
@@ -1,19 +0,0 @@
-error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
-  --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1
-   |
-LL | / impl<T> Trait for T
-LL | | where
-LL | |     T: 'static,
-LL | |     for<'a> T: WithAssoc<'a>,
-LL | |     for<'a> Box<<T as WithAssoc<'a>>::Assoc>: WhereBound,
-   | |_________________________________________________________- first implementation here
-...
-LL |   impl<T> Trait for Box<T> {}
-   |   ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
-   |
-   = note: downstream crates may implement trait `WithAssoc<'a>` for type `std::boxed::Box<_>`
-   = note: downstream crates may implement trait `WhereBound` for type `std::boxed::Box<<std::boxed::Box<_> as WithAssoc<'a>>::Assoc>`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs
index 8eeadb3dc75..f5fb5aefb5c 100644
--- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.rs
@@ -2,9 +2,6 @@
 // "Coherence incorrectly considers `unnormalizable_projection: Trait` to not hold even if it could"
 #![crate_type = "lib"]
 
-//@ revisions: classic next
-//@[next] compile-flags: -Znext-solver
-
 pub trait WhereBound {}
 impl WhereBound for () {}
 
diff --git a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr
index 781ab0fcbf7..22673cef640 100644
--- a/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.next.stderr
+++ b/tests/ui/coherence/coherence-overlap-unnormalizable-projection-1.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait` for type `Box<_>`
-  --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:26:1
+  --> $DIR/coherence-overlap-unnormalizable-projection-1.rs:23:1
    |
 LL | / impl<T> Trait for T
 LL | | where
diff --git a/tests/ui/coherence/coherent-due-to-fulfill.rs b/tests/ui/coherence/coherent-due-to-fulfill.rs
index 084f9be0a8c..f4555ee5171 100644
--- a/tests/ui/coherence/coherent-due-to-fulfill.rs
+++ b/tests/ui/coherence/coherent-due-to-fulfill.rs
@@ -1,6 +1,4 @@
-//@ compile-flags: -Znext-solver=coherence
 //@ check-pass
-
 trait Mirror {
     type Assoc;
 }
diff --git a/tests/ui/coherence/incoherent-even-though-we-fulfill.rs b/tests/ui/coherence/incoherent-even-though-we-fulfill.rs
index b3c9cf328c2..28e5b6d3db0 100644
--- a/tests/ui/coherence/incoherent-even-though-we-fulfill.rs
+++ b/tests/ui/coherence/incoherent-even-though-we-fulfill.rs
@@ -1,5 +1,3 @@
-//@ compile-flags: -Znext-solver=coherence
-
 trait Mirror {
     type Assoc;
 }
diff --git a/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr b/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr
index b16465d2011..0b15a4e100e 100644
--- a/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr
+++ b/tests/ui/coherence/incoherent-even-though-we-fulfill.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Foo` for type `()`
-  --> $DIR/incoherent-even-though-we-fulfill.rs:17:1
+  --> $DIR/incoherent-even-though-we-fulfill.rs:15:1
    |
 LL | impl<T> Foo for T where (): Mirror<Assoc = T> {}
    | --------------------------------------------- first implementation here
diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr
deleted file mode 100644
index 74be598c44c..00000000000
--- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.old.stderr
+++ /dev/null
@@ -1,17 +0,0 @@
-error[E0119]: conflicting implementations of trait `From<()>` for type `S`
-  --> $DIR/inter-crate-ambiguity-causes-notes.rs:12:1
-   |
-LL |   impl From<()> for S {
-   |   ------------------- first implementation here
-...
-LL | / impl<I> From<I> for S
-LL | |
-LL | | where
-LL | |     I: Iterator<Item = ()>,
-   | |___________________________^ conflicting implementation for `S`
-   |
-   = note: upstream crates may add a new impl of trait `std::iter::Iterator` for type `()` in future versions
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs
index 3dead2f0d19..5b11c78ab26 100644
--- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs
+++ b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.rs
@@ -1,6 +1,3 @@
-//@ revisions: old next
-//@[next] compile-flags: -Znext-solver
-
 struct S;
 
 impl From<()> for S {
diff --git a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.next.stderr b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
index 74be598c44c..b32283274c6 100644
--- a/tests/ui/coherence/inter-crate-ambiguity-causes-notes.next.stderr
+++ b/tests/ui/coherence/inter-crate-ambiguity-causes-notes.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `From<()>` for type `S`
-  --> $DIR/inter-crate-ambiguity-causes-notes.rs:12:1
+  --> $DIR/inter-crate-ambiguity-causes-notes.rs:9:1
    |
 LL |   impl From<()> for S {
    |   ------------------- first implementation here
diff --git a/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr b/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr
index f515c39ea8d..bf1ffcb5f00 100644
--- a/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr
+++ b/tests/ui/coherence/negative-coherence-check-placeholder-outlives.stderr
@@ -5,6 +5,8 @@ LL | impl<T> Bar for T where T: Foo {}
    | ------------------------------ first implementation here
 LL | impl<T> Bar for Box<T> {}
    | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `Box<_>`
+   |
+   = note: downstream crates may implement trait `Foo` for type `std::boxed::Box<_>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr
index f24de10f6ac..97e2e9759c1 100644
--- a/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr
+++ b/tests/ui/coherence/negative-coherence-considering-regions.any_lt.stderr
@@ -6,6 +6,8 @@ LL | impl<T> Bar for T where T: Foo {}
 ...
 LL | impl<T> Bar for &T {}
    | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+   |
+   = note: downstream crates may implement trait `Foo` for type `&_`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr
index 832c56a4554..8d59cbc3466 100644
--- a/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr
+++ b/tests/ui/coherence/negative-coherence-placeholder-region-constraints-on-unification.explicit.stderr
@@ -8,6 +8,7 @@ LL | impl<T: ?Sized> FnMarker for fn(&T) {}
    |
    = warning: the behavior may change in a future release
    = note: for more information, see issue #56105 <https://github.com/rust-lang/rust/issues/56105>
+   = note: downstream crates may implement trait `Marker` for type `&_`
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 note: the lint level is defined here
   --> $DIR/negative-coherence-placeholder-region-constraints-on-unification.rs:4:11
diff --git a/tests/ui/coherence/normalize-for-errors.current.stderr b/tests/ui/coherence/normalize-for-errors.current.stderr
deleted file mode 100644
index dcbb73bd1ff..00000000000
--- a/tests/ui/coherence/normalize-for-errors.current.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, _)`
-  --> $DIR/normalize-for-errors.rs:17:1
-   |
-LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
-   | ------------------------------------------------------ first implementation here
-LL |
-LL | impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `(Box<(MyType,)>, _)`
-   |
-   = note: upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/normalize-for-errors.rs b/tests/ui/coherence/normalize-for-errors.rs
index c17bb766b5b..3ef91eb0386 100644
--- a/tests/ui/coherence/normalize-for-errors.rs
+++ b/tests/ui/coherence/normalize-for-errors.rs
@@ -1,7 +1,3 @@
-//@ revisions: current next
-//@ ignore-compare-mode-next-solver (explicit revisions)
-//@[next] compile-flags: -Znext-solver
-
 struct MyType;
 trait MyTrait<S> {}
 
@@ -18,6 +14,6 @@ impl<S: Iterator> MyTrait<S> for (Box<<(MyType,) as Mirror>::Assoc>, S::Item) {}
 //~^ ERROR conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>,
 //~| NOTE conflicting implementation for `(Box<(MyType,)>,
 //~| NOTE upstream crates may add a new impl of trait `std::marker::Copy` for type `std::boxed::Box<(MyType,)>` in future versions
-//[next]~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions
+//~| NOTE upstream crates may add a new impl of trait `std::clone::Clone` for type `std::boxed::Box<(MyType,)>` in future versions
 
 fn main() {}
diff --git a/tests/ui/coherence/normalize-for-errors.next.stderr b/tests/ui/coherence/normalize-for-errors.stderr
index 44952dc1944..6fbcf5b0e1a 100644
--- a/tests/ui/coherence/normalize-for-errors.next.stderr
+++ b/tests/ui/coherence/normalize-for-errors.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `MyTrait<_>` for type `(Box<(MyType,)>, <_ as Iterator>::Item)`
-  --> $DIR/normalize-for-errors.rs:17:1
+  --> $DIR/normalize-for-errors.rs:13:1
    |
 LL | impl<T: Copy, S: Iterator> MyTrait<S> for (T, S::Item) {}
    | ------------------------------------------------------ first implementation here
diff --git a/tests/ui/coherence/occurs-check/associated-type.next.stderr b/tests/ui/coherence/occurs-check/associated-type.next.stderr
index 9544bdbb468..466b991471e 100644
--- a/tests/ui/coherence/occurs-check/associated-type.next.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.next.stderr
@@ -3,7 +3,7 @@
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(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, '^0.Named(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
+  --> $DIR/associated-type.rs:32:1
    |
 LL |   impl<T> Overlap<T> for T {
    |   ------------------------ first implementation here
@@ -17,7 +17,7 @@ LL | |     for<'a> *const T: ToUnit<'a>,
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
 error[E0284]: type annotations needed: cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`
-  --> $DIR/associated-type.rs:44:59
+  --> $DIR/associated-type.rs:45:59
    |
 LL |     foo::<for<'a> fn(&'a (), ()), for<'a> fn(&'a (), ())>(3usize);
    |                                                           ^^^^^^ cannot normalize `<for<'a> fn(&'a (), ()) as Overlap<for<'a> fn(&'a (), ())>>::Assoc`
diff --git a/tests/ui/coherence/occurs-check/associated-type.old.stderr b/tests/ui/coherence/occurs-check/associated-type.old.stderr
index ccc7f30fa6f..1e0345f4ec0 100644
--- a/tests/ui/coherence/occurs-check/associated-type.old.stderr
+++ b/tests/ui/coherence/occurs-check/associated-type.old.stderr
@@ -1,13 +1,9 @@
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [*const ?1t, '^0.Named(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, !2_0.Named(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, '^0.Named(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, !2_0.Named(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, '^0.Named(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, !2_0.Named(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, '^0.Named(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, !2_0.Named(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
+error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), ())>` for type `for<'a> fn(&'a (), ())`
+  --> $DIR/associated-type.rs:32:1
    |
 LL |   impl<T> Overlap<T> for T {
    |   ------------------------ first implementation here
@@ -16,7 +12,7 @@ LL | / impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T
 LL | |
 LL | | where
 LL | |     for<'a> *const T: ToUnit<'a>,
-   | |_________________________________^ conflicting implementation for `for<'a> fn(&'a (), _)`
+   | |_________________________________^ conflicting implementation for `for<'a> fn(&'a (), ())`
    |
    = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
diff --git a/tests/ui/coherence/occurs-check/associated-type.rs b/tests/ui/coherence/occurs-check/associated-type.rs
index df03d5f60a0..e450c33e809 100644
--- a/tests/ui/coherence/occurs-check/associated-type.rs
+++ b/tests/ui/coherence/occurs-check/associated-type.rs
@@ -1,4 +1,5 @@
 //@ revisions: old next
+//@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 
 // A regression test for #105787
diff --git a/tests/ui/coherence/occurs-check/opaques.current.stderr b/tests/ui/coherence/occurs-check/opaques.current.stderr
new file mode 100644
index 00000000000..f3fc22027c2
--- /dev/null
+++ b/tests/ui/coherence/occurs-check/opaques.current.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Trait<_>`
+  --> $DIR/opaques.rs:28:1
+   |
+LL | impl<T> Trait<T> for T {
+   | ---------------------- first implementation here
+...
+LL | impl<T> Trait<T> for defining_scope::Alias<T> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/occurs-check/opaques.next.stderr b/tests/ui/coherence/occurs-check/opaques.next.stderr
index 11d1edcca2f..3de479963bb 100644
--- a/tests/ui/coherence/occurs-check/opaques.next.stderr
+++ b/tests/ui/coherence/occurs-check/opaques.next.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Trait<_>`
-  --> $DIR/opaques.rs:30:1
+  --> $DIR/opaques.rs:28:1
    |
 LL | impl<T> Trait<T> for T {
    | ---------------------- first implementation here
@@ -8,7 +8,7 @@ LL | impl<T> Trait<T> for defining_scope::Alias<T> {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error[E0282]: type annotations needed
-  --> $DIR/opaques.rs:13:20
+  --> $DIR/opaques.rs:11:20
    |
 LL |     pub fn cast<T>(x: Container<Alias<T>, T>) -> Container<T, T> {
    |                    ^ cannot infer type
diff --git a/tests/ui/coherence/occurs-check/opaques.rs b/tests/ui/coherence/occurs-check/opaques.rs
index 241a247c841..e197256c78c 100644
--- a/tests/ui/coherence/occurs-check/opaques.rs
+++ b/tests/ui/coherence/occurs-check/opaques.rs
@@ -1,10 +1,8 @@
-//@revisions: old next
+//@ revisions: current next
+//@ ignore-compare-mode-next-solver (explicit revisions)
 //@[next] compile-flags: -Znext-solver
 
 // A regression test for #105787
-
-//@[old] known-bug: #105787
-//@[old] check-pass
 #![feature(type_alias_impl_trait)]
 mod defining_scope {
     use super::*;
@@ -28,7 +26,7 @@ impl<T> Trait<T> for T {
     type Assoc = Box<u32>;
 }
 impl<T> Trait<T> for defining_scope::Alias<T> {
-    //[next]~^ ERROR conflicting implementations of trait
+    //~^ ERROR conflicting implementations of trait
     type Assoc = usize;
 }
 
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr
deleted file mode 100644
index 44f76f321cf..00000000000
--- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.next.stderr
+++ /dev/null
@@ -1,21 +0,0 @@
-error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
-   |
-LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
-   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-   |
-   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
-   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
-
-error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
-   |
-LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
-   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-   |
-   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
-   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
-
-error: aborting due to 2 previous errors
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
index 8dc02b081c5..02e9eb65570 100644
--- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.rs
@@ -1,8 +1,5 @@
 // Opaque types never cover type parameters.
 
-//@ revisions: classic next
-//@[next] compile-flags: -Znext-solver
-
 //@ aux-crate:foreign=parametrized-trait.rs
 //@ edition:2021
 
diff --git a/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr
index 44f76f321cf..57f5bbd2278 100644
--- a/tests/ui/coherence/orphan-check-opaque-types-not-covering.classic.stderr
+++ b/tests/ui/coherence/orphan-check-opaque-types-not-covering.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-opaque-types-not-covering.rs:17:6
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:14:6
    |
 LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
    |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
@@ -8,7 +8,7 @@ LL | impl<T> foreign::Trait0<Local, T, ()> for Identity<T> {}
    = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
 
 error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-opaque-types-not-covering.rs:26:6
+  --> $DIR/orphan-check-opaque-types-not-covering.rs:23:6
    |
 LL | impl<T> foreign::Trait1<Local, T> for Opaque<T> {}
    |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
diff --git a/tests/ui/coherence/orphan-check-projections-covering.rs b/tests/ui/coherence/orphan-check-projections-covering.rs
index ae1917ec161..804784463a1 100644
--- a/tests/ui/coherence/orphan-check-projections-covering.rs
+++ b/tests/ui/coherence/orphan-check-projections-covering.rs
@@ -5,9 +5,6 @@
 // first which would've lead to real-word regressions.
 
 //@ check-pass
-//@ revisions: classic next
-//@[next] compile-flags: -Znext-solver
-
 //@ aux-crate:foreign=parametrized-trait.rs
 //@ edition:2021
 
diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr
deleted file mode 100644
index 276833fa171..00000000000
--- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.next.stderr
+++ /dev/null
@@ -1,12 +0,0 @@
-error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6
-   |
-LL | impl<T> foreign::Trait1<Local, T> for Identity<T> {}
-   |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-   |
-   = note: implementing a foreign trait is only possible if at least one of the types for which it is implemented is local, and no uncovered type parameters appear before that first local type
-   = note: in this case, 'before' refers to the following order: `impl<..> ForeignTrait<T1, ..., Tn> for T0`, where `T0` is the first and `Tn` is the last
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0210`.
diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs
index 9ebc45a8829..6d9bccc4c68 100644
--- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs
+++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.rs
@@ -1,8 +1,5 @@
 // Weak aliases might not cover type parameters.
 
-//@ revisions: classic next
-//@[next] compile-flags: -Znext-solver
-
 //@ aux-crate:foreign=parametrized-trait.rs
 //@ edition:2021
 
diff --git a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr
index 276833fa171..df915141a76 100644
--- a/tests/ui/coherence/orphan-check-weak-aliases-not-covering.classic.stderr
+++ b/tests/ui/coherence/orphan-check-weak-aliases-not-covering.stderr
@@ -1,5 +1,5 @@
 error[E0210]: type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
-  --> $DIR/orphan-check-weak-aliases-not-covering.rs:16:6
+  --> $DIR/orphan-check-weak-aliases-not-covering.rs:13:6
    |
 LL | impl<T> foreign::Trait1<Local, T> for Identity<T> {}
    |      ^ type parameter `T` must be covered by another type when it appears before the first local type (`Local`)
diff --git a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr b/tests/ui/coherence/skip-reporting-if-references-err.current.stderr
deleted file mode 100644
index 5eef3256b2c..00000000000
--- a/tests/ui/coherence/skip-reporting-if-references-err.current.stderr
+++ /dev/null
@@ -1,27 +0,0 @@
-error[E0726]: implicit elided lifetime not allowed here
-  --> $DIR/skip-reporting-if-references-err.rs:10:9
-   |
-LL | impl<T> ToUnit for T {}
-   |         ^^^^^^ expected lifetime parameter
-   |
-help: indicate the anonymous lifetime
-   |
-LL | impl<T> ToUnit<'_> for T {}
-   |               ++++
-
-error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
-  --> $DIR/skip-reporting-if-references-err.rs:15:29
-   |
-LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {}
-   |                             ^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()`
-
-error[E0277]: the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
-  --> $DIR/skip-reporting-if-references-err.rs:15:18
-   |
-LL | impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {}
-   |                  ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `()`
-
-error: aborting due to 3 previous errors
-
-Some errors have detailed explanations: E0277, E0726.
-For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/coherence/skip-reporting-if-references-err.rs b/tests/ui/coherence/skip-reporting-if-references-err.rs
index f9eaa498232..dd8a71c4700 100644
--- a/tests/ui/coherence/skip-reporting-if-references-err.rs
+++ b/tests/ui/coherence/skip-reporting-if-references-err.rs
@@ -1,8 +1,4 @@
 // Regression test for #121006.
-//@ revisions: current next
-//@ ignore-compare-mode-next-solver (explicit revisions)
-//@[next] compile-flags: -Znext-solver
-
 trait ToUnit<'a> {
     type Unit;
 }
@@ -13,7 +9,5 @@ impl<T> ToUnit for T {}
 trait Overlap {}
 impl<U> Overlap for fn(U) {}
 impl Overlap for for<'a> fn(<() as ToUnit<'a>>::Unit) {}
-//[current]~^ ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
-//[current]~| ERROR the trait bound `for<'a> (): ToUnit<'a>` is not satisfied
 
 fn main() {}
diff --git a/tests/ui/coherence/skip-reporting-if-references-err.next.stderr b/tests/ui/coherence/skip-reporting-if-references-err.stderr
index 5de4cf626e4..0ff3e88a0af 100644
--- a/tests/ui/coherence/skip-reporting-if-references-err.next.stderr
+++ b/tests/ui/coherence/skip-reporting-if-references-err.stderr
@@ -1,5 +1,5 @@
 error[E0726]: implicit elided lifetime not allowed here
-  --> $DIR/skip-reporting-if-references-err.rs:10:9
+  --> $DIR/skip-reporting-if-references-err.rs:6:9
    |
 LL | impl<T> ToUnit for T {}
    |         ^^^^^^ expected lifetime parameter
diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr
deleted file mode 100644
index fb01cf158d9..00000000000
--- a/tests/ui/coherence/super-traits/super-trait-knowable-1.current.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()`
-  --> $DIR/super-trait-knowable-1.rs:16:1
-   |
-LL | impl<T, U: Sub<T>> Overlap<T> for U {}
-   | ----------------------------------- first implementation here
-LL | impl<T> Overlap<T> for () {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
-   |
-   = note: downstream crates may implement trait `Sub<_>` for type `()`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-1.rs b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs
index 80df8c19ee5..77af4d0f2e3 100644
--- a/tests/ui/coherence/super-traits/super-trait-knowable-1.rs
+++ b/tests/ui/coherence/super-traits/super-trait-knowable-1.rs
@@ -3,10 +3,7 @@
 // We therefore elaborate super trait bounds in the implicit negative
 // overlap check.
 
-//@ revisions: current next
-//@ ignore-compare-mode-next-solver (explicit revisions)
-//@[next] compile-flags: -Znext-solver
-//@[next] check-pass
+//@ check-pass
 
 trait Super {}
 trait Sub<T>: Super {}
@@ -14,6 +11,5 @@ trait Sub<T>: Super {}
 trait Overlap<T> {}
 impl<T, U: Sub<T>> Overlap<T> for U {}
 impl<T> Overlap<T> for () {}
-//[current]~^ ERROR conflicting implementations
 
 fn main() {}
diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-2.rs b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs
index d1f2e8d1c1a..323ee0b10c9 100644
--- a/tests/ui/coherence/super-traits/super-trait-knowable-2.rs
+++ b/tests/ui/coherence/super-traits/super-trait-knowable-2.rs
@@ -9,9 +9,6 @@
 // which caused the old solver to emit a `Tensor: TensorValue` goal in
 // `fn normalize_to_error` which then failed, causing this test to pass.
 
-//@ revisions: current next
-//@ ignore-compare-mode-next-solver (explicit revisions)
-//@[next] compile-flags: -Znext-solver
 //@ check-pass
 
 pub trait TensorValue {
diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr b/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr
deleted file mode 100644
index 542edb8b7f6..00000000000
--- a/tests/ui/coherence/super-traits/super-trait-knowable-3.current.stderr
+++ /dev/null
@@ -1,13 +0,0 @@
-error[E0119]: conflicting implementations of trait `Overlap<_>` for type `()`
-  --> $DIR/super-trait-knowable-3.rs:19:1
-   |
-LL | impl<T, U: Bound<W<T>>> Overlap<T> for U {}
-   | ---------------------------------------- first implementation here
-LL | impl<T> Overlap<T> for () {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `()`
-   |
-   = note: downstream crates may implement trait `Sub<_>` for type `()`
-
-error: aborting due to 1 previous error
-
-For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/coherence/super-traits/super-trait-knowable-3.rs b/tests/ui/coherence/super-traits/super-trait-knowable-3.rs
index 295d7ac48d8..6198d3d303b 100644
--- a/tests/ui/coherence/super-traits/super-trait-knowable-3.rs
+++ b/tests/ui/coherence/super-traits/super-trait-knowable-3.rs
@@ -2,10 +2,7 @@
 // super trait bound is in a nested goal so this would not
 // compile if we were to only elaborate root goals.
 
-//@ revisions: current next
-//@ ignore-compare-mode-next-solver (explicit revisions)
-//@[next] compile-flags: -Znext-solver
-//@[next] check-pass
+//@ check-pass
 
 trait Super {}
 trait Sub<T>: Super {}
@@ -17,6 +14,5 @@ impl<T: Sub<U>, U> Bound<W<U>> for T {}
 trait Overlap<T> {}
 impl<T, U: Bound<W<T>>> Overlap<T> for U {}
 impl<T> Overlap<T> for () {}
-//[current]~^ ERROR conflicting implementations of trait `Overlap<_>` for type `()`
 
 fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs
index 05a3487ffca..42c930f952d 100644
--- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs
+++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.rs
@@ -22,6 +22,7 @@ mod v20 {
     impl v17<512, v0> {
         pub const fn v21() -> v18 {}
         //~^ ERROR cannot find type `v18` in this scope
+        //~| ERROR duplicate definitions with name `v21`
     }
 
     impl<const v10: usize> v17<v10, v2> {
diff --git a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
index 39f022fbee9..b336f2b3fca 100644
--- a/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unevaluated-const-ice-119731.stderr
@@ -1,5 +1,5 @@
 error[E0432]: unresolved import `v20::v13`
-  --> $DIR/unevaluated-const-ice-119731.rs:37:15
+  --> $DIR/unevaluated-const-ice-119731.rs:38:15
    |
 LL | pub use v20::{v13, v17};
    |               ^^^
@@ -23,7 +23,7 @@ LL |         pub const fn v21() -> v18 {}
    |                               ^^^ help: a type alias with a similar name exists: `v11`
 
 error[E0412]: cannot find type `v18` in this scope
-  --> $DIR/unevaluated-const-ice-119731.rs:30:31
+  --> $DIR/unevaluated-const-ice-119731.rs:31:31
    |
 LL |     pub type v11 = [[usize; v4]; v4];
    |     --------------------------------- similarly named type alias `v11` defined here
@@ -32,7 +32,7 @@ LL |         pub const fn v21() -> v18 {
    |                               ^^^ help: a type alias with a similar name exists: `v11`
 
 error[E0422]: cannot find struct, variant or union type `v18` in this scope
-  --> $DIR/unevaluated-const-ice-119731.rs:32:13
+  --> $DIR/unevaluated-const-ice-119731.rs:33:13
    |
 LL |     pub type v11 = [[usize; v4]; v4];
    |     --------------------------------- similarly named type alias `v11` defined here
@@ -73,20 +73,29 @@ LL + #![feature(adt_const_params)]
    |
 
 error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
-  --> $DIR/unevaluated-const-ice-119731.rs:27:37
+  --> $DIR/unevaluated-const-ice-119731.rs:28:37
    |
 LL |     impl<const v10: usize> v17<v10, v2> {
    |                                     ^^
 
 error: maximum number of nodes exceeded in constant v20::v17::<v10, v2>::{constant#1}
-  --> $DIR/unevaluated-const-ice-119731.rs:27:37
+  --> $DIR/unevaluated-const-ice-119731.rs:28:37
    |
 LL |     impl<const v10: usize> v17<v10, v2> {
    |                                     ^^
    |
    = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 9 previous errors; 2 warnings emitted
+error[E0592]: duplicate definitions with name `v21`
+  --> $DIR/unevaluated-const-ice-119731.rs:23:9
+   |
+LL |         pub const fn v21() -> v18 {}
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^ duplicate definitions for `v21`
+...
+LL |         pub const fn v21() -> v18 {
+   |         ------------------------- other definition for `v21`
+
+error: aborting due to 10 previous errors; 2 warnings emitted
 
-Some errors have detailed explanations: E0412, E0422, E0425, E0432.
+Some errors have detailed explanations: E0412, E0422, E0425, E0432, E0592.
 For more information about an error, try `rustc --explain E0412`.
diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs
index dd0b1e8c9f7..81ac9979bd8 100644
--- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs
+++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.rs
@@ -10,6 +10,5 @@ trait Trait {}
 impl<const N: u32> Trait for A<N> {}
 
 impl<const N: u32> Trait for A<N> {}
-//~^ ERROR conflicting implementations of trait `Trait` for type `A<_>`
 
 pub fn main() {}
diff --git a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr
index 80ac96d4870..e29c49ff042 100644
--- a/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr
+++ b/tests/ui/const-generics/generic_const_exprs/unknown-alias-defkind-anonconst-ice-116710.stderr
@@ -4,16 +4,6 @@ error[E0423]: expected value, found builtin type `u8`
 LL | struct A<const N: u32 = 1, const M: u32 = u8>;
    |                                           ^^ not a value
 
-error[E0119]: conflicting implementations of trait `Trait` for type `A<_>`
-  --> $DIR/unknown-alias-defkind-anonconst-ice-116710.rs:12:1
-   |
-LL | impl<const N: u32> Trait for A<N> {}
-   | --------------------------------- first implementation here
-LL |
-LL | impl<const N: u32> Trait for A<N> {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `A<_>`
-
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-Some errors have detailed explanations: E0119, E0423.
-For more information about an error, try `rustc --explain E0119`.
+For more information about this error, try `rustc --explain E0423`.
diff --git a/tests/ui/const-generics/invariant.rs b/tests/ui/const-generics/invariant.rs
index ee4ad4e7c4e..95a28b61dde 100644
--- a/tests/ui/const-generics/invariant.rs
+++ b/tests/ui/const-generics/invariant.rs
@@ -5,7 +5,7 @@ use std::marker::PhantomData;
 trait SadBee {
     const ASSOC: usize;
 }
-// fn(&'static ())` is a supertype of `for<'a> fn(&'a ())` while
+// `fn(&'static ())` is a supertype of `for<'a> fn(&'a ())` while
 // we allow two different impls for these types, leading
 // to different const eval results.
 impl SadBee for for<'a> fn(&'a ()) {
diff --git a/tests/ui/consts/const-float-bits-conv.rs b/tests/ui/consts/const-float-bits-conv.rs
index 3a526c54dc3..869498d1076 100644
--- a/tests/ui/consts/const-float-bits-conv.rs
+++ b/tests/ui/consts/const-float-bits-conv.rs
@@ -1,10 +1,9 @@
 //@ compile-flags: -Zmir-opt-level=0
 //@ run-pass
 
-#![feature(const_float_bits_conv)]
 #![feature(const_float_classify)]
-#![feature(f16)]
-#![feature(f128)]
+#![feature(f16, f16_const)]
+#![feature(f128, f128_const)]
 #![allow(unused_macro_rules)]
 // Don't promote
 const fn nop<T>(x: T) -> T { x }
diff --git a/tests/ui/consts/const-float-classify.rs b/tests/ui/consts/const-float-classify.rs
index c64d31a5c60..6e5097f7f2b 100644
--- a/tests/ui/consts/const-float-classify.rs
+++ b/tests/ui/consts/const-float-classify.rs
@@ -2,7 +2,6 @@
 //@ known-bug: #110395
 // FIXME(effects) run-pass
 
-#![feature(const_float_bits_conv)]
 #![feature(const_float_classify)]
 #![feature(const_trait_impl, effects)]
 #![allow(incomplete_features)]
diff --git a/tests/ui/consts/const-float-classify.stderr b/tests/ui/consts/const-float-classify.stderr
index 38acb8a2281..a35de8ad0ea 100644
--- a/tests/ui/consts/const-float-classify.stderr
+++ b/tests/ui/consts/const-float-classify.stderr
@@ -1,5 +1,5 @@
 error: const `impl` for trait `PartialEq` which is not marked with `#[const_trait]`
-  --> $DIR/const-float-classify.rs:13:12
+  --> $DIR/const-float-classify.rs:12:12
    |
 LL | impl const PartialEq<NonDet> for bool {
    |            ^^^^^^^^^^^^^^^^^
diff --git a/tests/ui/consts/missing_assoc_const_type.rs b/tests/ui/consts/missing_assoc_const_type.rs
index 8d95e3dca63..633998e9bc1 100644
--- a/tests/ui/consts/missing_assoc_const_type.rs
+++ b/tests/ui/consts/missing_assoc_const_type.rs
@@ -16,7 +16,7 @@ impl Range for TwoDigits {
 
 const fn digits(x: u8) -> usize {
     match x {
-        TwoDigits::FIRST..=TwoDigits::LAST => 0,
+        TwoDigits::FIRST..=TwoDigits::LAST => 0, //~ ERROR: could not evaluate constant pattern
         0..=9 | 100..=255 => panic!(),
     }
 }
diff --git a/tests/ui/consts/missing_assoc_const_type.stderr b/tests/ui/consts/missing_assoc_const_type.stderr
index 28af1f0f321..ef7ff962d2d 100644
--- a/tests/ui/consts/missing_assoc_const_type.stderr
+++ b/tests/ui/consts/missing_assoc_const_type.stderr
@@ -4,5 +4,11 @@ error: missing type for `const` item
 LL |     const FIRST:  = 10;
    |                 ^ help: provide a type for the associated constant: `u8`
 
-error: aborting due to 1 previous error
+error: could not evaluate constant pattern
+  --> $DIR/missing_assoc_const_type.rs:19:9
+   |
+LL |         TwoDigits::FIRST..=TwoDigits::LAST => 0,
+   |         ^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
 
diff --git a/tests/ui/delegation/generics/impl-to-free-fn-pass.rs b/tests/ui/delegation/generics/impl-to-free-fn-pass.rs
new file mode 100644
index 00000000000..3b39a457467
--- /dev/null
+++ b/tests/ui/delegation/generics/impl-to-free-fn-pass.rs
@@ -0,0 +1,29 @@
+//@ run-pass
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+mod to_reuse {
+    pub fn foo<T, U>(_: T, y: U) -> U { y }
+}
+
+trait Trait<T> {
+    fn foo(&self, x: T) -> T { x }
+}
+struct F;
+impl<T> Trait<T> for F {}
+
+struct S<T>(F, T);
+
+impl<T, U> Trait<T> for S<U> {
+    reuse to_reuse::foo { &self.0 }
+}
+
+impl<T> S<T> {
+    reuse to_reuse::foo;
+}
+
+fn main() {
+    let s = S(F, 42);
+    assert_eq!(S::<i32>::foo(F, 1), 1);
+    assert_eq!(<S<_> as Trait<_>>::foo(&s, 1), 1);
+}
diff --git a/tests/ui/delegation/generics/impl-to-trait-method.rs b/tests/ui/delegation/generics/impl-to-trait-method.rs
new file mode 100644
index 00000000000..39e32e2ed15
--- /dev/null
+++ b/tests/ui/delegation/generics/impl-to-trait-method.rs
@@ -0,0 +1,44 @@
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+mod bounds {
+    trait Trait0 {}
+
+    trait Trait1<T> {
+        fn foo<U>(&self)
+        where
+            T: Trait0,
+            U: Trait0,
+            Self: Trait0,
+            //~^ ERROR the trait bound `bounds::S: Trait0` is not satisfied
+        {
+        }
+    }
+
+    struct F;
+    impl<T> Trait1<T> for F {}
+
+    struct S(F);
+
+    impl<T> Trait1<T> for S {
+        reuse Trait1::<T>::foo { &self.0 }
+        //~^ ERROR the trait bound `bounds::F: Trait0` is not satisfied
+    }
+}
+
+mod unconstrained_parameter {
+    trait Trait<T> {
+        fn foo(&self) {}
+    }
+
+    struct F;
+    impl<T> Trait<T> for F {}
+
+    struct S(F);
+    impl S {
+        reuse Trait::foo { &self.0 }
+        //~^ ERROR type annotations needed
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/generics/impl-to-trait-method.stderr b/tests/ui/delegation/generics/impl-to-trait-method.stderr
new file mode 100644
index 00000000000..aeba30de043
--- /dev/null
+++ b/tests/ui/delegation/generics/impl-to-trait-method.stderr
@@ -0,0 +1,49 @@
+error[E0277]: the trait bound `bounds::S: Trait0` is not satisfied
+  --> $DIR/impl-to-trait-method.rs:12:19
+   |
+LL |             Self: Trait0,
+   |                   ^^^^^^ the trait `Trait0` is not implemented for `bounds::S`
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/impl-to-trait-method.rs:5:5
+   |
+LL |     trait Trait0 {}
+   |     ^^^^^^^^^^^^
+   = help: see issue #48214
+help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+   |
+LL + #![feature(trivial_bounds)]
+   |
+
+error[E0277]: the trait bound `bounds::F: Trait0` is not satisfied
+  --> $DIR/impl-to-trait-method.rs:24:34
+   |
+LL |         reuse Trait1::<T>::foo { &self.0 }
+   |                            ---   ^^^^^^^ the trait `Trait0` is not implemented for `bounds::F`
+   |                            |
+   |                            required by a bound introduced by this call
+   |
+help: this trait has no implementations, consider adding one
+  --> $DIR/impl-to-trait-method.rs:5:5
+   |
+LL |     trait Trait0 {}
+   |     ^^^^^^^^^^^^
+note: required by a bound in `Trait1::foo`
+  --> $DIR/impl-to-trait-method.rs:12:19
+   |
+LL |         fn foo<U>(&self)
+   |            --- required by a bound in this associated function
+...
+LL |             Self: Trait0,
+   |                   ^^^^^^ required by this bound in `Trait1::foo`
+
+error[E0282]: type annotations needed
+  --> $DIR/impl-to-trait-method.rs:39:22
+   |
+LL |         reuse Trait::foo { &self.0 }
+   |                      ^^^ cannot infer type for type parameter `T` declared on the trait `Trait`
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0277, E0282.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/delegation/generics/impl-trait-to-trait-method-pass.rs b/tests/ui/delegation/generics/impl-trait-to-trait-method-pass.rs
new file mode 100644
index 00000000000..72440fe82d4
--- /dev/null
+++ b/tests/ui/delegation/generics/impl-trait-to-trait-method-pass.rs
@@ -0,0 +1,77 @@
+//@ run-pass
+
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+use std::iter::{Iterator, Map};
+
+pub mod same_trait {
+    use super::*;
+
+    pub struct MapOuter<I, F> {
+        pub inner: Map<I, F>
+    }
+
+    impl<B, I: Iterator, F> Iterator for MapOuter<I, F>
+    where
+        F: FnMut(I::Item) -> B,
+    {
+        type Item = <Map<I, F> as Iterator>::Item;
+
+        reuse Iterator::{next, fold} { self.inner }
+    }
+}
+use same_trait::MapOuter;
+
+mod another_trait {
+    use super::*;
+
+    trait ZipImpl<A, B> {
+        type Item;
+
+        fn next(&mut self) -> Option<Self::Item>;
+    }
+
+    pub struct Zip<A, B> {
+        pub a: A,
+        pub b: B,
+    }
+
+    impl<A: Iterator, B: Iterator> ZipImpl<A, B> for Zip<A, B> {
+        type Item = (A::Item, B::Item);
+
+        fn next(&mut self) -> Option<(A::Item, B::Item)> {
+            let x = self.a.next()?;
+            let y = self.b.next()?;
+            Some((x, y))
+        }
+    }
+
+    impl<A: Iterator, B: Iterator> Iterator for Zip<A, B> {
+        type Item = (A::Item, B::Item);
+
+        // Parameters are inherited from `Iterator::next`, not from `ZipImpl::next`.
+        // Otherwise, there would be a compilation error due to an unconstrained parameter.
+        reuse ZipImpl::next;
+    }
+}
+use another_trait::Zip;
+
+fn main() {
+    {
+        let x = vec![1, 2, 3];
+        let iter = x.iter().map(|val| val * 2);
+        let outer_iter = MapOuter { inner: iter };
+        let val = outer_iter.fold(0, |acc, x| acc + x);
+        assert_eq!(val, 12);
+    }
+
+    {
+        let x = vec![1, 2];
+        let y = vec![4, 5];
+
+        let mut zip = Zip { a: x.iter(), b: y.iter() };
+        assert_eq!(zip.next(), Some((&1, &4)));
+        assert_eq!(zip.next(), Some((&2, &5)));
+    }
+}
diff --git a/tests/ui/delegation/generics/inherent-impl-to-trait-method-pass.rs b/tests/ui/delegation/generics/inherent-impl-to-trait-method-pass.rs
new file mode 100644
index 00000000000..6f3bb178971
--- /dev/null
+++ b/tests/ui/delegation/generics/inherent-impl-to-trait-method-pass.rs
@@ -0,0 +1,23 @@
+//@ run-pass
+
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+trait Trait<T> {
+    fn foo<U>(&self, x: T, y: U) -> (T, U) {
+        (x, y)
+    }
+}
+
+impl<T> Trait<T> for () {}
+struct S<T>(T, ());
+
+impl<T> S<T> {
+    reuse Trait::foo { self.1 }
+}
+
+
+fn main() {
+    let s = S((), ());
+    assert_eq!(s.foo(1u32, 2i32), (1u32, 2i32));
+}
diff --git a/tests/ui/delegation/generics/trait-method-to-other-pass.rs b/tests/ui/delegation/generics/trait-method-to-other-pass.rs
new file mode 100644
index 00000000000..2094705a05c
--- /dev/null
+++ b/tests/ui/delegation/generics/trait-method-to-other-pass.rs
@@ -0,0 +1,30 @@
+//@ run-pass
+
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+mod to_reuse {
+    pub fn foo<T>(x: T) -> T { x }
+}
+
+trait Trait1<T, U> {
+    fn foo(&self, _: T, x: U) -> U { x }
+}
+
+#[derive(Default)]
+struct F;
+
+impl<T, U> Trait1<T, U> for F {}
+
+trait Trait2<T> {
+    fn get_f(&self) -> &F { &F }
+    reuse Trait1::foo as bar { self.get_f() }
+    reuse to_reuse::foo as baz;
+}
+
+impl Trait2<u64> for F {}
+
+fn main() {
+    assert_eq!(F.bar(1u8, 2u16), 2u16);
+    assert_eq!(F::baz(1u8), 1u8);
+}
diff --git a/tests/ui/delegation/ice-issue-124347.rs b/tests/ui/delegation/ice-issue-124347.rs
index 3bfae8face5..ee2bf9e33eb 100644
--- a/tests/ui/delegation/ice-issue-124347.rs
+++ b/tests/ui/delegation/ice-issue-124347.rs
@@ -1,12 +1,12 @@
 #![feature(fn_delegation)]
 #![allow(incomplete_features)]
 
+// FIXME(fn_delegation): `recursive delegation` error should be emitted here
 trait Trait {
     reuse Trait::foo { &self.0 }
-    //~^ ERROR recursive delegation is not supported yet
+    //~^ ERROR cycle detected when computing generics of `Trait::foo`
 }
 
-// FIXME(fn_delegation): `recursive delegation` error should be emitted here
 reuse foo;
 //~^ ERROR cycle detected when computing generics of `foo`
 
diff --git a/tests/ui/delegation/ice-issue-124347.stderr b/tests/ui/delegation/ice-issue-124347.stderr
index 87dd75ffec8..bd0bc970b94 100644
--- a/tests/ui/delegation/ice-issue-124347.stderr
+++ b/tests/ui/delegation/ice-issue-124347.stderr
@@ -1,8 +1,16 @@
-error: recursive delegation is not supported yet
-  --> $DIR/ice-issue-124347.rs:5:18
+error[E0391]: cycle detected when computing generics of `Trait::foo`
+  --> $DIR/ice-issue-124347.rs:6:18
    |
 LL |     reuse Trait::foo { &self.0 }
-   |                  ^^^ callee defined here
+   |                  ^^^
+   |
+   = note: ...which immediately requires computing generics of `Trait::foo` again
+note: cycle used when inheriting delegation signature
+  --> $DIR/ice-issue-124347.rs:6:18
+   |
+LL |     reuse Trait::foo { &self.0 }
+   |                  ^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
 error[E0391]: cycle detected when computing generics of `foo`
   --> $DIR/ice-issue-124347.rs:10:7
diff --git a/tests/ui/delegation/not-supported.rs b/tests/ui/delegation/not-supported.rs
deleted file mode 100644
index d5ac68ecf1b..00000000000
--- a/tests/ui/delegation/not-supported.rs
+++ /dev/null
@@ -1,116 +0,0 @@
-#![feature(const_trait_impl)]
-#![feature(c_variadic)]
-#![feature(effects)]
-#![feature(fn_delegation)]
-#![allow(incomplete_features)]
-
-mod generics {
-    trait GenericTrait<T> {
-        fn bar(&self, x: T) -> T { x }
-        fn bar1() {}
-    }
-    trait Trait {
-        fn foo(&self, x: i32) -> i32 { x }
-        fn foo1<'a>(&self, x: &'a i32) -> &'a i32 { x }
-        fn foo2<T>(&self, x: T) -> T { x }
-        fn foo3<'a: 'a>(_: &'a u32) {}
-
-        reuse GenericTrait::bar;
-        //~^ ERROR early bound generics are not supported for associated delegation items
-        reuse GenericTrait::bar1;
-        //~^ ERROR early bound generics are not supported for associated delegation items
-    }
-
-    struct F;
-    impl Trait for F {}
-    impl<T> GenericTrait<T> for F {}
-
-    struct S(F);
-
-    impl<T> GenericTrait<T> for S {
-        reuse <F as GenericTrait<T>>::bar { &self.0 }
-        //~^ ERROR early bound generics are not supported for associated delegation items
-        reuse GenericTrait::<T>::bar1;
-        //~^ ERROR early bound generics are not supported for associated delegation items
-    }
-
-    impl GenericTrait<()> for () {
-        reuse GenericTrait::bar { &F }
-        //~^ ERROR early bound generics are not supported for associated delegation items
-        reuse GenericTrait::bar1;
-        //~^ ERROR early bound generics are not supported for associated delegation items
-    }
-
-    impl Trait for &S {
-        reuse Trait::foo;
-        //~^ ERROR early bound generics are not supported for associated delegation items
-    }
-
-    impl Trait for S {
-        reuse Trait::foo1 { &self.0 }
-        reuse Trait::foo2 { &self.0 }
-        //~^ ERROR early bound generics are not supported for associated delegation items
-        //~| ERROR method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
-        reuse <F as Trait>::foo3;
-        //~^ ERROR early bound generics are not supported for associated delegation items
-        //~| ERROR lifetime parameters or bounds on associated function `foo3` do not match the trait declaration
-    }
-
-    struct GenericS<T>(T);
-    impl<T> Trait for GenericS<T> {
-        reuse Trait::foo { &self.0 }
-        //~^ ERROR early bound generics are not supported for associated delegation items
-    }
-}
-
-mod opaque {
-    trait Trait {}
-    impl Trait for () {}
-
-    mod to_reuse {
-        use super::Trait;
-
-        pub fn opaque_ret() -> impl Trait { unimplemented!() }
-        //~^ warn: this function depends on never type fallback being `()`
-        //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-    }
-
-    trait ToReuse {
-        fn opaque_ret() -> impl Trait { unimplemented!() }
-        //~^ warn: this function depends on never type fallback being `()`
-        //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-    }
-
-    // FIXME: Inherited `impl Trait`s create query cycles when used inside trait impls.
-    impl ToReuse for u8 {
-        reuse to_reuse::opaque_ret; //~ ERROR cycle detected when computing type
-    }
-    impl ToReuse for u16 {
-        reuse ToReuse::opaque_ret; //~ ERROR cycle detected when computing type
-    }
-}
-
-mod recursive {
-    mod to_reuse1 {
-        pub mod to_reuse2 {
-            pub fn foo() {}
-        }
-
-        pub reuse to_reuse2::foo;
-    }
-
-    reuse to_reuse1::foo;
-    //~^ ERROR recursive delegation is not supported yet
-}
-
-mod effects {
-    #[const_trait]
-    trait Trait {
-        fn foo();
-    }
-
-    reuse Trait::foo;
-    //~^ ERROR delegation to a function with effect parameter is not supported yet
-}
-
-fn main() {}
diff --git a/tests/ui/delegation/not-supported.stderr b/tests/ui/delegation/not-supported.stderr
deleted file mode 100644
index 14d6b374bd2..00000000000
--- a/tests/ui/delegation/not-supported.stderr
+++ /dev/null
@@ -1,204 +0,0 @@
-error: using `#![feature(effects)]` without enabling next trait solver globally
-   |
-   = note: the next trait solver must be enabled globally for the effects feature to work correctly
-   = help: use `-Znext-solver` to enable
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:18:29
-   |
-LL |         fn bar(&self, x: T) -> T { x }
-   |         ------------------------ callee defined here
-...
-LL |         reuse GenericTrait::bar;
-   |                             ^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:20:29
-   |
-LL |         fn bar1() {}
-   |         --------- callee defined here
-...
-LL |         reuse GenericTrait::bar1;
-   |                             ^^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:31:39
-   |
-LL |         fn bar(&self, x: T) -> T { x }
-   |         ------------------------ callee defined here
-...
-LL |         reuse <F as GenericTrait<T>>::bar { &self.0 }
-   |                                       ^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:33:34
-   |
-LL |         fn bar1() {}
-   |         --------- callee defined here
-...
-LL |         reuse GenericTrait::<T>::bar1;
-   |                                  ^^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:38:29
-   |
-LL |         fn bar(&self, x: T) -> T { x }
-   |         ------------------------ callee defined here
-...
-LL |         reuse GenericTrait::bar { &F }
-   |                             ^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:40:29
-   |
-LL |         fn bar1() {}
-   |         --------- callee defined here
-...
-LL |         reuse GenericTrait::bar1;
-   |                             ^^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:45:22
-   |
-LL |         fn foo(&self, x: i32) -> i32 { x }
-   |         ---------------------------- callee defined here
-...
-LL |         reuse Trait::foo;
-   |                      ^^^
-
-error[E0049]: method `foo2` has 0 type parameters but its trait declaration has 1 type parameter
-  --> $DIR/not-supported.rs:51:22
-   |
-LL |         fn foo2<T>(&self, x: T) -> T { x }
-   |                 - expected 1 type parameter
-...
-LL |         reuse Trait::foo2 { &self.0 }
-   |                      ^^^^ found 0 type parameters
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:54:29
-   |
-LL |         fn foo3<'a: 'a>(_: &'a u32) {}
-   |         --------------------------- callee defined here
-...
-LL |         reuse <F as Trait>::foo3;
-   |                             ^^^^
-
-error[E0195]: lifetime parameters or bounds on associated function `foo3` do not match the trait declaration
-  --> $DIR/not-supported.rs:54:29
-   |
-LL |         fn foo3<'a: 'a>(_: &'a u32) {}
-   |                -------- lifetimes in impl do not match this associated function in trait
-...
-LL |         reuse <F as Trait>::foo3;
-   |                             ^^^^ lifetimes do not match associated function in trait
-
-error: delegation to a function with effect parameter is not supported yet
-  --> $DIR/not-supported.rs:112:18
-   |
-LL |         fn foo();
-   |         --------- callee defined here
-...
-LL |     reuse Trait::foo;
-   |                  ^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:61:22
-   |
-LL |         fn foo(&self, x: i32) -> i32 { x }
-   |         ---------------------------- callee defined here
-...
-LL |         reuse Trait::foo { &self.0 }
-   |                      ^^^
-
-error: early bound generics are not supported for associated delegation items
-  --> $DIR/not-supported.rs:51:22
-   |
-LL |         fn foo2<T>(&self, x: T) -> T { x }
-   |         ---------------------------- callee defined here
-...
-LL |         reuse Trait::foo2 { &self.0 }
-   |                      ^^^^
-
-warning: this function depends on never type fallback being `()`
-  --> $DIR/not-supported.rs:79:9
-   |
-LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
-   = help: specify the types explicitly
-note: in edition 2024, the requirement `!: opaque::Trait` will fail
-  --> $DIR/not-supported.rs:79:28
-   |
-LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
-   |                            ^^^^^^^^^^
-   = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
-
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:24>::{synthetic#0}`
-  --> $DIR/not-supported.rs:86:25
-   |
-LL |         reuse to_reuse::opaque_ret;
-   |                         ^^^^^^^^^^
-   |
-note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
-  --> $DIR/not-supported.rs:86:25
-   |
-LL |         reuse to_reuse::opaque_ret;
-   |                         ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:85:5: 85:24>::{synthetic#0}`, completing the cycle
-note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:85:5: 85:24>` is well-formed
-  --> $DIR/not-supported.rs:85:5
-   |
-LL |     impl ToReuse for u8 {
-   |     ^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-warning: this function depends on never type fallback being `()`
-  --> $DIR/not-supported.rs:73:9
-   |
-LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
-   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
-   |
-   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
-   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
-   = help: specify the types explicitly
-note: in edition 2024, the requirement `!: opaque::Trait` will fail
-  --> $DIR/not-supported.rs:73:32
-   |
-LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
-   |                                ^^^^^^^^^^
-
-error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/not-supported.rs:88:5: 88:25>::{synthetic#0}`
-  --> $DIR/not-supported.rs:89:24
-   |
-LL |         reuse ToReuse::opaque_ret;
-   |                        ^^^^^^^^^^
-   |
-note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
-  --> $DIR/not-supported.rs:89:24
-   |
-LL |         reuse ToReuse::opaque_ret;
-   |                        ^^^^^^^^^^
-   = note: ...which again requires computing type of `opaque::<impl at $DIR/not-supported.rs:88:5: 88:25>::{synthetic#0}`, completing the cycle
-note: cycle used when checking that `opaque::<impl at $DIR/not-supported.rs:88:5: 88:25>` is well-formed
-  --> $DIR/not-supported.rs:88:5
-   |
-LL |     impl ToReuse for u16 {
-   |     ^^^^^^^^^^^^^^^^^^^^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
-
-error: recursive delegation is not supported yet
-  --> $DIR/not-supported.rs:102:22
-   |
-LL |         pub reuse to_reuse2::foo;
-   |                              --- callee defined here
-...
-LL |     reuse to_reuse1::foo;
-   |                      ^^^
-
-error: aborting due to 17 previous errors; 2 warnings emitted
-
-Some errors have detailed explanations: E0049, E0195, E0391.
-For more information about an error, try `rustc --explain E0049`.
diff --git a/tests/ui/delegation/unsupported.rs b/tests/ui/delegation/unsupported.rs
new file mode 100644
index 00000000000..e57effff48d
--- /dev/null
+++ b/tests/ui/delegation/unsupported.rs
@@ -0,0 +1,57 @@
+#![feature(const_trait_impl)]
+#![feature(c_variadic)]
+#![feature(effects)]
+#![feature(fn_delegation)]
+#![allow(incomplete_features)]
+
+mod opaque {
+    trait Trait {}
+    impl Trait for () {}
+
+    mod to_reuse {
+        use super::Trait;
+
+        pub fn opaque_ret() -> impl Trait { unimplemented!() }
+        //~^ warn: this function depends on never type fallback being `()`
+        //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    }
+
+    trait ToReuse {
+        fn opaque_ret() -> impl Trait { unimplemented!() }
+        //~^ warn: this function depends on never type fallback being `()`
+        //~| warn: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+    }
+
+    // FIXME: Inherited `impl Trait`s create query cycles when used inside trait impls.
+    impl ToReuse for u8 {
+        reuse to_reuse::opaque_ret; //~ ERROR cycle detected when computing type
+    }
+    impl ToReuse for u16 {
+        reuse ToReuse::opaque_ret; //~ ERROR cycle detected when computing type
+    }
+}
+
+mod recursive {
+    mod to_reuse1 {
+        pub mod to_reuse2 {
+            pub fn foo() {}
+        }
+
+        pub reuse to_reuse2::foo;
+    }
+
+    reuse to_reuse1::foo;
+    //~^ ERROR recursive delegation is not supported yet
+}
+
+mod effects {
+    #[const_trait]
+    trait Trait {
+        fn foo();
+    }
+
+    reuse Trait::foo;
+    //~^ ERROR delegation to a function with effect parameter is not supported yet
+}
+
+fn main() {}
diff --git a/tests/ui/delegation/unsupported.stderr b/tests/ui/delegation/unsupported.stderr
new file mode 100644
index 00000000000..03ded300bb4
--- /dev/null
+++ b/tests/ui/delegation/unsupported.stderr
@@ -0,0 +1,95 @@
+error: using `#![feature(effects)]` without enabling next trait solver globally
+   |
+   = note: the next trait solver must be enabled globally for the effects feature to work correctly
+   = help: use `-Znext-solver` to enable
+
+warning: this function depends on never type fallback being `()`
+  --> $DIR/unsupported.rs:20:9
+   |
+LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `!: opaque::Trait` will fail
+  --> $DIR/unsupported.rs:20:28
+   |
+LL |         fn opaque_ret() -> impl Trait { unimplemented!() }
+   |                            ^^^^^^^^^^
+   = note: `#[warn(dependency_on_unit_never_type_fallback)]` on by default
+
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:26:5: 26:24>::{synthetic#0}`
+  --> $DIR/unsupported.rs:27:25
+   |
+LL |         reuse to_reuse::opaque_ret;
+   |                         ^^^^^^^^^^
+   |
+note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
+  --> $DIR/unsupported.rs:27:25
+   |
+LL |         reuse to_reuse::opaque_ret;
+   |                         ^^^^^^^^^^
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:26:5: 26:24>::{synthetic#0}`, completing the cycle
+note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:26:5: 26:24>` is well-formed
+  --> $DIR/unsupported.rs:26:5
+   |
+LL |     impl ToReuse for u8 {
+   |     ^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+warning: this function depends on never type fallback being `()`
+  --> $DIR/unsupported.rs:14:9
+   |
+LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
+   |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+   |
+   = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
+   = note: for more information, see issue #123748 <https://github.com/rust-lang/rust/issues/123748>
+   = help: specify the types explicitly
+note: in edition 2024, the requirement `!: opaque::Trait` will fail
+  --> $DIR/unsupported.rs:14:32
+   |
+LL |         pub fn opaque_ret() -> impl Trait { unimplemented!() }
+   |                                ^^^^^^^^^^
+
+error[E0391]: cycle detected when computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:25>::{synthetic#0}`
+  --> $DIR/unsupported.rs:30:24
+   |
+LL |         reuse ToReuse::opaque_ret;
+   |                        ^^^^^^^^^^
+   |
+note: ...which requires comparing an impl and trait method signature, inferring any hidden `impl Trait` types in the process...
+  --> $DIR/unsupported.rs:30:24
+   |
+LL |         reuse ToReuse::opaque_ret;
+   |                        ^^^^^^^^^^
+   = note: ...which again requires computing type of `opaque::<impl at $DIR/unsupported.rs:29:5: 29:25>::{synthetic#0}`, completing the cycle
+note: cycle used when checking that `opaque::<impl at $DIR/unsupported.rs:29:5: 29:25>` is well-formed
+  --> $DIR/unsupported.rs:29:5
+   |
+LL |     impl ToReuse for u16 {
+   |     ^^^^^^^^^^^^^^^^^^^^
+   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+
+error: recursive delegation is not supported yet
+  --> $DIR/unsupported.rs:43:22
+   |
+LL |         pub reuse to_reuse2::foo;
+   |                              --- callee defined here
+...
+LL |     reuse to_reuse1::foo;
+   |                      ^^^
+
+error: delegation to a function with effect parameter is not supported yet
+  --> $DIR/unsupported.rs:53:18
+   |
+LL |         fn foo();
+   |         --------- callee defined here
+...
+LL |     reuse Trait::foo;
+   |                  ^^^
+
+error: aborting due to 5 previous errors; 2 warnings emitted
+
+For more information about this error, try `rustc --explain E0391`.
diff --git a/tests/ui/error-codes/e0119/issue-23563.stderr b/tests/ui/error-codes/e0119/issue-23563.stderr
index 86737742f74..a308769af13 100644
--- a/tests/ui/error-codes/e0119/issue-23563.stderr
+++ b/tests/ui/error-codes/e0119/issue-23563.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `LolFrom<&[_]>` for type `LocalType<_>`
+error[E0119]: conflicting implementations of trait `LolFrom<&[u8]>` for type `LocalType<u8>`
   --> $DIR/issue-23563.rs:13:1
    |
 LL | impl<'a, T> LolFrom<&'a [T]> for LocalType<T> {
diff --git a/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr b/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr
index ba076568088..b32f54aaecf 100644
--- a/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr
+++ b/tests/ui/feature-gates/feature-gate-with_negative_coherence.stderr
@@ -6,6 +6,8 @@ LL | impl<T: std::ops::DerefMut> Foo for T { }
 LL |
 LL | impl<T> Foo for &T { }
    | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `&_`
+   |
+   = note: downstream crates may implement trait `std::ops::DerefMut` for type `&_`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs
index beda719ac20..9a44fd2e64a 100644
--- a/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs
+++ b/tests/ui/higher-ranked/leak-check/leak-check-in-selection-5-ambig.rs
@@ -3,9 +3,9 @@
 //@ check-pass
 
 // The new trait solver does not return region constraints if the goal
-// is still ambiguous. This causes the following test to fail with ambiguity,
-// even though `(): LeakCheckFailure<'!a, V>` would return `'!a: 'static`
-// which would have caused a leak check failure.
+// is still ambiguous. However, the `'!a = 'static` constraint from
+// `(): LeakCheckFailure<'!a, V>`  is also returned via the canonical
+// var values, causing this test to compile.
 
 trait Ambig {}
 impl Ambig for u32 {}
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.rs b/tests/ui/higher-ranked/structually-relate-aliases.rs
index 8df24702811..69882450961 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.rs
+++ b/tests/ui/higher-ranked/structually-relate-aliases.rs
@@ -11,7 +11,6 @@ type Assoc<'a, T> = <T as ToUnit<'a>>::Unit;
 impl<T> Overlap<T> for T {}
 
 impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-//~^ ERROR 13:17: 13:49: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied [E0277]
-//~| ERROR 13:36: 13:48: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied [E0277]
+//~^ ERROR conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>`
 
 fn main() {}
diff --git a/tests/ui/higher-ranked/structually-relate-aliases.stderr b/tests/ui/higher-ranked/structually-relate-aliases.stderr
index 7de30efae1c..4ecd5829bc3 100644
--- a/tests/ui/higher-ranked/structually-relate-aliases.stderr
+++ b/tests/ui/higher-ranked/structually-relate-aliases.stderr
@@ -1,27 +1,18 @@
  WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
- WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, !2_0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
-error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
-  --> $DIR/structually-relate-aliases.rs:13:36
-   |
-LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-   |                                    ^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
-   |
-help: consider restricting type parameter `T`
-   |
-LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-   |       ++++++++++++++++++++
-
-error[E0277]: the trait bound `for<'a> T: ToUnit<'a>` is not satisfied
-  --> $DIR/structually-relate-aliases.rs:13:17
+ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
+ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
+ WARN rustc_infer::infer::relate::generalize may incompletely handle alias type: AliasTy { args: [?1t, '^0.Named(DefId(0:15 ~ structually_relate_aliases[de75]::{impl#1}::'a), "'a")], def_id: DefId(0:5 ~ structually_relate_aliases[de75]::ToUnit::Unit), .. }
+error[E0119]: conflicting implementations of trait `Overlap<for<'a> fn(&'a (), _)>` for type `for<'a> fn(&'a (), _)`
+  --> $DIR/structually-relate-aliases.rs:13:1
    |
+LL | impl<T> Overlap<T> for T {}
+   | ------------------------ first implementation here
+LL |
 LL | impl<T> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-   |                 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `for<'a> ToUnit<'a>` is not implemented for `T`
-   |
-help: consider restricting type parameter `T`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `for<'a> fn(&'a (), _)`
    |
-LL | impl<T: for<'a> ToUnit<'a>> Overlap<for<'a> fn(&'a (), Assoc<'a, T>)> for T {}
-   |       ++++++++++++++++++++
+   = note: this behavior recently changed as a result of a bug fix; see rust-lang/rust#56105 for details
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/impl-trait/auto-trait-coherence.old.stderr b/tests/ui/impl-trait/auto-trait-coherence.old.stderr
index 3f979d1a50b..cd91bfcb48d 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.old.stderr
+++ b/tests/ui/impl-trait/auto-trait-coherence.old.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 e3036fd0fe2..0d7fef21cc9 100644
--- a/tests/ui/impl-trait/auto-trait-coherence.rs
+++ b/tests/ui/impl-trait/auto-trait-coherence.rs
@@ -1,6 +1,3 @@
-//@ revisions: old next
-//@[next] compile-flags: -Znext-solver
-
 // Tests that type alias impls traits do not leak auto-traits for
 // the purposes of coherence checking
 #![feature(type_alias_impl_trait)]
@@ -22,8 +19,7 @@ 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> {
-    //[old]~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
-    //[next]~^^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>`
+    //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>`
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/auto-trait-coherence.stderr b/tests/ui/impl-trait/auto-trait-coherence.stderr
new file mode 100644
index 00000000000..e0f4c857717
--- /dev/null
+++ b/tests/ui/impl-trait/auto-trait-coherence.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>`
+  --> $DIR/auto-trait-coherence.rs:21:1
+   |
+LL | impl<T: Send> AnotherTrait for T {}
+   | -------------------------------- first implementation here
+...
+LL | impl AnotherTrait for D<OpaqueType> {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs
index df47208bf36..e8c1fcdd213 100644
--- a/tests/ui/impl-trait/coherence-treats-tait-ambig.rs
+++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.rs
@@ -5,7 +5,7 @@ type T = impl Sized;
 struct Foo;
 
 impl Into<T> for Foo {
-//~^ ERROR conflicting implementations of trait `Into<T>` for type `Foo`
+//~^ ERROR conflicting implementations of trait `Into<_>` for type `Foo`
     fn into(self) -> T {
         Foo
     }
diff --git a/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr b/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr
index faaad276927..618bef1f271 100644
--- a/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr
+++ b/tests/ui/impl-trait/coherence-treats-tait-ambig.stderr
@@ -1,4 +1,4 @@
-error[E0119]: conflicting implementations of trait `Into<T>` for type `Foo`
+error[E0119]: conflicting implementations of trait `Into<_>` for type `Foo`
   --> $DIR/coherence-treats-tait-ambig.rs:7:1
    |
 LL | impl Into<T> for Foo {
diff --git a/tests/ui/impl-trait/negative-reasoning.rs b/tests/ui/impl-trait/negative-reasoning.rs
index 70e24a3a9d0..0474dc0beda 100644
--- a/tests/ui/impl-trait/negative-reasoning.rs
+++ b/tests/ui/impl-trait/negative-reasoning.rs
@@ -17,7 +17,7 @@ impl<T: std::fmt::Debug> AnotherTrait for T {}
 
 // This is in error, because we cannot assume that `OpaqueType: !Debug`
 impl AnotherTrait for D<OpaqueType> {
-    //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+    //~^ ERROR conflicting implementations of trait `AnotherTrait` for type `D<_>`
 }
 
 fn main() {}
diff --git a/tests/ui/impl-trait/negative-reasoning.stderr b/tests/ui/impl-trait/negative-reasoning.stderr
index 3cb4be16fc3..631784c817b 100644
--- a/tests/ui/impl-trait/negative-reasoning.stderr
+++ b/tests/ui/impl-trait/negative-reasoning.stderr
@@ -1,13 +1,11 @@
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<OpaqueType>`
+error[E0119]: conflicting implementations of trait `AnotherTrait` for type `D<_>`
   --> $DIR/negative-reasoning.rs:19:1
    |
 LL | impl<T: std::fmt::Debug> AnotherTrait for T {}
    | ------------------------------------------- first implementation here
 ...
 LL | impl AnotherTrait for D<OpaqueType> {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<OpaqueType>`
-   |
-   = note: upstream crates may add a new impl of trait `std::marker::FnPtr` for type `OpaqueType` in future versions
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D<_>`
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-unused-tps.rs b/tests/ui/impl-unused-tps.rs
index 3eb9daedf76..a5836db3c8e 100644
--- a/tests/ui/impl-unused-tps.rs
+++ b/tests/ui/impl-unused-tps.rs
@@ -1,34 +1,35 @@
-//~ ERROR overflow evaluating the requirement `([isize; 0], _): Sized
-
 trait Foo<A> {
-    fn get(&self, A: &A) { }
+    fn get(&self, A: &A) {}
 }
 
 trait Bar {
     type Out;
 }
 
-impl<T> Foo<T> for [isize;0] {
+impl<T> Foo<T> for [isize; 0] {
     // OK, T is used in `Foo<T>`.
 }
 
-impl<T,U> Foo<T> for [isize;1] {
+impl<T, U> Foo<T> for [isize; 1] {
     //~^ ERROR the type parameter `U` is not constrained
 }
 
-impl<T,U> Foo<T> for [isize;2] where T : Bar<Out=U> {
+impl<T, U> Foo<T> for [isize; 2]
+where
+    T: Bar<Out = U>,
+{
     // OK, `U` is now constrained by the output type parameter.
 }
 
-impl<T:Bar<Out=U>,U> Foo<T> for [isize;3] {
+impl<T: Bar<Out = U>, U> Foo<T> for [isize; 3] {
     // OK, same as above but written differently.
 }
 
-impl<T,U> Foo<T> for U {
+impl<T, U> Foo<T> for U {
     //~^ ERROR conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
 }
 
-impl<T,U> Bar for T {
+impl<T, U> Bar for T {
     //~^ ERROR the type parameter `U` is not constrained
 
     type Out = U;
@@ -36,28 +37,33 @@ impl<T,U> Bar for T {
     // Using `U` in an associated type within the impl is not good enough!
 }
 
-impl<T,U> Bar for T
-    where T : Bar<Out=U>
+impl<T, U> Bar for T
+where
+    T: Bar<Out = U>,
 {
-    //~^^^ ERROR the type parameter `U` is not constrained
-
+    //~^^^^ ERROR the type parameter `U` is not constrained by the impl trait, self type, or predicates
+    //~| ERROR conflicting implementations of trait `Bar`
     // This crafty self-referential attempt is still no good.
 }
 
-impl<T,U,V> Foo<T> for T
-    where (T,U): Bar<Out=V>
+impl<T, U, V> Foo<T> for T
+where
+    (T, U): Bar<Out = V>,
 {
-    //~^^^ ERROR the type parameter `U` is not constrained
-    //~|   ERROR the type parameter `V` is not constrained
+    //~^^^^ ERROR the type parameter `U` is not constrained
+    //~| ERROR the type parameter `V` is not constrained
+    //~| ERROR conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]`
 
     // Here, `V` is bound by an output type parameter, but the inputs
     // are not themselves constrained.
 }
 
-impl<T,U,V> Foo<(T,U)> for T
-    where (T,U): Bar<Out=V>
+impl<T, U, V> Foo<(T, U)> for T
+where
+    (T, U): Bar<Out = V>,
 {
+    //~^^^^ ERROR conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]`
     // As above, but both T and U ARE constrained.
 }
 
-fn main() { }
+fn main() {}
diff --git a/tests/ui/impl-unused-tps.stderr b/tests/ui/impl-unused-tps.stderr
index af427cb5f3e..da4589dee82 100644
--- a/tests/ui/impl-unused-tps.stderr
+++ b/tests/ui/impl-unused-tps.stderr
@@ -1,56 +1,76 @@
 error[E0119]: conflicting implementations of trait `Foo<_>` for type `[isize; 0]`
-  --> $DIR/impl-unused-tps.rs:27:1
+  --> $DIR/impl-unused-tps.rs:28:1
    |
-LL | impl<T> Foo<T> for [isize;0] {
-   | ---------------------------- first implementation here
+LL | impl<T> Foo<T> for [isize; 0] {
+   | ----------------------------- first implementation here
 ...
-LL | impl<T,U> Foo<T> for U {
-   | ^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
+LL | impl<T, U> Foo<T> for U {
+   | ^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `[isize; 0]`
 
-error[E0275]: overflow evaluating the requirement `([isize; 0], _): Sized`
+error[E0119]: conflicting implementations of trait `Bar`
+  --> $DIR/impl-unused-tps.rs:40:1
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`impl_unused_tps`)
-note: required for `([isize; 0], _)` to implement `Bar`
-  --> $DIR/impl-unused-tps.rs:31:11
+LL |   impl<T, U> Bar for T {
+   |   -------------------- first implementation here
+...
+LL | / impl<T, U> Bar for T
+LL | | where
+LL | |     T: Bar<Out = U>,
+   | |____________________^ conflicting implementation
+
+error[E0119]: conflicting implementations of trait `Foo<[isize; 0]>` for type `[isize; 0]`
+  --> $DIR/impl-unused-tps.rs:49:1
+   |
+LL |   impl<T> Foo<T> for [isize; 0] {
+   |   ----------------------------- first implementation here
+...
+LL | / impl<T, U, V> Foo<T> for T
+LL | | where
+LL | |     (T, U): Bar<Out = V>,
+   | |_________________________^ conflicting implementation for `[isize; 0]`
+
+error[E0119]: conflicting implementations of trait `Foo<([isize; 0], _)>` for type `[isize; 0]`
+  --> $DIR/impl-unused-tps.rs:61:1
    |
-LL | impl<T,U> Bar for T {
-   |      -    ^^^     ^
-   |      |
-   |      unsatisfied trait bound introduced here
-   = note: 126 redundant requirements hidden
-   = note: required for `([isize; 0], _)` to implement `Bar`
+LL |   impl<T> Foo<T> for [isize; 0] {
+   |   ----------------------------- first implementation here
+...
+LL | / impl<T, U, V> Foo<(T, U)> for T
+LL | | where
+LL | |     (T, U): Bar<Out = V>,
+   | |_________________________^ conflicting implementation for `[isize; 0]`
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:15:8
+  --> $DIR/impl-unused-tps.rs:13:9
    |
-LL | impl<T,U> Foo<T> for [isize;1] {
-   |        ^ unconstrained type parameter
+LL | impl<T, U> Foo<T> for [isize; 1] {
+   |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:31:8
+  --> $DIR/impl-unused-tps.rs:32:9
    |
-LL | impl<T,U> Bar for T {
-   |        ^ unconstrained type parameter
+LL | impl<T, U> Bar for T {
+   |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:39:8
+  --> $DIR/impl-unused-tps.rs:40:9
    |
-LL | impl<T,U> Bar for T
-   |        ^ unconstrained type parameter
+LL | impl<T, U> Bar for T
+   |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `U` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:47:8
+  --> $DIR/impl-unused-tps.rs:49:9
    |
-LL | impl<T,U,V> Foo<T> for T
-   |        ^ unconstrained type parameter
+LL | impl<T, U, V> Foo<T> for T
+   |         ^ unconstrained type parameter
 
 error[E0207]: the type parameter `V` is not constrained by the impl trait, self type, or predicates
-  --> $DIR/impl-unused-tps.rs:47:10
+  --> $DIR/impl-unused-tps.rs:49:12
    |
-LL | impl<T,U,V> Foo<T> for T
-   |          ^ unconstrained type parameter
+LL | impl<T, U, V> Foo<T> for T
+   |            ^ unconstrained type parameter
 
-error: aborting due to 7 previous errors
+error: aborting due to 9 previous errors
 
-Some errors have detailed explanations: E0119, E0207, E0275.
+Some errors have detailed explanations: E0119, E0207.
 For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-2.rs b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-2.rs
new file mode 100644
index 00000000000..ca8b8b7e4d9
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-2.rs
@@ -0,0 +1,13 @@
+//@ check-pass
+//@ known-bug: #25860
+
+static UNIT: &'static &'static () = &&();
+
+fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T, _: &()) -> &'a T { v }
+
+fn bad<'a, T>(x: &'a T) -> &'static T {
+    let f: fn(_, &'a T, &()) -> &'static T = foo;
+    f(UNIT, x, &())
+}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.rs b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.rs
new file mode 100644
index 00000000000..226a6fa3016
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.rs
@@ -0,0 +1,13 @@
+// Regression test for #129021.
+
+static UNIT: &'static &'static () = &&();
+
+fn foo<'a: 'a, 'b: 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }
+
+fn bad<'a, T>(x: &'a T) -> &'static T {
+    let f: fn(_, &'a T) -> &'static T = foo;
+    //~^ ERROR lifetime may not live long enough
+    f(UNIT, x)
+}
+
+fn main() {}
diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.stderr b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.stderr
new file mode 100644
index 00000000000..84d2a6d2b6a
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-early-bound.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+  --> $DIR/implied-bounds-on-nested-references-plus-variance-early-bound.rs:8:12
+   |
+LL | fn bad<'a, T>(x: &'a T) -> &'static T {
+   |        -- lifetime `'a` defined here
+LL |     let f: fn(_, &'a T) -> &'static T = foo;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.rs b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.rs
new file mode 100644
index 00000000000..f3068990189
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.rs
@@ -0,0 +1,19 @@
+// Regression test for #129021.
+
+trait ToArg<T> {
+    type Arg;
+}
+impl<T, U> ToArg<T> for U {
+    type Arg = T;
+}
+
+fn extend_inner<'a, 'b>(x: &'a str) -> <&'b &'a () as ToArg<&'b str>>::Arg { x }
+fn extend<'a, 'b>(x: &'a str) -> &'b str {
+    (extend_inner as fn(_) -> _)(x)
+    //~^ ERROR lifetime may not live long enough
+}
+
+fn main() {
+    let y = extend(&String::from("Hello World"));
+    println!("{}", y);
+}
diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.stderr b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.stderr
new file mode 100644
index 00000000000..4cdb959786a
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance-unnormalized.stderr
@@ -0,0 +1,14 @@
+error: lifetime may not live long enough
+  --> $DIR/implied-bounds-on-nested-references-plus-variance-unnormalized.rs:12:5
+   |
+LL | fn extend<'a, 'b>(x: &'a str) -> &'b str {
+   |           --  -- lifetime `'b` defined here
+   |           |
+   |           lifetime `'a` defined here
+LL |     (extend_inner as fn(_) -> _)(x)
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function was supposed to return data with lifetime `'b` but it is returning data with lifetime `'a`
+   |
+   = help: consider adding the following bound: `'a: 'b`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs
index f3401f34eec..6de81cba728 100644
--- a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs
+++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.rs
@@ -1,8 +1,4 @@
-//@ check-pass
-//@ known-bug: #25860
-
-// Should fail. The combination of variance and implied bounds for nested
-// references allows us to infer a longer lifetime than we can prove.
+// Regression test for #129021.
 
 static UNIT: &'static &'static () = &&();
 
@@ -10,6 +6,7 @@ fn foo<'a, 'b, T>(_: &'a &'b (), v: &'b T) -> &'a T { v }
 
 fn bad<'a, T>(x: &'a T) -> &'static T {
     let f: fn(_, &'a T) -> &'static T = foo;
+    //~^ ERROR lifetime may not live long enough
     f(UNIT, x)
 }
 
diff --git a/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.stderr b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.stderr
new file mode 100644
index 00000000000..c96fa92937b
--- /dev/null
+++ b/tests/ui/implied-bounds/implied-bounds-on-nested-references-plus-variance.stderr
@@ -0,0 +1,10 @@
+error: lifetime may not live long enough
+  --> $DIR/implied-bounds-on-nested-references-plus-variance.rs:8:12
+   |
+LL | fn bad<'a, T>(x: &'a T) -> &'static T {
+   |        -- lifetime `'a` defined here
+LL |     let f: fn(_, &'a T) -> &'static T = foo;
+   |            ^^^^^^^^^^^^^^^^^^^^^^^^^^ type annotation requires that `'a` must outlive `'static`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/issues/issue-48728.rs b/tests/ui/issues/issue-48728.rs
index 7ef05f4277b..8ad9289c65c 100644
--- a/tests/ui/issues/issue-48728.rs
+++ b/tests/ui/issues/issue-48728.rs
@@ -1,12 +1,8 @@
 // Regression test for #48728, an ICE that occurred computing
 // coherence "help" information.
 
-//@ revisions: current next
-//@ ignore-compare-mode-next-solver (explicit revisions)
-//@[next] compile-flags: -Znext-solver
-//@[next] check-pass
-
-#[derive(Clone)] //[current]~ ERROR conflicting implementations of trait `Clone`
+//@ check-pass
+#[derive(Clone)]
 struct Node<T: ?Sized>(Box<T>);
 
 impl<T: Clone + ?Sized> Clone for Node<[T]> {
diff --git a/tests/ui/lexer/prefixed-lifetime.rs b/tests/ui/lexer/prefixed-lifetime.rs
new file mode 100644
index 00000000000..6191b97d576
--- /dev/null
+++ b/tests/ui/lexer/prefixed-lifetime.rs
@@ -0,0 +1,10 @@
+//@ edition: 2021
+
+macro_rules! w {
+    ($($tt:tt)*) => {};
+}
+
+w!('foo#lifetime);
+//~^ ERROR prefix `'foo` is unknown
+
+fn main() {}
diff --git a/tests/ui/lexer/prefixed-lifetime.stderr b/tests/ui/lexer/prefixed-lifetime.stderr
new file mode 100644
index 00000000000..39e8b5a2a57
--- /dev/null
+++ b/tests/ui/lexer/prefixed-lifetime.stderr
@@ -0,0 +1,14 @@
+error: prefix `'foo` is unknown
+  --> $DIR/prefixed-lifetime.rs:7:4
+   |
+LL | w!('foo#lifetime);
+   |    ^^^^ unknown prefix
+   |
+   = note: prefixed identifiers and literals are reserved since Rust 2021
+help: consider inserting whitespace here
+   |
+LL | w!('foo #lifetime);
+   |        +
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lifetimes/raw/gen-lt.e2024.stderr b/tests/ui/lifetimes/raw/gen-lt.e2024.stderr
new file mode 100644
index 00000000000..232453df8ef
--- /dev/null
+++ b/tests/ui/lifetimes/raw/gen-lt.e2024.stderr
@@ -0,0 +1,8 @@
+error: lifetimes cannot use keyword names
+  --> $DIR/gen-lt.rs:11:11
+   |
+LL | fn gen_lt<'gen>() {}
+   |           ^^^^
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lifetimes/raw/gen-lt.rs b/tests/ui/lifetimes/raw/gen-lt.rs
new file mode 100644
index 00000000000..4f3ede5b4a2
--- /dev/null
+++ b/tests/ui/lifetimes/raw/gen-lt.rs
@@ -0,0 +1,14 @@
+//@ revisions: e2021 e2024
+
+//@[e2021] edition:2021
+//@[e2024] edition:2024
+//@[e2024] compile-flags: -Zunstable-options
+
+//@[e2021] check-pass
+
+fn raw_gen_lt<'r#gen>() {}
+
+fn gen_lt<'gen>() {}
+//[e2024]~^ ERROR lifetimes cannot use keyword names
+
+fn main() {}
diff --git a/tests/ui/lifetimes/raw/lifetimes-eq.rs b/tests/ui/lifetimes/raw/lifetimes-eq.rs
new file mode 100644
index 00000000000..dddafb829ba
--- /dev/null
+++ b/tests/ui/lifetimes/raw/lifetimes-eq.rs
@@ -0,0 +1,8 @@
+//@ edition: 2021
+//@ check-pass
+
+// Test that `'r#a` is `'a`.
+
+fn test<'r#a>(x: &'a ()) {}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/raw/macro-lt.rs b/tests/ui/lifetimes/raw/macro-lt.rs
new file mode 100644
index 00000000000..d1167b00467
--- /dev/null
+++ b/tests/ui/lifetimes/raw/macro-lt.rs
@@ -0,0 +1,12 @@
+//@ check-pass
+//@ edition: 2021
+
+macro_rules! lifetime {
+    ($lt:lifetime) => {
+        fn hello<$lt>() {}
+    }
+}
+
+lifetime!('r#struct);
+
+fn main() {}
diff --git a/tests/ui/lifetimes/raw/multiple-prefixes.rs b/tests/ui/lifetimes/raw/multiple-prefixes.rs
new file mode 100644
index 00000000000..f335373d8a7
--- /dev/null
+++ b/tests/ui/lifetimes/raw/multiple-prefixes.rs
@@ -0,0 +1,6 @@
+//@ edition: 2021
+
+fn test(x: &'r#r#r ()) {}
+//~^ ERROR expected type, found `#`
+
+fn main() {}
diff --git a/tests/ui/lifetimes/raw/multiple-prefixes.stderr b/tests/ui/lifetimes/raw/multiple-prefixes.stderr
new file mode 100644
index 00000000000..8d5479e0a4f
--- /dev/null
+++ b/tests/ui/lifetimes/raw/multiple-prefixes.stderr
@@ -0,0 +1,8 @@
+error: expected type, found `#`
+  --> $DIR/multiple-prefixes.rs:3:17
+   |
+LL | fn test(x: &'r#r#r ()) {}
+   |                 ^ expected type
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/lifetimes/raw/prim-lt.rs b/tests/ui/lifetimes/raw/prim-lt.rs
new file mode 100644
index 00000000000..ca45efb65fd
--- /dev/null
+++ b/tests/ui/lifetimes/raw/prim-lt.rs
@@ -0,0 +1,8 @@
+//@ check-pass
+//@ edition: 2021
+
+// Checks a primitive name can be defined as a lifetime.
+
+fn foo<'r#i32>() {}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/raw/simple.rs b/tests/ui/lifetimes/raw/simple.rs
new file mode 100644
index 00000000000..6f70a272203
--- /dev/null
+++ b/tests/ui/lifetimes/raw/simple.rs
@@ -0,0 +1,21 @@
+//@ check-pass
+//@ edition: 2021
+
+fn foo<'r#struct>() {}
+
+fn hr<T>() where for<'r#struct> T: Into<&'r#struct ()> {}
+
+trait Foo<'r#struct> {}
+
+trait Bar<'r#struct> {
+    fn method(&'r#struct self) {}
+    fn method2(self: &'r#struct Self) {}
+}
+
+fn labeled() {
+    'r#struct: loop {
+        break 'r#struct;
+    }
+}
+
+fn main() {}
diff --git a/tests/ui/lifetimes/raw/static-lt.rs b/tests/ui/lifetimes/raw/static-lt.rs
new file mode 100644
index 00000000000..1fec7097dab
--- /dev/null
+++ b/tests/ui/lifetimes/raw/static-lt.rs
@@ -0,0 +1,8 @@
+//@ check-pass
+//@ edition: 2021
+
+// Makes sure that `'r#static` is `'static`
+
+const FOO: &'r#static str = "hello, world";
+
+fn main() {}
diff --git a/tests/ui/lifetimes/raw/three-tokens.rs b/tests/ui/lifetimes/raw/three-tokens.rs
new file mode 100644
index 00000000000..2ae54ebbcb5
--- /dev/null
+++ b/tests/ui/lifetimes/raw/three-tokens.rs
@@ -0,0 +1,12 @@
+//@ edition: 2015
+//@ check-pass
+// Ensure that we parse `'r#lt` as three tokens in edition 2015.
+
+macro_rules! ed2015 {
+    ('r # lt) => {};
+    ($lt:lifetime) => { compile_error!() };
+}
+
+ed2015!('r#lt);
+
+fn main() {}
diff --git a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
index 8c5426a60cb..2d8c6e99643 100644
--- a/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
+++ b/tests/ui/lint/elided-named-lifetimes/example-from-issue48686.stderr
@@ -9,6 +9,10 @@ note: the lint level is defined here
    |
 LL | #![deny(elided_named_lifetimes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL |     pub fn get_mut(&'static self, x: &mut u8) -> &'static mut u8 {
+   |                                                   +++++++
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
index c465aab1a03..3c01375d501 100644
--- a/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
+++ b/tests/ui/lint/elided-named-lifetimes/not-tied-to-crate.stderr
@@ -9,6 +9,10 @@ note: the lint level is defined here
    |
 LL | #[warn(elided_named_lifetimes)]
    |        ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL |     fn bar(x: &'static u8) -> &'static u8 {
+   |                                +++++++
 
 error: elided lifetime has a name
   --> $DIR/not-tied-to-crate.rs:11:31
@@ -21,6 +25,10 @@ note: the lint level is defined here
    |
 LL |     #[deny(elided_named_lifetimes)]
    |            ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL |     fn baz(x: &'static u8) -> &'static u8 {
+   |                                +++++++
 
 error: aborting due to 1 previous error; 1 warning emitted
 
diff --git a/tests/ui/lint/elided-named-lifetimes/static.stderr b/tests/ui/lint/elided-named-lifetimes/static.stderr
index d2e9776cb4f..fa2a2d3460f 100644
--- a/tests/ui/lint/elided-named-lifetimes/static.stderr
+++ b/tests/ui/lint/elided-named-lifetimes/static.stderr
@@ -9,24 +9,43 @@ note: the lint level is defined here
    |
 LL | #![deny(elided_named_lifetimes)]
    |         ^^^^^^^^^^^^^^^^^^^^^^
+help: consider specifying it explicitly
+   |
+LL | fn ampersand(x: &'static u8) -> &'static u8 {
+   |                                  +++++++
 
 error: elided lifetime has a name
   --> $DIR/static.rs:23:32
    |
 LL | fn brackets(x: &'static u8) -> Brackets {
    |                                ^^^^^^^^ this elided lifetime gets resolved as `'static`
+   |
+help: consider specifying it explicitly
+   |
+LL | fn brackets(x: &'static u8) -> Brackets<'static> {
+   |                                        +++++++++
 
 error: elided lifetime has a name
   --> $DIR/static.rs:30:34
    |
 LL | fn comma(x: &'static u8) -> Comma<u8> {
    |                                  ^ this elided lifetime gets resolved as `'static`
+   |
+help: consider specifying it explicitly
+   |
+LL | fn comma(x: &'static u8) -> Comma<'static, u8> {
+   |                                   ++++++++
 
 error: elided lifetime has a name
   --> $DIR/static.rs:35:35
    |
 LL | fn underscore(x: &'static u8) -> &'_ u8 {
    |                                   ^^ this elided lifetime gets resolved as `'static`
+   |
+help: consider specifying it explicitly
+   |
+LL | fn underscore(x: &'static u8) -> &'static u8 {
+   |                                   ~~~~~~~
 
 error: aborting due to 4 previous errors
 
diff --git a/tests/ui/parser/extern-crate-unexpected-token.stderr b/tests/ui/parser/extern-crate-unexpected-token.stderr
index f83bb3e3e35..951b0274b0d 100644
--- a/tests/ui/parser/extern-crate-unexpected-token.stderr
+++ b/tests/ui/parser/extern-crate-unexpected-token.stderr
@@ -3,6 +3,11 @@ error: expected one of `crate` or `{`, found `crte`
    |
 LL | extern crte foo;
    |        ^^^^ expected one of `crate` or `{`
+   |
+help: there is a keyword `crate` with a similar name
+   |
+LL | extern crate foo;
+   |        ~~~~~
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
index 79c574ead61..00f372bc008 100644
--- a/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
+++ b/tests/ui/parser/issues/issue-70549-resolve-after-recovered-self-ctor.stderr
@@ -8,10 +8,16 @@ error: expected one of `:`, `@`, or `|`, found keyword `Self`
   --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
    |
 LL |     fn foo(&mur Self) {}
-   |            -----^^^^
-   |            |    |
-   |            |    expected one of `:`, `@`, or `|`
-   |            help: declare the type after the parameter binding: `<identifier>: <type>`
+   |                 ^^^^ expected one of `:`, `@`, or `|`
+   |
+help: there is a keyword `mut` with a similar name
+   |
+LL |     fn foo(&mut Self) {}
+   |             ~~~
+help: declare the type after the parameter binding
+   |
+LL |     fn foo(<identifier>: <type>) {}
+   |            ~~~~~~~~~~~~~~~~~~~~
 
 error: unexpected lifetime `'static` in pattern
   --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:13
@@ -35,16 +41,27 @@ error: expected one of `:`, `@`, or `|`, found keyword `Self`
   --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:8:25
    |
 LL |     fn bar(&'static mur Self) {}
-   |            -------------^^^^
-   |            |            |
-   |            |            expected one of `:`, `@`, or `|`
-   |            help: declare the type after the parameter binding: `<identifier>: <type>`
+   |                         ^^^^ expected one of `:`, `@`, or `|`
+   |
+help: there is a keyword `mut` with a similar name
+   |
+LL |     fn bar(&'static mut Self) {}
+   |                     ~~~
+help: declare the type after the parameter binding
+   |
+LL |     fn bar(<identifier>: <type>) {}
+   |            ~~~~~~~~~~~~~~~~~~~~
 
 error: expected one of `:`, `@`, or `|`, found keyword `Self`
   --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:14:17
    |
 LL |     fn baz(&mur Self @ _) {}
    |                 ^^^^ expected one of `:`, `@`, or `|`
+   |
+help: there is a keyword `mut` with a similar name
+   |
+LL |     fn baz(&mut Self @ _) {}
+   |             ~~~
 
 error[E0533]: expected unit struct, found self constructor `Self`
   --> $DIR/issue-70549-resolve-after-recovered-self-ctor.rs:4:17
diff --git a/tests/ui/parser/misspelled-keywords/assoc-type.rs b/tests/ui/parser/misspelled-keywords/assoc-type.rs
new file mode 100644
index 00000000000..a6b694a2abe
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/assoc-type.rs
@@ -0,0 +1,6 @@
+trait Animal {
+    Type Result = u8;
+    //~^ ERROR expected one of
+}
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/assoc-type.stderr b/tests/ui/parser/misspelled-keywords/assoc-type.stderr
new file mode 100644
index 00000000000..677da53e340
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/assoc-type.stderr
@@ -0,0 +1,18 @@
+error: expected one of `!` or `::`, found `Result`
+  --> $DIR/assoc-type.rs:2:10
+   |
+LL | trait Animal {
+   |              - while parsing this item list starting here
+LL |     Type Result = u8;
+   |          ^^^^^^ expected one of `!` or `::`
+LL |
+LL | }
+   | - the item list ends here
+   |
+help: write keyword `type` in lowercase
+   |
+LL |     type Result = u8;
+   |     ~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/async-move.rs b/tests/ui/parser/misspelled-keywords/async-move.rs
new file mode 100644
index 00000000000..702a905e918
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/async-move.rs
@@ -0,0 +1,6 @@
+//@ edition: 2018
+
+fn main() {
+    async Move {}
+    //~^ ERROR expected one of
+}
diff --git a/tests/ui/parser/misspelled-keywords/async-move.stderr b/tests/ui/parser/misspelled-keywords/async-move.stderr
new file mode 100644
index 00000000000..4be4b56e505
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/async-move.stderr
@@ -0,0 +1,13 @@
+error: expected one of `move`, `|`, or `||`, found `Move`
+  --> $DIR/async-move.rs:4:11
+   |
+LL |     async Move {}
+   |           ^^^^ expected one of `move`, `|`, or `||`
+   |
+help: write keyword `move` in lowercase
+   |
+LL |     async move {}
+   |           ~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/const-fn.rs b/tests/ui/parser/misspelled-keywords/const-fn.rs
new file mode 100644
index 00000000000..c4174b6a2ef
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/const-fn.rs
@@ -0,0 +1,5 @@
+cnst fn code() {}
+//~^ ERROR expected one of
+
+fn main() {
+}
diff --git a/tests/ui/parser/misspelled-keywords/const-fn.stderr b/tests/ui/parser/misspelled-keywords/const-fn.stderr
new file mode 100644
index 00000000000..5646b26143c
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/const-fn.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found keyword `fn`
+  --> $DIR/const-fn.rs:1:6
+   |
+LL | cnst fn code() {}
+   |      ^^ expected one of `!` or `::`
+   |
+help: there is a keyword `const` with a similar name
+   |
+LL | const fn code() {}
+   | ~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/const-generics.rs b/tests/ui/parser/misspelled-keywords/const-generics.rs
new file mode 100644
index 00000000000..2df64a87e27
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/const-generics.rs
@@ -0,0 +1,4 @@
+fn foo<consta N: usize>(_arr: [i32; N]) {}
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/const-generics.stderr b/tests/ui/parser/misspelled-keywords/const-generics.stderr
new file mode 100644
index 00000000000..fd59999ab63
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/const-generics.stderr
@@ -0,0 +1,13 @@
+error: expected one of `,`, `:`, `=`, or `>`, found `N`
+  --> $DIR/const-generics.rs:1:15
+   |
+LL | fn foo<consta N: usize>(_arr: [i32; N]) {}
+   |               ^ expected one of `,`, `:`, `=`, or `>`
+   |
+help: there is a keyword `const` with a similar name
+   |
+LL | fn foo<const N: usize>(_arr: [i32; N]) {}
+   |        ~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/const.rs b/tests/ui/parser/misspelled-keywords/const.rs
new file mode 100644
index 00000000000..b481408cb62
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/const.rs
@@ -0,0 +1,4 @@
+cons A: u8 = 10;
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/const.stderr b/tests/ui/parser/misspelled-keywords/const.stderr
new file mode 100644
index 00000000000..35e4d731db7
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/const.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found `A`
+  --> $DIR/const.rs:1:6
+   |
+LL | cons A: u8 = 10;
+   |      ^ expected one of `!` or `::`
+   |
+help: there is a keyword `const` with a similar name
+   |
+LL | const A: u8 = 10;
+   | ~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/for-loop.rs b/tests/ui/parser/misspelled-keywords/for-loop.rs
new file mode 100644
index 00000000000..6aba581cf17
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/for-loop.rs
@@ -0,0 +1,4 @@
+fn main() {
+    form i in 1..10 {}
+    //~^ ERROR expected one of
+}
diff --git a/tests/ui/parser/misspelled-keywords/for-loop.stderr b/tests/ui/parser/misspelled-keywords/for-loop.stderr
new file mode 100644
index 00000000000..d2236ab074d
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/for-loop.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `i`
+  --> $DIR/for-loop.rs:2:10
+   |
+LL |     form i in 1..10 {}
+   |          ^ expected one of 8 possible tokens
+   |
+help: there is a keyword `for` with a similar name
+   |
+LL |     for i in 1..10 {}
+   |     ~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/hrdt.rs b/tests/ui/parser/misspelled-keywords/hrdt.rs
new file mode 100644
index 00000000000..9ca9e1bfbee
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/hrdt.rs
@@ -0,0 +1,16 @@
+struct Closure<F> {
+    data: (u8, u16),
+    func: F,
+}
+
+impl<F> Closure<F>
+    Where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
+//~^ ERROR expected one of
+{
+    fn call(&self) -> &u8 {
+        (self.func)(&self.data)
+    }
+}
+
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/hrdt.stderr b/tests/ui/parser/misspelled-keywords/hrdt.stderr
new file mode 100644
index 00000000000..5393a730506
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/hrdt.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found keyword `for`
+  --> $DIR/hrdt.rs:7:11
+   |
+LL |     Where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
+   |           ^^^ expected one of 7 possible tokens
+   |
+help: write keyword `where` in lowercase (notice the capitalization difference)
+   |
+LL |     where for<'a> F: Fn(&'a (u8, u16)) -> &'a u8,
+   |     ~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/impl-block.rs b/tests/ui/parser/misspelled-keywords/impl-block.rs
new file mode 100644
index 00000000000..dc2570c22c5
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-block.rs
@@ -0,0 +1,6 @@
+struct Human;
+
+ipml Human {}
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/impl-block.stderr b/tests/ui/parser/misspelled-keywords/impl-block.stderr
new file mode 100644
index 00000000000..d86ae326ce2
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-block.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found `Human`
+  --> $DIR/impl-block.rs:3:6
+   |
+LL | ipml Human {}
+   |      ^^^^^ expected one of `!` or `::`
+   |
+help: there is a keyword `impl` with a similar name
+   |
+LL | impl Human {}
+   | ~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/impl-return.rs b/tests/ui/parser/misspelled-keywords/impl-return.rs
new file mode 100644
index 00000000000..c9d1973179e
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-return.rs
@@ -0,0 +1,4 @@
+fn code() -> Impl Display {}
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/impl-return.stderr b/tests/ui/parser/misspelled-keywords/impl-return.stderr
new file mode 100644
index 00000000000..883f5cea73e
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-return.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `Display`
+  --> $DIR/impl-return.rs:1:19
+   |
+LL | fn code() -> Impl Display {}
+   |                   ^^^^^^^ expected one of 7 possible tokens
+   |
+help: write keyword `impl` in lowercase (notice the capitalization difference)
+   |
+LL | fn code() -> impl Display {}
+   |              ~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/impl-trait-for.rs b/tests/ui/parser/misspelled-keywords/impl-trait-for.rs
new file mode 100644
index 00000000000..c6f3fcda5ad
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-trait-for.rs
@@ -0,0 +1,6 @@
+struct Human;
+
+impl Debug form Human {}
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/impl-trait-for.stderr b/tests/ui/parser/misspelled-keywords/impl-trait-for.stderr
new file mode 100644
index 00000000000..8dd5a4645f3
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-trait-for.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `Human`
+  --> $DIR/impl-trait-for.rs:3:17
+   |
+LL | impl Debug form Human {}
+   |                 ^^^^^ expected one of 7 possible tokens
+   |
+help: there is a keyword `for` with a similar name
+   |
+LL | impl Debug for Human {}
+   |            ~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/impl-trait.rs b/tests/ui/parser/misspelled-keywords/impl-trait.rs
new file mode 100644
index 00000000000..99380b8ac0e
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-trait.rs
@@ -0,0 +1,4 @@
+fn code<T: impll Debug>() -> u8 {}
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/impl-trait.stderr b/tests/ui/parser/misspelled-keywords/impl-trait.stderr
new file mode 100644
index 00000000000..15a8f99b8b1
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/impl-trait.stderr
@@ -0,0 +1,17 @@
+error: expected one of `(`, `+`, `,`, `::`, `<`, `=`, or `>`, found `Debug`
+  --> $DIR/impl-trait.rs:1:18
+   |
+LL | fn code<T: impll Debug>() -> u8 {}
+   |                  ^^^^^ expected one of 7 possible tokens
+   |
+help: there is a keyword `impl` with a similar name
+   |
+LL | fn code<T: impl Debug>() -> u8 {}
+   |            ~~~~
+help: you might have meant to end the type parameters here
+   |
+LL | fn code<T: impll> Debug>() -> u8 {}
+   |                 +
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/let-else.rs b/tests/ui/parser/misspelled-keywords/let-else.rs
new file mode 100644
index 00000000000..0d5a03e3e43
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/let-else.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let Some(a) = Some(10) elze {}
+    //~^ ERROR expected one of
+}
diff --git a/tests/ui/parser/misspelled-keywords/let-else.stderr b/tests/ui/parser/misspelled-keywords/let-else.stderr
new file mode 100644
index 00000000000..6f41a0d99db
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/let-else.stderr
@@ -0,0 +1,13 @@
+error: expected one of `.`, `;`, `?`, `else`, or an operator, found `elze`
+  --> $DIR/let-else.rs:2:28
+   |
+LL |     let Some(a) = Some(10) elze {}
+   |                            ^^^^ expected one of `.`, `;`, `?`, `else`, or an operator
+   |
+help: there is a keyword `else` with a similar name
+   |
+LL |     let Some(a) = Some(10) else {}
+   |                            ~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/let-mut.rs b/tests/ui/parser/misspelled-keywords/let-mut.rs
new file mode 100644
index 00000000000..83228fe8c66
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/let-mut.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let muta a = 10;
+    //~^ ERROR expected one of
+}
diff --git a/tests/ui/parser/misspelled-keywords/let-mut.stderr b/tests/ui/parser/misspelled-keywords/let-mut.stderr
new file mode 100644
index 00000000000..766d2a04909
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/let-mut.stderr
@@ -0,0 +1,13 @@
+error: expected one of `:`, `;`, `=`, `@`, or `|`, found `a`
+  --> $DIR/let-mut.rs:2:14
+   |
+LL |     let muta a = 10;
+   |              ^ expected one of `:`, `;`, `=`, `@`, or `|`
+   |
+help: there is a keyword `mut` with a similar name
+   |
+LL |     let mut a = 10;
+   |         ~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/let.rs b/tests/ui/parser/misspelled-keywords/let.rs
new file mode 100644
index 00000000000..461c3e518db
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/let.rs
@@ -0,0 +1,9 @@
+fn main() {
+    Let a = 10;
+    //~^ ERROR expected one of
+}
+
+fn code() {
+    lett a = 10;
+    //~^ ERROR expected one of
+}
diff --git a/tests/ui/parser/misspelled-keywords/let.stderr b/tests/ui/parser/misspelled-keywords/let.stderr
new file mode 100644
index 00000000000..c2dcdef541d
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/let.stderr
@@ -0,0 +1,24 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `a`
+  --> $DIR/let.rs:2:9
+   |
+LL |     Let a = 10;
+   |         ^ expected one of 8 possible tokens
+   |
+help: write keyword `let` in lowercase
+   |
+LL |     let a = 10;
+   |     ~~~
+
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `a`
+  --> $DIR/let.rs:7:10
+   |
+LL |     lett a = 10;
+   |          ^ expected one of 8 possible tokens
+   |
+help: there is a keyword `let` with a similar name
+   |
+LL |     let a = 10;
+   |     ~~~
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/parser/misspelled-keywords/match.rs b/tests/ui/parser/misspelled-keywords/match.rs
new file mode 100644
index 00000000000..a31840a2d71
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/match.rs
@@ -0,0 +1,5 @@
+fn main() {
+    let a = 10;
+    matche a {}
+    //~^ ERROR expected one of
+}
diff --git a/tests/ui/parser/misspelled-keywords/match.stderr b/tests/ui/parser/misspelled-keywords/match.stderr
new file mode 100644
index 00000000000..90780ebd38e
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/match.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `a`
+  --> $DIR/match.rs:3:12
+   |
+LL |     matche a {}
+   |            ^ expected one of 8 possible tokens
+   |
+help: there is a keyword `match` with a similar name
+   |
+LL |     match a {}
+   |     ~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/mod.rs b/tests/ui/parser/misspelled-keywords/mod.rs
new file mode 100644
index 00000000000..24f0101bc5a
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/mod.rs
@@ -0,0 +1,4 @@
+mode parser;
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/mod.stderr b/tests/ui/parser/misspelled-keywords/mod.stderr
new file mode 100644
index 00000000000..6daeb4e5a15
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/mod.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found `parser`
+  --> $DIR/mod.rs:1:6
+   |
+LL | mode parser;
+   |      ^^^^^^ expected one of `!` or `::`
+   |
+help: there is a keyword `mod` with a similar name
+   |
+LL | mod parser;
+   | ~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/pub-fn.rs b/tests/ui/parser/misspelled-keywords/pub-fn.rs
new file mode 100644
index 00000000000..50d7129ce51
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/pub-fn.rs
@@ -0,0 +1,5 @@
+puB fn code() {}
+//~^ ERROR expected one of
+
+fn main() {
+}
diff --git a/tests/ui/parser/misspelled-keywords/pub-fn.stderr b/tests/ui/parser/misspelled-keywords/pub-fn.stderr
new file mode 100644
index 00000000000..82ca7105a49
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/pub-fn.stderr
@@ -0,0 +1,13 @@
+error: expected one of `#`, `async`, `auto`, `const`, `default`, `enum`, `extern`, `fn`, `gen`, `impl`, `macro_rules`, `macro`, `mod`, `pub`, `safe`, `static`, `struct`, `trait`, `type`, `unsafe`, or `use`, found `puB`
+  --> $DIR/pub-fn.rs:1:1
+   |
+LL | puB fn code() {}
+   | ^^^ expected one of 21 possible tokens
+   |
+help: write keyword `pub` in lowercase
+   |
+LL | pub fn code() {}
+   | ~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/ref.rs b/tests/ui/parser/misspelled-keywords/ref.rs
new file mode 100644
index 00000000000..76b367ae99b
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/ref.rs
@@ -0,0 +1,9 @@
+fn main() {
+    let a = Some(vec![1, 2]);
+    match a {
+        Some(refe list) => println!("{list:?}"),
+        //~^ ERROR expected one of
+        //~| ERROR this pattern has 2 fields,
+        _ => println!("none"),
+    }
+}
diff --git a/tests/ui/parser/misspelled-keywords/ref.stderr b/tests/ui/parser/misspelled-keywords/ref.stderr
new file mode 100644
index 00000000000..3a79b7bdb00
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/ref.stderr
@@ -0,0 +1,27 @@
+error: expected one of `)`, `,`, `@`, or `|`, found `list`
+  --> $DIR/ref.rs:4:19
+   |
+LL |         Some(refe list) => println!("{list:?}"),
+   |                   ^^^^ expected one of `)`, `,`, `@`, or `|`
+   |
+help: there is a keyword `ref` with a similar name
+   |
+LL |         Some(ref list) => println!("{list:?}"),
+   |              ~~~
+help: missing `,`
+   |
+LL |         Some(refe, list) => println!("{list:?}"),
+   |                  +
+
+error[E0023]: this pattern has 2 fields, but the corresponding tuple variant has 1 field
+  --> $DIR/ref.rs:4:14
+   |
+LL |         Some(refe list) => println!("{list:?}"),
+   |              ^^^^ ^^^^ expected 1 field, found 2
+  --> $SRC_DIR/core/src/option.rs:LL:COL
+   |
+   = note: tuple variant has 1 field
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0023`.
diff --git a/tests/ui/parser/misspelled-keywords/return.rs b/tests/ui/parser/misspelled-keywords/return.rs
new file mode 100644
index 00000000000..4bbe55d37da
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/return.rs
@@ -0,0 +1,7 @@
+fn code() -> u8 {
+    let a = 10;
+    returnn a;
+    //~^ ERROR expected one of
+}
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/return.stderr b/tests/ui/parser/misspelled-keywords/return.stderr
new file mode 100644
index 00000000000..efa45f32299
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/return.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `a`
+  --> $DIR/return.rs:3:13
+   |
+LL |     returnn a;
+   |             ^ expected one of 8 possible tokens
+   |
+help: there is a keyword `return` with a similar name
+   |
+LL |     return a;
+   |     ~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/static-mut.rs b/tests/ui/parser/misspelled-keywords/static-mut.rs
new file mode 100644
index 00000000000..6509f62470a
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/static-mut.rs
@@ -0,0 +1,5 @@
+static muta a: u8 = 0;
+//~^ ERROR expected one of
+//~| ERROR missing type for
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/static-mut.stderr b/tests/ui/parser/misspelled-keywords/static-mut.stderr
new file mode 100644
index 00000000000..3c25af548a3
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/static-mut.stderr
@@ -0,0 +1,24 @@
+error: expected one of `:`, `;`, or `=`, found `a`
+  --> $DIR/static-mut.rs:1:13
+   |
+LL | static muta a: u8 = 0;
+   |             ^ expected one of `:`, `;`, or `=`
+   |
+help: there is a keyword `mut` with a similar name
+   |
+LL | static mut a: u8 = 0;
+   |        ~~~
+
+error: missing type for `static` item
+  --> $DIR/static-mut.rs:1:12
+   |
+LL | static muta a: u8 = 0;
+   |            ^
+   |
+help: provide a type for the item
+   |
+LL | static muta: <type> a: u8 = 0;
+   |            ++++++++
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/parser/misspelled-keywords/static.rs b/tests/ui/parser/misspelled-keywords/static.rs
new file mode 100644
index 00000000000..240f4f52c8d
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/static.rs
@@ -0,0 +1,4 @@
+Static a = 0;
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/static.stderr b/tests/ui/parser/misspelled-keywords/static.stderr
new file mode 100644
index 00000000000..003aa3929bc
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/static.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found `a`
+  --> $DIR/static.rs:1:8
+   |
+LL | Static a = 0;
+   |        ^ expected one of `!` or `::`
+   |
+help: write keyword `static` in lowercase (notice the capitalization difference)
+   |
+LL | static a = 0;
+   | ~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/struct.rs b/tests/ui/parser/misspelled-keywords/struct.rs
new file mode 100644
index 00000000000..0f64dec6f56
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/struct.rs
@@ -0,0 +1,4 @@
+Struct Foor {
+//~^ ERROR expected one of
+    hello: String,
+}
diff --git a/tests/ui/parser/misspelled-keywords/struct.stderr b/tests/ui/parser/misspelled-keywords/struct.stderr
new file mode 100644
index 00000000000..559182f9c8f
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/struct.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found `Foor`
+  --> $DIR/struct.rs:1:8
+   |
+LL | Struct Foor {
+   |        ^^^^ expected one of `!` or `::`
+   |
+help: write keyword `struct` in lowercase (notice the capitalization difference)
+   |
+LL | struct Foor {
+   | ~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/unsafe-fn.rs b/tests/ui/parser/misspelled-keywords/unsafe-fn.rs
new file mode 100644
index 00000000000..49a1322ad63
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/unsafe-fn.rs
@@ -0,0 +1,4 @@
+unsafee fn code() {}
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/unsafe-fn.stderr b/tests/ui/parser/misspelled-keywords/unsafe-fn.stderr
new file mode 100644
index 00000000000..b13281b0395
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/unsafe-fn.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found keyword `fn`
+  --> $DIR/unsafe-fn.rs:1:9
+   |
+LL | unsafee fn code() {}
+   |         ^^ expected one of `!` or `::`
+   |
+help: there is a keyword `unsafe` with a similar name
+   |
+LL | unsafe fn code() {}
+   | ~~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/use.rs b/tests/ui/parser/misspelled-keywords/use.rs
new file mode 100644
index 00000000000..f4911654354
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/use.rs
@@ -0,0 +1,4 @@
+usee a::b;
+//~^ ERROR expected one of
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/use.stderr b/tests/ui/parser/misspelled-keywords/use.stderr
new file mode 100644
index 00000000000..db6dffdb613
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/use.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!` or `::`, found `a`
+  --> $DIR/use.rs:1:6
+   |
+LL | usee a::b;
+   |      ^ expected one of `!` or `::`
+   |
+help: there is a keyword `use` with a similar name
+   |
+LL | use a::b;
+   | ~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/where-clause.rs b/tests/ui/parser/misspelled-keywords/where-clause.rs
new file mode 100644
index 00000000000..c03d04d5fee
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/where-clause.rs
@@ -0,0 +1,8 @@
+fn code<T>() -> u8
+wheree
+//~^ ERROR expected one of
+    T: Debug,
+{
+}
+
+fn main() {}
diff --git a/tests/ui/parser/misspelled-keywords/where-clause.stderr b/tests/ui/parser/misspelled-keywords/where-clause.stderr
new file mode 100644
index 00000000000..5143c30ca51
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/where-clause.stderr
@@ -0,0 +1,15 @@
+error: expected one of `!`, `(`, `+`, `::`, `<`, `where`, or `{`, found `wheree`
+  --> $DIR/where-clause.rs:2:1
+   |
+LL | fn code<T>() -> u8
+   |                   - expected one of 7 possible tokens
+LL | wheree
+   | ^^^^^^ unexpected token
+   |
+help: there is a keyword `where` with a similar name
+   |
+LL | where
+   |
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/while-loop.rs b/tests/ui/parser/misspelled-keywords/while-loop.rs
new file mode 100644
index 00000000000..37d337f3f19
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/while-loop.rs
@@ -0,0 +1,5 @@
+fn main() {
+    whilee a < b {
+    //~^ ERROR expected one of
+    }
+}
diff --git a/tests/ui/parser/misspelled-keywords/while-loop.stderr b/tests/ui/parser/misspelled-keywords/while-loop.stderr
new file mode 100644
index 00000000000..7d150443f57
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/while-loop.stderr
@@ -0,0 +1,13 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `a`
+  --> $DIR/while-loop.rs:2:12
+   |
+LL |     whilee a < b {
+   |            ^ expected one of 8 possible tokens
+   |
+help: there is a keyword `while` with a similar name
+   |
+LL |     while a < b {
+   |     ~~~~~
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/parser/misspelled-keywords/while-without-identifiers.rs b/tests/ui/parser/misspelled-keywords/while-without-identifiers.rs
new file mode 100644
index 00000000000..203db8306af
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/while-without-identifiers.rs
@@ -0,0 +1,4 @@
+fn main() {
+    whilee 2 > 1 {}
+    //~^ ERROR expected one of
+}
diff --git a/tests/ui/parser/misspelled-keywords/while-without-identifiers.stderr b/tests/ui/parser/misspelled-keywords/while-without-identifiers.stderr
new file mode 100644
index 00000000000..121e3931314
--- /dev/null
+++ b/tests/ui/parser/misspelled-keywords/while-without-identifiers.stderr
@@ -0,0 +1,8 @@
+error: expected one of `!`, `.`, `::`, `;`, `?`, `{`, `}`, or an operator, found `2`
+  --> $DIR/while-without-identifiers.rs:2:12
+   |
+LL |     whilee 2 > 1 {}
+   |            ^ expected one of 8 possible tokens
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/rust-2024/gen-kw.e2015.stderr b/tests/ui/rust-2024/gen-kw.e2015.stderr
index b1074f77e00..ff552f663c7 100644
--- a/tests/ui/rust-2024/gen-kw.e2015.stderr
+++ b/tests/ui/rust-2024/gen-kw.e2015.stderr
@@ -31,5 +31,14 @@ LL |     () => { mod test { fn gen() {} } }
    = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
-error: aborting due to 3 previous errors
+error: `gen` is a keyword in the 2024 edition
+  --> $DIR/gen-kw.rs:25:9
+   |
+LL | fn test<'gen>() {}
+   |         ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
+   |
+   = warning: this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/rust-2024/gen-kw.e2018.stderr b/tests/ui/rust-2024/gen-kw.e2018.stderr
index b902cff7fdb..efa812069c3 100644
--- a/tests/ui/rust-2024/gen-kw.e2018.stderr
+++ b/tests/ui/rust-2024/gen-kw.e2018.stderr
@@ -31,5 +31,14 @@ LL |     () => { mod test { fn gen() {} } }
    = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
    = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
 
-error: aborting due to 3 previous errors
+error: `gen` is a keyword in the 2024 edition
+  --> $DIR/gen-kw.rs:25:9
+   |
+LL | fn test<'gen>() {}
+   |         ^^^^ help: you can use a raw identifier to stay compatible: `'r#gen`
+   |
+   = warning: this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
+   = note: for more information, see issue #49716 <https://github.com/rust-lang/rust/issues/49716>
+
+error: aborting due to 4 previous errors
 
diff --git a/tests/ui/rust-2024/gen-kw.rs b/tests/ui/rust-2024/gen-kw.rs
index 04251cbcac4..5a658470c0a 100644
--- a/tests/ui/rust-2024/gen-kw.rs
+++ b/tests/ui/rust-2024/gen-kw.rs
@@ -22,4 +22,9 @@ macro_rules! t {
     //[e2018]~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
 }
 
+fn test<'gen>() {}
+//~^ ERROR `gen` is a keyword in the 2024 edition
+//[e2015]~| WARNING this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2024!
+//[e2018]~| WARNING this is accepted in the current edition (Rust 2018) but is a hard error in Rust 2024!
+
 t!();
diff --git a/tests/crashes/118987-2.rs b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs
index 4382a7bcb63..1691530fa0a 100644
--- a/tests/crashes/118987-2.rs
+++ b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.rs
@@ -1,4 +1,4 @@
-//@ known-bug: #118987
+// regression test for #118987
 #![feature(specialization)] //~ WARN the feature `specialization` is incomplete
 
 trait Assoc {
@@ -15,3 +15,5 @@ trait Foo {}
 
 impl Foo for <u8 as Assoc>::Output {}
 impl Foo for <u16 as Assoc>::Output {}
+//~^ ERROR the trait bound `u16: Assoc` is not satisfied
+fn main() {}
diff --git a/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr
new file mode 100644
index 00000000000..a2fca2ef5b6
--- /dev/null
+++ b/tests/ui/specialization/coherence/default-impl-normalization-ambig-2.stderr
@@ -0,0 +1,21 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/default-impl-normalization-ambig-2.rs:2:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0277]: the trait bound `u16: Assoc` is not satisfied
+  --> $DIR/default-impl-normalization-ambig-2.rs:17:14
+   |
+LL | impl Foo for <u16 as Assoc>::Output {}
+   |              ^^^^^^^^^^^^^^^^^^^^^^ the trait `Assoc` is not implemented for `u16`
+   |
+   = help: the trait `Assoc` is implemented for `u8`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0277`.
diff --git a/tests/crashes/74299.rs b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs
index 0e2ddce1c5b..af7cf332d5f 100644
--- a/tests/crashes/74299.rs
+++ b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.rs
@@ -1,5 +1,5 @@
-//@ known-bug: #74299
-#![feature(specialization)]
+// regression test for #73299.
+#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
 
 trait X {
     type U;
@@ -18,6 +18,7 @@ trait Y {
 
 impl Y for <() as X>::U {}
 impl Y for <i32 as X>::U {}
+//~^ ERROR conflicting implementations of trait `Y` for type `<() as X>::U`
 
 fn main() {
     ().f().g();
diff --git a/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr
new file mode 100644
index 00000000000..a15151cc9c4
--- /dev/null
+++ b/tests/ui/specialization/coherence/default-item-normalization-ambig-1.stderr
@@ -0,0 +1,21 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/default-item-normalization-ambig-1.rs:2:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0119]: conflicting implementations of trait `Y` for type `<() as X>::U`
+  --> $DIR/default-item-normalization-ambig-1.rs:20:1
+   |
+LL | impl Y for <() as X>::U {}
+   | ----------------------- first implementation here
+LL | impl Y for <i32 as X>::U {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `<() as X>::U`
+
+error: aborting due to 1 previous error; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/defaultimpl/specialization-no-default.rs b/tests/ui/specialization/defaultimpl/specialization-no-default.rs
index 661724eef8a..ddc32337306 100644
--- a/tests/ui/specialization/defaultimpl/specialization-no-default.rs
+++ b/tests/ui/specialization/defaultimpl/specialization-no-default.rs
@@ -71,7 +71,8 @@ impl<T: Clone> Redundant for T {
 }
 
 default impl Redundant for i32 {
-    fn redundant(&self) {} //~ ERROR E0520
+    fn redundant(&self) {}
+    //~^ ERROR `redundant` specializes an item from a parent `impl`, but that item is not marked `default`
 }
 
 fn main() {}
diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr
new file mode 100644
index 00000000000..36df6bfd9fc
--- /dev/null
+++ b/tests/ui/specialization/specialization-default-items-drop-coherence.current.stderr
@@ -0,0 +1,12 @@
+error[E0119]: conflicting implementations of trait `Overlap` for type `u32`
+  --> $DIR/specialization-default-items-drop-coherence.rs:26:1
+   |
+LL | impl Overlap for u32 {
+   | -------------------- first implementation here
+...
+LL | impl Overlap for <u32 as Default>::Id {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr
index e9498a00317..36df6bfd9fc 100644
--- a/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr
+++ b/tests/ui/specialization/specialization-default-items-drop-coherence.next.stderr
@@ -1,5 +1,5 @@
 error[E0119]: conflicting implementations of trait `Overlap` for type `u32`
-  --> $DIR/specialization-default-items-drop-coherence.rs:29:1
+  --> $DIR/specialization-default-items-drop-coherence.rs:26:1
    |
 LL | impl Overlap for u32 {
    | -------------------- first implementation here
diff --git a/tests/ui/specialization/specialization-default-items-drop-coherence.rs b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
index 6dc01277639..b3c1f72777c 100644
--- a/tests/ui/specialization/specialization-default-items-drop-coherence.rs
+++ b/tests/ui/specialization/specialization-default-items-drop-coherence.rs
@@ -1,8 +1,5 @@
-//@ revisions: classic coherence next
+//@ revisions: current next
 //@[next] compile-flags: -Znext-solver
-//@[coherence] compile-flags: -Znext-solver=coherence
-//@[classic] check-pass
-//@[classic] known-bug: #105782
 
 // Should fail. Default items completely drop candidates instead of ambiguity,
 // which is unsound during coherence, since coherence requires completeness.
@@ -27,8 +24,7 @@ impl Overlap for u32 {
 }
 
 impl Overlap for <u32 as Default>::Id {
-    //[coherence]~^ ERROR conflicting implementations of trait `Overlap` for type `u32`
-    //[next]~^^ ERROR conflicting implementations of trait `Overlap` for type `u32`
+    //~^ ERROR conflicting implementations of trait `Overlap` for type `u32`
     type Assoc = Box<usize>;
 }
 
diff --git a/tests/ui/specialization/specialization-overlap-projection.current.stderr b/tests/ui/specialization/specialization-overlap-projection.current.stderr
index a69826fa96b..4e77cb17fbb 100644
--- a/tests/ui/specialization/specialization-overlap-projection.current.stderr
+++ b/tests/ui/specialization/specialization-overlap-projection.current.stderr
@@ -1,5 +1,5 @@
 warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/specialization-overlap-projection.rs:10:12
+  --> $DIR/specialization-overlap-projection.rs:4:12
    |
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
@@ -8,5 +8,23 @@ LL | #![feature(specialization)]
    = help: consider using `min_specialization` instead, which is more stable and complete
    = note: `#[warn(incomplete_features)]` on by default
 
-warning: 1 warning emitted
+error[E0119]: conflicting implementations of trait `Foo` for type `u32`
+  --> $DIR/specialization-overlap-projection.rs:19:1
+   |
+LL | impl Foo for u32 {}
+   | ---------------- first implementation here
+LL | impl Foo for <u8 as Assoc>::Output {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error[E0119]: conflicting implementations of trait `Foo` for type `u32`
+  --> $DIR/specialization-overlap-projection.rs:21:1
+   |
+LL | impl Foo for u32 {}
+   | ---------------- first implementation here
+...
+LL | impl Foo for <u16 as Assoc>::Output {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error: aborting due to 2 previous errors; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/ui/specialization/specialization-overlap-projection.next.stderr b/tests/ui/specialization/specialization-overlap-projection.next.stderr
index 5b17696162e..4e77cb17fbb 100644
--- a/tests/ui/specialization/specialization-overlap-projection.next.stderr
+++ b/tests/ui/specialization/specialization-overlap-projection.next.stderr
@@ -1,5 +1,5 @@
 warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
-  --> $DIR/specialization-overlap-projection.rs:10:12
+  --> $DIR/specialization-overlap-projection.rs:4:12
    |
 LL | #![feature(specialization)]
    |            ^^^^^^^^^^^^^^
@@ -9,7 +9,7 @@ LL | #![feature(specialization)]
    = note: `#[warn(incomplete_features)]` on by default
 
 error[E0119]: conflicting implementations of trait `Foo` for type `u32`
-  --> $DIR/specialization-overlap-projection.rs:25:1
+  --> $DIR/specialization-overlap-projection.rs:19:1
    |
 LL | impl Foo for u32 {}
    | ---------------- first implementation here
@@ -17,7 +17,7 @@ LL | impl Foo for <u8 as Assoc>::Output {}
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
 
 error[E0119]: conflicting implementations of trait `Foo` for type `u32`
-  --> $DIR/specialization-overlap-projection.rs:27:1
+  --> $DIR/specialization-overlap-projection.rs:21:1
    |
 LL | impl Foo for u32 {}
    | ---------------- first implementation here
diff --git a/tests/ui/specialization/specialization-overlap-projection.rs b/tests/ui/specialization/specialization-overlap-projection.rs
index 16dccf82dcb..f7a2a792243 100644
--- a/tests/ui/specialization/specialization-overlap-projection.rs
+++ b/tests/ui/specialization/specialization-overlap-projection.rs
@@ -1,13 +1,8 @@
-//@ revisions: current next
-//@ ignore-compare-mode-next-solver (explicit revisions)
-//@[next] compile-flags: -Znext-solver
-//@[current] check-pass
-
 // Test that impls on projected self types can resolve overlap, even when the
 // projections involve specialization, so long as the associated type is
 // provided by the most specialized impl.
-
-#![feature(specialization)] //~ WARN the feature `specialization` is incomplete
+#![feature(specialization)]
+//~^ WARN the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
 
 trait Assoc {
     type Output;
@@ -23,8 +18,8 @@ impl Assoc for u16 { type Output = u16; }
 trait Foo {}
 impl Foo for u32 {}
 impl Foo for <u8 as Assoc>::Output {}
-//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32`
+//~^ ERROR conflicting implementations of trait `Foo` for type `u32`
 impl Foo for <u16 as Assoc>::Output {}
-//[next]~^ ERROR conflicting implementations of trait `Foo` for type `u32`
+//~^ ERROR conflicting implementations of trait `Foo` for type `u32`
 
 fn main() {}
diff --git a/tests/ui/specialization/specialization-overlap-projection.stderr b/tests/ui/specialization/specialization-overlap-projection.stderr
new file mode 100644
index 00000000000..5f3cd9c66cf
--- /dev/null
+++ b/tests/ui/specialization/specialization-overlap-projection.stderr
@@ -0,0 +1,30 @@
+warning: the feature `specialization` is incomplete and may not be safe to use and/or cause compiler crashes
+  --> $DIR/specialization-overlap-projection.rs:4:12
+   |
+LL | #![feature(specialization)]
+   |            ^^^^^^^^^^^^^^
+   |
+   = note: see issue #31844 <https://github.com/rust-lang/rust/issues/31844> for more information
+   = help: consider using `min_specialization` instead, which is more stable and complete
+   = note: `#[warn(incomplete_features)]` on by default
+
+error[E0119]: conflicting implementations of trait `Foo` for type `u32`
+  --> $DIR/specialization-overlap-projection.rs:20:1
+   |
+LL | impl Foo for u32 {}
+   | ---------------- first implementation here
+LL | impl Foo for <u8 as Assoc>::Output {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error[E0119]: conflicting implementations of trait `Foo` for type `u32`
+  --> $DIR/specialization-overlap-projection.rs:22:1
+   |
+LL | impl Foo for u32 {}
+   | ---------------- first implementation here
+...
+LL | impl Foo for <u16 as Assoc>::Output {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `u32`
+
+error: aborting due to 2 previous errors; 1 warning emitted
+
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/crashes/124164.rs b/tests/ui/static/missing-type.rs
index 8c9b4bddbe8..2569f47b7c3 100644
--- a/tests/crashes/124164.rs
+++ b/tests/ui/static/missing-type.rs
@@ -1,4 +1,5 @@
-//@ known-bug: #124164
+// reported as #124164
 static S_COUNT: = std::sync::atomic::AtomicUsize::new(0);
+//~^ ERROR: missing type for `static` item
 
 fn main() {}
diff --git a/tests/ui/static/missing-type.stderr b/tests/ui/static/missing-type.stderr
new file mode 100644
index 00000000000..6489ceb700a
--- /dev/null
+++ b/tests/ui/static/missing-type.stderr
@@ -0,0 +1,8 @@
+error: missing type for `static` item
+  --> $DIR/missing-type.rs:2:16
+   |
+LL | static S_COUNT: = std::sync::atomic::AtomicUsize::new(0);
+   |                ^ help: provide a type for the static variable: `AtomicUsize`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/traits/alias/issue-83613.rs b/tests/ui/traits/alias/issue-83613.rs
index 2462e703a71..6f0012bf089 100644
--- a/tests/ui/traits/alias/issue-83613.rs
+++ b/tests/ui/traits/alias/issue-83613.rs
@@ -8,5 +8,5 @@ fn mk_opaque() -> OpaqueType {
 trait AnotherTrait {}
 impl<T: Send> AnotherTrait for T {}
 impl AnotherTrait for OpaqueType {}
-//~^ ERROR conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+//~^ ERROR conflicting implementations of trait `AnotherTrait`
 fn main() {}
diff --git a/tests/ui/traits/alias/issue-83613.stderr b/tests/ui/traits/alias/issue-83613.stderr
index 847fda41776..47181c3f33e 100644
--- a/tests/ui/traits/alias/issue-83613.stderr
+++ b/tests/ui/traits/alias/issue-83613.stderr
@@ -1,10 +1,10 @@
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+error[E0119]: conflicting implementations of trait `AnotherTrait`
   --> $DIR/issue-83613.rs:10:1
    |
 LL | impl<T: Send> AnotherTrait for T {}
    | -------------------------------- first implementation here
 LL | impl AnotherTrait for OpaqueType {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/traits/issue-105231.rs b/tests/ui/traits/issue-105231.rs
index 7338642beef..83c3158c106 100644
--- a/tests/ui/traits/issue-105231.rs
+++ b/tests/ui/traits/issue-105231.rs
@@ -1,4 +1,3 @@
-//~ ERROR overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
 struct A<T>(B<T>);
 //~^ ERROR recursive types `A` and `B` have infinite size
 //~| ERROR `T` is only used recursively
@@ -7,5 +6,5 @@ struct B<T>(A<A<T>>);
 trait Foo {}
 impl<T> Foo for T where T: Send {}
 impl Foo for B<u8> {}
-
+//~^ ERROR conflicting implementations of trait `Foo` for type `B<u8>`
 fn main() {}
diff --git a/tests/ui/traits/issue-105231.stderr b/tests/ui/traits/issue-105231.stderr
index d3014a79ad6..e113f8382b2 100644
--- a/tests/ui/traits/issue-105231.stderr
+++ b/tests/ui/traits/issue-105231.stderr
@@ -1,5 +1,5 @@
 error[E0072]: recursive types `A` and `B` have infinite size
-  --> $DIR/issue-105231.rs:2:1
+  --> $DIR/issue-105231.rs:1:1
    |
 LL | struct A<T>(B<T>);
    | ^^^^^^^^^^^ ---- recursive without indirection
@@ -16,7 +16,7 @@ LL ~ struct B<T>(Box<A<A<T>>>);
    |
 
 error: type parameter `T` is only used recursively
-  --> $DIR/issue-105231.rs:2:15
+  --> $DIR/issue-105231.rs:1:15
    |
 LL | struct A<T>(B<T>);
    |          -    ^
@@ -27,7 +27,7 @@ LL | struct A<T>(B<T>);
    = note: all type parameters must be used in a non-recursive way in order to constrain their variance
 
 error: type parameter `T` is only used recursively
-  --> $DIR/issue-105231.rs:5:17
+  --> $DIR/issue-105231.rs:4:17
    |
 LL | struct B<T>(A<A<T>>);
    |          -      ^
@@ -37,16 +37,18 @@ LL | struct B<T>(A<A<T>>);
    = help: consider removing `T`, referring to it in a field, or using a marker such as `PhantomData`
    = note: all type parameters must be used in a non-recursive way in order to constrain their variance
 
-error[E0275]: overflow evaluating the requirement `A<A<A<A<A<A<A<...>>>>>>>: Send`
+error[E0119]: conflicting implementations of trait `Foo` for type `B<u8>`
+  --> $DIR/issue-105231.rs:8:1
    |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`)
-note: required because it appears within the type `B<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<A<u8>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>`
-  --> $DIR/issue-105231.rs:5:8
+LL | impl<T> Foo for T where T: Send {}
+   | ------------------------------- first implementation here
+LL | impl Foo for B<u8> {}
+   | ^^^^^^^^^^^^^^^^^^ conflicting implementation for `B<u8>`
    |
-LL | struct B<T>(A<A<T>>);
-   |        ^
+   = note: overflow evaluating the requirement `B<u8>: Send`
+   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`issue_105231`)
 
 error: aborting due to 4 previous errors
 
-Some errors have detailed explanations: E0072, E0275.
+Some errors have detailed explanations: E0072, E0119.
 For more information about an error, try `rustc --explain E0072`.
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
index d37943b929a..43443be88df 100644
--- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.rs
@@ -1,4 +1,3 @@
-//~ ERROR overflow
 // A regression test for #111729 checking that we correctly
 // track recursion depth for obligations returned by confirmation.
 use std::panic::RefUnwindSafe;
@@ -18,6 +17,7 @@ impl<T: RefUnwindSafe> Database for T {
     type Storage = SalsaStorage;
 }
 impl Database for RootDatabase {
+    //~^ ERROR conflicting implementations of trait `Database` for type `RootDatabase`
     type Storage = SalsaStorage;
 }
 
diff --git a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
index 2ab150fc0f6..1da7671b451 100644
--- a/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
+++ b/tests/ui/traits/solver-cycles/cycle-via-builtin-auto-trait-impl.stderr
@@ -1,24 +1,12 @@
-error[E0275]: overflow evaluating the requirement `Runtime<RootDatabase>: RefUnwindSafe`
-   |
-   = help: consider increasing the recursion limit by adding a `#![recursion_limit = "256"]` attribute to your crate (`cycle_via_builtin_auto_trait_impl`)
-note: required because it appears within the type `RootDatabase`
-  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:13:8
-   |
-LL | struct RootDatabase {
-   |        ^^^^^^^^^^^^
-note: required for `RootDatabase` to implement `Database`
-  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:17:24
+error[E0119]: conflicting implementations of trait `Database` for type `RootDatabase`
+  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:19:1
    |
 LL | impl<T: RefUnwindSafe> Database for T {
-   |         -------------  ^^^^^^^^     ^
-   |         |
-   |         unsatisfied trait bound introduced here
-note: required because it appears within the type `Runtime<RootDatabase>`
-  --> $DIR/cycle-via-builtin-auto-trait-impl.rs:24:8
-   |
-LL | struct Runtime<DB: Database> {
-   |        ^^^^^^^
+   | ------------------------------------- first implementation here
+...
+LL | impl Database for RootDatabase {
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `RootDatabase`
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0275`.
+For more information about this error, try `rustc --explain E0119`.
diff --git a/tests/crashes/124207.rs b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.rs
index a11eedb140a..0cebc99cd41 100644
--- a/tests/crashes/124207.rs
+++ b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.rs
@@ -1,9 +1,11 @@
-//@ known-bug: #124207
 #![feature(transmutability)]
 #![feature(type_alias_impl_trait)]
 trait OpaqueTrait {}
 type OpaqueType = impl OpaqueTrait;
+//~^ ERROR unconstrained opaque type
 trait AnotherTrait {}
 impl<T: std::mem::TransmuteFrom<(), ()>> AnotherTrait for T {}
+//~^ ERROR type provided when a constant was expected
 impl AnotherTrait for OpaqueType {}
+//~^ ERROR conflicting implementations of trait `AnotherTrait`
 pub fn main() {}
diff --git a/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr
new file mode 100644
index 00000000000..2424541af23
--- /dev/null
+++ b/tests/ui/transmutability/malformed-program-gracefulness/coherence-bikeshed-intrinsic-from.stderr
@@ -0,0 +1,27 @@
+error: unconstrained opaque type
+  --> $DIR/coherence-bikeshed-intrinsic-from.rs:4:19
+   |
+LL | type OpaqueType = impl OpaqueTrait;
+   |                   ^^^^^^^^^^^^^^^^
+   |
+   = note: `OpaqueType` must be used in combination with a concrete type within the same module
+
+error[E0747]: type provided when a constant was expected
+  --> $DIR/coherence-bikeshed-intrinsic-from.rs:7:37
+   |
+LL | impl<T: std::mem::TransmuteFrom<(), ()>> AnotherTrait for T {}
+   |                                     ^^
+
+error[E0119]: conflicting implementations of trait `AnotherTrait`
+  --> $DIR/coherence-bikeshed-intrinsic-from.rs:9:1
+   |
+LL | impl<T: std::mem::TransmuteFrom<(), ()>> AnotherTrait for T {}
+   | ----------------------------------------------------------- first implementation here
+LL |
+LL | impl AnotherTrait for OpaqueType {}
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
+
+error: aborting due to 3 previous errors
+
+Some errors have detailed explanations: E0119, E0747.
+For more information about an error, try `rustc --explain E0119`.
diff --git a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
index e35913be899..aaf75cc3db9 100644
--- a/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
+++ b/tests/ui/type-alias-impl-trait/impl_trait_for_same_tait.stderr
@@ -15,8 +15,6 @@ LL | impl Bop for Bar<()> {}
 ...
 LL | impl Bop for Barr {}
    | ^^^^^^^^^^^^^^^^^ conflicting implementation for `Bar<()>`
-   |
-   = note: upstream crates may add a new impl of trait `std::marker::FnPtr` for type `Barr` in future versions
 
 error[E0119]: conflicting implementations of trait `Bop` for type `Bar<()>`
   --> $DIR/impl_trait_for_same_tait.rs:30:1
diff --git a/tests/ui/type-alias-impl-trait/issue-104817.rs b/tests/ui/type-alias-impl-trait/issue-104817.rs
index 4679d025fce..49146321614 100644
--- a/tests/ui/type-alias-impl-trait/issue-104817.rs
+++ b/tests/ui/type-alias-impl-trait/issue-104817.rs
@@ -14,6 +14,6 @@ fn mk_opaque() -> OpaqueType {
 trait AnotherTrait {}
 impl<T: Send> AnotherTrait for T {}
 impl AnotherTrait for OpaqueType {}
-//[stock]~^ conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+//[stock]~^ conflicting implementations of trait `AnotherTrait`
 
 fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
index 41c5206d9e8..df5a6c320a8 100644
--- a/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
+++ b/tests/ui/type-alias-impl-trait/issue-104817.stock.stderr
@@ -1,10 +1,10 @@
-error[E0119]: conflicting implementations of trait `AnotherTrait` for type `OpaqueType`
+error[E0119]: conflicting implementations of trait `AnotherTrait`
   --> $DIR/issue-104817.rs:16:1
    |
 LL | impl<T: Send> AnotherTrait for T {}
    | -------------------------------- first implementation here
 LL | impl AnotherTrait for OpaqueType {}
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `OpaqueType`
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation
 
 error: aborting due to 1 previous error
 
diff --git a/tests/crashes/126896.rs b/tests/ui/type-alias-impl-trait/taint.rs
index 49c539d7acc..dfb947637c0 100644
--- a/tests/crashes/126896.rs
+++ b/tests/ui/type-alias-impl-trait/taint.rs
@@ -1,6 +1,7 @@
-//@ known-bug: rust-lang/rust#126896
 //@ compile-flags: -Zvalidate-mir -Zinline-mir=yes
 
+// reported as rust-lang/rust#126896
+
 #![feature(type_alias_impl_trait)]
 type Two<'a, 'b> = impl std::fmt::Debug;
 
@@ -9,9 +10,8 @@ fn set(x: &mut isize) -> isize {
 }
 
 fn d(x: Two) {
-    let c1 = || set(x);
+    let c1 = || set(x); //~ ERROR: expected generic lifetime parameter, found `'_`
     c1;
 }
 
-fn main() {
-}
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/taint.stderr b/tests/ui/type-alias-impl-trait/taint.stderr
new file mode 100644
index 00000000000..17fcd4b7e93
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/taint.stderr
@@ -0,0 +1,12 @@
+error[E0792]: expected generic lifetime parameter, found `'_`
+  --> $DIR/taint.rs:13:17
+   |
+LL | type Two<'a, 'b> = impl std::fmt::Debug;
+   |          -- this generic parameter must be used with a generic lifetime parameter
+...
+LL |     let c1 = || set(x);
+   |                 ^^^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0792`.
diff --git a/triagebot.toml b/triagebot.toml
index 1afcad7d131..f379f8cc7af 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -914,6 +914,7 @@ cc = ["@kobzol"]
 warn_non_default_branch = true
 contributing_url = "https://rustc-dev-guide.rust-lang.org/getting-started.html"
 users_on_vacation = [
+    "fmease",
     "jhpratt",
     "joboet",
     "jyn514",