about summary refs log tree commit diff
diff options
context:
space:
mode:
authorhkalbasi <hamidrezakalbasi@protonmail.com>2023-07-22 01:06:58 +0330
committerhkalbasi <hamidrezakalbasi@protonmail.com>2023-07-22 01:06:58 +0330
commitb7d91ca5b26c239c523b9f6096e8431b8571ff3d (patch)
tree4c14d1fa3dca7516b999e6979c74688f7200fe33
parented8e1fd472dc4961a3d92245a5dfcd62559ce8e5 (diff)
downloadrust-b7d91ca5b26c239c523b9f6096e8431b8571ff3d.tar.gz
rust-b7d91ca5b26c239c523b9f6096e8431b8571ff3d.zip
Normalize expected ty in call arguments
-rw-r--r--crates/hir-ty/src/infer/expr.rs1
-rw-r--r--crates/hir-ty/src/tests/traits.rs44
2 files changed, 45 insertions, 0 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 4b14345aa39..72e6443beb7 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -1665,6 +1665,7 @@ impl InferenceContext<'_> {
                 // the parameter to coerce to the expected type (for example in
                 // `coerce_unsize_expected_type_4`).
                 let param_ty = self.normalize_associated_types_in(param_ty);
+                let expected_ty = self.normalize_associated_types_in(expected_ty);
                 let expected = Expectation::rvalue_hint(self, expected_ty);
                 // infer with the expected type we have...
                 let ty = self.infer_expr_inner(arg, &expected);
diff --git a/crates/hir-ty/src/tests/traits.rs b/crates/hir-ty/src/tests/traits.rs
index 5f5cd794512..542df8b3468 100644
--- a/crates/hir-ty/src/tests/traits.rs
+++ b/crates/hir-ty/src/tests/traits.rs
@@ -4434,3 +4434,47 @@ fn test(v: S<i32>) {
 "#,
     );
 }
+
+#[test]
+fn associated_type_in_argument() {
+    check(
+        r#"
+    trait A {
+        fn m(&self) -> i32;
+    }
+
+    fn x<T: B>(k: &<T as B>::Ty) {
+        k.m();
+    }
+
+    struct X;
+    struct Y;
+
+    impl A for X {
+        fn m(&self) -> i32 {
+            8
+        }
+    }
+
+    impl A for Y {
+        fn m(&self) -> i32 {
+            32
+        }
+    }
+
+    trait B {
+        type Ty: A;
+    }
+
+    impl B for u16 {
+        type Ty = X;
+    }
+
+    fn ttt() {
+        let inp = Y;
+        x::<u16>(&inp);
+               //^^^^ expected &X, got &Y
+    }
+    "#,
+    );
+}