Test empty types better

This commit is contained in:
Nadrieril 2023-10-29 10:13:07 +01:00
parent f967532a47
commit 4e376cc104
11 changed files with 2598 additions and 494 deletions

View File

@ -0,0 +1,63 @@
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:17:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-match-check-notes.rs:7:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:20:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:27:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:30:9
|
LL | _ if false => {}
| ^
error[E0005]: refutable pattern in local binding
--> $DIR/empty-match-check-notes.rs:35:9
|
LL | let None = x;
| ^^^^ pattern `Some(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
= note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let None = x { todo!() };
| ++ +++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/empty-match-check-notes.rs:45:11
|
LL | match 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 => {},
LL + _ => todo!()
|
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.

View File

@ -0,0 +1,62 @@
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:17:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-match-check-notes.rs:7:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:20:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:27:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-match-check-notes.rs:30:9
|
LL | _ if false => {}
| ^
error[E0005]: refutable pattern in local binding
--> $DIR/empty-match-check-notes.rs:35:9
|
LL | let None = x;
| ^^^^ pattern `Some(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let None = x { todo!() };
| ++ +++++++++++
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/empty-match-check-notes.rs:45:11
|
LL | match 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 => {},
LL + _ => todo!()
|
error: aborting due to 6 previous errors
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.

View File

@ -0,0 +1,52 @@
// aux-build:empty.rs
// revisions: normal exhaustive_patterns
//
// This tests a match with no arms on various types, and checks NOTEs.
#![feature(never_type)]
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
#![deny(unreachable_patterns)]
//~^ NOTE the lint level is defined here
extern crate empty;
enum EmptyEnum {}
fn empty_enum(x: EmptyEnum) {
match x {} // ok
match x {
_ => {} //~ ERROR unreachable pattern
}
match x {
_ if false => {} //~ ERROR unreachable pattern
}
}
fn empty_foreign_enum(x: empty::EmptyForeignEnum) {
match x {} // ok
match x {
_ => {} //~ ERROR unreachable pattern
}
match x {
_ if false => {} //~ ERROR unreachable pattern
}
}
fn empty_foreign_enum_private(x: Option<empty::SecretlyUninhabitedForeignStruct>) {
let None = x;
//~^ ERROR refutable pattern in local binding
//~| NOTE `let` bindings require an "irrefutable pattern"
//~| NOTE for more information, visit
//~| NOTE the matched value is of type
//~| NOTE pattern `Some(_)` not covered
//[exhaustive_patterns]~| NOTE currently uninhabited, but this variant contains private fields
}
fn main() {
match 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
_ if false => {}
}
}

View File

