about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/check/expr.rs50
-rw-r--r--src/test/ui/issues/issue-77218.rs7
-rw-r--r--src/test/ui/issues/issue-77218.stderr14
-rw-r--r--src/test/ui/suggestions/if-let-typo.rs1
-rw-r--r--src/test/ui/suggestions/if-let-typo.stderr18
5 files changed, 56 insertions, 34 deletions
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index 9990f86a36b..03e448a00cc 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -769,34 +769,40 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let mut err = self.demand_suptype_diag(expr.span, expected_ty, actual_ty).unwrap();
             let lhs_ty = self.check_expr(&lhs);
             let rhs_ty = self.check_expr(&rhs);
-            if self.can_coerce(lhs_ty, rhs_ty) {
-                if !lhs.is_syntactic_place_expr() {
-                    // Do not suggest `if let x = y` as `==` is way more likely to be the intention.
-                    if let hir::Node::Expr(hir::Expr {
-                        kind: ExprKind::Match(_, _, hir::MatchSource::IfDesugar { .. }),
-                        ..
-                    }) = self.tcx.hir().get(
-                        self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
-                    ) {
-                        // Likely `if let` intended.
-                        err.span_suggestion_verbose(
-                            expr.span.shrink_to_lo(),
-                            "you might have meant to use pattern matching",
-                            "let ".to_string(),
-                            Applicability::MaybeIncorrect,
-                        );
-                    }
+            let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
+                (Applicability::MachineApplicable, true)
+            } else {
+                (Applicability::MaybeIncorrect, false)
+            };
+            if !lhs.is_syntactic_place_expr() {
+                // Do not suggest `if let x = y` as `==` is way more likely to be the intention.
+                if let hir::Node::Expr(hir::Expr {
+                    kind:
+                        ExprKind::Match(
+                            _,
+                            _,
+                            hir::MatchSource::IfDesugar { .. } | hir::MatchSource::WhileDesugar,
+                        ),
+                    ..
+                }) = self.tcx.hir().get(
+                    self.tcx.hir().get_parent_node(self.tcx.hir().get_parent_node(expr.hir_id)),
+                ) {
+                    // Likely `if let` intended.
+                    err.span_suggestion_verbose(
+                        expr.span.shrink_to_lo(),
+                        "you might have meant to use pattern matching",
+                        "let ".to_string(),
+                        applicability,
+                    );
                 }
+            }
+            if eq {
                 err.span_suggestion_verbose(
                     *span,
                     "you might have meant to compare for equality",
                     "==".to_string(),
-                    Applicability::MaybeIncorrect,
+                    applicability,
                 );
-            } else {
-                // Do this to cause extra errors about the assignment.
-                let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace);
-                let _ = self.check_expr_coercable_to_type(&rhs, lhs_ty, Some(lhs));
             }
 
             if self.sess().if_let_suggestions.borrow().get(&expr.span).is_some() {
diff --git a/src/test/ui/issues/issue-77218.rs b/src/test/ui/issues/issue-77218.rs
new file mode 100644
index 00000000000..bc992c21dca
--- /dev/null
+++ b/src/test/ui/issues/issue-77218.rs
@@ -0,0 +1,7 @@
+fn main() {
+    let value = [7u8];
+    while Some(0) = value.get(0) { //~ ERROR mismatched types
+        //~^ NOTE expected `bool`, found `()`
+        //~| HELP you might have meant to use pattern matching
+    }
+}
diff --git a/src/test/ui/issues/issue-77218.stderr b/src/test/ui/issues/issue-77218.stderr
new file mode 100644
index 00000000000..eca44725eb2
--- /dev/null
+++ b/src/test/ui/issues/issue-77218.stderr
@@ -0,0 +1,14 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-77218.rs:3:11
+   |
+LL |     while Some(0) = value.get(0) {
+   |           ^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     while let Some(0) = value.get(0) {
+   |           ^^^
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/src/test/ui/suggestions/if-let-typo.rs b/src/test/ui/suggestions/if-let-typo.rs
index c1e417b97f6..87def13c476 100644
--- a/src/test/ui/suggestions/if-let-typo.rs
+++ b/src/test/ui/suggestions/if-let-typo.rs
@@ -4,6 +4,5 @@ fn main() {
     if Some(x) = foo {} //~ ERROR cannot find value `x` in this scope
     if Some(foo) = bar {} //~ ERROR mismatched types
     if 3 = foo {} //~ ERROR mismatched types
-    //~^ ERROR mismatched types
     if Some(3) = foo {} //~ ERROR mismatched types
 }
diff --git a/src/test/ui/suggestions/if-let-typo.stderr b/src/test/ui/suggestions/if-let-typo.stderr
index bb2ea8cb477..d8e50cae55a 100644
--- a/src/test/ui/suggestions/if-let-typo.stderr
+++ b/src/test/ui/suggestions/if-let-typo.stderr
@@ -25,22 +25,18 @@ LL |     if Some(foo) == bar {}
    |                  ^^
 
 error[E0308]: mismatched types
-  --> $DIR/if-let-typo.rs:6:12
-   |
-LL |     if 3 = foo {}
-   |            ^^^ expected integer, found enum `Option`
-   |
-   = note: expected type `{integer}`
-              found enum `Option<{integer}>`
-
-error[E0308]: mismatched types
   --> $DIR/if-let-typo.rs:6:8
    |
 LL |     if 3 = foo {}
    |        ^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to use pattern matching
+   |
+LL |     if let 3 = foo {}
+   |        ^^^
 
 error[E0308]: mismatched types
-  --> $DIR/if-let-typo.rs:8:8
+  --> $DIR/if-let-typo.rs:7:8
    |
 LL |     if Some(3) = foo {}
    |        ^^^^^^^^^^^^^ expected `bool`, found `()`
@@ -54,7 +50,7 @@ help: you might have meant to compare for equality
 LL |     if Some(3) == foo {}
    |                ^^
 
-error: aborting due to 5 previous errors
+error: aborting due to 4 previous errors
 
 Some errors have detailed explanations: E0308, E0425.
 For more information about an error, try `rustc --explain E0308`.