From dec7fc3ced5bc3c18d0e5d29921d087f93189cb8 Mon Sep 17 00:00:00 2001
From: Theodore Luo Wang <wangtheo662@gmail.com>
Date: Sat, 28 Aug 2021 21:18:20 -0400
Subject: [PATCH 1/2] Fix an ICE caused by type mismatch errors being ignored

---
 compiler/rustc_typeck/src/check/demand.rs                | 6 ------
 .../ui/typeck/issue-87771-ice-assign-assign-to-bool.rs   | 4 ++++
 .../typeck/issue-87771-ice-assign-assign-to-bool.stderr  | 9 +++++++++
 3 files changed, 13 insertions(+), 6 deletions(-)
 create mode 100644 src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.rs
 create mode 100644 src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.stderr

diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index 808685d7fa9c8..f186d35bcbc84 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -145,12 +145,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let expr_ty = self.resolve_vars_with_obligations(checked_ty);
         let mut err = self.report_mismatched_types(&cause, expected, expr_ty, e);
 
-        if self.is_assign_to_bool(expr, expected) {
-            // Error reported in `check_assign` so avoid emitting error again.
-            err.delay_as_bug();
-            return (expected, None);
-        }
-
         self.emit_coerce_suggestions(&mut err, expr, expr_ty, expected, expected_ty_expr);
 
         (expected, Some(err))
diff --git a/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.rs b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.rs
new file mode 100644
index 0000000000000..751dc8719cf33
--- /dev/null
+++ b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.rs
@@ -0,0 +1,4 @@
+fn main() {
+    let mut a;
+    a = a = true; //~ ERROR mismatched types
+}
diff --git a/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.stderr b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.stderr
new file mode 100644
index 0000000000000..fe10fa733d238
--- /dev/null
+++ b/src/test/ui/typeck/issue-87771-ice-assign-assign-to-bool.stderr
@@ -0,0 +1,9 @@
+error[E0308]: mismatched types
+  --> $DIR/issue-87771-ice-assign-assign-to-bool.rs:3:9
+   |
+LL |     a = a = true;
+   |         ^^^^^^^^ expected `bool`, found `()`
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0308`.

From 09d55d516bdd3e89bef4cb1cabc598a16d9ad401 Mon Sep 17 00:00:00 2001
From: Theodore Luo Wang <wangtheo662@gmail.com>
Date: Thu, 16 Sep 2021 23:31:16 -0400
Subject: [PATCH 2/2] Remove special checks to is_assign_to_bool

---
 compiler/rustc_typeck/src/check/coercion.rs | 16 +---------------
 compiler/rustc_typeck/src/check/demand.rs   |  8 --------
 compiler/rustc_typeck/src/check/expr.rs     |  3 +--
 3 files changed, 2 insertions(+), 25 deletions(-)

diff --git a/compiler/rustc_typeck/src/check/coercion.rs b/compiler/rustc_typeck/src/check/coercion.rs
index 3bfab9d513f37..ab6f8742e3f07 100644
--- a/compiler/rustc_typeck/src/check/coercion.rs
+++ b/compiler/rustc_typeck/src/check/coercion.rs
@@ -1494,21 +1494,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
                     fcx.emit_coerce_suggestions(&mut err, expr, found, expected, None);
                 }
 
-                // Error possibly reported in `check_assign` so avoid emitting error again.
-                let assign_to_bool = expression
-                    // #67273: Use initial expected type as opposed to `expected`.
-                    // Otherwise we end up using prior coercions in e.g. a `match` expression:
-                    // ```
-                    // match i {
-                    //     0 => true, // Because of this...
-                    //     1 => i = 1, // ...`expected == bool` now, but not when checking `i = 1`.
-                    //     _ => (),
-                    // };
-                    // ```
-                    .filter(|e| fcx.is_assign_to_bool(e, self.expected_ty()))
-                    .is_some();
-
-                err.emit_unless(assign_to_bool || unsized_return);
+                err.emit_unless(unsized_return);
 
                 self.final_ty = Some(fcx.tcx.ty_error());
             }
diff --git a/compiler/rustc_typeck/src/check/demand.rs b/compiler/rustc_typeck/src/check/demand.rs
index f186d35bcbc84..02228b6430794 100644
--- a/compiler/rustc_typeck/src/check/demand.rs
+++ b/compiler/rustc_typeck/src/check/demand.rs
@@ -166,14 +166,6 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         }
     }
 
-    /// Returns whether the expected type is `bool` and the expression is `x = y`.
-    pub fn is_assign_to_bool(&self, expr: &hir::Expr<'_>, expected: Ty<'tcx>) -> bool {
-        if let hir::ExprKind::Assign(..) = expr.kind {
-            return expected == self.tcx.types.bool;
-        }
-        false
-    }
-
     /// If the expected type is an enum (Issue #55250) with any variants whose
     /// sole field is of the found type, suggest such variants. (Issue #42764)
     fn suggest_compatible_variants(
diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs
index ab927b7944223..58545d3ec983a 100644
--- a/compiler/rustc_typeck/src/check/expr.rs
+++ b/compiler/rustc_typeck/src/check/expr.rs
@@ -92,8 +92,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             let expr = expr.peel_drop_temps();
             self.suggest_deref_ref_or_into(&mut err, expr, expected_ty, ty, None);
             extend_err(&mut err);
-            // Error possibly reported in `check_assign` so avoid emitting error again.
-            err.emit_unless(self.is_assign_to_bool(expr, expected_ty));
+            err.emit();
         }
         ty
     }