about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-08-28 03:35:22 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2025-09-10 00:53:15 +0300
commit1acb4c2c1621578ea787afb698ed8718cbdf3d4f (patch)
tree80de0ff7f2bfdb93e9b034e7ac46401306b85656 /src
parent0cce47c05bea6ac7748c46dfe2a5b1a64fe72cd6 (diff)
downloadrust-1acb4c2c1621578ea787afb698ed8718cbdf3d4f.tar.gz
rust-1acb4c2c1621578ea787afb698ed8718cbdf3d4f.zip
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.
Diffstat (limited to 'src')
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/next_solver/mapping.rs5
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs27
2 files changed, 31 insertions, 1 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/mapping.rs b/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/mapping.rs
index f66b8dace30..57a56b3f0c6 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/next_solver/mapping.rs
+++ b/src/tools/rust-analyzer/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/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs b/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs
index 97473bbabba..471108d964f 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs
+++ b/src/tools/rust-analyzer/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<F>(self, f: F)
+    where
+        F: FnMut(&Self::Item) -> bool,
+    {
+    }
+}
+
+struct Iter;
+impl Iterator for Iter {
+    type Item = i32;
+}
+
+fn main() {
+    Iter.partition(|n| true);
+}
+    "#,
+    );
+}