about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/check_match.rs11
-rw-r--r--src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs5
-rw-r--r--src/test/ui/match/match_non_exhaustive.rs32
-rw-r--r--src/test/ui/match/match_non_exhaustive.stderr36
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/enum.stderr6
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr2
-rw-r--r--src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr2
7 files changed, 88 insertions, 6 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 fdecbb94788..e4419070cbd 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/check_match.rs
@@ -496,12 +496,21 @@ fn non_exhaustive_match<'p, 'tcx>(
         err.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
     };
 
+    let is_variant_list_non_exhaustive = match scrut_ty.kind() {
+        ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did.is_local() => true,
+        _ => false,
+    };
+
     adt_defined_here(cx, &mut err, scrut_ty, &witnesses);
     err.help(
         "ensure that all possible cases are being handled, \
               possibly by adding wildcards or more match arms",
     );
-    err.note(&format!("the matched value is of type `{}`", scrut_ty));
+    err.note(&format!(
+        "the matched value is of type `{}`{}",
+        scrut_ty,
+        if is_variant_list_non_exhaustive { ", which is marked as non-exhaustive" } else { "" }
+    ));
     if (scrut_ty == cx.tcx.types.usize || scrut_ty == cx.tcx.types.isize)
         && !is_empty_match
         && witnesses.len() == 1
diff --git a/src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs b/src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs
new file mode 100644
index 00000000000..3be72551e09
--- /dev/null
+++ b/src/test/ui/match/auxiliary/match_non_exhaustive_lib.rs
@@ -0,0 +1,5 @@
+#[non_exhaustive]
+pub enum E1 {}
+
+#[non_exhaustive]
+pub enum E2 { A, B }
diff --git a/src/test/ui/match/match_non_exhaustive.rs b/src/test/ui/match/match_non_exhaustive.rs
new file mode 100644
index 00000000000..8219f0eb135
--- /dev/null
+++ b/src/test/ui/match/match_non_exhaustive.rs
@@ -0,0 +1,32 @@
+// aux-build:match_non_exhaustive_lib.rs
+
+/* The error message for non-exhaustive matches on non-local enums
+ * marked as non-exhaustive should mention the fact that the enum
+ * is marked as non-exhaustive (issue #85227).
+ */
+
+// Ignore non_exhaustive in the same crate
+#[non_exhaustive]
+enum L { A, B }
+
+extern crate match_non_exhaustive_lib;
+use match_non_exhaustive_lib::{E1, E2};
+
+fn foo() -> L {todo!()}
+fn bar() -> (E1, E2) {todo!()}
+
+fn main() {
+    let l = foo();
+    // No error for enums defined in this crate
+    match l { L::A => (), L::B => () };
+    // (except if the match is already non-exhaustive)
+    match l { L::A => () };
+    //~^ ERROR: non-exhaustive patterns: `B` not covered [E0004]
+
+    // E1 is not visibly uninhabited from here
+    let (e1, e2) = bar();
+    match e1 {};
+    //~^ ERROR: non-exhaustive patterns: type `E1` is non-empty [E0004]
+    match e2 { E2::A => (), E2::B => () };
+    //~^ ERROR: non-exhaustive patterns: `_` not covered [E0004]
+}
diff --git a/src/test/ui/match/match_non_exhaustive.stderr b/src/test/ui/match/match_non_exhaustive.stderr
new file mode 100644
index 00000000000..5debfe1c566
--- /dev/null
+++ b/src/test/ui/match/match_non_exhaustive.stderr
@@ -0,0 +1,36 @@
+error[E0004]: non-exhaustive patterns: `B` not covered
+  --> $DIR/match_non_exhaustive.rs:23:11
+   |
+LL | enum L { A, B }
+   | ---------------
+   | |           |
+   | |           not covered
+   | `L` defined here
+...
+LL |     match l { L::A => () };
+   |           ^ pattern `B` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `L`
+
+error[E0004]: non-exhaustive patterns: type `E1` is non-empty
+  --> $DIR/match_non_exhaustive.rs:28:11
+   |
+LL |     match e1 {};
+   |           ^^
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `E1`, which is marked as non-exhaustive
+
+error[E0004]: non-exhaustive patterns: `_` not covered
+  --> $DIR/match_non_exhaustive.rs:30:11
+   |
+LL |     match e2 { E2::A => (), E2::B => () };
+   |           ^^ pattern `_` not covered
+   |
+   = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
+   = note: the matched value is of type `E2`, which is marked as non-exhaustive
+
+error: aborting due to 3 previous errors
+
+For more information about this error, try `rustc --explain E0004`.
diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr
index 1d1c43c9e8f..cd9ded81e6a 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr
@@ -5,7 +5,7 @@ LL |     match x {}
    |           ^
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `EmptyNonExhaustiveEnum`
+   = note: the matched value is of type `EmptyNonExhaustiveEnum`, which is marked as non-exhaustive
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/enum.rs:16:11
@@ -14,7 +14,7 @@ LL |     match enum_unit {
    |           ^^^^^^^^^ pattern `_` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `NonExhaustiveEnum`
+   = note: the matched value is of type `NonExhaustiveEnum`, which is marked as non-exhaustive
 
 error[E0004]: non-exhaustive patterns: `_` not covered
   --> $DIR/enum.rs:23:11
@@ -23,7 +23,7 @@ LL |     match enum_unit {};
    |           ^^^^^^^^^ pattern `_` not covered
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `NonExhaustiveEnum`
+   = note: the matched value is of type `NonExhaustiveEnum`, which is marked as non-exhaustive
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
index 1f981ba82d0..746c1fd4ace 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr
@@ -5,7 +5,7 @@ LL |     match x {}
    |           ^
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `UninhabitedEnum`
+   = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
 
 error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
   --> $DIR/match.rs:23:11
diff --git a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
index 0ff1c01cbdd..46e84dc09a3 100644
--- a/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
+++ b/src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr
@@ -5,7 +5,7 @@ LL |     match x {}
    |           ^
    |
    = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
-   = note: the matched value is of type `UninhabitedEnum`
+   = note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
 
 error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
   --> $DIR/match_with_exhaustive_patterns.rs:26:11