@ -1,62 +1,5 @@
error: unreachable pattern
--> $DIR/empty-match.rs:68:9
|
LL | _ => {},
| ^
|
note: the lint level is defined here
--> $DIR/empty-match.rs:8:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-match.rs:71:9
|
LL | _ if false => {},
| ^
error: unreachable pattern
--> $DIR/empty-match.rs:78:9
|
LL | _ => {},
| ^
error: unreachable pattern
--> $DIR/empty-match.rs:81:9
|
LL | _ if false => {},
| ^
error[E0005]: refutable pattern in local binding
--> $DIR/empty-match.rs:86:9
|
LL | let None = x;
| ^^^^ pattern `Some(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: pattern `Some(_)` is currently uninhabited, but this variant contains private fields which may become inhabited in the future
= note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let None = x { todo!() };
| ++ +++++++++++
error: unreachable pattern
--> $DIR/empty-match.rs:98:9
|
LL | _ => {},
| ^
error: unreachable pattern
--> $DIR/empty-match.rs:101:9
|
LL | _ if false => {},
| ^
error[E0004]: non-exhaustive patterns: type `u8` is non-empty
--> $DIR/empty-match.rs:119:20
--> $DIR/empty-match.rs:46:20
|
LL | match_no_arms!(0u8);
| ^^^
@ -65,122 +8,121 @@ LL | match_no_arms!(0u8);
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
--> $DIR/empty-match.rs:121:20
--> $DIR/empty-match.rs:47:20
|
LL | match_no_arms!(NonEmptyStruct1);
| ^^^^^^^^^^^^^^^
|
note: `NonEmptyStruct1` defined here
--> $DIR/empty-match.rs:15:8
--> $DIR/empty-match.rs:22:12
|
LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^
LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty
--> $DIR/empty-match.rs:123:20
--> $DIR/empty-match.rs:48:20
|
LL | match_no_arms!(NonEmptyStruct2(true));
| ^^^^^^^^^^^^^^^^^^^^^
|
note: `NonEmptyStruct2` defined here
--> $DIR/empty-match.rs:18:8
--> $DIR/empty-match.rs:23:12
|
LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^
LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
--> $DIR/empty-match.rs:125:20
--> $DIR/empty-match.rs:49:20
|
LL | match_no_arms!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `NonEmptyUnion1` defined here
--> $DIR/empty-match.rs:21:7
--> $DIR/empty-match.rs:24:11
|
LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^
LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
--> $DIR/empty-match.rs:127:20
--> $DIR/empty-match.rs:50:20
|
LL | match_no_arms!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `NonEmptyUnion2` defined here
--> $DIR/empty-match.rs:26:7
--> $DIR/empty-match.rs:27:11
|
LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^
LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:129:20
--> $DIR/empty-match.rs:51:20
|
LL | match_no_arms!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:32:6
--> $DIR/empty-match.rs:31:10
|
LL | enum NonEmptyEnum1 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
LL | enum NonEmptyEnum1 {
| ^^^^^^^^^^^^^
LL | Foo(bool),
| --- not covered
= note: the matched value is of type `NonEmptyEnum1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:132:20
--> $DIR/empty-match.rs:52:20
|
LL | match_no_arms!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:39:6
--> $DIR/empty-match.rs:34:10
|
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
...
LL | Bar,
| --- not covered
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
LL | Foo(bool),
| --- not covered
LL | Bar,
| --- not covered
= note: the matched value is of type `NonEmptyEnum2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:135:20
--> $DIR/empty-match.rs:53:20
|
LL | match_no_arms!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:49:6
--> $DIR/empty-match.rs:38:10
|
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
...
LL | V1, V2, V3, V4, V5,
| -- -- -- -- -- not covered
| | | | |
| | | | not covered
| | | not covered
| | not covered
| not covered
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
LL | V1,
| -- not covered
LL | V2,
| -- not covered
LL | V3,
| -- not covered
LL | V4,
| -- not covered
LL | V5,
| -- not covered
= note: the matched value is of type `NonEmptyEnum5`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/empty-match.rs:139:24
--> $DIR/empty-match.rs:55:24
|
LL | match_guarded_arm!(0u8);
| ^^^ pattern `_` not covered
@ -189,161 +131,159 @@ LL | match_guarded_arm!(0u8);
= 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 => {},
LL + _ => todo!()
LL ~ _ if false => {},
LL + _ => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
--> $DIR/empty-match.rs:144:24
--> $DIR/empty-match.rs:56:24
|
LL | match_guarded_arm!(NonEmptyStruct1);
| ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
|
note: `NonEmptyStruct1` defined here
--> $DIR/empty-match.rs:15:8
--> $DIR/empty-match.rs:22:12
|
LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyStruct1 => todo!()
LL ~ _ if false => {},
LL + NonEmptyStruct1 => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
--> $DIR/empty-match.rs:149:24
--> $DIR/empty-match.rs:57:24
|
LL | match_guarded_arm!(NonEmptyStruct2(true));
| ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
|
note: `NonEmptyStruct2` defined here
--> $DIR/empty-match.rs:18:8
--> $DIR/empty-match.rs:23:12
|
LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyStruct2(_) => todo!()
LL ~ _ if false => {},
LL + NonEmptyStruct2(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
--> $DIR/empty-match.rs:154:24
--> $DIR/empty-match.rs:58:24
|
LL | match_guarded_arm!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
|
note: `NonEmptyUnion1` defined here
--> $DIR/empty-match.rs:21:7
--> $DIR/empty-match.rs:24:11
|
LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyUnion1 { .. } => todo!()
LL ~ _ if false => {},
LL + NonEmptyUnion1 { .. } => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
--> $DIR/empty-match.rs:159:24
--> $DIR/empty-match.rs:59:24
|
LL | match_guarded_arm!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
|
note: `NonEmptyUnion2` defined here
--> $DIR/empty-match.rs:26:7
--> $DIR/empty-match.rs:27:11
|
LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyUnion2 { .. } => todo!()
LL ~ _ if false => {},
LL + NonEmptyUnion2 { .. } => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:164:24
--> $DIR/empty-match.rs:60:24
|
LL | match_guarded_arm!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:32:6
--> $DIR/empty-match.rs:31:10
|
LL | enum NonEmptyEnum1 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
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 => {},
LL + NonEmptyEnum1::Foo(_) => todo!()
LL ~ _ if false => {},
LL + NonEmptyEnum1::Foo(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:169:24
--> $DIR/empty-match.rs:61:24
|
LL | match_guarded_arm!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:39:6
--> $DIR/empty-match.rs:34:10
|
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
...
LL | Bar,
| --- not covered
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
LL | Foo(bool),
| --- not covered
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 => {},
LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
LL ~ _ if false => {},
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:174:24
--> $DIR/empty-match.rs:62:24
|
LL | match_guarded_arm!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:49:6
--> $DIR/empty-match.rs:38:10
|
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
...
LL | V1, V2, V3, V4, V5,
| -- -- -- -- -- not covered
| | | | |
| | | | not covered
| | | not covered
| | not covered
| not covered
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
LL | V1,
| -- not covered
LL | V2,
| -- not covered
LL | V3,
| -- not covered
LL | V4,
| -- not covered
LL | V5,
| -- not covered
= 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 => {},
LL + _ => todo!()
LL ~ _ if false => {},
LL + _ => todo!()
|
error: aborting due to 23 previous errors
error: aborting due to 16 previous errors
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.
For more information about this error, try `rustc --explain E0004`.

View File

@ -1,61 +1,5 @@
error: unreachable pattern
--> $DIR/empty-match.rs:68:9
|
LL | _ => {},
| ^
|
note: the lint level is defined here
--> $DIR/empty-match.rs:8:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-match.rs:71:9
|
LL | _ if false => {},
| ^
error: unreachable pattern
--> $DIR/empty-match.rs:78:9
|
LL | _ => {},
| ^
error: unreachable pattern
--> $DIR/empty-match.rs:81:9
|
LL | _ if false => {},
| ^
error[E0005]: refutable pattern in local binding
--> $DIR/empty-match.rs:86:9
|
LL | let None = x;
| ^^^^ pattern `Some(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `Option<SecretlyUninhabitedForeignStruct>`
help: you might want to use `if let` to ignore the variant that isn't matched
|
LL | if let None = x { todo!() };
| ++ +++++++++++
error: unreachable pattern
--> $DIR/empty-match.rs:98:9
|
LL | _ => {},
| ^
error: unreachable pattern
--> $DIR/empty-match.rs:101:9
|
LL | _ if false => {},
| ^
error[E0004]: non-exhaustive patterns: type `u8` is non-empty
--> $DIR/empty-match.rs:119:20
--> $DIR/empty-match.rs:46:20
|
LL | match_no_arms!(0u8);
| ^^^
@ -64,122 +8,121 @@ LL | match_no_arms!(0u8);
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty
--> $DIR/empty-match.rs:121:20
--> $DIR/empty-match.rs:47:20
|
LL | match_no_arms!(NonEmptyStruct1);
| ^^^^^^^^^^^^^^^
|
note: `NonEmptyStruct1` defined here
--> $DIR/empty-match.rs:15:8
--> $DIR/empty-match.rs:22:12
|
LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^
LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyStruct2` is non-empty
--> $DIR/empty-match.rs:123:20
--> $DIR/empty-match.rs:48:20
|
LL | match_no_arms!(NonEmptyStruct2(true));
| ^^^^^^^^^^^^^^^^^^^^^
|
note: `NonEmptyStruct2` defined here
--> $DIR/empty-match.rs:18:8
--> $DIR/empty-match.rs:23:12
|
LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^
LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyStruct2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion1` is non-empty
--> $DIR/empty-match.rs:125:20
--> $DIR/empty-match.rs:49:20
|
LL | match_no_arms!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `NonEmptyUnion1` defined here
--> $DIR/empty-match.rs:21:7
--> $DIR/empty-match.rs:24:11
|
LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^
LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: type `NonEmptyUnion2` is non-empty
--> $DIR/empty-match.rs:127:20
--> $DIR/empty-match.rs:50:20
|
LL | match_no_arms!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: `NonEmptyUnion2` defined here
--> $DIR/empty-match.rs:26:7
--> $DIR/empty-match.rs:27:11
|
LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^
LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^
= note: the matched value is of type `NonEmptyUnion2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern
error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:129:20
--> $DIR/empty-match.rs:51:20
|
LL | match_no_arms!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:32:6
--> $DIR/empty-match.rs:31:10
|
LL | enum NonEmptyEnum1 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
LL | enum NonEmptyEnum1 {
| ^^^^^^^^^^^^^
LL | Foo(bool),
| --- not covered
= note: the matched value is of type `NonEmptyEnum1`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern
error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:132:20
--> $DIR/empty-match.rs:52:20
|
LL | match_no_arms!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:39:6
--> $DIR/empty-match.rs:34:10
|
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
...
LL | Bar,
| --- not covered
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
LL | Foo(bool),
| --- not covered
LL | Bar,
| --- not covered
= note: the matched value is of type `NonEmptyEnum2`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
error[E0004]: non-exhaustive patterns: `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
--> $DIR/empty-match.rs:135:20
--> $DIR/empty-match.rs:53:20
|
LL | match_no_arms!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:49:6
--> $DIR/empty-match.rs:38:10
|
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
...
LL | V1, V2, V3, V4, V5,
| -- -- -- -- -- not covered
| | | | |
| | | | not covered
| | | not covered
| | not covered
| not covered
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
LL | V1,
| -- not covered
LL | V2,
| -- not covered
LL | V3,
| -- not covered
LL | V4,
| -- not covered
LL | V5,
| -- not covered
= note: the matched value is of type `NonEmptyEnum5`
= help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or multiple match arms
error[E0004]: non-exhaustive patterns: `_` not covered
--> $DIR/empty-match.rs:139:24
--> $DIR/empty-match.rs:55:24
|
LL | match_guarded_arm!(0u8);
| ^^^ pattern `_` not covered
@ -188,161 +131,159 @@ LL | match_guarded_arm!(0u8);
= 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 => {},
LL + _ => todo!()
LL ~ _ if false => {},
LL + _ => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyStruct1` not covered
--> $DIR/empty-match.rs:144:24
--> $DIR/empty-match.rs:56:24
|
LL | match_guarded_arm!(NonEmptyStruct1);
| ^^^^^^^^^^^^^^^ pattern `NonEmptyStruct1` not covered
|
note: `NonEmptyStruct1` defined here
--> $DIR/empty-match.rs:15:8
--> $DIR/empty-match.rs:22:12
|
LL | struct NonEmptyStruct1;
| ^^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyStruct1 => todo!()
LL ~ _ if false => {},
LL + NonEmptyStruct1 => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyStruct2(_)` not covered
--> $DIR/empty-match.rs:149:24
--> $DIR/empty-match.rs:57:24
|
LL | match_guarded_arm!(NonEmptyStruct2(true));
| ^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyStruct2(_)` not covered
|
note: `NonEmptyStruct2` defined here
--> $DIR/empty-match.rs:18:8
--> $DIR/empty-match.rs:23:12
|
LL | struct NonEmptyStruct2(bool);
| ^^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyStruct2(_) => todo!()
LL ~ _ if false => {},
LL + NonEmptyStruct2(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyUnion1 { .. }` not covered
--> $DIR/empty-match.rs:154:24
--> $DIR/empty-match.rs:58:24
|
LL | match_guarded_arm!((NonEmptyUnion1 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion1 { .. }` not covered
|
note: `NonEmptyUnion1` defined here
--> $DIR/empty-match.rs:21:7
--> $DIR/empty-match.rs:24:11
|
LL | union NonEmptyUnion1 {
| ^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyUnion1 { .. } => todo!()
LL ~ _ if false => {},
LL + NonEmptyUnion1 { .. } => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyUnion2 { .. }` not covered
--> $DIR/empty-match.rs:159:24
--> $DIR/empty-match.rs:59:24
|
LL | match_guarded_arm!((NonEmptyUnion2 { foo: () }));
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyUnion2 { .. }` not covered
|
note: `NonEmptyUnion2` defined here
--> $DIR/empty-match.rs:26:7
--> $DIR/empty-match.rs:27:11
|
LL | union NonEmptyUnion2 {
| ^^^^^^^^^^^^^^
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 => {},
LL + NonEmptyUnion2 { .. } => todo!()
LL ~ _ if false => {},
LL + NonEmptyUnion2 { .. } => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyEnum1::Foo(_)` not covered
--> $DIR/empty-match.rs:164:24
--> $DIR/empty-match.rs:60:24
|
LL | match_guarded_arm!(NonEmptyEnum1::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `NonEmptyEnum1::Foo(_)` not covered
|
note: `NonEmptyEnum1` defined here
--> $DIR/empty-match.rs:32:6
--> $DIR/empty-match.rs:31:10
|
LL | enum NonEmptyEnum1 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
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 => {},
LL + NonEmptyEnum1::Foo(_) => todo!()
LL ~ _ if false => {},
LL + NonEmptyEnum1::Foo(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
--> $DIR/empty-match.rs:169:24
--> $DIR/empty-match.rs:61:24
|
LL | match_guarded_arm!(NonEmptyEnum2::Foo(true));
| ^^^^^^^^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
|
note: `NonEmptyEnum2` defined here
--> $DIR/empty-match.rs:39:6
--> $DIR/empty-match.rs:34:10
|
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
...
LL | Foo(bool),
| --- not covered
...
LL | Bar,
| --- not covered
LL | enum NonEmptyEnum2 {
| ^^^^^^^^^^^^^
LL | Foo(bool),
| --- not covered
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 => {},
LL + NonEmptyEnum2::Foo(_) | NonEmptyEnum2::Bar => todo!()
LL ~ _ if false => {},
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:174:24
--> $DIR/empty-match.rs:62:24
|
LL | match_guarded_arm!(NonEmptyEnum5::V1);
| ^^^^^^^^^^^^^^^^^ patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
|
note: `NonEmptyEnum5` defined here
--> $DIR/empty-match.rs:49:6
--> $DIR/empty-match.rs:38:10
|
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
...
LL | V1, V2, V3, V4, V5,
| -- -- -- -- -- not covered
| | | | |
| | | | not covered
| | | not covered
| | not covered
| not covered
LL | enum NonEmptyEnum5 {
| ^^^^^^^^^^^^^
LL | V1,
| -- not covered
LL | V2,
| -- not covered
LL | V3,
| -- not covered
LL | V4,
| -- not covered
LL | V5,
| -- not covered
= 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 => {},
LL + _ => todo!()
LL ~ _ if false => {},
LL + _ => todo!()
|
error: aborting due to 23 previous errors
error: aborting due to 16 previous errors
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.
For more information about this error, try `rustc --explain E0004`.

View File

@ -1,179 +1,65 @@
// aux-build:empty.rs
// revisions: normal exhaustive_patterns
//
// This tests a match with no arms on various types.
#![feature(never_type)]
#![feature(never_type_fallback)]
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
#![deny(unreachable_patterns)]
//~^ NOTE the lint level is defined here
extern crate empty;
enum EmptyEnum {}
struct NonEmptyStruct1;
//~^ NOTE `NonEmptyStruct1` defined here
//~| NOTE `NonEmptyStruct1` defined here
struct NonEmptyStruct2(bool);
//~^ NOTE `NonEmptyStruct2` defined here
//~| NOTE `NonEmptyStruct2` defined here
union NonEmptyUnion1 {
//~^ NOTE `NonEmptyUnion1` defined here
//~| NOTE `NonEmptyUnion1` defined here
foo: (),
}
union NonEmptyUnion2 {
//~^ NOTE `NonEmptyUnion2` defined here
//~| NOTE `NonEmptyUnion2` defined here
foo: (),
bar: (),
}
enum NonEmptyEnum1 {
//~^ NOTE `NonEmptyEnum1` defined here
//~| NOTE `NonEmptyEnum1` defined here
Foo(bool),
//~^ NOTE not covered
//~| NOTE not covered
}
enum NonEmptyEnum2 {
//~^ NOTE `NonEmptyEnum2` defined here
//~| NOTE `NonEmptyEnum2` defined here
Foo(bool),
//~^ NOTE not covered
//~| NOTE not covered
Bar,
//~^ NOTE not covered
//~| NOTE not covered
}
enum NonEmptyEnum5 {
//~^ NOTE `NonEmptyEnum5` defined here
//~| NOTE `NonEmptyEnum5` defined here
V1, V2, V3, V4, V5,
//~^ NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
//~| NOTE not covered
}
fn empty_enum(x: EmptyEnum) {
match x {} // ok
match x {
_ => {}, //~ ERROR unreachable pattern
fn nonempty() {
macro_rules! match_no_arms {
($e:expr) => {
match $e {}
};
}
match x {
_ if false => {}, //~ ERROR unreachable pattern
macro_rules! match_guarded_arm {
($e:expr) => {
match $e {
_ if false => {}
}
};
}
}
fn empty_foreign_enum(x: empty::EmptyForeignEnum) {
match x {} // ok
match x {
_ => {}, //~ ERROR unreachable pattern
struct NonEmptyStruct1;
struct NonEmptyStruct2(bool);
union NonEmptyUnion1 {
foo: (),
}
match x {
_ if false => {}, //~ ERROR unreachable pattern
union NonEmptyUnion2 {
foo: (),
bar: !,
}
}
fn empty_foreign_enum_private(x: Option<empty::SecretlyUninhabitedForeignStruct>) {
let None = x;
//~^ ERROR refutable pattern in local binding
//~| NOTE `let` bindings require an "irrefutable pattern"
//~| NOTE for more information, visit
//~| NOTE the matched value is of type
//~| NOTE pattern `Some(_)` not covered
//[exhaustive_patterns]~| NOTE currently uninhabited, but this variant contains private fields
}
fn never(x: !) {
match x {} // ok
match x {
_ => {}, //~ ERROR unreachable pattern
enum NonEmptyEnum1 {
Foo(bool),
}
match x {
_ if false => {}, //~ ERROR unreachable pattern
enum NonEmptyEnum2 {
Foo(bool),
Bar,
}
enum NonEmptyEnum5 {
V1,
V2,
V3,
V4,
V5,
}
}
macro_rules! match_no_arms {
($e:expr) => {
match $e {}
};
}
macro_rules! match_guarded_arm {
($e:expr) => {
match $e {
_ if false => {}
}
};
}
fn main() {
match_no_arms!(0u8); //~ ERROR type `u8` is non-empty
//~| NOTE the matched value is of type
match_no_arms!(NonEmptyStruct1); //~ ERROR type `NonEmptyStruct1` is non-empty
//~| NOTE the matched value is of type
match_no_arms!(NonEmptyStruct2(true)); //~ ERROR type `NonEmptyStruct2` is non-empty
//~| NOTE the matched value is of type
match_no_arms!((NonEmptyUnion1 { foo: () })); //~ ERROR type `NonEmptyUnion1` is non-empty
//~| NOTE the matched value is of type
match_no_arms!((NonEmptyUnion2 { foo: () })); //~ ERROR type `NonEmptyUnion2` is non-empty
//~| NOTE the matched value is of type
match_no_arms!(NonEmptyEnum1::Foo(true)); //~ ERROR `NonEmptyEnum1::Foo(_)` not covered
//~| NOTE pattern `NonEmptyEnum1::Foo(_)` not covered
//~| NOTE the matched value is of type
match_no_arms!(NonEmptyEnum2::Foo(true)); //~ ERROR `NonEmptyEnum2::Foo(_)` and `NonEmptyEnum2::Bar` not covered
//~| NOTE patterns `NonEmptyEnum2::Foo(_)` and
//~| NOTE the matched value is of type
match_no_arms!(NonEmptyEnum5::V1); //~ ERROR `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`, `NonEmptyEnum5::V3` and 2 more not covered
//~| NOTE patterns `NonEmptyEnum5::V1`, `NonEmptyEnum5::V2`
//~| NOTE the matched value is of type
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!
}
fn main() {}

View File

@ -0,0 +1,776 @@
error: unreachable pattern
--> $DIR/empty-types.rs:47:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-types.rs:13:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:50:9
|
LL | _x => {}
| ^^
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
--> $DIR/empty-types.rs:54:11
|
LL | match ref_never {}
| ^^^^^^^^^
|
= note: the matched value is of type `&!`
= note: references are always considered inhabited
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match ref_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:62:9
|
LL | &_ => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:69:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:76:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:79:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:83:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `Ok(_)` not covered
--> $DIR/empty-types.rs:87:11
|
LL | match res_u32_never {}
| ^^^^^^^^^^^^^ pattern `Ok(_)` not covered
|
note: `Result<u32, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, !>`
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 res_u32_never {
LL + Ok(_) => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:95:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:100:9
|
LL | Err(_) => {}
| ^^^^^^
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:97:11
|
LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
|
note: `Result<u32, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, !>`
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 ~ Err(_) => {},
LL ~ Ok(1_u32..=u32::MAX) => todo!()
|
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:104:9
|
LL | let Ok(_x) = res_u32_never.as_ref();
| ^^^^^^ pattern `Err(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `Result<&u32, &!>`
help: you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
| ++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:115:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:119:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:122:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:123:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:126:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:127:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:136:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:139:13
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:148:13
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:152:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:158:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:167:13
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:171:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:175:13
|
LL | _a => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:180:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:185:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:204:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:209:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:214:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:219:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:225:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:234:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:239:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:245:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:251:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:256:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:262:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:268:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:284:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:287:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:290:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:291:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:296:9
|
LL | &_ => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:299:9
|
LL | Uninit { value: _ } => {}
| ^^^^^^^^^^^^^^^^^^^
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
--> $DIR/empty-types.rs:323:11
|
LL | match slice_never {}
| ^^^^^^^^^^^
|
= note: the matched value is of type `&[!]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match slice_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:331:9
|
LL | [_] => {}
| ^^^
error: unreachable pattern
--> $DIR/empty-types.rs:332:9
|
LL | [_, _, ..] => {}
| ^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:337:9
|
LL | [_, _, _, ..] => {}
| ^^^^^^^^^^^^^
error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:334:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered
|
= note: the matched value is of type `&[!]`
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 | [_, _, _, ..] => {}, &[] => todo!()
| ++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:341:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:345:9
|
LL | _x => {}
| ^^
error[E0004]: non-exhaustive patterns: `&[]` not covered
--> $DIR/empty-types.rs:347:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[]` not covered
|
= note: the matched value is of type `&[!]`
= 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 => {},
LL + &[] => todo!()
|
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
--> $DIR/empty-types.rs:353:11
|
LL | match *slice_never {}
| ^^^^^^^^^^^^
|
= note: the matched value is of type `[!]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *slice_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:363:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:366:9
|
LL | [_, _, _] => {}
| ^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:369:9
|
LL | [_, ..] => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:375:9
|
LL | &[_, _, _] => {}
| ^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:379:9
|
LL | &[_x, _, _] => {}
| ^^^^^^^^^^^
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:383:11
|
LL | match array_0_never {}
| ^^^^^^^^^^^^^
|
= note: the matched value is of type `[!; 0]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match array_0_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:390:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:392:11
|
LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered
|
= note: the matched value is of type `[!; 0]`
= 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 => {},
LL + [] => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:411:9
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:416:9
|
LL | Some(_a) => {}
| ^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:421:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:426:9
|
LL | _a => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:436:9
|
LL | &_ => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:444:9
|
LL | &_a => {}
| ^^^
error: unreachable pattern
--> $DIR/empty-types.rs:453:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:458:9
|
LL | _a => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:463:9
|
LL | &_ => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:468:9
|
LL | &_a => {}
| ^^^
error: unreachable pattern
--> $DIR/empty-types.rs:475:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:479:9
|
LL | _a => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:485:9
|
LL | ref _a => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:494:9
|
LL | Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:499:9
|
LL | Some(_a) => {}
| ^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:504:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:509:9
|
LL | _a => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:514:14
|
LL | _a @ Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:521:9
|
LL | ref _a => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:526:18
|
LL | ref _a @ Some(_) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:531:18
|
LL | ref _a @ Some(_b) => {}
| ^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:538:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:542:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:544:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:549:9
|
LL | Ok(_a) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:553:9
|
LL | Ok(_a) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:555:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:559:9
|
LL | Ok(_a) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:561:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:569:9
|
LL | (_, _) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:573:9
|
LL | (_x, _) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:577:9
|
LL | (_, _x) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:581:9
|
LL | (0, _x) => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:583:9
|
LL | (1.., _) => {}
| ^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:598:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:601:9
|
LL | _x => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:604:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:607:9
|
LL | _x if false => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:613:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:615:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:622:9
|
LL | _a if false => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:624:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:629:9
|
LL | _a if false => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:634:9
|
LL | &_a if false => {}
| ^^^
error: unreachable pattern
--> $DIR/empty-types.rs:641:9
|
LL | Ok(_x) if false => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:643:9
|
LL | Ok(_) => {}
| ^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:645:9
|
LL | Err(_) => {}
| ^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:650:9
|
LL | (_, _x) if false => {}
| ^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:652:9
|
LL | (_, _) => {}
| ^^^^^^
error: aborting due to 113 previous errors
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.

View File

@ -0,0 +1,721 @@
error: unreachable pattern
--> $DIR/empty-types.rs:47:9
|
LL | _ => {}
| ^
|
note: the lint level is defined here
--> $DIR/empty-types.rs:13:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/empty-types.rs:50:9
|
LL | _x => {}
| ^^
error[E0004]: non-exhaustive patterns: type `&!` is non-empty
--> $DIR/empty-types.rs:54:11
|
LL | match ref_never {}
| ^^^^^^^^^
|
= note: the matched value is of type `&!`
= note: references are always considered inhabited
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match ref_never {
LL + _ => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:66:11
|
LL | match tuple_half_never {}
| ^^^^^^^^^^^^^^^^
|
= note: the matched value is of type `(u32, !)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match tuple_half_never {
LL + _ => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
--> $DIR/empty-types.rs:73:11
|
LL | match tuple_never {}
| ^^^^^^^^^^^
|
= note: the matched value is of type `(!, !)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match tuple_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:83:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
--> $DIR/empty-types.rs:87:11
|
LL | match res_u32_never {}
| ^^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
|
note: `Result<u32, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, !>`
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 ~ match res_u32_never {
LL + Ok(_) | Err(_) => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:89:11
|
LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Err(_)` not covered
|
note: `Result<u32, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, !>`
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 ~ Ok(_) => {},
LL + Err(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `Ok(1_u32..=u32::MAX)` not covered
--> $DIR/empty-types.rs:97:11
|
LL | match res_u32_never {
| ^^^^^^^^^^^^^ pattern `Ok(1_u32..=u32::MAX)` not covered
|
note: `Result<u32, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<u32, !>`
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 ~ Err(_) => {},
LL ~ Ok(1_u32..=u32::MAX) => todo!()
|
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:102:9
|
LL | let Ok(_x) = res_u32_never;
| ^^^^^^ pattern `Err(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `Result<u32, !>`
help: you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(_x) = res_u32_never else { todo!() };
| ++++++++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:104:9
|
LL | let Ok(_x) = res_u32_never.as_ref();
| ^^^^^^ pattern `Err(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `Result<&u32, &!>`
help: you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(_x) = res_u32_never.as_ref() else { todo!() };
| ++++++++++++++++
error[E0005]: refutable pattern in local binding
--> $DIR/empty-types.rs:108:9
|
LL | let Ok(_x) = &res_u32_never;
| ^^^^^^ pattern `&Err(_)` not covered
|
= note: `let` bindings require an "irrefutable pattern", like a `struct` or an `enum` with only one variant
= note: for more information, visit https://doc.rust-lang.org/book/ch18-02-refutability.html
= note: the matched value is of type `&Result<u32, !>`
help: you might want to use `let else` to handle the variant that isn't matched
|
LL | let Ok(_x) = &res_u32_never else { todo!() };
| ++++++++++++++++
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
--> $DIR/empty-types.rs:112:11
|
LL | match result_never {}
| ^^^^^^^^^^^^ patterns `Ok(_)` and `Err(_)` not covered
|
note: `Result<!, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<!, !>`
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 ~ match result_never {
LL + Ok(_) | Err(_) => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:117:11
|
LL | match result_never {
| ^^^^^^^^^^^^ pattern `Err(_)` not covered
|
note: `Result<!, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<!, !>`
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 | Ok(_) => {}, Err(_) => todo!()
| +++++++++++++++++++
error: unreachable pattern
--> $DIR/empty-types.rs:136:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:139:13
|
LL | _ if false => {}
| ^
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:142:15
|
LL | match opt_void {
| ^^^^^^^^ pattern `Some(_)` not covered
|
note: `Option<Void>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<Void>`
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 ~ None => {},
LL + Some(_) => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:158:13
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:161:15
|
LL | match *ref_opt_void {
| ^^^^^^^^^^^^^ pattern `Some(_)` not covered
|
note: `Option<Void>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<Void>`
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 ~ None => {},
LL + Some(_) => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:180:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:185:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:204:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:209:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:214:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:219:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:225:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:234:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:239:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:245:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:251:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:256:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:262:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:268:13
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:284:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:312:11
|
LL | match *x {}
| ^^
|
= note: the matched value is of type `(u32, !)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *x {
LL + _ => todo!(),
LL ~ }
|
error[E0004]: non-exhaustive patterns: type `(!, !)` is non-empty
--> $DIR/empty-types.rs:314:11
|
LL | match *x {}
| ^^
|
= note: the matched value is of type `(!, !)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *x {
LL + _ => todo!(),
LL ~ }
|
error[E0004]: non-exhaustive patterns: `Ok(_)` and `Err(_)` not covered
--> $DIR/empty-types.rs:316:11
|
LL | match *x {}
| ^^ patterns `Ok(_)` and `Err(_)` not covered
|
note: `Result<!, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<!, !>`
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 ~ match *x {
LL + Ok(_) | Err(_) => todo!(),
LL ~ }
|
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
--> $DIR/empty-types.rs:318:11
|
LL | match *x {}
| ^^
|
= note: the matched value is of type `[!; 3]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *x {
LL + _ => todo!(),
LL ~ }
|
error[E0004]: non-exhaustive patterns: type `&[!]` is non-empty
--> $DIR/empty-types.rs:323:11
|
LL | match slice_never {}
| ^^^^^^^^^^^
|
= note: the matched value is of type `&[!]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match slice_never {
LL + _ => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
--> $DIR/empty-types.rs:325:11
|
LL | match slice_never {
| ^^^^^^^^^^^ pattern `&[_, ..]` not covered
|
= note: the matched value is of type `&[!]`
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 ~ [] => {},
LL + &[_, ..] => todo!()
|
error[E0004]: non-exhaustive patterns: `&[]`, `&[_]` and `&[_, _]` not covered
--> $DIR/empty-types.rs:334:11
|
LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]`, `&[_]` and `&[_, _]` not covered
|
= note: the matched value is of type `&[!]`
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 | [_, _, _, ..] => {}, &[] | &[_] | &[_, _] => todo!()
| +++++++++++++++++++++++++++++++++
error[E0004]: non-exhaustive patterns: `&[]` and `&[_, ..]` not covered
--> $DIR/empty-types.rs:347:11
|
LL | match slice_never {
| ^^^^^^^^^^^ patterns `&[]` and `&[_, ..]` not covered
|
= note: the matched value is of type `&[!]`
= 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 => {},
LL + &[] | &[_, ..] => todo!()
|
error[E0004]: non-exhaustive patterns: type `[!]` is non-empty
--> $DIR/empty-types.rs:353:11
|
LL | match *slice_never {}
| ^^^^^^^^^^^^
|
= note: the matched value is of type `[!]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *slice_never {
LL + _ => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: type `[!; 3]` is non-empty
--> $DIR/empty-types.rs:360:11
|
LL | match array_3_never {}
| ^^^^^^^^^^^^^
|
= note: the matched value is of type `[!; 3]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match array_3_never {
LL + _ => todo!(),
LL + }
|
error[E0004]: non-exhaustive patterns: type `[!; 0]` is non-empty
--> $DIR/empty-types.rs:383:11
|
LL | match array_0_never {}
| ^^^^^^^^^^^^^
|
= note: the matched value is of type `[!; 0]`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match array_0_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:390:9
|
LL | _ => {}
| ^
error[E0004]: non-exhaustive patterns: `[]` not covered
--> $DIR/empty-types.rs:392:11
|
LL | match array_0_never {
| ^^^^^^^^^^^^^ pattern `[]` not covered
|
= note: the matched value is of type `[!; 0]`
= 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 => {},
LL + [] => todo!()
|
error[E0004]: non-exhaustive patterns: `&Some(_)` not covered
--> $DIR/empty-types.rs:446:11
|
LL | match ref_opt_never {
| ^^^^^^^^^^^^^ pattern `&Some(_)` not covered
|
note: `Option<!>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `&Option<!>`
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 ~ &None => {},
LL + &Some(_) => todo!()
|
error: unreachable pattern
--> $DIR/empty-types.rs:475:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:479:9
|
LL | _a => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:485:9
|
LL | ref _a => {}
| ^^^^^^
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:487:11
|
LL | match *ref_opt_never {
| ^^^^^^^^^^^^^^ pattern `Some(_)` not covered
|
note: `Option<!>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<!>`
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 ~ None => {},
LL + Some(_) => todo!()
|
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:535:11
|
LL | match *ref_res_never {
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
|
note: `Result<!, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<!, !>`
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 | Ok(_) => {}, Err(_) => todo!()
| +++++++++++++++++++
error[E0004]: non-exhaustive patterns: `Err(_)` not covered
--> $DIR/empty-types.rs:546:11
|
LL | match *ref_res_never {
| ^^^^^^^^^^^^^^ pattern `Err(_)` not covered
|
note: `Result<!, !>` defined here
--> $SRC_DIR/core/src/result.rs:LL:COL
::: $SRC_DIR/core/src/result.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Result<!, !>`
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 | Ok(_a) => {}, Err(_) => todo!()
| +++++++++++++++++++
error[E0004]: non-exhaustive patterns: type `(u32, !)` is non-empty
--> $DIR/empty-types.rs:565:11
|
LL | match *ref_tuple_half_never {}
| ^^^^^^^^^^^^^^^^^^^^^
|
= note: the matched value is of type `(u32, !)`
help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown
|
LL ~ match *ref_tuple_half_never {
LL + _ => todo!(),
LL + }
|
error: unreachable pattern
--> $DIR/empty-types.rs:598:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:601:9
|
LL | _x => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:604:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:607:9
|
LL | _x if false => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:613:9
|
LL | _ if false => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:615:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:622:9
|
LL | _a if false => {}
| ^^
error: unreachable pattern
--> $DIR/empty-types.rs:624:9
|
LL | _ => {}
| ^
error: unreachable pattern
--> $DIR/empty-types.rs:629:9
|
LL | _a if false => {}
| ^^
error[E0004]: non-exhaustive patterns: `&_` not covered
--> $DIR/empty-types.rs:631:11
|
LL | match ref_never {
| ^^^^^^^^^ pattern `&_` not covered
|
= note: the matched value is of type `&!`
= note: references are always considered inhabited
= 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 | &_a if false => {}, &_ => todo!()
| +++++++++++++++
error[E0004]: non-exhaustive patterns: `Some(_)` not covered
--> $DIR/empty-types.rs:659:11
|
LL | match *x {
| ^^ pattern `Some(_)` not covered
|
note: `Option<Result<!, !>>` defined here
--> $SRC_DIR/core/src/option.rs:LL:COL
::: $SRC_DIR/core/src/option.rs:LL:COL
|
= note: not covered
= note: the matched value is of type `Option<Result<!, !>>`
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 ~ None => {},
LL + Some(_) => todo!()
|
error: aborting due to 66 previous errors
Some errors have detailed explanations: E0004, E0005.
For more information about an error, try `rustc --explain E0004`.

View File

@ -0,0 +1,665 @@
// revisions: normal exhaustive_patterns
//
// This tests correct handling of empty types in exhaustiveness checking.
//
// Most of the subtlety of this file happens in scrutinee places which are not required to hold
// valid data, namely dereferences and union field accesses. In these cases, empty arms can
// generally not be omitted, except with `exhaustive_patterns` which ignores this..
#![feature(never_type)]
// This feature is useful to avoid `!` falling back to `()` all the time.
#![feature(never_type_fallback)]
#![cfg_attr(exhaustive_patterns, feature(exhaustive_patterns))]
#![allow(dead_code, unreachable_code)]
#![deny(unreachable_patterns)]
#[derive(Copy, Clone)]
enum Void {}
/// A bunch of never situations that can't be normally constructed.
#[derive(Copy, Clone)]
struct NeverBundle {
never: !,
void: Void,
tuple_never: (!, !),
tuple_half_never: (u32, !),
array_3_never: [!; 3],
result_never: Result<!, !>,
}
/// A simplified `MaybeUninit` to test union field accesses.
#[derive(Copy, Clone)]
union Uninit<T: Copy> {
value: T,
uninit: (),
}
impl<T: Copy> Uninit<T> {
fn new() -> Self {
Self { uninit: () }
}
}
// Simple cases of omitting empty arms, all with known_valid scrutinees.
fn basic(x: NeverBundle) {
let never: ! = x.never;
match never {}
match never {
_ => {} //~ ERROR unreachable pattern
}
match never {
_x => {} //~ ERROR unreachable pattern
}
let ref_never: &! = &x.never;
match ref_never {}
//~^ ERROR non-empty
match ref_never {
// useful, reachable
_ => {}
}
match ref_never {
// useful, reachable
&_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let tuple_half_never: (u32, !) = x.tuple_half_never;
match tuple_half_never {}
//[normal]~^ ERROR non-empty
match tuple_half_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let tuple_never: (!, !) = x.tuple_never;
match tuple_never {}
//[normal]~^ ERROR non-empty
match tuple_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match tuple_never.0 {}
match tuple_never.0 {
_ => {} //~ ERROR unreachable pattern
}
let res_u32_never: Result<u32, !> = Ok(0);
match res_u32_never {}
//~^ ERROR non-exhaustive
match res_u32_never {
//[normal]~^ ERROR non-exhaustive
Ok(_) => {}
}
match res_u32_never {
Ok(_) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match res_u32_never {
//~^ ERROR non-exhaustive
Ok(0) => {}
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let Ok(_x) = res_u32_never;
//[normal]~^ ERROR refutable
let Ok(_x) = res_u32_never.as_ref();
//~^ ERROR refutable
// Non-obvious difference: here there's an implicit dereference in the patterns, which makes the
// inner place !known_valid. `exhaustive_patterns` ignores this.
let Ok(_x) = &res_u32_never;
//[normal]~^ ERROR refutable
let result_never: Result<!, !> = x.result_never;
match result_never {}
//[normal]~^ ERROR non-exhaustive
match result_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
//[normal]~^ ERROR non-exhaustive
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
}
// Check for a few cases that `Void` and `!` are treated the same.
fn void_same_as_never(x: NeverBundle) {
unsafe {
match x.void {}
match x.void {
_ => {} //~ ERROR unreachable pattern
}
match x.void {
_ if false => {} //~ ERROR unreachable pattern
}
let opt_void: Option<Void> = None;
match opt_void {
//[normal]~^ ERROR non-exhaustive
None => {}
}
match opt_void {
None => {}
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_void {
None => {}
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let ref_void: &Void = &x.void;
match *ref_void {}
match *ref_void {
_ => {} //~ ERROR unreachable pattern
}
let ref_opt_void: &Option<Void> = &None;
match *ref_opt_void {
//[normal]~^ ERROR non-exhaustive
None => {}
}
match *ref_opt_void {
None => {}
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_void {
None => {}
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_void {
None => {}
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let union_void = Uninit::<Void>::new();
match union_void.value {}
match union_void.value {
_ => {} //~ ERROR unreachable pattern
}
let ptr_void: *const Void = std::ptr::null();
match *ptr_void {}
match *ptr_void {
_ => {} //~ ERROR unreachable pattern
}
}
}
// Test if we correctly determine validity from the scrutinee expression.
fn invalid_scrutinees(x: NeverBundle) {
let ptr_never: *const ! = std::ptr::null();
let never: ! = x.never;
let ref_never: &! = &never;
struct NestedNeverBundle(NeverBundle);
let nested_x = NestedNeverBundle(x);
// These should be considered known_valid and warn unreachable.
unsafe {
// A plain `!` value must be valid.
match never {}
match never {
_ => {} //~ ERROR unreachable pattern
}
// A block forces a copy.
match { *ptr_never } {}
match { *ptr_never } {
_ => {} //~ ERROR unreachable pattern
}
// This field access is not a dereference.
match x.never {}
match x.never {
_ => {} //~ ERROR unreachable pattern
}
// This nested field access is not a dereference.
match nested_x.0.never {}
match nested_x.0.never {
_ => {} //~ ERROR unreachable pattern
}
// Indexing is like a field access. This one does not access behind a reference.
let array_3_never: [!; 3] = x.array_3_never;
match array_3_never[0] {}
match array_3_never[0] {
_ => {} //~ ERROR unreachable pattern
}
}
// These should be considered !known_valid and not warn unreachable.
unsafe {
// A pointer may point to a place with an invalid value.
match *ptr_never {}
match *ptr_never {
_ => {} //~ ERROR unreachable pattern
}
// A reference may point to a place with an invalid value.
match *ref_never {}
match *ref_never {
_ => {} //~ ERROR unreachable pattern
}
// This field access is a dereference.
let ref_x: &NeverBundle = &x;
match ref_x.never {}
match ref_x.never {
_ => {} //~ ERROR unreachable pattern
}
// This nested field access is a dereference.
let nested_ref_x: &NestedNeverBundle = &nested_x;
match nested_ref_x.0.never {}
match nested_ref_x.0.never {
_ => {} //~ ERROR unreachable pattern
}
// A cast does not load.
match (*ptr_never as Void) {}
match (*ptr_never as Void) {
_ => {} //~ ERROR unreachable pattern
}
// A union field may contain invalid data.
let union_never = Uninit::<!>::new();
match union_never.value {}
match union_never.value {
_ => {} //~ ERROR unreachable pattern
}
// Indexing is like a field access. This one accesses behind a reference.
let slice_never: &[!] = &[];
match slice_never[0] {}
match slice_never[0] {
_ => {} //~ ERROR unreachable pattern
}
}
}
// Test we correctly track validity as we dig into patterns. Validity changes when we go under a
// dereference or a union field access, and it otherwise preserved.
fn nested_validity_tracking(bundle: NeverBundle) {
let never: ! = bundle.never;
let ref_never: &! = &never;
let tuple_never: (!, !) = bundle.tuple_never;
let result_never: Result<!, !> = bundle.result_never;
let union_never = Uninit::<!>::new();
// These should be considered known_valid and warn unreachable.
match never {
_ => {} //~ ERROR unreachable pattern
}
match tuple_never {
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match result_never {
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
// These should be considered !known_valid and not warn unreachable.
match ref_never {
&_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match union_never {
Uninit { value: _ } => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
}
// Test we don't allow empty matches on empty types if the scrutinee is `!known_valid`.
fn invalid_empty_match(bundle: NeverBundle) {
// We allow these two for backwards-compability.
let x: &! = &bundle.never;
match *x {}
let x: &Void = &bundle.void;
match *x {}
let x: &(u32, !) = &bundle.tuple_half_never;
match *x {} //[normal]~ ERROR non-exhaustive
let x: &(!, !) = &bundle.tuple_never;
match *x {} //[normal]~ ERROR non-exhaustive
let x: &Result<!, !> = &bundle.result_never;
match *x {} //[normal]~ ERROR non-exhaustive
let x: &[!; 3] = &bundle.array_3_never;
match *x {} //[normal]~ ERROR non-exhaustive
}
fn arrays_and_slices(x: NeverBundle) {
let slice_never: &[!] = &[];
match slice_never {}
//~^ ERROR non-empty
match slice_never {
//[normal]~^ ERROR not covered
[] => {}
}
match slice_never {
[] => {}
[_] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
[_, _, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match slice_never {
//[normal]~^ ERROR `&[]`, `&[_]` and `&[_, _]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
[_, _, _, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match slice_never {
[] => {}
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match slice_never {
[] => {}
_x => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match slice_never {
//[normal]~^ ERROR `&[]` and `&[_, ..]` not covered
//[exhaustive_patterns]~^^ ERROR `&[]` not covered
&[..] if false => {}
}
match *slice_never {}
//~^ ERROR non-empty
match *slice_never {
_ => {}
}
let array_3_never: [!; 3] = x.array_3_never;
match array_3_never {}
//[normal]~^ ERROR non-empty
match array_3_never {
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match array_3_never {
[_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match array_3_never {
[_, ..] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let ref_array_3_never: &[!; 3] = &array_3_never;
match ref_array_3_never {
// useful, reachable
&[_, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match ref_array_3_never {
// useful, !reachable
&[_x, _, _] => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let array_0_never: [!; 0] = [];
match array_0_never {}
//~^ ERROR non-empty
match array_0_never {
[] => {}
}
match array_0_never {
[] => {}
_ => {} //~ ERROR unreachable pattern
}
match array_0_never {
//~^ ERROR `[]` not covered
[..] if false => {}
}
}
// The difference between `_` and `_a` patterns is that `_a` loads the value. In case of an empty
// type, this asserts validity of the value, and thus the binding is unreachable. We don't yet
// distinguish these cases since we don't lint "unreachable" on `useful && !reachable` arms.
// Once/if never patterns are a thing, we can warn that the `_a` cases should be never patterns.
fn bindings(x: NeverBundle) {
let opt_never: Option<!> = None;
let ref_never: &! = &x.never;
let ref_opt_never: &Option<!> = &None;
// On a known_valid place.
match opt_never {
None => {}
// !useful, !reachable
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match opt_never {
None => {}
// !useful, !reachable
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
// The scrutinee is known_valid, but under the `&` isn't anymore.
match ref_never {
// useful, reachable
_ => {}
}
match ref_never {
// useful, reachable
&_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match ref_never {
// useful, reachable
_a => {}
}
match ref_never {
// useful, !reachable
&_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match ref_opt_never {
//[normal]~^ ERROR non-exhaustive
&None => {}
}
match ref_opt_never {
&None => {}
// useful, reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match ref_opt_never {
&None => {}
// useful, reachable
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match ref_opt_never {
&None => {}
// useful, reachable
&_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match ref_opt_never {
&None => {}
// useful, !reachable
&_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
// On a !known_valid place.
match *ref_never {}
match *ref_never {
// useful, reachable
_ => {} //~ ERROR unreachable pattern
}
match *ref_never {
// useful, !reachable
_a => {} //~ ERROR unreachable pattern
}
// This is equivalent to `match ref_never { _a => {} }`. In other words, it asserts validity of
// `ref_never` but says nothing of the data at `*ref_never`.
match *ref_never {
// useful, reachable
ref _a => {} //~ ERROR unreachable pattern
}
match *ref_opt_never {
//[normal]~^ ERROR non-exhaustive
None => {}
}
match *ref_opt_never {
None => {}
// useful, reachable
Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_never {
None => {}
// useful, !reachable
Some(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_never {
None => {}
// useful, reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_never {
None => {}
// useful, !reachable
_a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_never {
None => {}
// useful, !reachable
_a @ Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
// This is equivalent to `match ref_opt_never { None => {}, _a => {} }`. In other words, it
// asserts validity of `ref_opt_never` but says nothing of the data at `*ref_opt_never`.
match *ref_opt_never {
None => {}
// useful, reachable
ref _a => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_never {
None => {}
// useful, reachable
ref _a @ Some(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_opt_never {
None => {}
// useful, !reachable
ref _a @ Some(_b) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let ref_res_never: &Result<!, !> = &x.result_never;
match *ref_res_never {
//[normal]~^ ERROR non-exhaustive
// useful, reachable
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_res_never {
// useful, reachable
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
// useful, reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_res_never {
//[normal]~^ ERROR non-exhaustive
// useful, !reachable
Ok(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_res_never {
// useful, !reachable
Ok(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
// useful, reachable
_ => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_res_never {
// useful, !reachable
Ok(_a) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
// useful, reachable
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let ref_tuple_half_never: &(u32, !) = &x.tuple_half_never;
match *ref_tuple_half_never {}
//[normal]~^ ERROR non-empty
match *ref_tuple_half_never {
// useful, reachable
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_tuple_half_never {
// useful, reachable
(_x, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_tuple_half_never {
// useful, !reachable
(_, _x) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
match *ref_tuple_half_never {
// useful, !reachable
(0, _x) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
// useful, reachable
(1.., _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
}
// When we execute the condition for a guard we loads from all bindings. This asserts validity at
// all places with bindings. Surprisingly this can make subsequent arms unreachable. We choose to
// not detect this in exhaustiveness because this is rather subtle. With never patterns, we would
// recommend using a never pattern instead.
fn guards_and_validity(x: NeverBundle) {
let never: ! = x.never;
let ref_never: &! = &never;
// Basic guard behavior when known_valid.
match never {}
match never {
_ => {} //~ ERROR unreachable pattern
}
match never {
_x => {} //~ ERROR unreachable pattern
}
match never {
_ if false => {} //~ ERROR unreachable pattern
}
match never {
_x if false => {} //~ ERROR unreachable pattern
}
// If the pattern under the guard doesn't load, all is normal.
match *ref_never {
// useful, reachable
_ if false => {} //~ ERROR unreachable pattern
// useful, reachable
_ => {} //~ ERROR unreachable pattern
}
// Now the madness commences. The guard caused a load of the value thus asserting validity. So
// there's no invalid value for `_` to catch. So the second pattern is unreachable despite the
// guard not being taken.
match *ref_never {
// useful, !reachable
_a if false => {} //~ ERROR unreachable pattern
// !useful, !reachable
_ => {} //~ ERROR unreachable pattern
}
// The above still applies to the implicit `_` pattern used for exhaustiveness.
match *ref_never {
// useful, !reachable
_a if false => {} //~ ERROR unreachable pattern
}
match ref_never {
//[normal]~^ ERROR non-exhaustive
// useful, !reachable
&_a if false => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
// Same but with subpatterns.
let ref_result_never: &Result<!, !> = &x.result_never;
match *ref_result_never {
// useful, !reachable
Ok(_x) if false => {} //[exhaustive_patterns]~ ERROR unreachable pattern
// !useful, !reachable
Ok(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
// useful, !reachable
Err(_) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
let ref_tuple_never: &(!, !) = &x.tuple_never;
match *ref_tuple_never {
// useful, !reachable
(_, _x) if false => {} //[exhaustive_patterns]~ ERROR unreachable pattern
// !useful, !reachable
(_, _) => {} //[exhaustive_patterns]~ ERROR unreachable pattern
}
}
fn diagnostics_subtlety(x: NeverBundle) {
// Regression test for diagnostics: don't report `Some(Ok(_))` and `Some(Err(_))`.
let x: &Option<Result<!, !>> = &None;
match *x {
//[normal]~^ ERROR `Some(_)` not covered
None => {}
}
}
fn main() {}

View File

@ -1,8 +1,6 @@
#![feature(box_patterns)]
#![feature(never_type)]
#![feature(exhaustive_patterns)]
#![deny(unreachable_patterns)]
mod foo {
@ -23,22 +21,22 @@ fn main() {
let x: &[!] = &[];
match x {
&[] => (),
&[..] => (), //~ ERROR unreachable pattern
&[] => (),
&[..] => (), //~ ERROR unreachable pattern
};
let x: Result<Box<NotSoSecretlyEmpty>, &[Result<!, !>]> = Err(&[]);
match x {
Ok(box _) => (), //~ ERROR unreachable pattern
Ok(box _) => (), //~ ERROR unreachable pattern
Err(&[]) => (),
Err(&[..]) => (), //~ ERROR unreachable pattern
Err(&[..]) => (), //~ ERROR unreachable pattern
}
let x: Result<foo::SecretlyEmpty, Result<NotSoSecretlyEmpty, u32>> = Err(Err(123));
match x {
Ok(_y) => (),
Err(Err(_y)) => (),
Err(Ok(_y)) => (), //~ ERROR unreachable pattern
Err(Ok(_y)) => (), //~ ERROR unreachable pattern
}
while let Some(_y) = foo() {

View File

@ -1,35 +1,35 @@
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:27:9
--> $DIR/uninhabited-patterns.rs:25:9
|
LL | &[..] => (),
| ^^^^^
|
note: the lint level is defined here
--> $DIR/uninhabited-patterns.rs:6:9
--> $DIR/uninhabited-patterns.rs:4:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:32:9
--> $DIR/uninhabited-patterns.rs:30:9
|
LL | Ok(box _) => (),
| ^^^^^^^^^
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:34:9
--> $DIR/uninhabited-patterns.rs:32:9
|
LL | Err(&[..]) => (),
| ^^^^^^^^^^
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:41:9
--> $DIR/uninhabited-patterns.rs:39:9
|
LL | Err(Ok(_y)) => (),
| ^^^^^^^^^^^
error: unreachable pattern
--> $DIR/uninhabited-patterns.rs:44:15
--> $DIR/uninhabited-patterns.rs:42:15
|
LL | while let Some(_y) = foo() {
| ^^^^^^^^