diff --git a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs new file mode 100644 index 0000000000000..0a8194253a3c0 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.rs @@ -0,0 +1,46 @@ +#![feature(never_type)] +#![feature(exhaustive_patterns)] +#![deny(unreachable_patterns)] +enum Foo {} + +struct NonEmptyStruct(bool); +enum NonEmptyEnum1 { + Foo(bool), +} +enum NonEmptyEnum2 { + Foo(bool), + Bar, +} +enum NonEmptyEnum5 { + V1, V2, V3, V4, V5, +} + +fn foo(x: Foo) { + match x {} // ok + match x { + _ => {}, //~ ERROR unreachable pattern + } +} + +fn main() { + // `exhaustive_patterns` is not on, so uninhabited branches are not detected as unreachable. + match None:: { + None => {} + Some(_) => {} //~ ERROR unreachable pattern + } + match None:: { + None => {} + Some(_) => {} //~ ERROR unreachable pattern + } + + match 0u8 {} + //~^ ERROR type `u8` is non-empty + match NonEmptyStruct(true) {} + //~^ ERROR type `NonEmptyStruct` is non-empty + match NonEmptyEnum1::Foo(true) {} + //~^ ERROR type `NonEmptyEnum1` is non-empty + match NonEmptyEnum2::Foo(true) {} + //~^ ERROR type `NonEmptyEnum2` is non-empty + match NonEmptyEnum5::V1 {} + //~^ ERROR type `NonEmptyEnum5` is non-empty +} diff --git a/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr new file mode 100644 index 0000000000000..8d143494026d4 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-empty-exhaustive_patterns.stderr @@ -0,0 +1,67 @@ +error: unreachable pattern + --> $DIR/match-empty-exhaustive_patterns.rs:21:9 + | +LL | _ => {}, + | ^ + | +note: lint level defined here + --> $DIR/match-empty-exhaustive_patterns.rs:3:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-empty-exhaustive_patterns.rs:29:9 + | +LL | Some(_) => {} + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-empty-exhaustive_patterns.rs:33:9 + | +LL | Some(_) => {} + | ^^^^^^^ + +error[E0004]: non-exhaustive patterns: type `u8` is non-empty + --> $DIR/match-empty-exhaustive_patterns.rs:36:11 + | +LL | match 0u8 {} + | ^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `NonEmptyStruct` is non-empty + --> $DIR/match-empty-exhaustive_patterns.rs:38:11 + | +LL | match NonEmptyStruct(true) {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `NonEmptyEnum1` is non-empty + --> $DIR/match-empty-exhaustive_patterns.rs:40:11 + | +LL | match NonEmptyEnum1::Foo(true) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `NonEmptyEnum2` is non-empty + --> $DIR/match-empty-exhaustive_patterns.rs:42:11 + | +LL | match NonEmptyEnum2::Foo(true) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `NonEmptyEnum5` is non-empty + --> $DIR/match-empty-exhaustive_patterns.rs:44:11 + | +LL | match NonEmptyEnum5::V1 {} + | ^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/match-empty.rs b/src/test/ui/pattern/usefulness/match-empty.rs new file mode 100644 index 0000000000000..28ebde6c4c173 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-empty.rs @@ -0,0 +1,48 @@ +#![feature(never_type)] +#![deny(unreachable_patterns)] +enum Foo {} + +struct NonEmptyStruct(bool); //~ `NonEmptyStruct` defined here +enum NonEmptyEnum1 { //~ `NonEmptyEnum1` defined here + Foo(bool), //~ variant not covered +} +enum NonEmptyEnum2 { //~ `NonEmptyEnum2` defined here + Foo(bool), //~ variant not covered + Bar, //~ variant not covered +} +enum NonEmptyEnum5 { //~ `NonEmptyEnum5` defined here + V1, V2, V3, V4, V5, +} + +fn foo1(x: Foo) { + match x {} // ok +} + +fn foo2(x: Foo) { + match x { + _ => {}, // FIXME: should be unreachable + } +} + +fn main() { + // `exhaustive_patterns` is not on, so uninhabited branches are not detected as unreachable. + match None:: { + None => {} + Some(_) => {} + } + match None:: { + None => {} + Some(_) => {} + } + + match 0u8 {} + //~^ ERROR type `u8` is non-empty + match NonEmptyStruct(true) {} + //~^ ERROR pattern `NonEmptyStruct` of type `NonEmptyStruct` is not handled + match NonEmptyEnum1::Foo(true) {} + //~^ ERROR pattern `Foo` of type `NonEmptyEnum1` is not handled + match NonEmptyEnum2::Foo(true) {} + //~^ ERROR multiple patterns of type `NonEmptyEnum2` are not handled + match NonEmptyEnum5::V1 {} + //~^ ERROR type `NonEmptyEnum5` is non-empty +} diff --git a/src/test/ui/pattern/usefulness/match-empty.stderr b/src/test/ui/pattern/usefulness/match-empty.stderr new file mode 100644 index 0000000000000..eb6cfaa61df82 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-empty.stderr @@ -0,0 +1,68 @@ +error[E0004]: non-exhaustive patterns: type `u8` is non-empty + --> $DIR/match-empty.rs:38:11 + | +LL | match 0u8 {} + | ^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `NonEmptyStruct` of type `NonEmptyStruct` is not handled + --> $DIR/match-empty.rs:40:11 + | +LL | struct NonEmptyStruct(bool); + | ---------------------------- + | | | + | | variant not covered + | `NonEmptyStruct` defined here +... +LL | match NonEmptyStruct(true) {} + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: pattern `Foo` of type `NonEmptyEnum1` is not handled + --> $DIR/match-empty.rs:42:11 + | +LL | / enum NonEmptyEnum1 { +LL | | Foo(bool), + | | --- variant not covered +LL | | } + | |_- `NonEmptyEnum1` defined here +... +LL | match NonEmptyEnum1::Foo(true) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: multiple patterns of type `NonEmptyEnum2` are not handled + --> $DIR/match-empty.rs:44:11 + | +LL | / enum NonEmptyEnum2 { +LL | | Foo(bool), + | | --- variant not covered +LL | | Bar, + | | --- variant not covered +LL | | } + | |_- `NonEmptyEnum2` defined here +... +LL | match NonEmptyEnum2::Foo(true) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `NonEmptyEnum5` is non-empty + --> $DIR/match-empty.rs:46:11 + | +LL | / enum NonEmptyEnum5 { +LL | | V1, V2, V3, V4, V5, +LL | | } + | |_- `NonEmptyEnum5` defined here +... +LL | match NonEmptyEnum5::V1 {} + | ^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs index bbc25d40256ff..8516bafef9bd9 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/auxiliary/enums.rs @@ -6,3 +6,6 @@ pub enum NonExhaustiveEnum { Tuple(u32), Struct { field: u32 } } + +#[non_exhaustive] +pub enum EmptyNonExhaustiveEnum {} diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum.rs b/src/test/ui/rfc-2008-non-exhaustive/enum.rs index 7423a970e2e3b..67fa21ab0bc5d 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/enum.rs +++ b/src/test/ui/rfc-2008-non-exhaustive/enum.rs @@ -1,7 +1,14 @@ // aux-build:enums.rs extern crate enums; -use enums::NonExhaustiveEnum; +use enums::{EmptyNonExhaustiveEnum, NonExhaustiveEnum}; + +fn empty(x: EmptyNonExhaustiveEnum) { + match x {} //~ ERROR type `enums::EmptyNonExhaustiveEnum` is non-empty + match x { + _ => {}, // ok + } +} fn main() { let enum_unit = NonExhaustiveEnum::Unit; @@ -13,6 +20,9 @@ fn main() { NonExhaustiveEnum::Struct { .. } => "third" }; + match enum_unit {}; + //~^ ERROR non-exhaustive patterns: multiple patterns of type `enums::NonExhaustiveEnum` are not handled [E0004] + // Everything below this is expected to compile successfully. let enum_unit = NonExhaustiveEnum::Unit; diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr index b5c1a4ebba4ac..6db1eb16eb4e6 100644 --- a/src/test/ui/rfc-2008-non-exhaustive/enum.stderr +++ b/src/test/ui/rfc-2008-non-exhaustive/enum.stderr @@ -1,11 +1,27 @@ +error[E0004]: non-exhaustive patterns: type `enums::EmptyNonExhaustiveEnum` is non-empty + --> $DIR/enum.rs:7:11 + | +LL | match x {} + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/enum.rs:9:11 + --> $DIR/enum.rs:16:11 | LL | match enum_unit { | ^^^^^^^^^ pattern `_` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms -error: aborting due to previous error +error[E0004]: non-exhaustive patterns: multiple patterns of type `enums::NonExhaustiveEnum` are not handled + --> $DIR/enum.rs:23:11 + | +LL | match enum_unit {}; + | ^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs new file mode 100644 index 0000000000000..f605464949448 --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.rs @@ -0,0 +1,37 @@ +#![deny(unreachable_patterns)] + +#[non_exhaustive] +pub enum NonExhaustiveEnum { + Unit, + //~^ variant not covered + Tuple(u32), + //~^ variant not covered + Struct { field: u32 } + //~^ variant not covered +} + +pub enum NormalEnum { + Unit, + //~^ variant not covered + Tuple(u32), + //~^ variant not covered + Struct { field: u32 } + //~^ variant not covered +} + +#[non_exhaustive] +pub enum EmptyNonExhaustiveEnum {} + +fn empty_non_exhaustive(x: EmptyNonExhaustiveEnum) { + match x {} + match x { + _ => {} // FIXME: should be unreachable + } +} + +fn main() { + match NonExhaustiveEnum::Unit {} + //~^ ERROR multiple patterns of type `NonExhaustiveEnum` are not handled [E0004] + match NormalEnum::Unit {} + //~^ ERROR multiple patterns of type `NormalEnum` are not handled [E0004] +} diff --git a/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr new file mode 100644 index 0000000000000..ac6c23e6d64db --- /dev/null +++ b/src/test/ui/rfc-2008-non-exhaustive/enum_same_crate_empty_match.stderr @@ -0,0 +1,45 @@ +error[E0004]: non-exhaustive patterns: multiple patterns of type `NonExhaustiveEnum` are not handled + --> $DIR/enum_same_crate_empty_match.rs:33:11 + | +LL | / pub enum NonExhaustiveEnum { +LL | | Unit, + | | ---- variant not covered +LL | | +LL | | Tuple(u32), + | | ----- variant not covered +LL | | +LL | | Struct { field: u32 } + | | ------ variant not covered +LL | | +LL | | } + | |_- `NonExhaustiveEnum` defined here +... +LL | match NonExhaustiveEnum::Unit {} + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: multiple patterns of type `NormalEnum` are not handled + --> $DIR/enum_same_crate_empty_match.rs:35:11 + | +LL | / pub enum NormalEnum { +LL | | Unit, + | | ---- variant not covered +LL | | +LL | | Tuple(u32), + | | ----- variant not covered +LL | | +LL | | Struct { field: u32 } + | | ------ variant not covered +LL | | +LL | | } + | |_- `NormalEnum` defined here +... +LL | match NormalEnum::Unit {} + | ^^^^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0004`.