about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs21
-rw-r--r--tests/ui/type/type-check/assignment-expected-bool.rs5
-rw-r--r--tests/ui/type/type-check/assignment-expected-bool.stderr13
3 files changed, 36 insertions, 3 deletions
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 1b47fa81904..7d753216534 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -1131,8 +1131,17 @@ 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);
+            let refs_can_coerce = |lhs: Ty<'tcx>, rhs: Ty<'tcx>| {
+                let lhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, lhs.peel_refs());
+                let rhs = Ty::new_imm_ref(self.tcx, self.tcx.lifetimes.re_erased, rhs.peel_refs());
+                self.can_coerce(rhs, lhs)
+            };
             let (applicability, eq) = if self.can_coerce(rhs_ty, lhs_ty) {
                 (Applicability::MachineApplicable, true)
+            } else if refs_can_coerce(rhs_ty, lhs_ty) {
+                // The lhs and rhs are likely missing some references in either side. Subsequent
+                // suggestions will show up.
+                (Applicability::MaybeIncorrect, true)
             } else if let ExprKind::Binary(
                 Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
                 _,
@@ -1142,7 +1151,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // if x == 1 && y == 2 { .. }
                 //                 +
                 let actual_lhs_ty = self.check_expr(rhs_expr);
-                (Applicability::MaybeIncorrect, self.can_coerce(rhs_ty, actual_lhs_ty))
+                (
+                    Applicability::MaybeIncorrect,
+                    self.can_coerce(rhs_ty, actual_lhs_ty)
+                        || refs_can_coerce(rhs_ty, actual_lhs_ty),
+                )
             } else if let ExprKind::Binary(
                 Spanned { node: hir::BinOpKind::And | hir::BinOpKind::Or, .. },
                 lhs_expr,
@@ -1152,7 +1165,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 // if x == 1 && y == 2 { .. }
                 //       +
                 let actual_rhs_ty = self.check_expr(lhs_expr);
-                (Applicability::MaybeIncorrect, self.can_coerce(actual_rhs_ty, lhs_ty))
+                (
+                    Applicability::MaybeIncorrect,
+                    self.can_coerce(actual_rhs_ty, lhs_ty)
+                        || refs_can_coerce(actual_rhs_ty, lhs_ty),
+                )
             } else {
                 (Applicability::MaybeIncorrect, false)
             };
diff --git a/tests/ui/type/type-check/assignment-expected-bool.rs b/tests/ui/type/type-check/assignment-expected-bool.rs
index 191939bdb70..fe8af64b43d 100644
--- a/tests/ui/type/type-check/assignment-expected-bool.rs
+++ b/tests/ui/type/type-check/assignment-expected-bool.rs
@@ -31,4 +31,9 @@ fn main() {
     let _: usize = 0 = 0;
     //~^ ERROR mismatched types [E0308]
     //~| ERROR invalid left-hand side of assignment [E0070]
+
+    let foo = &String::new();
+    let bar = "";
+    if foo = bar {}
+    //~^ ERROR mismatched types [E0308]
 }
diff --git a/tests/ui/type/type-check/assignment-expected-bool.stderr b/tests/ui/type/type-check/assignment-expected-bool.stderr
index 56494baff6b..6c44e389a21 100644
--- a/tests/ui/type/type-check/assignment-expected-bool.stderr
+++ b/tests/ui/type/type-check/assignment-expected-bool.stderr
@@ -135,7 +135,18 @@ LL |     let _: usize = 0 = 0;
    |            |
    |            expected due to this
 
-error: aborting due to 13 previous errors
+error[E0308]: mismatched types
+  --> $DIR/assignment-expected-bool.rs:37:8
+   |
+LL |     if foo = bar {}
+   |        ^^^^^^^^^ expected `bool`, found `()`
+   |
+help: you might have meant to compare for equality
+   |
+LL |     if foo == bar {}
+   |             +
+
+error: aborting due to 14 previous errors
 
 Some errors have detailed explanations: E0070, E0308.
 For more information about an error, try `rustc --explain E0070`.