mirror of
https://github.com/rust-lang/rust.git
synced 2025-01-26 14:43:24 +00:00
Test empty types better
This commit is contained in:
parent
f967532a47
commit
4e376cc104
@ -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`.
|
@ -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`.
|
52
tests/ui/pattern/usefulness/empty-match-check-notes.rs
Normal file
52
tests/ui/pattern/usefulness/empty-match-check-notes.rs
Normal 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 => {}
|
||||
}
|
||||
}
|
@ -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`.
|
||||
|
@ -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`.
|
||||
|
@ -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() {}
|
||||
|
@ -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`.
|
721
tests/ui/pattern/usefulness/empty-types.normal.stderr
Normal file
721
tests/ui/pattern/usefulness/empty-types.normal.stderr
Normal 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`.
|
665
tests/ui/pattern/usefulness/empty-types.rs
Normal file
665
tests/ui/pattern/usefulness/empty-types.rs
Normal 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() {}
|
@ -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() {
|
||||
|
@ -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() {
|
||||
| ^^^^^^^^
|
||||
|
Loading…
Reference in New Issue
Block a user