about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyo Yoshida <low.ryoshida@gmail.com>2022-07-03 02:31:07 +0900
committerRyo Yoshida <low.ryoshida@gmail.com>2022-07-03 03:29:15 +0900
commit649e1f54cfb9b2b0a17261e5fb20d7745ffec4d3 (patch)
tree1eb5b63d4e9fb33dcc349f848cfe40e2813983fa
parentafdbd6cce247d057e1e4014d20b79bb2a2d4bfac (diff)
downloadrust-649e1f54cfb9b2b0a17261e5fb20d7745ffec4d3.tar.gz
rust-649e1f54cfb9b2b0a17261e5fb20d7745ffec4d3.zip
fix: report type mismatch on identifier in destructuring assignments
-rw-r--r--crates/hir-ty/src/infer/expr.rs10
-rw-r--r--crates/hir-ty/src/tests/simple.rs27
2 files changed, 36 insertions, 1 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 08abf8a461b..6dee0322a9b 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -911,7 +911,15 @@ impl<'a> InferenceContext<'a> {
                 let lhs_ty = self.insert_type_vars_shallow(lhs_ty);
                 let ty = match self.coerce(None, &rhs_ty, &lhs_ty) {
                     Ok(ty) => ty,
-                    Err(_) => self.err_ty(),
+                    Err(_) => {
+                        self.result.type_mismatches.insert(
+                            lhs.into(),
+                            TypeMismatch { expected: rhs_ty.clone(), actual: lhs_ty.clone() },
+                        );
+                        // `rhs_ty` is returned so no further type mismatches are
+                        // reported because of this mismatch.
+                        rhs_ty
+                    }
                 };
                 self.write_expr_ty(lhs, ty.clone());
                 return ty;
diff --git a/crates/hir-ty/src/tests/simple.rs b/crates/hir-ty/src/tests/simple.rs
index 535b948371c..5b08f552109 100644
--- a/crates/hir-ty/src/tests/simple.rs
+++ b/crates/hir-ty/src/tests/simple.rs
@@ -3043,3 +3043,30 @@ fn main() {
         "#,
     );
 }
+
+#[test]
+fn destructuring_assignment_type_mismatch_on_identifier() {
+    check(
+        r#"
+struct S { v: i64 }
+struct TS(i64);
+fn main() {
+    let mut a: usize = 0;
+    (a,) = (0i64,);
+   //^expected i64, got usize
+
+    let mut a: usize = 0;
+    [a,] = [0i64,];
+   //^expected i64, got usize
+
+    let mut a: usize = 0;
+    S { v: a } = S { v: 0 };
+         //^expected i64, got usize
+
+    let mut a: usize = 0;
+    TS(a) = TS(0);
+     //^expected i64, got usize
+}
+        "#,
+    );
+}