about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2022-10-31 15:39:20 +0000
committerbors <bors@rust-lang.org>2022-10-31 15:39:20 +0000
commit07f6efc4e7302d05f31a4bde1f5bd23424ba6a45 (patch)
tree3f2ddde3722210f3d97a6585133dfeaa9080b06d
parent8142d1f606dc2e52b1d2b8992671e2bd73379f28 (diff)
parentdb8c7523f85d8f177b2cd9676fd97b90aeea0388 (diff)
downloadrust-07f6efc4e7302d05f31a4bde1f5bd23424ba6a45.tar.gz
rust-07f6efc4e7302d05f31a4bde1f5bd23424ba6a45.zip
Auto merge of #13523 - lowr:fix/adjust-expectation-for-if, r=lnicola
fix: disregard type variable expectation for if expressions

Fixes #13522

As [the comment](https://github.com/rust-lang/rust-analyzer/blob/8142d1f606dc2e52b1d2b8992671e2bd73379f28/crates/hir-ty/src/infer.rs#L1087-L1090) on `Expectation::adjust_for_branches` explains:

> If the expected type is just a type variable, then don't use an expected type. Otherwise, we might write parts of the type when checking the 'then' block which are incompatible with the 'else' branch.

Note that we already use it in match expressions. I've added tests for them too nevertheless.
-rw-r--r--crates/hir-ty/src/infer/expr.rs1
-rw-r--r--crates/hir-ty/src/tests/coercion.rs33
2 files changed, 34 insertions, 0 deletions
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index f56108b26c4..b1f4de82607 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -85,6 +85,7 @@ impl<'a> InferenceContext<'a> {
         let ty = match &self.body[tgt_expr] {
             Expr::Missing => self.err_ty(),
             &Expr::If { condition, then_branch, else_branch } => {
+                let expected = &expected.adjust_for_branches(&mut self.table);
                 self.infer_expr(
                     condition,
                     &Expectation::has_type(TyKind::Scalar(Scalar::Bool).intern(Interner)),
diff --git a/crates/hir-ty/src/tests/coercion.rs b/crates/hir-ty/src/tests/coercion.rs
index d301595bcd9..1abdb0be7f8 100644
--- a/crates/hir-ty/src/tests/coercion.rs
+++ b/crates/hir-ty/src/tests/coercion.rs
@@ -123,6 +123,23 @@ fn test() {
 }
 
 #[test]
+fn if_else_adjust_for_branches_discard_type_var() {
+    check_no_mismatches(
+        r#"
+fn test() {
+    let f = || {
+        if true {
+            &""
+        } else {
+            ""
+        }
+    };
+}
+"#,
+    );
+}
+
+#[test]
 fn match_first_coerce() {
     check_no_mismatches(
         r#"
@@ -183,6 +200,22 @@ fn test() {
 }
 
 #[test]
+fn match_adjust_for_branches_discard_type_var() {
+    check_no_mismatches(
+        r#"
+fn test() {
+    let f = || {
+        match 0i32 {
+            0i32 => &"",
+            _ => "",
+        }
+    };
+}
+"#,
+    );
+}
+
+#[test]
 fn return_coerce_unknown() {
     check_types(
         r"