Unnamed repository; edit this file 'description' to name the repository.
Normalize expected ty in call arguments
hkalbasi 2023-07-22
parent ed8e1fd · commit b7d91ca
-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 4b14345aa3..72e6443beb 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 5f5cd79451..542df8b346 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
+ }
+ "#,
+ );
+}