Skip to content

Commit 69b352e

Browse files
committed
Auto merge of #85233 - FabianWolff:issue-85227, r=petrochenkov
Improve error message for non-exhaustive matches on non-exhaustive enums This pull request fixes #85227. For an enum marked with `#[non_exhaustive]` and not defined in the current crate, the error message for non-exhaustive matches now mentions the fact that the enum is marked as non-exhaustive: ``` error[E0004]: non-exhaustive patterns: `_` not covered --> main.rs:12:11 | 12 | match e { | ^ 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 `E`, which is marked as non-exhaustive ```
2 parents 91f2e2d + 57291b8 commit 69b352e

File tree

7 files changed

+88
-6
lines changed

7 files changed

+88
-6
lines changed

compiler/rustc_mir_build/src/thir/pattern/check_match.rs

+10-1
Original file line numberDiff line numberDiff line change
@@ -496,12 +496,21 @@ fn non_exhaustive_match<'p, 'tcx>(
496496
err.span_label(sp, pattern_not_covered_label(&witnesses, &joined_patterns));
497497
};
498498

499+
let is_variant_list_non_exhaustive = match scrut_ty.kind() {
500+
ty::Adt(def, _) if def.is_variant_list_non_exhaustive() && !def.did.is_local() => true,
501+
_ => false,
502+
};
503+
499504
adt_defined_here(cx, &mut err, scrut_ty, &witnesses);
500505
err.help(
501506
"ensure that all possible cases are being handled, \
502507
possibly by adding wildcards or more match arms",
503508
);
504-
err.note(&format!("the matched value is of type `{}`", scrut_ty));
509+
err.note(&format!(
510+
"the matched value is of type `{}`{}",
511+
scrut_ty,
512+
if is_variant_list_non_exhaustive { ", which is marked as non-exhaustive" } else { "" }
513+
));
505514
if (scrut_ty == cx.tcx.types.usize || scrut_ty == cx.tcx.types.isize)
506515
&& !is_empty_match
507516
&& witnesses.len() == 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
#[non_exhaustive]
2+
pub enum E1 {}
3+
4+
#[non_exhaustive]
5+
pub enum E2 { A, B }
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// aux-build:match_non_exhaustive_lib.rs
2+
3+
/* The error message for non-exhaustive matches on non-local enums
4+
* marked as non-exhaustive should mention the fact that the enum
5+
* is marked as non-exhaustive (issue #85227).
6+
*/
7+
8+
// Ignore non_exhaustive in the same crate
9+
#[non_exhaustive]
10+
enum L { A, B }
11+
12+
extern crate match_non_exhaustive_lib;
13+
use match_non_exhaustive_lib::{E1, E2};
14+
15+
fn foo() -> L {todo!()}
16+
fn bar() -> (E1, E2) {todo!()}
17+
18+
fn main() {
19+
let l = foo();
20+
// No error for enums defined in this crate
21+
match l { L::A => (), L::B => () };
22+
// (except if the match is already non-exhaustive)
23+
match l { L::A => () };
24+
//~^ ERROR: non-exhaustive patterns: `B` not covered [E0004]
25+
26+
// E1 is not visibly uninhabited from here
27+
let (e1, e2) = bar();
28+
match e1 {};
29+
//~^ ERROR: non-exhaustive patterns: type `E1` is non-empty [E0004]
30+
match e2 { E2::A => (), E2::B => () };
31+
//~^ ERROR: non-exhaustive patterns: `_` not covered [E0004]
32+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
error[E0004]: non-exhaustive patterns: `B` not covered
2+
--> $DIR/match_non_exhaustive.rs:23:11
3+
|
4+
LL | enum L { A, B }
5+
| ---------------
6+
| | |
7+
| | not covered
8+
| `L` defined here
9+
...
10+
LL | match l { L::A => () };
11+
| ^ pattern `B` not covered
12+
|
13+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
14+
= note: the matched value is of type `L`
15+
16+
error[E0004]: non-exhaustive patterns: type `E1` is non-empty
17+
--> $DIR/match_non_exhaustive.rs:28:11
18+
|
19+
LL | match e1 {};
20+
| ^^
21+
|
22+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
23+
= note: the matched value is of type `E1`, which is marked as non-exhaustive
24+
25+
error[E0004]: non-exhaustive patterns: `_` not covered
26+
--> $DIR/match_non_exhaustive.rs:30:11
27+
|
28+
LL | match e2 { E2::A => (), E2::B => () };
29+
| ^^ pattern `_` not covered
30+
|
31+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
32+
= note: the matched value is of type `E2`, which is marked as non-exhaustive
33+
34+
error: aborting due to 3 previous errors
35+
36+
For more information about this error, try `rustc --explain E0004`.

src/test/ui/rfc-2008-non-exhaustive/enum.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | match x {}
55
| ^
66
|
77
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
8-
= note: the matched value is of type `EmptyNonExhaustiveEnum`
8+
= note: the matched value is of type `EmptyNonExhaustiveEnum`, which is marked as non-exhaustive
99

1010
error[E0004]: non-exhaustive patterns: `_` not covered
1111
--> $DIR/enum.rs:16:11
@@ -14,7 +14,7 @@ LL | match enum_unit {
1414
| ^^^^^^^^^ pattern `_` not covered
1515
|
1616
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
17-
= note: the matched value is of type `NonExhaustiveEnum`
17+
= note: the matched value is of type `NonExhaustiveEnum`, which is marked as non-exhaustive
1818

1919
error[E0004]: non-exhaustive patterns: `_` not covered
2020
--> $DIR/enum.rs:23:11
@@ -23,7 +23,7 @@ LL | match enum_unit {};
2323
| ^^^^^^^^^ pattern `_` not covered
2424
|
2525
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
26-
= note: the matched value is of type `NonExhaustiveEnum`
26+
= note: the matched value is of type `NonExhaustiveEnum`, which is marked as non-exhaustive
2727

2828
error: aborting due to 3 previous errors
2929

src/test/ui/rfc-2008-non-exhaustive/uninhabited/match.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | match x {}
55
| ^
66
|
77
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
8-
= note: the matched value is of type `UninhabitedEnum`
8+
= note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
99

1010
error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
1111
--> $DIR/match.rs:23:11

src/test/ui/rfc-2008-non-exhaustive/uninhabited/match_with_exhaustive_patterns.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ LL | match x {}
55
| ^
66
|
77
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
8-
= note: the matched value is of type `UninhabitedEnum`
8+
= note: the matched value is of type `UninhabitedEnum`, which is marked as non-exhaustive
99

1010
error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
1111
--> $DIR/match_with_exhaustive_patterns.rs:26:11

0 commit comments

Comments
 (0)