about summary refs log tree commit diff
diff options
context:
space:
mode:
authorEric Mark Martin <ericmarkmartin@gmail.com>2023-06-22 01:52:31 -0400
committerEric Mark Martin <ericmarkmartin@gmail.com>2023-06-28 01:51:53 -0400
commitfbd1e0252fc68368379f5a85ca43d8bfd8939ca9 (patch)
treef56f7137e344b8e3c2936db2aa32116a0f4ed8c0
parent6b46c996e1d3a07dd73beb2873d74a8a0458d05f (diff)
downloadrust-fbd1e0252fc68368379f5a85ca43d8bfd8939ca9.tar.gz
rust-fbd1e0252fc68368379f5a85ca43d8bfd8939ca9.zip
add note for non-exhaustive matches with guards
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs5
-rw-r--r--tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr22
-rw-r--r--tests/ui/pattern/usefulness/empty-match.normal.stderr22
-rw-r--r--tests/ui/pattern/usefulness/empty-match.rs8
-rw-r--r--tests/ui/pattern/usefulness/issue-3601.rs18
-rw-r--r--tests/ui/pattern/usefulness/issue-3601.stderr7
-rw-r--r--tests/ui/pattern/usefulness/match-non-exhaustive.rs1
-rw-r--r--tests/ui/pattern/usefulness/match-non-exhaustive.stderr1
8 files changed, 60 insertions, 24 deletions
diff --git a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
index e7e88351bbd..ff0dcdd2d1b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -830,6 +830,11 @@ fn non_exhaustive_match<'p, 'tcx>(
             _ => " or multiple match arms",
         },
     );
