about summary refs log tree commit diff
diff options
context:
space:
mode:
authorChayim Refael Friedman <chayimfr@gmail.com>2025-08-25 20:19:33 +0300
committerChayim Refael Friedman <chayimfr@gmail.com>2025-08-25 20:23:18 +0300
commitaa49c0b8bb27700ab77fd8cb7231d18f4f6d2e97 (patch)
treeb327c26b7ad32835bcc165d3d88438a38a492acf
parent781e0268eeab7fb8eca11034da595b2ee6a3dccb (diff)
downloadrust-aa49c0b8bb27700ab77fd8cb7231d18f4f6d2e97.tar.gz
rust-aa49c0b8bb27700ab77fd8cb7231d18f4f6d2e97.zip
Normalize all types when finishing inference
The new solver does not eagerly normalize, but things after inference expect types to be normalized. rustc does the same.

Also, I'm afraid other things in r-a don't expect results of the solver to be unnormalized. We'll need to handle that.
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs3
-rw-r--r--src/tools/rust-analyzer/crates/hir-ty/src/tests/regression/new_solver.rs26
2 files changed, 29 insertions, 0 deletions
diff --git a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
index a709aebfa9c..bb4782bd419 100644
--- a/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
+++ b/src/tools/rust-analyzer/crates/hir-ty/src/infer/unify.rs
@@ -621,6 +621,9 @@ impl<'a> InferenceTable<'a> {
     where
         T: HasInterner<Interner = Interner> + TypeFoldable<Interner>,
     {
+        let t = self.resolve_with_fallback(t, &|_, _, d, _| d);
+        let t = self.normalize_associated_types_in(t);
+        // Resolve again, because maybe normalization inserted infer vars.
         self.resolve_with_fallback(t, &|_, _, d, _| d)
     }
 
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 059f4ad32a5..20190fbc045 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
@@ -24,3 +24,29 @@ impl<'a> IntoIterator for &'a Grid {
         "#]],
     );
 }
+
+#[test]
+fn normalization() {
+    check_infer(
+        r#"
+//- minicore: iterator, iterators
+fn main() {
+    _ = [0i32].into_iter().filter_map(|_n| Some(1i32));
+}
+    "#,
+        expect![[r#"
+            10..69 '{     ...2)); }': ()
+            16..17 '_': FilterMap<IntoIter<i32, 1>, impl FnMut(i32) -> Option<i32>>
+            16..66 '_ = [0...1i32))': ()
+            20..26 '[0i32]': [i32; 1]
+            20..38 '[0i32]...iter()': IntoIter<i32, 1>
+            20..66 '[0i32]...1i32))': FilterMap<IntoIter<i32, 1>, impl FnMut(i32) -> Option<i32>>
+            21..25 '0i32': i32
+            50..65 '|_n| Some(1i32)': impl FnMut(i32) -> Option<i32>
+            51..53 '_n': i32
+            55..59 'Some': fn Some<i32>(i32) -> Option<i32>
+            55..65 'Some(1i32)': Option<i32>
+            60..64 '1i32': i32
+        "#]],
+    );
+}