From 0f1adf43df36f202aaf0f214e4a57ce920c2736e Mon Sep 17 00:00:00 2001 From: Chayim Refael Friedman Date: Thu, 28 Aug 2025 03:35:22 +0300 Subject: [PATCH] An associated type is not a projection! More correctly, a `TyKind::AssociatedType` is not the same as `TyKind::Projection`. We used to map next-solver `TyKind::Alias` to Chalk's `TyKind::AssociatedType`. This is very incorrect, as `AssociatedType` is assumed to be fully normalized, and caused a lot of type mismatches. Unfortunately fixing this causes a lot of stack overflows, because the next solver doesn't have something akin to `AssociatedType` so we normalize again and again. The reason is that is the lazy-normalization nature of the next solver, which means we need to stop normalizing everything. This will be fixed in the next commit. --- crates/hir-ty/src/next_solver/mapping.rs | 5 +++- .../hir-ty/src/tests/regression/new_solver.rs | 27 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) diff --git a/crates/hir-ty/src/next_solver/mapping.rs b/crates/hir-ty/src/next_solver/mapping.rs index f66b8dace3..57a56b3f0c 100644 --- a/crates/hir-ty/src/next_solver/mapping.rs +++ b/crates/hir-ty/src/next_solver/mapping.rs @@ -1358,7 +1358,10 @@ pub(crate) fn convert_ty_for_result<'db>(interner: DbInterner<'db>, ty: Ty<'db>) }; let associated_ty_id = to_assoc_type_id(assoc_ty_id); let substitution = convert_args_for_result(interner, alias_ty.args.as_slice()); - TyKind::AssociatedType(associated_ty_id, substitution) + TyKind::Alias(crate::AliasTy::Projection(crate::ProjectionTy { + associated_ty_id, + substitution, + })) } rustc_type_ir::AliasTyKind::Opaque => { let opaque_ty_id = match alias_ty.def_id { diff --git a/crates/hir-ty/src/tests/regression/new_solver.rs b/crates/hir-ty/src/tests/regression/new_solver.rs index 97473bbabb..471108d964 100644 --- a/crates/hir-ty/src/tests/regression/new_solver.rs +++ b/crates/hir-ty/src/tests/regression/new_solver.rs @@ -71,3 +71,30 @@ fn main() { }"#, ); } + +#[test] +fn projection_is_not_associated_type() { + check_no_mismatches( + r#" +//- minicore: fn +trait Iterator { + type Item; + + fn partition(self, f: F) + where + F: FnMut(&Self::Item) -> bool, + { + } +} + +struct Iter; +impl Iterator for Iter { + type Item = i32; +} + +fn main() { + Iter.partition(|n| true); +} + "#, + ); +}