Rollup merge of #67026 - Nadrieril:improve-usefulness-empty, r=varkor,Centril,estebank

Improve diagnostics and code for exhaustiveness of empty matches

There was a completely separate check and diagnostics for the case of an empty match. This led to slightly different error messages and duplicated code.
This improves code reuse and generally clarifies what happens for empty matches. This also clarifies the action of the `exhaustive_patterns` feature, and ensures that this feature doesn't change diagnostics in places it doesn't need to.
This commit is contained in:
Mazdak Farrokhzad 2019-12-13 20:35:28 +01:00 committed by GitHub
commit df9e491fb2
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
20 changed files with 889 additions and 182 deletions

View file

@ -1,8 +1,8 @@
error[E0004]: non-exhaustive patterns: multiple patterns of type `std::option::Option<i32>` are not handled
error[E0004]: non-exhaustive patterns: `None` and `Some(_)` not covered
--> $DIR/E0004-2.rs:4:11
|
LL | match x { }
| ^
| ^ patterns `None` and `Some(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

View file

@ -1,8 +1,8 @@
error[E0004]: non-exhaustive patterns: `_` not covered
error[E0004]: non-exhaustive patterns: `Box(_)` not covered
--> $DIR/issue-3601.rs:30:44
|
LL | box NodeKind::Element(ed) => match ed.kind {
| ^^^^^^^ pattern `_` not covered
| ^^^^^^^ pattern `Box(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

View file

@ -9,8 +9,13 @@ LL | match uninhab_ref() {
error[E0004]: non-exhaustive patterns: type `Foo` is non-empty
--> $DIR/always-inhabited-union-ref.rs:27:11
|
LL | match uninhab_union() {
| ^^^^^^^^^^^^^^^
LL | / pub union Foo {
LL | | foo: !,
LL | | }
| |_- `Foo` defined here
...
LL | match uninhab_union() {
| ^^^^^^^^^^^^^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

View file

@ -0,0 +1,93 @@
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![deny(unreachable_patterns)]
enum Foo {}
struct NonEmptyStruct(bool); //~ `NonEmptyStruct` defined here
union NonEmptyUnion1 { //~ `NonEmptyUnion1` defined here
foo: (),
}
union NonEmptyUnion2 { //~ `NonEmptyUnion2` defined here
foo: (),
bar: (),
}
enum NonEmptyEnum1 { //~ `NonEmptyEnum1` defined here
Foo(bool),
//~^ not covered
//~| not covered
}
enum NonEmptyEnum2 { //~ `NonEmptyEnum2` defined here
Foo(bool),
//~^ not covered
//~| not covered
Bar,
//~^ not covered
//~| not covered
}
enum NonEmptyEnum5 { //~ `NonEmptyEnum5` defined here
V1, V2, V3, V4, V5,
}
macro_rules! match_empty {
($e:expr) => {
match $e {}
};
}
macro_rules! match_false {
($e:expr) => {
match $e {
_ if false => {}
}
};
}
fn foo(x: Foo) {
match_empty!(x); // ok
match x {
_ => {}, //~ ERROR unreachable pattern
}
match x {
_ if false => {}, //~ ERROR unreachable pattern
}
}
fn main() {
match None::<!> {
None => {}
Some(_) => {} //~ ERROR unreachable pattern
}
match None::<Foo> {
None => {}
Some(_) => {} //~ ERROR unreachable pattern
}
match_empty!(0u8);
//~^ ERROR type `u8` is non-empty
match_empty!(NonEmptyStruct(true));
//~^ ERROR type `NonEmptyStruct` is non-empty
match_empty!((NonEmptyUnion1 { foo: () }));
//~^ ERROR type `NonEmptyUnion1` is non-empty
match_empty!((NonEmptyUnion2 { foo: () }));
//~^ ERROR type `NonEmptyUnion2` is non-empty
match_empty!(NonEmptyEnum1::Foo(true));
//~^ ERROR `Foo(_)` not covered
match_empty!(NonEmptyEnum2::Foo(true));
//~^ ERROR `Foo(_)` and `Bar` not covered
match_empty!(NonEmptyEnum5::V1);
//~^ ERROR `V1`, `V2`, `V3` and 2 more not covered
match_false!(0u8);
//~^ ERROR `_` not covered
match_false!(NonEmptyStruct(true));
//~^ ERROR `NonEmptyStruct(_)` not covered
match_false!((NonEmptyUnion1 { foo: () }));
//~^ ERROR `NonEmptyUnion1 { .. }` not covered
match_false!((NonEmptyUnion2 { foo: () }));
//~^ ERROR `NonEmptyUnion2 { .. }` not covered
match_false!(NonEmptyEnum1::Foo(true));
//~^ ERROR `Foo(_)` not covered
match_false!(NonEmptyEnum2::Foo(true));
//~^ ERROR `Foo(_)` and `Bar` not covered
match_false!(NonEmptyEnum5::V1);
//~^ ERROR `V1`, `V2`, `V3` and 2 more not covered
}

View file

@ -0,0 +1,223 @@
error: unreachable pattern
--> $DIR/match-empty-exhaustive_patterns.rs:47:9
|
LL | _ => {},
| ^
|
note: lint level defined here
--> $DIR/match-empty-exhaustive_patterns.rs:3:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/match-empty-exhaustive_patterns.rs:50:9
|
LL | _ if false => {},
| ^
error: unreachable pattern
--> $DIR/match-empty-exhaustive_patterns.rs:57:9
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/match-empty-exhaustive_patterns.rs:61:9
|
LL | Some(_) => {}
| ^^^^^^^
error[E0004]: non-exhaustive patterns: type `u8` is non-empty
--> $DIR/match-empty-exhaustive_patterns.rs:64:18
|
LL | match_empty!(0u8);
| ^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `NonEmptyStruct` is non-empty
--> $DIR/match-empty-exhaustive_patterns.rs:66:18
|
LL | struct NonEmptyStruct(bool);
| ---------------------------- `NonEmptyStruct` defined here
...
LL | match_empty!(NonEmptyStruct(true));
| ^^^^^^^^^^^^^^^^^^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
--> $DIR/match-empty-exhaustive_patterns.rs:68:18
|
LL | / union NonEmptyUnion1 {
LL | | foo: (),
LL | | }
| |_- `NonEmptyUnion1` defined here
...
LL | match_empty!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
--> $DIR/match-empty-exhaustive_patterns.rs:70:18
|
LL | / union NonEmptyUnion2 {
LL | | foo: (),
LL | | bar: (),
LL | | }
| |_- `NonEmptyUnion2` defined here
...
LL | match_empty!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:72:18
|
LL | / enum NonEmptyEnum1 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum1` defined here
...
LL | match_empty!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:74:18
|
LL | / enum NonEmptyEnum2 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | Bar,
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum2` defined here
...
LL | match_empty!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
--> $DIR/match-empty-exhaustive_patterns.rs:76:18
|
LL | / enum NonEmptyEnum5 {
LL | | V1, V2, V3, V4, V5,
LL | | }
| |_- `NonEmptyEnum5` defined here
...
LL | match_empty!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:79:18
|
LL | match_false!(0u8);
| ^^^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `NonEmptyStruct(_)` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:81:18
|
LL | struct NonEmptyStruct(bool);
| ---------------------------- `NonEmptyStruct` defined here
...
LL | match_false!(NonEmptyStruct(true));
| ^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:83:18
|
LL | / union NonEmptyUnion1 {
LL | | foo: (),
LL | | }
| |_- `NonEmptyUnion1` defined here
...
LL | match_false!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:85:18
|
LL | / union NonEmptyUnion2 {
LL | | foo: (),
LL | | bar: (),
LL | | }
| |_- `NonEmptyUnion2` defined here
...
LL | match_false!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:87:18
|
LL | / enum NonEmptyEnum1 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum1` defined here
...
LL | match_false!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
--> $DIR/match-empty-exhaustive_patterns.rs:89:18
|
LL | / enum NonEmptyEnum2 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | Bar,
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum2` defined here
...
LL | match_false!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
--> $DIR/match-empty-exhaustive_patterns.rs:91:18
|
LL | / enum NonEmptyEnum5 {
LL | | V1, V2, V3, V4, V5,
LL | | }
| |_- `NonEmptyEnum5` defined here
...
LL | match_false!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error: aborting due to 18 previous errors
For more information about this error, try `rustc --explain E0004`.

View file

@ -0,0 +1,92 @@
#![feature(never_type)]
#![deny(unreachable_patterns)]
enum Foo {}
struct NonEmptyStruct(bool); //~ `NonEmptyStruct` defined here
union NonEmptyUnion1 { //~ `NonEmptyUnion1` defined here
foo: (),
}
union NonEmptyUnion2 { //~ `NonEmptyUnion2` defined here
foo: (),
bar: (),
}
enum NonEmptyEnum1 { //~ `NonEmptyEnum1` defined here
Foo(bool),
//~^ not covered
//~| not covered
}
enum NonEmptyEnum2 { //~ `NonEmptyEnum2` defined here
Foo(bool),
//~^ not covered
//~| not covered
Bar,
//~^ not covered
//~| not covered
}
enum NonEmptyEnum5 { //~ `NonEmptyEnum5` defined here
V1, V2, V3, V4, V5,
}
macro_rules! match_empty {
($e:expr) => {
match $e {}
};
}
macro_rules! match_false {
($e:expr) => {
match $e {
_ if false => {}
}
};
}
fn foo(x: Foo) {
match_empty!(x); // ok
match_false!(x); // Not detected as unreachable nor exhaustive.
//~^ ERROR non-exhaustive patterns: `_` not covered
match x {
_ => {}, // Not detected as unreachable, see #55123.
}
}
fn main() {
// `exhaustive_patterns` is not on, so uninhabited branches are not detected as unreachable.
match None::<!> {
None => {}
Some(_) => {}
}
match None::<Foo> {
None => {}
Some(_) => {}
}
match_empty!(0u8);
//~^ ERROR type `u8` is non-empty
match_empty!(NonEmptyStruct(true));
//~^ ERROR type `NonEmptyStruct` is non-empty
match_empty!((NonEmptyUnion1 { foo: () }));
//~^ ERROR type `NonEmptyUnion1` is non-empty
match_empty!((NonEmptyUnion2 { foo: () }));
//~^ ERROR type `NonEmptyUnion2` is non-empty
match_empty!(NonEmptyEnum1::Foo(true));
//~^ ERROR `Foo(_)` not covered
match_empty!(NonEmptyEnum2::Foo(true));
//~^ ERROR `Foo(_)` and `Bar` not covered
match_empty!(NonEmptyEnum5::V1);
//~^ ERROR `V1`, `V2`, `V3` and 2 more not covered
match_false!(0u8);
//~^ ERROR `_` not covered
match_false!(NonEmptyStruct(true));
//~^ ERROR `NonEmptyStruct(_)` not covered
match_false!((NonEmptyUnion1 { foo: () }));
//~^ ERROR `NonEmptyUnion1 { .. }` not covered
match_false!((NonEmptyUnion2 { foo: () }));
//~^ ERROR `NonEmptyUnion2 { .. }` not covered
match_false!(NonEmptyEnum1::Foo(true));
//~^ ERROR `Foo(_)` not covered
match_false!(NonEmptyEnum2::Foo(true));
//~^ ERROR `Foo(_)` and `Bar` not covered
match_false!(NonEmptyEnum5::V1);
//~^ ERROR `V1`, `V2`, `V3` and 2 more not covered
}

View file

@ -0,0 +1,204 @@
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/match-empty.rs:45:18
|
LL | enum Foo {}
| ----------- `Foo` defined here
...
LL | match_false!(x); // Not detected as unreachable nor exhaustive.
| ^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `u8` is non-empty
--> $DIR/match-empty.rs:63:18
|
LL | match_empty!(0u8);
| ^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `NonEmptyStruct` is non-empty
--> $DIR/match-empty.rs:65:18
|
LL | struct NonEmptyStruct(bool);
| ---------------------------- `NonEmptyStruct` defined here
...
LL | match_empty!(NonEmptyStruct(true));
| ^^^^^^^^^^^^^^^^^^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
--> $DIR/match-empty.rs:67:18
|
LL | / union NonEmptyUnion1 {
LL | | foo: (),
LL | | }
| |_- `NonEmptyUnion1` defined here
...
LL | match_empty!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
--> $DIR/match-empty.rs:69:18
|
LL | / union NonEmptyUnion2 {
LL | | foo: (),
LL | | bar: (),
LL | | }
| |_- `NonEmptyUnion2` defined here
...
LL | match_empty!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
--> $DIR/match-empty.rs:71:18
|
LL | / enum NonEmptyEnum1 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum1` defined here
...
LL | match_empty!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
--> $DIR/match-empty.rs:73:18
|
LL | / enum NonEmptyEnum2 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | Bar,
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum2` defined here
...
LL | match_empty!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
--> $DIR/match-empty.rs:75:18
|
LL | / enum NonEmptyEnum5 {
LL | | V1, V2, V3, V4, V5,
LL | | }
| |_- `NonEmptyEnum5` defined here
...
LL | match_empty!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/match-empty.rs:78:18
|
LL | match_false!(0u8);
| ^^^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `NonEmptyStruct(_)` not covered
--> $DIR/match-empty.rs:80:18
|
LL | struct NonEmptyStruct(bool);
| ---------------------------- `NonEmptyStruct` defined here
...
LL | match_false!(NonEmptyStruct(true));
| ^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
--> $DIR/match-empty.rs:82:18
|
LL | / union NonEmptyUnion1 {
LL | | foo: (),
LL | | }
| |_- `NonEmptyUnion1` defined here
...
LL | match_false!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
--> $DIR/match-empty.rs:84:18
|
LL | / union NonEmptyUnion2 {
LL | | foo: (),
LL | | bar: (),
LL | | }
| |_- `NonEmptyUnion2` defined here
...
LL | match_false!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` not covered
--> $DIR/match-empty.rs:86:18
|
LL | / enum NonEmptyEnum1 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum1` defined here
...
LL | match_false!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo(_)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Foo(_)` and `Bar` not covered
--> $DIR/match-empty.rs:88:18
|
LL | / enum NonEmptyEnum2 {
LL | | Foo(bool),
| | --- not covered
LL | |
LL | |
LL | | Bar,
| | --- not covered
LL | |
LL | |
LL | | }
| |_- `NonEmptyEnum2` defined here
...
LL | match_false!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `Foo(_)` and `Bar` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `V1`, `V2`, `V3` and 2 more not covered
--> $DIR/match-empty.rs:90:18
|
LL | / enum NonEmptyEnum5 {
LL | | V1, V2, V3, V4, V5,
LL | | }
| |_- `NonEmptyEnum5` defined here
...
LL | match_false!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `V1`, `V2`, `V3` and 2 more not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error: aborting due to 15 previous errors
For more information about this error, try `rustc --explain E0004`.

View file

@ -6,3 +6,6 @@ pub enum NonExhaustiveEnum {
Tuple(u32),
Struct { field: u32 }
}
#[non_exhaustive]
pub enum EmptyNonExhaustiveEnum {}

View file

@ -1,7 +1,14 @@
// aux-build:enums.rs
extern crate enums;
use enums::NonExhaustiveEnum;
use enums::{EmptyNonExhaustiveEnum, NonExhaustiveEnum};
fn empty(x: EmptyNonExhaustiveEnum) {
match x {} //~ ERROR type `enums::EmptyNonExhaustiveEnum` is non-empty
match x {
_ => {}, // ok
}
}
fn main() {
let enum_unit = NonExhaustiveEnum::Unit;
@ -13,6 +20,9 @@ fn main() {
NonExhaustiveEnum::Struct { .. } => "third"
};
match enum_unit {};
//~^ ERROR non-exhaustive patterns: `_` not covered [E0004]
// Everything below this is expected to compile successfully.
let enum_unit = NonExhaustiveEnum::Unit;

View file

@ -1,11 +1,27 @@
error[E0004]: non-exhaustive patterns: type `enums::EmptyNonExhaustiveEnum` is non-empty
--> $DIR/enum.rs:7:11
|
LL | match x {}
| ^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/enum.rs:9:11
--> $DIR/enum.rs:16:11
|
LL | match enum_unit {
| ^^^^^^^^^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error: aborting due to previous error
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/enum.rs:23:11
|
LL | match enum_unit {};
| ^^^^^^^^^ pattern `_` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0004`.

View file

@ -0,0 +1,37 @@
#![deny(unreachable_patterns)]
#[non_exhaustive]
pub enum NonExhaustiveEnum {
Unit,
//~^ not covered
Tuple(u32),
//~^ not covered
Struct { field: u32 }
//~^ not covered
}
pub enum NormalEnum {
Unit,
//~^ not covered
Tuple(u32),
//~^ not covered
Struct { field: u32 }
//~^ not covered
}
#[non_exhaustive]
pub enum EmptyNonExhaustiveEnum {}
fn empty_non_exhaustive(x: EmptyNonExhaustiveEnum) {
match x {}
match x {
_ => {} // not detected as unreachable
}
}
fn main() {
match NonExhaustiveEnum::Unit {}
//~^ ERROR `Unit`, `Tuple(_)` and `Struct { .. }` not covered [E0004]
match NormalEnum::Unit {}
//~^ ERROR `Unit`, `Tuple(_)` and `Struct { .. }` not covered [E0004]
}

View file

@ -0,0 +1,45 @@
error[E0004]: non-exhaustive patterns: `Unit`, `Tuple(_)` and `Struct { .. }` not covered
--> $DIR/enum_same_crate_empty_match.rs:33:11
|
LL | / pub enum NonExhaustiveEnum {
LL | | Unit,
| | ---- not covered
LL | |
LL | | Tuple(u32),
| | ----- not covered
LL | |
LL | | Struct { field: u32 }
| | ------ not covered
LL | |
LL | | }
| |_- `NonExhaustiveEnum` defined here
...
LL | match NonExhaustiveEnum::Unit {}
| ^^^^^^^^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: `Unit`, `Tuple(_)` and `Struct { .. }` not covered
--> $DIR/enum_same_crate_empty_match.rs:35:11
|
LL | / pub enum NormalEnum {
LL | | Unit,
| | ---- not covered
LL | |
LL | | Tuple(u32),
| | ----- not covered
LL | |
LL | | Struct { field: u32 }
| | ------ not covered
LL | |
LL | | }
| |_- `NormalEnum` defined here
...
LL | match NormalEnum::Unit {}
| ^^^^^^^^^^^^^^^^ patterns `Unit`, `Tuple(_)` and `Struct { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error: aborting due to 2 previous errors
For more information about this error, try `rustc --explain E0004`.

View file

@ -1,4 +1,4 @@
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `uninhabited::IndirectUninhabitedEnum` is not handled
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedEnum` is non-empty
--> $DIR/indirect_match.rs:18:11
|
LL | match x {}
@ -6,7 +6,7 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `uninhabited::IndirectUninhabitedStruct` is not handled
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedStruct` is non-empty
--> $DIR/indirect_match.rs:22:11
|
LL | match x {}
@ -14,7 +14,7 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `uninhabited::IndirectUninhabitedTupleStruct` is not handled
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedTupleStruct` is non-empty
--> $DIR/indirect_match.rs:26:11
|
LL | match x {}
@ -22,7 +22,7 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `uninhabited::IndirectUninhabitedVariants` is not handled
error[E0004]: non-exhaustive patterns: type `uninhabited::IndirectUninhabitedVariants` is non-empty
--> $DIR/indirect_match.rs:32:11
|
LL | match x {}

View file

@ -1,53 +1,41 @@
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedEnum` of type `IndirectUninhabitedEnum` is not handled
error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedEnum` is non-empty
--> $DIR/indirect_match_same_crate.rs:32:11
|
LL | pub struct IndirectUninhabitedEnum(UninhabitedEnum);
| ----------------------------------------------------
| | |
| | variant not covered
| `IndirectUninhabitedEnum` defined here
| ---------------------------------------------------- `IndirectUninhabitedEnum` defined here
...
LL | match x {}
| ^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedStruct` of type `IndirectUninhabitedStruct` is not handled
error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedStruct` is non-empty
--> $DIR/indirect_match_same_crate.rs:36:11
|
LL | pub struct IndirectUninhabitedStruct(UninhabitedStruct);
| --------------------------------------------------------
| | |
| | variant not covered
| `IndirectUninhabitedStruct` defined here
| -------------------------------------------------------- `IndirectUninhabitedStruct` defined here
...
LL | match x {}
| ^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedTupleStruct` of type `IndirectUninhabitedTupleStruct` is not handled
error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedTupleStruct` is non-empty
--> $DIR/indirect_match_same_crate.rs:40:11
|
LL | pub struct IndirectUninhabitedTupleStruct(UninhabitedTupleStruct);
| ------------------------------------------------------------------
| | |
| | variant not covered
| `IndirectUninhabitedTupleStruct` defined here
| ------------------------------------------------------------------ `IndirectUninhabitedTupleStruct` defined here
...
LL | match x {}
| ^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `IndirectUninhabitedVariants` of type `IndirectUninhabitedVariants` is not handled
error[E0004]: non-exhaustive patterns: type `IndirectUninhabitedVariants` is non-empty
--> $DIR/indirect_match_same_crate.rs:46:11
|
LL | pub struct IndirectUninhabitedVariants(UninhabitedVariants);
| ------------------------------------------------------------
| | |
| | variant not covered
| `IndirectUninhabitedVariants` defined here
| ------------------------------------------------------------ `IndirectUninhabitedVariants` defined here
...
LL | match x {}
| ^

View file

@ -6,7 +6,7 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `uninhabited::UninhabitedStruct` is not handled
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedStruct` is non-empty
--> $DIR/match.rs:22:11
|
LL | match x {}
@ -14,7 +14,7 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `uninhabited::UninhabitedTupleStruct` is not handled
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedTupleStruct` is non-empty
--> $DIR/match.rs:26:11
|
LL | match x {}
@ -22,11 +22,11 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: multiple patterns of type `uninhabited::UninhabitedVariants` are not handled
error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
--> $DIR/match.rs:30:11
|
LL | match x {}
| ^
| ^ patterns `Tuple(_)` and `Struct { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

View file

@ -1,10 +1,7 @@
error[E0004]: non-exhaustive patterns: pattern `UninhabitedStruct` of type `UninhabitedStruct` is not handled
error[E0004]: non-exhaustive patterns: type `UninhabitedStruct` is non-empty
--> $DIR/match_same_crate.rs:28:11
|
LL | pub struct UninhabitedStruct {
| - ----------------- variant not covered
| _|
| |
LL | / pub struct UninhabitedStruct {
LL | | _priv: !,
LL | | }
| |_- `UninhabitedStruct` defined here
@ -14,33 +11,30 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: pattern `UninhabitedTupleStruct` of type `UninhabitedTupleStruct` is not handled
error[E0004]: non-exhaustive patterns: type `UninhabitedTupleStruct` is non-empty
--> $DIR/match_same_crate.rs:32:11
|
LL | pub struct UninhabitedTupleStruct(!);
| -------------------------------------
| | |
| | variant not covered
| `UninhabitedTupleStruct` defined here
| ------------------------------------- `UninhabitedTupleStruct` defined here
...
LL | match x {}
| ^
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: multiple patterns of type `UninhabitedVariants` are not handled
error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
--> $DIR/match_same_crate.rs:36:11
|
LL | / pub enum UninhabitedVariants {
LL | | #[non_exhaustive] Tuple(!),
| | ----- variant not covered
| | ----- not covered
LL | | #[non_exhaustive] Struct { x: ! }
| | ------ variant not covered
| | ------ not covered
LL | | }
| |_- `UninhabitedVariants` defined here
...
LL | match x {}
| ^
| ^ patterns `Tuple(_)` and `Struct { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

View file

@ -22,11 +22,11 @@ LL | match x {}
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
error[E0004]: non-exhaustive patterns: type `uninhabited::UninhabitedVariants` is non-empty
error[E0004]: non-exhaustive patterns: `Tuple(_)` and `Struct { .. }` not covered
--> $DIR/match_with_exhaustive_patterns.rs:33:11
|
LL | match x {}
| ^
| ^ patterns `Tuple(_)` and `Struct { .. }` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

View file

@ -9,6 +9,9 @@ LL | let _ = match x {
error[E0004]: non-exhaustive patterns: type `&Void` is non-empty
--> $DIR/uninhabited-matches-feature-gated.rs:12:19
|
LL | enum Void {}
| ------------ `Void` defined here
...
LL | let _ = match x {};
| ^
|