diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs
index 243313ee8767a..87300f5bb83c6 100644
--- a/compiler/rustc_hir_typeck/src/_match.rs
+++ b/compiler/rustc_hir_typeck/src/_match.rs
@@ -77,12 +77,20 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         let mut prior_non_diverging_arms = vec![]; // Used only for diagnostics.
         let mut prior_arm = None;
         for arm in arms {
+            self.diverges.set(Diverges::Maybe);
+
             if let Some(e) = &arm.guard {
-                self.diverges.set(Diverges::Maybe);
                 self.check_expr_has_type_or_error(e, tcx.types.bool, |_| {});
+
+                // FIXME: If this is the first arm and the pattern is irrefutable,
+                // e.g. `_` or `x`, and the guard diverges, then the whole match
+                // may also be considered to diverge. We should warn on all subsequent
+                // arms, too, just like we do for diverging scrutinees above.
             }
 
-            self.diverges.set(Diverges::Maybe);
+            // N.B. We don't reset diverges here b/c we want to warn in the arm
+            // if the guard diverges, like: `x if { loop {} } => f()`, and we
+            // also want to consider the arm to diverge itself.
 
             let arm_ty = self.check_expr_with_expectation(arm.body, expected);
             all_arms_diverge &= self.diverges.get();
diff --git a/tests/ui/reachable/expr_match.rs b/tests/ui/reachable/expr_match.rs
index 2fd26b54e15ee..1bae061c98421 100644
--- a/tests/ui/reachable/expr_match.rs
+++ b/tests/ui/reachable/expr_match.rs
@@ -21,9 +21,13 @@ fn d() {
 }
 
 fn e() {
-    // Here the compiler fails to figure out that the `println` is dead.
-    match () { () if return => (), () => return }
+    match () {
+        () if return => (),
+        //~^ ERROR unreachable expression
+        () => return,
+    }
     println!("I am dead");
+    //~^ ERROR unreachable statement
 }
 
 fn f() {
diff --git a/tests/ui/reachable/expr_match.stderr b/tests/ui/reachable/expr_match.stderr
index d15208609cff8..ae202a6e0c34a 100644
--- a/tests/ui/reachable/expr_match.stderr
+++ b/tests/ui/reachable/expr_match.stderr
@@ -23,5 +23,27 @@ LL |     println!("I am dead");
    |
    = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
 
-error: aborting due to 2 previous errors
+error: unreachable expression
+  --> $DIR/expr_match.rs:25:25
+   |
+LL |         () if return => (),
+   |               ------    ^^ unreachable expression
+   |               |
+   |               any code following this expression is unreachable
+
+error: unreachable statement
+  --> $DIR/expr_match.rs:29:5
+   |
+LL | /     match () {
+LL | |         () if return => (),
+LL | |
+LL | |         () => return,
+LL | |     }
+   | |_____- any code following this `match` expression is unreachable, as all arms diverge
+LL |       println!("I am dead");
+   |       ^^^^^^^^^^^^^^^^^^^^^ unreachable statement
+   |
+   = note: this error originates in the macro `println` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error: aborting due to 4 previous errors