+
+    let all_arms_have_guards = arms.iter().all(|arm_id| thir[*arm_id].guard.is_some());
+    if !is_empty_match && all_arms_have_guards {
+        err.note("match arms with guards don't count towards exhaustivity");
+    }
     if let Some((span, sugg)) = suggestion {
         err.span_suggestion_verbose(span, msg, sugg, Applicability::HasPlaceholders);
     } else {
diff --git a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
index 49b6dfca62e..5b81a8c3d3c 100644
--- a/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
+++ b/tests/ui/pattern/usefulness/empty-match.exhaustive_patterns.stderr
@@ -176,6 +176,7 @@ LL |     match_guarded_arm!(0u8);
    |                        ^^^ pattern `_` not covered
    |
    = note: the matched value is of type `u8`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -183,7 +184,7 @@ LL +             _ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
-  --> $DIR/empty-match.rs:133:24
+  --> $DIR/empty-match.rs:134:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@@ -194,6 +195,7 @@ note: `NonEmptyStruct1` defined here
 LL | struct NonEmptyStruct1;
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -201,7 +203,7 @@ LL +             NonEmptyStruct1 => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
-  --> $DIR/empty-match.rs:137:24
+  --> $DIR/empty-match.rs:139:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@@ -212,6 +214,7 @@ note: `NonEmptyStruct2` defined here
 LL | struct NonEmptyStruct2(bool);
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -219,7 +222,7 @@ LL +             NonEmptyStruct2(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
-  --> $DIR/empty-match.rs:141:24
+  --> $DIR/empty-match.rs:144:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@@ -230,6 +233,7 @@ note: `NonEmptyUnion1` defined here
 LL | union NonEmptyUnion1 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -237,7 +241,7 @@ LL +             NonEmptyUnion1 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
-  --> $DIR/empty-match.rs:145:24
+  --> $DIR/empty-match.rs:149:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@@ -248,6 +252,7 @@ note: `NonEmptyUnion2` defined here
 LL | union NonEmptyUnion2 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -255,7 +260,7 @@ LL +             NonEmptyUnion2 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:149:24
+  --> $DIR/empty-match.rs:154:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -268,6 +273,7 @@ LL | enum NonEmptyEnum1 {
 LL |     Foo(bool),
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -275,7 +281,7 @@ LL +             NonEmptyEnum1::Foo(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:153:24
+  --> $DIR/empty-match.rs:159:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -291,6 +297,7 @@ LL |     Foo(bool),
 LL |     Bar,
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~             _ if false => {},
@@ -298,7 +305,7 @@ LL +             NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:157:24
+  --> $DIR/empty-match.rs:164:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum5::V1);
    |                        ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -309,6 +316,7 @@ note: `NonEmptyEnum5` defined here
 LL | enum NonEmptyEnum5 {
    |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
    |
 LL ~             _ if false => {},
diff --git a/tests/ui/pattern/usefulness/empty-match.normal.stderr b/tests/ui/pattern/usefulness/empty-match.normal.stderr
index f54a3f3364f..6d17455086b 100644
--- a/tests/ui/pattern/usefulness/empty-match.normal.stderr
+++ b/tests/ui/pattern/usefulness/empty-match.normal.stderr
@@ -175,6 +175,7 @@ LL |     match_guarded_arm!(0u8);
    |                        ^^^ pattern `_` not covered
    |
    = note: the matched value is of type `u8`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -182,7 +183,7 @@ LL +             _ => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
-  --> $DIR/empty-match.rs:133:24
+  --> $DIR/empty-match.rs:134:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct1);
    |                        ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
@@ -193,6 +194,7 @@ note: `NonEmptyStruct1` defined here
 LL | struct NonEmptyStruct1;
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -200,7 +202,7 @@ LL +             NonEmptyStruct1 => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
-  --> $DIR/empty-match.rs:137:24
+  --> $DIR/empty-match.rs:139:24
    |
 LL |     match_guarded_arm!(NonEmptyStruct2(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
@@ -211,6 +213,7 @@ note: `NonEmptyStruct2` defined here
 LL | struct NonEmptyStruct2(bool);
    |        ^^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyStruct2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -218,7 +221,7 @@ LL +             NonEmptyStruct2(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
-  --> $DIR/empty-match.rs:141:24
+  --> $DIR/empty-match.rs:144:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion1 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
@@ -229,6 +232,7 @@ note: `NonEmptyUnion1` defined here
 LL | union NonEmptyUnion1 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -236,7 +240,7 @@ LL +             NonEmptyUnion1 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
-  --> $DIR/empty-match.rs:145:24
+  --> $DIR/empty-match.rs:149:24
    |
 LL |     match_guarded_arm!((NonEmptyUnion2 { foo: () }));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
@@ -247,6 +251,7 @@ note: `NonEmptyUnion2` defined here
 LL | union NonEmptyUnion2 {
    |       ^^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyUnion2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -254,7 +259,7 @@ LL +             NonEmptyUnion2 { .. } => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
-  --> $DIR/empty-match.rs:149:24
+  --> $DIR/empty-match.rs:154:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum1::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
@@ -267,6 +272,7 @@ LL | enum NonEmptyEnum1 {
 LL |     Foo(bool),
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum1`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL ~             _ if false => {},
@@ -274,7 +280,7 @@ LL +             NonEmptyEnum1::Foo(_) => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
-  --> $DIR/empty-match.rs:153:24
+  --> $DIR/empty-match.rs:159:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum2::Foo(true));
    |                        ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
@@ -290,6 +296,7 @@ LL |     Foo(bool),
 LL |     Bar,
    |     ^^^ not covered
    = note: the matched value is of type `NonEmptyEnum2`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern, a match arm with multiple or-patterns as shown, or multiple match arms
    |
 LL ~             _ if false => {},
@@ -297,7 +304,7 @@ LL +             NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
    |
 
 error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
-  --> $DIR/empty-match.rs:157:24
+  --> $DIR/empty-match.rs:164:24
    |
 LL |     match_guarded_arm!(NonEmptyEnum5::V1);
    |                        ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
@@ -308,6 +315,7 @@ note: `NonEmptyEnum5` defined here
 LL | enum NonEmptyEnum5 {
    |      ^^^^^^^^^^^^^
    = note: the matched value is of type `NonEmptyEnum5`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown, or multiple match arms
    |
 LL ~             _ if false => {},
diff --git a/tests/ui/pattern/usefulness/empty-match.rs b/tests/ui/pattern/usefulness/empty-match.rs
index 062241faa4c..d56d2e3c817 100644
--- a/tests/ui/pattern/usefulness/empty-match.rs
+++ b/tests/ui/pattern/usefulness/empty-match.rs
@@ -128,34 +128,42 @@ fn main() {
 
     match_guarded_arm!(0u8); //~ ERROR `_` not covered
                              //~| NOTE the matched value is of type
+                             //~| NOTE match arms with guards don't count towards exhaustivity
                              //~| NOTE pattern `_` not covered
                              //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyStruct1); //~ ERROR `NonEmptyStruct1` not covered
                                          //~| NOTE pattern `NonEmptyStruct1` not covered
                                          //~| NOTE the matched value is of type
+                                         //~| NOTE match arms with guards don't count towards exhaustivity
                                          //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyStruct2(true)); //~ ERROR `NonEmptyStruct2(_)` not covered
                                                //~| NOTE the matched value is of type
                                                //~| NOTE pattern `NonEmptyStruct2(_)` not covered
+                                               //~| NOTE match arms with guards don't count towards exhaustivity
                                                //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!((NonEmptyUnion1 { foo: () })); //~ ERROR `NonEmptyUnion1 { .. }` not covered
                                                       //~| NOTE the matched value is of type
                                                       //~| NOTE pattern `NonEmptyUnion1 { .. }` not covered
+                                                      //~| NOTE match arms with guards don't count towards exhaustivity
                                                       //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!((NonEmptyUnion2 { foo: () })); //~ ERROR `NonEmptyUnion2 { .. }` not covered
                                                       //~| NOTE the matched value is of type
                                                       //~| NOTE pattern `NonEmptyUnion2 { .. }` not covered
+                                                      //~| NOTE match arms with guards don't count towards exhaustivity
                                                       //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
                                                   //~| NOTE the matched value is of type
                                                   //~| NOTE pattern `NonEmptyEnum1::Foo(_)` not covered
+                                                  //~| NOTE match arms with guards don't count towards exhaustivity
                                                   //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
                                                   //~| NOTE the matched value is of type
                                                   //~| NOTE patterns `NonEmptyEnum2::Foo(_)` and
+                                                  //~| NOTE match arms with guards don't count towards exhaustivity
                                                   //~| NOTE in this expansion of match_guarded_arm!
     match_guarded_arm!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
                                            //~| NOTE the matched value is of type
                                            //~| NOTE patterns `NonEmptyEnum5::V1`,
+                                           //~| NOTE match arms with guards don't count towards exhaustivity
                                            //~| NOTE in this expansion of match_guarded_arm!
 }
diff --git a/tests/ui/pattern/usefulness/issue-3601.rs b/tests/ui/pattern/usefulness/issue-3601.rs
index 6215a23980d..d096e39e2cf 100644
--- a/tests/ui/pattern/usefulness/issue-3601.rs
+++ b/tests/ui/pattern/usefulness/issue-3601.rs
@@ -1,19 +1,19 @@
 #![feature(box_patterns)]
 
 struct HTMLImageData {
-    image: Option<String>
+    image: Option<String>,
 }
 
 struct ElementData {
-    kind: Box<ElementKind>
+    kind: Box<ElementKind>,
 }
 
 enum ElementKind {
-    HTMLImageElement(HTMLImageData)
+    HTMLImageElement(HTMLImageData),
 }
 
 enum NodeKind {
-    Element(ElementData)
+    Element(ElementData),
 }
 
 struct NodeData {
@@ -25,10 +25,14 @@ fn main() {
     let ed = ElementData { kind: Box::new(ElementKind::HTMLImageElement(id)) };
     let n = NodeData { kind: Box::new(NodeKind::Element(ed)) };
 
-    // n.b. span could be better
     match n.kind {
-        box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns
-            box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true }
+        box NodeKind::Element(ed) => match ed.kind {
+            //~^ ERROR non-exhaustive patterns
+            //~| NOTE the matched value is of type
+            //~| NOTE match arms with guards don't count towards exhaustivity
+            //~| NOTE pattern `box _` not covered
+            //~| NOTE `Box<ElementKind>` defined here
+            box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => true,
         },
     };
 }
diff --git a/tests/ui/pattern/usefulness/issue-3601.stderr b/tests/ui/pattern/usefulness/issue-3601.stderr
index 2f6b167d4f8..6a7c6b13e25 100644
--- a/tests/ui/pattern/usefulness/issue-3601.stderr
+++ b/tests/ui/pattern/usefulness/issue-3601.stderr
@@ -1,5 +1,5 @@
 error[E0004]: non-exhaustive patterns: `box _` not covered
-  --> $DIR/issue-3601.rs:30:44
+  --> $DIR/issue-3601.rs:29:44
    |
 LL |         box NodeKind::Element(ed) => match ed.kind {
    |                                            ^^^^^^^ pattern `box _` not covered
@@ -7,10 +7,11 @@ LL |         box NodeKind::Element(ed) => match ed.kind {
 note: `Box<ElementKind>` defined here
   --> $SRC_DIR/alloc/src/boxed.rs:LL:COL
    = note: the matched value is of type `Box<ElementKind>`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
-LL ~             box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true },
-LL +             box _ => todo!()
+LL ~             box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => true,
+LL ~             box _ => todo!(),
    |
 
 error: aborting due to previous error
diff --git a/tests/ui/pattern/usefulness/match-non-exhaustive.rs b/tests/ui/pattern/usefulness/match-non-exhaustive.rs
index 3b210a115d2..62c185d04b3 100644
--- a/tests/ui/pattern/usefulness/match-non-exhaustive.rs
+++ b/tests/ui/pattern/usefulness/match-non-exhaustive.rs
@@ -1,4 +1,5 @@
 fn main() {
     match 0 { 1 => () } //~ ERROR non-exhaustive patterns
     match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns
+    //-| NOTE match arms with guards don't count towards exhaustivity
 }
diff --git a/tests/ui/pattern/usefulness/match-non-exhaustive.stderr b/tests/ui/pattern/usefulness/match-non-exhaustive.stderr
index 08dde523a15..4fa3a729212 100644
--- a/tests/ui/pattern/usefulness/match-non-exhaustive.stderr
+++ b/tests/ui/pattern/usefulness/match-non-exhaustive.stderr
@@ -17,6 +17,7 @@ LL |     match 0 { 0 if false => () }
    |           ^ pattern `_` not covered
    |
    = note: the matched value is of type `i32`
+   = note: match arms with guards don't count towards exhaustivity
 help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown
    |
 LL |     match 0 { 0 if false => (), _ => todo!() }