diff options
| author | Nadrieril <nadrieril@gmail.com> | 2019-09-28 16:05:38 +0200 |
|---|---|---|
| committer | Nadrieril <nadrieril@gmail.com> | 2019-10-27 21:20:26 +0000 |
| commit | 09f9947ebc68a8199c3dff8607a41571c48cc377 (patch) | |
| tree | fb81c258de9902ea813c24c5ca08bcce9817a4bb /src/test/ui/pattern | |
| parent | 0f677c65e867d93a47ccbaeaf6e6725cde8c5ff6 (diff) | |
| download | rust-09f9947ebc68a8199c3dff8607a41571c48cc377.tar.gz rust-09f9947ebc68a8199c3dff8607a41571c48cc377.zip | |
Gather together usefulness tests
I took most tests that were testing only for match exhaustiveness, pattern refutability or match arm reachability, and put them in the same test folder.
Diffstat (limited to 'src/test/ui/pattern')
54 files changed, 2036 insertions, 0 deletions
diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs new file mode 100644 index 00000000000..11eae2af9c9 --- /dev/null +++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.rs @@ -0,0 +1,32 @@ +// The precise semantics of inhabitedness with respect to unions and references is currently +// undecided. This test file currently checks a conservative choice. + +#![feature(exhaustive_patterns)] +#![feature(never_type)] + +#![allow(dead_code)] +#![allow(unreachable_code)] + +pub union Foo { + foo: !, +} + +fn uninhab_ref() -> &'static ! { + unimplemented!() +} + +fn uninhab_union() -> Foo { + unimplemented!() +} + +fn match_on_uninhab() { + match uninhab_ref() { + //~^ ERROR non-exhaustive patterns: type `&'static !` is non-empty + } + + match uninhab_union() { + //~^ ERROR non-exhaustive patterns: type `Foo` is non-empty + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr new file mode 100644 index 00000000000..792ab6f59a4 --- /dev/null +++ b/src/test/ui/pattern/usefulness/always-inhabited-union-ref.stderr @@ -0,0 +1,19 @@ +error[E0004]: non-exhaustive patterns: type `&'static !` is non-empty + --> $DIR/always-inhabited-union-ref.rs:23:11 + | +LL | match uninhab_ref() { + | ^^^^^^^^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: type `Foo` is non-empty + --> $DIR/always-inhabited-union-ref.rs:27:11 + | +LL | match uninhab_union() { + | ^^^^^^^^^^^^^^^ + | + = 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`. diff --git a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs new file mode 100644 index 00000000000..59f74919897 --- /dev/null +++ b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs @@ -0,0 +1,157 @@ +#![feature(precise_pointer_size_matching)] +#![feature(exclusive_range_pattern)] +#![deny(unreachable_patterns)] +#![deny(overlapping_patterns)] + +use std::{char, u8, u16, u32, u64, u128, i8, i16, i32, i64, i128}; + +fn main() { + let x: u8 = 0; + + // A single range covering the entire domain. + match x { + 0 ..= 255 => {} // ok + } + + // A combination of ranges and values. + // These are currently allowed to be overlapping. + match x { + 0 ..= 32 => {} + 33 => {} + 34 .. 128 => {} + 100 ..= 200 => {} + 200 => {} //~ ERROR unreachable pattern + 201 ..= 255 => {} + } + + // An incomplete set of values. + match x { //~ ERROR non-exhaustive patterns + 0 .. 128 => {} + } + + // A more incomplete set of values. + match x { //~ ERROR non-exhaustive patterns + 0 ..= 10 => {} + 20 ..= 30 => {} + 35 => {} + 70 .. 255 => {} + } + + let x: i8 = 0; + match x { //~ ERROR non-exhaustive patterns + -7 => {} + -5..=120 => {} + -2..=20 => {} + //~^ ERROR unreachable pattern + 125 => {} + } + + // Let's test other types too! + let c: char = '\u{0}'; + match c { + '\u{0}' ..= char::MAX => {} // ok + } + + // We can actually get away with just covering the + // following two ranges, which correspond to all + // valid Unicode Scalar Values. + match c { + '\u{0000}' ..= '\u{D7FF}' => {} + '\u{E000}' ..= '\u{10_FFFF}' => {} + } + + match 0u16 { + 0 ..= u16::MAX => {} // ok + } + + match 0u32 { + 0 ..= u32::MAX => {} // ok + } + + match 0u64 { + 0 ..= u64::MAX => {} // ok + } + + match 0u128 { + 0 ..= u128::MAX => {} // ok + } + + match 0i8 { + -128 ..= 127 => {} // ok + } + + match 0i8 { //~ ERROR non-exhaustive patterns + -127 ..= 127 => {} + } + + match 0i16 { + i16::MIN ..= i16::MAX => {} // ok + } + + match 0i16 { //~ ERROR non-exhaustive patterns + i16::MIN ..= -1 => {} + 1 ..= i16::MAX => {} + } + + match 0i32 { + i32::MIN ..= i32::MAX => {} // ok + } + + match 0i64 { + i64::MIN ..= i64::MAX => {} // ok + } + + match 0i128 { + i128::MIN ..= i128::MAX => {} // ok + } + + // Make sure that guards don't factor into the exhaustiveness checks. + match 0u8 { //~ ERROR non-exhaustive patterns + 0 .. 128 => {} + 128 ..= 255 if true => {} + } + + match 0u8 { + 0 .. 128 => {} + 128 ..= 255 if false => {} + 128 ..= 255 => {} // ok, because previous arm was guarded + } + + // Now things start getting a bit more interesting. Testing products! + match (0u8, Some(())) { //~ ERROR non-exhaustive patterns + (1, _) => {} + (_, None) => {} + } + + match (0u8, true) { //~ ERROR non-exhaustive patterns + (0 ..= 125, false) => {} + (128 ..= 255, false) => {} + (0 ..= 255, true) => {} + } + + match (0u8, true) { // ok + (0 ..= 125, false) => {} + (128 ..= 255, false) => {} + (0 ..= 255, true) => {} + (125 .. 128, false) => {} + } + + match 0u8 { + 0 .. 2 => {} + 1 ..= 2 => {} //~ ERROR multiple patterns covering the same range + _ => {} + } + + const LIM: u128 = u128::MAX - 1; + match 0u128 { //~ ERROR non-exhaustive patterns + 0 ..= LIM => {} + } + + match 0u128 { //~ ERROR non-exhaustive patterns + 0 ..= 4 => {} + } + + match 0u128 { //~ ERROR non-exhaustive patterns + 4 ..= u128::MAX => {} + } +} diff --git a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr new file mode 100644 index 00000000000..7a3a36a820c --- /dev/null +++ b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr @@ -0,0 +1,123 @@ +error: unreachable pattern + --> $DIR/exhaustive_integer_patterns.rs:23:9 + | +LL | 200 => {} + | ^^^ + | +note: lint level defined here + --> $DIR/exhaustive_integer_patterns.rs:3:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0004]: non-exhaustive patterns: `128u8..=std::u8::MAX` not covered + --> $DIR/exhaustive_integer_patterns.rs:28:11 + | +LL | match x { + | ^ pattern `128u8..=std::u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered + --> $DIR/exhaustive_integer_patterns.rs:33:11 + | +LL | match x { + | ^ patterns `11u8..=19u8`, `31u8..=34u8`, `36u8..=69u8` and 1 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: unreachable pattern + --> $DIR/exhaustive_integer_patterns.rs:44:9 + | +LL | -2..=20 => {} + | ^^^^^^^ + +error[E0004]: non-exhaustive patterns: `std::i8::MIN..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered + --> $DIR/exhaustive_integer_patterns.rs:41:11 + | +LL | match x { + | ^ patterns `std::i8::MIN..=-8i8`, `-6i8`, `121i8..=124i8` and 1 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `std::i8::MIN` not covered + --> $DIR/exhaustive_integer_patterns.rs:83:11 + | +LL | match 0i8 { + | ^^^ pattern `std::i8::MIN` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `0i16` not covered + --> $DIR/exhaustive_integer_patterns.rs:91:11 + | +LL | match 0i16 { + | ^^^^ pattern `0i16` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `128u8..=std::u8::MAX` not covered + --> $DIR/exhaustive_integer_patterns.rs:109:11 + | +LL | match 0u8 { + | ^^^ pattern `128u8..=std::u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=std::u8::MAX, Some(_))` not covered + --> $DIR/exhaustive_integer_patterns.rs:121:11 + | +LL | match (0u8, Some(())) { + | ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=std::u8::MAX, Some(_))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `(126u8..=127u8, false)` not covered + --> $DIR/exhaustive_integer_patterns.rs:126:11 + | +LL | match (0u8, true) { + | ^^^^^^^^^^^ pattern `(126u8..=127u8, false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: multiple patterns covering the same range + --> $DIR/exhaustive_integer_patterns.rs:141:9 + | +LL | 0 .. 2 => {} + | ------ this range overlaps on `1u8` +LL | 1 ..= 2 => {} + | ^^^^^^^ overlapping patterns + | +note: lint level defined here + --> $DIR/exhaustive_integer_patterns.rs:4:9 + | +LL | #![deny(overlapping_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0004]: non-exhaustive patterns: `std::u128::MAX` not covered + --> $DIR/exhaustive_integer_patterns.rs:146:11 + | +LL | match 0u128 { + | ^^^^^ pattern `std::u128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `5u128..=std::u128::MAX` not covered + --> $DIR/exhaustive_integer_patterns.rs:150:11 + | +LL | match 0u128 { + | ^^^^^ pattern `5u128..=std::u128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `0u128..=3u128` not covered + --> $DIR/exhaustive_integer_patterns.rs:154:11 + | +LL | match 0u128 { + | ^^^^^ pattern `0u128..=3u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 14 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/guards-not-exhaustive.rs b/src/test/ui/pattern/usefulness/guards-not-exhaustive.rs new file mode 100644 index 00000000000..b74f162c0c6 --- /dev/null +++ b/src/test/ui/pattern/usefulness/guards-not-exhaustive.rs @@ -0,0 +1,18 @@ +// run-pass + +#![allow(non_snake_case)] + +#[derive(Copy, Clone)] +enum Q { R(Option<usize>) } + +fn xyzzy(q: Q) -> usize { + match q { + Q::R(S) if S.is_some() => { 0 } + _ => 1 + } +} + + +pub fn main() { + assert_eq!(xyzzy(Q::R(Some(5))), 0); +} diff --git a/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs b/src/test/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs index ff065882d96..ff065882d96 100644 --- a/src/test/ui/pattern/irrefutable-exhaustive-integer-binding.rs +++ b/src/test/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs diff --git a/src/test/ui/pattern/usefulness/irrefutable-unit.rs b/src/test/ui/pattern/usefulness/irrefutable-unit.rs new file mode 100644 index 00000000000..dd8f03b6dbd --- /dev/null +++ b/src/test/ui/pattern/usefulness/irrefutable-unit.rs @@ -0,0 +1,6 @@ +// run-pass +// pretty-expanded FIXME #23616 + +pub fn main() { + let ((),()) = ((),()); +} diff --git a/src/test/ui/pattern/usefulness/issue-35609.rs b/src/test/ui/pattern/usefulness/issue-35609.rs new file mode 100644 index 00000000000..8ef75e3511e --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-35609.rs @@ -0,0 +1,43 @@ +enum Enum { + A, B, C, D, E, F +} +use Enum::*; + +struct S(Enum, ()); +struct Sd { x: Enum, y: () } + +fn main() { + match (A, ()) { //~ ERROR non-exhaustive + (A, _) => {} + } + + match (A, A) { //~ ERROR non-exhaustive + (_, A) => {} + } + + match ((A, ()), ()) { //~ ERROR non-exhaustive + ((A, ()), _) => {} + } + + match ((A, ()), A) { //~ ERROR non-exhaustive + ((A, ()), _) => {} + } + + match ((A, ()), ()) { //~ ERROR non-exhaustive + ((A, _), _) => {} + } + + + match S(A, ()) { //~ ERROR non-exhaustive + S(A, _) => {} + } + + match (Sd { x: A, y: () }) { //~ ERROR non-exhaustive + Sd { x: A, y: _ } => {} + } + + match Some(A) { //~ ERROR non-exhaustive + Some(A) => (), + None => () + } +} diff --git a/src/test/ui/pattern/usefulness/issue-35609.stderr b/src/test/ui/pattern/usefulness/issue-35609.stderr new file mode 100644 index 00000000000..af22535c55e --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-35609.stderr @@ -0,0 +1,73 @@ +error[E0004]: non-exhaustive patterns: `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered + --> $DIR/issue-35609.rs:10:11 + | +LL | match (A, ()) { + | ^^^^^^^ patterns `(B, _)`, `(C, _)`, `(D, _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered + --> $DIR/issue-35609.rs:14:11 + | +LL | match (A, A) { + | ^^^^^^ patterns `(_, B)`, `(_, C)`, `(_, D)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + --> $DIR/issue-35609.rs:18:11 + | +LL | match ((A, ()), ()) { + | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + --> $DIR/issue-35609.rs:22:11 + | +LL | match ((A, ()), A) { + | ^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + --> $DIR/issue-35609.rs:26:11 + | +LL | match ((A, ()), ()) { + | ^^^^^^^^^^^^^ patterns `((B, _), _)`, `((C, _), _)`, `((D, _), _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered + --> $DIR/issue-35609.rs:31:11 + | +LL | struct S(Enum, ()); + | ------------------- `S` defined here +... +LL | match S(A, ()) { + | ^^^^^^^^ patterns `S(B, _)`, `S(C, _)`, `S(D, _)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered + --> $DIR/issue-35609.rs:35:11 + | +LL | struct Sd { x: Enum, y: () } + | ---------------------------- `Sd` defined here +... +LL | match (Sd { x: A, y: () }) { + | ^^^^^^^^^^^^^^^^^^^^ patterns `Sd { x: B, .. }`, `Sd { x: C, .. }`, `Sd { x: D, .. }` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered + --> $DIR/issue-35609.rs:39:11 + | +LL | match Some(A) { + | ^^^^^^^ patterns `Some(B)`, `Some(C)`, `Some(D)` and 2 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-43253.rs b/src/test/ui/pattern/usefulness/issue-43253.rs new file mode 100644 index 00000000000..5c6834459f0 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-43253.rs @@ -0,0 +1,47 @@ +// check-pass +#![feature(exclusive_range_pattern)] +#![warn(unreachable_patterns)] +#![warn(overlapping_patterns)] + +fn main() { + // These cases should generate no warning. + match 10 { + 1..10 => {}, + 10 => {}, + _ => {}, + } + + match 10 { + 1..10 => {}, + 9..=10 => {}, //~ WARNING multiple patterns covering the same range + _ => {}, + } + + match 10 { + 1..10 => {}, + 10..=10 => {}, + _ => {}, + } + + // These cases should generate "unreachable pattern" warnings. + match 10 { + 1..10 => {}, + 9 => {}, //~ WARNING unreachable pattern + _ => {}, + } + + match 10 { + 1..10 => {}, + 8..=9 => {}, //~ WARNING multiple patterns covering the same range + _ => {}, + } + + match 10 { + 5..7 => {}, + 6 => {}, //~ WARNING unreachable pattern + 1..10 => {}, //~ WARNING multiple patterns covering the same range + 9..=9 => {}, //~ WARNING unreachable pattern + 6 => {}, //~ WARNING unreachable pattern + _ => {}, + } +} diff --git a/src/test/ui/pattern/usefulness/issue-43253.stderr b/src/test/ui/pattern/usefulness/issue-43253.stderr new file mode 100644 index 00000000000..cb4a0486eef --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-43253.stderr @@ -0,0 +1,50 @@ +warning: multiple patterns covering the same range + --> $DIR/issue-43253.rs:16:9 + | +LL | 1..10 => {}, + | ----- this range overlaps on `9i32` +LL | 9..=10 => {}, + | ^^^^^^ overlapping patterns + | +note: lint level defined here + --> $DIR/issue-43253.rs:4:9 + | +LL | #![warn(overlapping_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +warning: unreachable pattern + --> $DIR/issue-43253.rs:29:9 + | +LL | 9 => {}, + | ^ + | +note: lint level defined here + --> $DIR/issue-43253.rs:3:9 + | +LL | #![warn(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +warning: unreachable pattern + --> $DIR/issue-43253.rs:35:9 + | +LL | 8..=9 => {}, + | ^^^^^ + +warning: unreachable pattern + --> $DIR/issue-43253.rs:41:9 + | +LL | 6 => {}, + | ^ + +warning: unreachable pattern + --> $DIR/issue-43253.rs:43:9 + | +LL | 9..=9 => {}, + | ^^^^^ + +warning: unreachable pattern + --> $DIR/issue-43253.rs:44:9 + | +LL | 6 => {}, + | ^ + diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.rs b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs new file mode 100644 index 00000000000..4c5f2d35649 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.rs @@ -0,0 +1,62 @@ +use self::Direction::{North, East, South, West}; + +#[derive(PartialEq, Eq)] +struct NewBool(bool); + +#[derive(PartialEq, Eq)] +enum Direction { + North, + East, + South, + West +} + +const TRUE_TRUE: (bool, bool) = (true, true); + +fn nonexhaustive_1() { + match (true, false) { + //~^ ERROR non-exhaustive patterns: `(true, false)` not covered + TRUE_TRUE => (), + (false, false) => (), + (false, true) => () + } +} + +const NONE: Option<Direction> = None; +const EAST: Direction = East; + +fn nonexhaustive_2() { + match Some(Some(North)) { + //~^ ERROR non-exhaustive patterns: `Some(Some(West))` not covered + Some(NONE) => (), + Some(Some(North)) => (), + Some(Some(EAST)) => (), + Some(Some(South)) => (), + None => () + } +} + +const NEW_FALSE: NewBool = NewBool(false); +struct Foo { + bar: Option<Direction>, + baz: NewBool +} + +const STATIC_FOO: Foo = Foo { bar: None, baz: NEW_FALSE }; + +fn nonexhaustive_3() { + match (Foo { bar: Some(North), baz: NewBool(true) }) { + //~^ ERROR non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` + Foo { bar: None, baz: NewBool(true) } => (), + Foo { bar: _, baz: NEW_FALSE } => (), + Foo { bar: Some(West), baz: NewBool(true) } => (), + Foo { bar: Some(South), .. } => (), + Foo { bar: Some(EAST), .. } => () + } +} + +fn main() { + nonexhaustive_1(); + nonexhaustive_2(); + nonexhaustive_3(); +} diff --git a/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr new file mode 100644 index 00000000000..8521e37d3fd --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-arm-statics-2.stderr @@ -0,0 +1,33 @@ +error[E0004]: non-exhaustive patterns: `(true, false)` not covered + --> $DIR/match-arm-statics-2.rs:17:11 + | +LL | match (true, false) { + | ^^^^^^^^^^^^^ pattern `(true, false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `Some(Some(West))` not covered + --> $DIR/match-arm-statics-2.rs:29:11 + | +LL | match Some(Some(North)) { + | ^^^^^^^^^^^^^^^^^ pattern `Some(Some(West))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `Foo { bar: Some(North), baz: NewBool(true) }` not covered + --> $DIR/match-arm-statics-2.rs:48:11 + | +LL | / struct Foo { +LL | | bar: Option<Direction>, +LL | | baz: NewBool +LL | | } + | |_- `Foo` defined here +... +LL | match (Foo { bar: Some(North), baz: NewBool(true) }) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { bar: Some(North), baz: NewBool(true) }` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/match-arm-statics.rs b/src/test/ui/pattern/usefulness/match-arm-statics.rs new file mode 100644 index 00000000000..91db76ebb9f --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-arm-statics.rs @@ -0,0 +1,69 @@ +#![allow(dead_code)] +#![deny(unreachable_patterns)] + +use self::Direction::{North, East, South, West}; + +#[derive(PartialEq, Eq)] +struct NewBool(bool); + +#[derive(PartialEq, Eq)] +enum Direction { + North, + East, + South, + West +} + +const TRUE_TRUE: (bool, bool) = (true, true); + +fn unreachable_1() { + match (true, false) { + TRUE_TRUE => (), + (false, false) => (), + (false, true) => (), + (true, false) => (), + (true, true) => () + //~^ ERROR unreachable pattern + } +} + +const NONE: Option<Direction> = None; +const EAST: Direction = East; + +fn unreachable_2() { + match Some(Some(North)) { + Some(NONE) => (), + Some(Some(North)) => (), + Some(Some(EAST)) => (), + Some(Some(South)) => (), + Some(Some(West)) => (), + Some(Some(East)) => (), + //~^ ERROR unreachable pattern + None => () + } +} + +const NEW_FALSE: NewBool = NewBool(false); +struct Foo { + bar: Option<Direction>, + baz: NewBool +} + +fn unreachable_3() { + match (Foo { bar: Some(EAST), baz: NewBool(true) }) { + Foo { bar: None, baz: NewBool(true) } => (), + Foo { bar: _, baz: NEW_FALSE } => (), + Foo { bar: Some(West), baz: NewBool(true) } => (), + Foo { bar: Some(South), .. } => (), + Foo { bar: Some(EAST), .. } => (), + Foo { bar: Some(North), baz: NewBool(true) } => (), + Foo { bar: Some(EAST), baz: NewBool(false) } => () + //~^ ERROR unreachable pattern + } +} + +fn main() { + unreachable_1(); + unreachable_2(); + unreachable_3(); +} diff --git a/src/test/ui/pattern/usefulness/match-arm-statics.stderr b/src/test/ui/pattern/usefulness/match-arm-statics.stderr new file mode 100644 index 00000000000..3d9e900a4e9 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-arm-statics.stderr @@ -0,0 +1,26 @@ +error: unreachable pattern + --> $DIR/match-arm-statics.rs:25:9 + | +LL | (true, true) => () + | ^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/match-arm-statics.rs:2:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-arm-statics.rs:40:9 + | +LL | Some(Some(East)) => (), + | ^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-arm-statics.rs:60:9 + | +LL | Foo { bar: Some(EAST), baz: NewBool(false) } => () + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.rs b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.rs new file mode 100644 index 00000000000..33468d03fae --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.rs @@ -0,0 +1,13 @@ +fn main() { + let buf = &[0, 1, 2, 3]; + + match buf { //~ ERROR non-exhaustive + b"AAAA" => {} + } + + let buf: &[u8] = buf; + + match buf { //~ ERROR non-exhaustive + b"AAAA" => {} + } +} diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr new file mode 100644 index 00000000000..d53e2e25b3d --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr @@ -0,0 +1,19 @@ +error[E0004]: non-exhaustive patterns: `&[_, _, _, _]` not covered + --> $DIR/match-byte-array-patterns-2.rs:4:11 + | +LL | match buf { + | ^^^ pattern `&[_, _, _, _]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 3 more not covered + --> $DIR/match-byte-array-patterns-2.rs:10:11 + | +LL | match buf { + | ^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 3 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs new file mode 100644 index 00000000000..7541ea3e2e2 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.rs @@ -0,0 +1,56 @@ +#![feature(slice_patterns)] +#![deny(unreachable_patterns)] + +fn main() { + let buf = &[0, 1, 2, 3]; + + match buf { + b"AAAA" => {}, + &[0x41, 0x41, 0x41, 0x41] => {} //~ ERROR unreachable pattern + _ => {} + } + + match buf { + &[0x41, 0x41, 0x41, 0x41] => {} + b"AAAA" => {}, //~ ERROR unreachable pattern + _ => {} + } + + match buf { + &[_, 0x41, 0x41, 0x41] => {}, + b"AAAA" => {}, //~ ERROR unreachable pattern + _ => {} + } + + match buf { + &[0x41, .., 0x41] => {} + b"AAAA" => {}, //~ ERROR unreachable pattern + _ => {} + } + + let buf: &[u8] = buf; + + match buf { + b"AAAA" => {}, + &[0x41, 0x41, 0x41, 0x41] => {} //~ ERROR unreachable pattern + _ => {} + } + + match buf { + &[0x41, 0x41, 0x41, 0x41] => {} + b"AAAA" => {}, //~ ERROR unreachable pattern + _ => {} + } + + match buf { + &[_, 0x41, 0x41, 0x41] => {}, + b"AAAA" => {}, //~ ERROR unreachable pattern + _ => {} + } + + match buf { + &[0x41, .., 0x41] => {} + b"AAAA" => {}, //~ ERROR unreachable pattern + _ => {} + } +} diff --git a/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr new file mode 100644 index 00000000000..b28646b50cf --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-byte-array-patterns.stderr @@ -0,0 +1,56 @@ +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:9:9 + | +LL | &[0x41, 0x41, 0x41, 0x41] => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/match-byte-array-patterns.rs:2:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:15:9 + | +LL | b"AAAA" => {}, + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:21:9 + | +LL | b"AAAA" => {}, + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:27:9 + | +LL | b"AAAA" => {}, + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:35:9 + | +LL | &[0x41, 0x41, 0x41, 0x41] => {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:41:9 + | +LL | b"AAAA" => {}, + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:47:9 + | +LL | b"AAAA" => {}, + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-byte-array-patterns.rs:53:9 + | +LL | b"AAAA" => {}, + | ^^^^^^^ + +error: aborting due to 8 previous errors + diff --git a/src/test/ui/pattern/usefulness/match-non-exhaustive.rs b/src/test/ui/pattern/usefulness/match-non-exhaustive.rs new file mode 100644 index 00000000000..3b210a115d2 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-non-exhaustive.rs @@ -0,0 +1,4 @@ +fn main() { + match 0 { 1 => () } //~ ERROR non-exhaustive patterns + match 0 { 0 if false => () } //~ ERROR non-exhaustive patterns +} diff --git a/src/test/ui/pattern/usefulness/match-non-exhaustive.stderr b/src/test/ui/pattern/usefulness/match-non-exhaustive.stderr new file mode 100644 index 00000000000..211f333882b --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-non-exhaustive.stderr @@ -0,0 +1,19 @@ +error[E0004]: non-exhaustive patterns: `std::i32::MIN..=0i32` and `2i32..=std::i32::MAX` not covered + --> $DIR/match-non-exhaustive.rs:2:11 + | +LL | match 0 { 1 => () } + | ^ patterns `std::i32::MIN..=0i32` and `2i32..=std::i32::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/match-non-exhaustive.rs:3:11 + | +LL | match 0 { 0 if false => () } + | ^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.rs b/src/test/ui/pattern/usefulness/match-privately-empty.rs new file mode 100644 index 00000000000..315eb03d165 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-privately-empty.rs @@ -0,0 +1,21 @@ +#![feature(never_type)] +#![feature(exhaustive_patterns)] + +mod private { + pub struct Private { + _bot: !, + pub misc: bool, + } + pub const DATA: Option<Private> = None; +} + +fn main() { + match private::DATA { + //~^ ERROR non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered + None => {} + Some(private::Private { + misc: false, + .. + }) => {} + } +} diff --git a/src/test/ui/pattern/usefulness/match-privately-empty.stderr b/src/test/ui/pattern/usefulness/match-privately-empty.stderr new file mode 100644 index 00000000000..f79d180a1b8 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-privately-empty.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: `Some(Private { misc: true, .. })` not covered + --> $DIR/match-privately-empty.rs:13:11 + | +LL | match private::DATA { + | ^^^^^^^^^^^^^ pattern `Some(Private { misc: true, .. })` 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 + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs b/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs new file mode 100644 index 00000000000..7de7b7e79be --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs @@ -0,0 +1,45 @@ +#![deny(unreachable_patterns, overlapping_patterns)] + +fn main() { + match 5 { + 1 ..= 10 => { } + 5 ..= 6 => { } + //~^ ERROR unreachable pattern + _ => {} + }; + + match 5 { + 3 ..= 6 => { } + 4 ..= 6 => { } + //~^ ERROR unreachable pattern + _ => {} + }; + + match 5 { + 4 ..= 6 => { } + 4 ..= 6 => { } + //~^ ERROR unreachable pattern + _ => {} + }; + + match 'c' { + 'A' ..= 'z' => {} + 'a' ..= 'z' => {} + //~^ ERROR unreachable pattern + _ => {} + }; + + match 1.0f64 { + 0.01f64 ..= 6.5f64 => {} + //~^ WARNING floating-point types cannot be used in patterns + //~| WARNING floating-point types cannot be used in patterns + //~| WARNING floating-point types cannot be used in patterns + //~| WARNING this was previously accepted by the compiler + //~| WARNING this was previously accepted by the compiler + //~| WARNING this was previously accepted by the compiler + 0.02f64 => {} //~ ERROR unreachable pattern + //~^ WARNING floating-point types cannot be used in patterns + //~| WARNING this was previously accepted by the compiler + _ => {} + }; +} diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr new file mode 100644 index 00000000000..c15186d2558 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr @@ -0,0 +1,75 @@ +error: unreachable pattern + --> $DIR/match-range-fail-dominate.rs:6:7 + | +LL | 5 ..= 6 => { } + | ^^^^^^^ + | +note: lint level defined here + --> $DIR/match-range-fail-dominate.rs:1:9 + | +LL | #![deny(unreachable_patterns, overlapping_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-range-fail-dominate.rs:13:7 + | +LL | 4 ..= 6 => { } + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-range-fail-dominate.rs:20:7 + | +LL | 4 ..= 6 => { } + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/match-range-fail-dominate.rs:27:7 + | +LL | 'a' ..= 'z' => {} + | ^^^^^^^^^^^ + +warning: floating-point types cannot be used in patterns + --> $DIR/match-range-fail-dominate.rs:33:7 + | +LL | 0.01f64 ..= 6.5f64 => {} + | ^^^^^^^ + | + = note: `#[warn(illegal_floating_point_literal_pattern)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> + +warning: floating-point types cannot be used in patterns + --> $DIR/match-range-fail-dominate.rs:33:19 + | +LL | 0.01f64 ..= 6.5f64 => {} + | ^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> + +warning: floating-point types cannot be used in patterns + --> $DIR/match-range-fail-dominate.rs:40:7 + | +LL | 0.02f64 => {} + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> + +error: unreachable pattern + --> $DIR/match-range-fail-dominate.rs:40:7 + | +LL | 0.02f64 => {} + | ^^^^^^^ + +warning: floating-point types cannot be used in patterns + --> $DIR/match-range-fail-dominate.rs:33:7 + | +LL | 0.01f64 ..= 6.5f64 => {} + | ^^^^^^^ + | + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620> + +error: aborting due to 5 previous errors + diff --git a/src/test/ui/pattern/usefulness/match-ref-ice.rs b/src/test/ui/pattern/usefulness/match-ref-ice.rs new file mode 100644 index 00000000000..dee110f96cd --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-ref-ice.rs @@ -0,0 +1,16 @@ +#![deny(unreachable_patterns)] + +// The arity of `ref x` is always 1. If the pattern is compared to some non-structural type whose +// arity is always 0, an ICE occurs. +// +// Related issue: #23009 + +fn main() { + let homura = [1, 2, 3]; + + match homura { + [1, ref _madoka, 3] => (), + [1, 2, 3] => (), //~ ERROR unreachable pattern + [_, _, _] => (), + } +} diff --git a/src/test/ui/pattern/usefulness/match-ref-ice.stderr b/src/test/ui/pattern/usefulness/match-ref-ice.stderr new file mode 100644 index 00000000000..c4bfa0afcc2 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-ref-ice.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/match-ref-ice.rs:13:9 + | +LL | [1, 2, 3] => (), + | ^^^^^^^^^ + | +note: lint level defined here + --> $DIR/match-ref-ice.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.rs b/src/test/ui/pattern/usefulness/match-slice-patterns.rs new file mode 100644 index 00000000000..afbeb61e441 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-slice-patterns.rs @@ -0,0 +1,14 @@ +#![feature(slice_patterns)] + +fn check(list: &[Option<()>]) { + match list { + //~^ ERROR `&[_, Some(_), None, _]` not covered + &[] => {}, + &[_] => {}, + &[_, _] => {}, + &[_, None, ..] => {}, + &[.., Some(_), _] => {}, + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/match-slice-patterns.stderr b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr new file mode 100644 index 00000000000..24769db34c9 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-slice-patterns.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: `&[_, Some(_), None, _]` not covered + --> $DIR/match-slice-patterns.rs:4:11 + | +LL | match list { + | ^^^^ pattern `&[_, Some(_), None, _]` 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 + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/match-vec-fixed.rs b/src/test/ui/pattern/usefulness/match-vec-fixed.rs new file mode 100644 index 00000000000..e611779dec2 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-vec-fixed.rs @@ -0,0 +1,18 @@ +#![deny(unreachable_patterns)] + +fn a() { + let v = [1, 2, 3]; + match v { + [_, _, _] => {} + [_, _, _] => {} //~ ERROR unreachable pattern + } + match v { + [_, 1, _] => {} + [_, 1, _] => {} //~ ERROR unreachable pattern + _ => {} + } +} + +fn main() { + a(); +} diff --git a/src/test/ui/pattern/usefulness/match-vec-fixed.stderr b/src/test/ui/pattern/usefulness/match-vec-fixed.stderr new file mode 100644 index 00000000000..ae2dd87b695 --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-vec-fixed.stderr @@ -0,0 +1,20 @@ +error: unreachable pattern + --> $DIR/match-vec-fixed.rs:7:9 + | +LL | [_, _, _] => {} + | ^^^^^^^^^ + | +note: lint level defined here + --> $DIR/match-vec-fixed.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-vec-fixed.rs:11:9 + | +LL | [_, 1, _] => {} + | ^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.rs b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs new file mode 100644 index 00000000000..78810525bad --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.rs @@ -0,0 +1,30 @@ +#![feature(slice_patterns)] +#![deny(unreachable_patterns)] + +fn main() { + let x: Vec<(isize, isize)> = Vec::new(); + let x: &[(isize, isize)] = &x; + match *x { + [a, (2, 3), _] => (), + [(1, 2), (2, 3), b] => (), //~ ERROR unreachable pattern + _ => () + } + + let x: Vec<String> = vec!["foo".to_string(), + "bar".to_string(), + "baz".to_string()]; + let x: &[String] = &x; + match *x { + [ref a, _, _, ..] => { println!("{}", a); } + [_, _, _, _, _] => { } //~ ERROR unreachable pattern + _ => { } + } + + let x: Vec<char> = vec!['a', 'b', 'c']; + let x: &[char] = &x; + match *x { + ['a', 'b', 'c', ref _tail @ ..] => {} + ['a', 'b', 'c'] => {} //~ ERROR unreachable pattern + _ => {} + } +} diff --git a/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr new file mode 100644 index 00000000000..415c24ae77e --- /dev/null +++ b/src/test/ui/pattern/usefulness/match-vec-unreachable.stderr @@ -0,0 +1,26 @@ +error: unreachable pattern + --> $DIR/match-vec-unreachable.rs:9:9 + | +LL | [(1, 2), (2, 3), b] => (), + | ^^^^^^^^^^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/match-vec-unreachable.rs:2:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-vec-unreachable.rs:19:9 + | +LL | [_, _, _, _, _] => { } + | ^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/match-vec-unreachable.rs:27:9 + | +LL | ['a', 'b', 'c'] => {} + | ^^^^^^^^^^^^^^^ + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/pattern/usefulness/nested-exhaustive-match.rs b/src/test/ui/pattern/usefulness/nested-exhaustive-match.rs new file mode 100644 index 00000000000..8b2294f8432 --- /dev/null +++ b/src/test/ui/pattern/usefulness/nested-exhaustive-match.rs @@ -0,0 +1,14 @@ +// run-pass +#![allow(dead_code)] +// pretty-expanded FIXME #23616 + +struct Foo { foo: bool, bar: Option<isize>, baz: isize } + +pub fn main() { + match (Foo{foo: true, bar: Some(10), baz: 20}) { + Foo{foo: true, bar: Some(_), ..} => {} + Foo{foo: false, bar: None, ..} => {} + Foo{foo: true, bar: None, ..} => {} + Foo{foo: false, bar: Some(_), ..} => {} + } +} diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs new file mode 100644 index 00000000000..6f009acbdfe --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.rs @@ -0,0 +1,72 @@ +// Test the "defined here" and "not covered" diagnostic hints. +// We also make sure that references are peeled off from the scrutinee type +// so that the diagnostics work better with default binding modes. + +#[derive(Clone)] +enum E { +//~^ `E` defined here +//~| `E` defined here +//~| `E` defined here +//~| `E` defined here +//~| `E` defined here +//~| `E` defined here + A, + B, + //~^ not covered + //~| not covered + //~| not covered + //~| not covered + //~| not covered + //~| not covered + C + //~^ not covered + //~| not covered + //~| not covered + //~| not covered + //~| not covered + //~| not covered +} + +fn by_val(e: E) { + let e1 = e.clone(); + match e1 { //~ ERROR non-exhaustive patterns: `B` and `C` not covered + E::A => {} + } + + let E::A = e; //~ ERROR refutable pattern in local binding: `B` and `C` not covered +} + +fn by_ref_once(e: &E) { + match e { //~ ERROR non-exhaustive patterns: `&B` and `&C` not covered + E::A => {} + } + + let E::A = e; //~ ERROR refutable pattern in local binding: `&B` and `&C` not covered +} + +fn by_ref_thrice(e: & &mut &E) { + match e { //~ ERROR non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered + E::A => {} + } + + let E::A = e; + //~^ ERROR refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered +} + +enum Opt { +//~^ `Opt` defined here +//~| `Opt` defined here + Some(u8), + None, + //~^ not covered +} + +fn ref_pat(e: Opt) { + match e {//~ ERROR non-exhaustive patterns: `None` not covered + Opt::Some(ref _x) => {} + } + + let Opt::Some(ref _x) = e; //~ ERROR refutable pattern in local binding: `None` not covered +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr new file mode 100644 index 00000000000..e5f01174ac1 --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-defined-here.stderr @@ -0,0 +1,198 @@ +error[E0004]: non-exhaustive patterns: `B` and `C` not covered + --> $DIR/non-exhaustive-defined-here.rs:32:11 + | +LL | / enum E { +LL | | +LL | | +LL | | +... | +LL | | B, + | | - not covered +... | +LL | | C + | | - not covered +... | +LL | | +LL | | } + | |_- `E` defined here +... +LL | match e1 { + | ^^ patterns `B` and `C` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0005]: refutable pattern in local binding: `B` and `C` not covered + --> $DIR/non-exhaustive-defined-here.rs:36:9 + | +LL | / enum E { +LL | | +LL | | +LL | | +... | +LL | | B, + | | - not covered +... | +LL | | C + | | - not covered +... | +LL | | +LL | | } + | |_- `E` defined here +... +LL | let E::A = e; + | ^^^^ patterns `B` and `C` 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 +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let E::A = e { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0004]: non-exhaustive patterns: `&B` and `&C` not covered + --> $DIR/non-exhaustive-defined-here.rs:40:11 + | +LL | / enum E { +LL | | +LL | | +LL | | +... | +LL | | B, + | | - not covered +... | +LL | | C + | | - not covered +... | +LL | | +LL | | } + | |_- `E` defined here +... +LL | match e { + | ^ patterns `&B` and `&C` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0005]: refutable pattern in local binding: `&B` and `&C` not covered + --> $DIR/non-exhaustive-defined-here.rs:44:9 + | +LL | / enum E { +LL | | +LL | | +LL | | +... | +LL | | B, + | | - not covered +... | +LL | | C + | | - not covered +... | +LL | | +LL | | } + | |_- `E` defined here +... +LL | let E::A = e; + | ^^^^ patterns `&B` and `&C` 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 +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let E::A = e { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0004]: non-exhaustive patterns: `&&mut &B` and `&&mut &C` not covered + --> $DIR/non-exhaustive-defined-here.rs:48:11 + | +LL | / enum E { +LL | | +LL | | +LL | | +... | +LL | | B, + | | - not covered +... | +LL | | C + | | - not covered +... | +LL | | +LL | | } + | |_- `E` defined here +... +LL | match e { + | ^ patterns `&&mut &B` and `&&mut &C` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0005]: refutable pattern in local binding: `&&mut &B` and `&&mut &C` not covered + --> $DIR/non-exhaustive-defined-here.rs:52:9 + | +LL | / enum E { +LL | | +LL | | +LL | | +... | +LL | | B, + | | - not covered +... | +LL | | C + | | - not covered +... | +LL | | +LL | | } + | |_- `E` defined here +... +LL | let E::A = e; + | ^^^^ patterns `&&mut &B` and `&&mut &C` 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 +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let E::A = e { /* */ } + | + +error[E0004]: non-exhaustive patterns: `None` not covered + --> $DIR/non-exhaustive-defined-here.rs:65:11 + | +LL | / enum Opt { +LL | | +LL | | +LL | | Some(u8), +LL | | None, + | | ---- not covered +LL | | +LL | | } + | |_- `Opt` defined here +... +LL | match e { + | ^ pattern `None` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0005]: refutable pattern in local binding: `None` not covered + --> $DIR/non-exhaustive-defined-here.rs:69:9 + | +LL | / enum Opt { +LL | | +LL | | +LL | | Some(u8), +LL | | None, + | | ---- not covered +LL | | +LL | | } + | |_- `Opt` defined here +... +LL | let Opt::Some(ref _x) = e; + | ^^^^^^^^^^^^^^^^^ pattern `None` 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 +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Opt::Some(ref _x) = e { /* */ } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 8 previous errors + +Some errors have detailed explanations: E0004, E0005. +For more information about an error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.rs new file mode 100644 index 00000000000..588fecbf10d --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.rs @@ -0,0 +1,13 @@ +#![allow(illegal_floating_point_literal_pattern)] +#![deny(unreachable_patterns)] + +fn main() { + match 0.0 { + 0.0..=1.0 => {} + _ => {} // ok + } + + match 0.0 { //~ ERROR non-exhaustive patterns + 0.0..=1.0 => {} + } +} diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr new file mode 100644 index 00000000000..6de615c3de4 --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr @@ -0,0 +1,11 @@ +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/non-exhaustive-float-range-match.rs:10:11 + | +LL | match 0.0 { + | ^^^ 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 + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs new file mode 100644 index 00000000000..9423a2891a6 --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.rs @@ -0,0 +1,21 @@ +#![feature(slice_patterns)] + +enum T { A(U), B } +enum U { C, D } + +fn match_nested_vecs<'a, T>(l1: Option<&'a [T]>, l2: Result<&'a [T], ()>) -> &'static str { + match (l1, l2) { //~ ERROR non-exhaustive patterns: `(Some(&[]), Err(_))` not covered + (Some(&[]), Ok(&[])) => "Some(empty), Ok(empty)", + (Some(&[_, ..]), Ok(_)) | (Some(&[_, ..]), Err(())) => "Some(non-empty), any", + (None, Ok(&[])) | (None, Err(())) | (None, Ok(&[_])) => "None, Ok(less than one element)", + (None, Ok(&[_, _, ..])) => "None, Ok(at least two elements)" + } +} + +fn main() { + let x = T::A(U::C); + match x { //~ ERROR non-exhaustive patterns: `A(C)` not covered + T::A(U::D) => { panic!("hello"); } + T::B => { panic!("goodbye"); } + } +} diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr new file mode 100644 index 00000000000..67c818e19cb --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match-nested.stderr @@ -0,0 +1,25 @@ +error[E0004]: non-exhaustive patterns: `(Some(&[]), Err(_))` not covered + --> $DIR/non-exhaustive-match-nested.rs:7:11 + | +LL | match (l1, l2) { + | ^^^^^^^^ pattern `(Some(&[]), Err(_))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `A(C)` not covered + --> $DIR/non-exhaustive-match-nested.rs:17:11 + | +LL | enum T { A(U), B } + | ------------------ + | | | + | | not covered + | `T` defined here +... +LL | match x { + | ^ pattern `A(C)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.rs b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs new file mode 100644 index 00000000000..0e5a9203c5f --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.rs @@ -0,0 +1,64 @@ +#![feature(slice_patterns)] +#![allow(illegal_floating_point_literal_pattern)] + +enum T { A, B } + +fn main() { + let x = T::A; + match x { T::B => { } } //~ ERROR non-exhaustive patterns: `A` not covered + match true { //~ ERROR non-exhaustive patterns: `false` not covered + true => {} + } + match Some(10) { //~ ERROR non-exhaustive patterns: `Some(_)` not covered + None => {} + } + match (2, 3, 4) { //~ ERROR non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` + // and `(_, _, 5i32..=std::i32::MAX)` not covered + (_, _, 4) => {} + } + match (T::A, T::A) { //~ ERROR non-exhaustive patterns: `(A, A)` not covered + (T::A, T::B) => {} + (T::B, T::A) => {} + } + match T::A { //~ ERROR non-exhaustive patterns: `B` not covered + T::A => {} + } + // This is exhaustive, though the algorithm got it wrong at one point + match (T::A, T::B) { + (T::A, _) => {} + (_, T::A) => {} + (T::B, T::B) => {} + } + let vec = vec![Some(42), None, Some(21)]; + let vec: &[Option<isize>] = &vec; + match *vec { //~ ERROR non-exhaustive patterns: `[]` not covered + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} + [None] => {} + } + let vec = vec![1]; + let vec: &[isize] = &vec; + match *vec { + [_, ref tail @ ..] => (), + [] => () + } + let vec = vec![0.5f32]; + let vec: &[f32] = &vec; + match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered + [0.1, 0.2, 0.3] => (), + [0.1, 0.2] => (), + [0.1] => (), + [] => () + } + let vec = vec![Some(42), None, Some(21)]; + let vec: &[Option<isize>] = &vec; + match *vec { + [Some(..), None, ref tail @ ..] => {} + [Some(..), Some(..), ref tail @ ..] => {} + [None, None, ref tail @ ..] => {} + [None, Some(..), ref tail @ ..] => {} + [Some(_)] => {} + [None] => {} + [] => {} + } +} diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr new file mode 100644 index 00000000000..5dba05e1642 --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-match.stderr @@ -0,0 +1,79 @@ +error[E0004]: non-exhaustive patterns: `A` not covered + --> $DIR/non-exhaustive-match.rs:8:11 + | +LL | enum T { A, B } + | --------------- + | | | + | | not covered + | `T` defined here +... +LL | match x { T::B => { } } + | ^ pattern `A` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `false` not covered + --> $DIR/non-exhaustive-match.rs:9:11 + | +LL | match true { + | ^^^^ pattern `false` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `Some(_)` not covered + --> $DIR/non-exhaustive-match.rs:12:11 + | +LL | match Some(10) { + | ^^^^^^^^ pattern `Some(_)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered + --> $DIR/non-exhaustive-match.rs:15:11 + | +LL | match (2, 3, 4) { + | ^^^^^^^^^ patterns `(_, _, std::i32::MIN..=3i32)` and `(_, _, 5i32..=std::i32::MAX)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `(A, A)` not covered + --> $DIR/non-exhaustive-match.rs:19:11 + | +LL | match (T::A, T::A) { + | ^^^^^^^^^^^^ pattern `(A, A)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `B` not covered + --> $DIR/non-exhaustive-match.rs:23:11 + | +LL | enum T { A, B } + | --------------- + | | | + | | not covered + | `T` defined here +... +LL | match T::A { + | ^^^^ pattern `B` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `[]` not covered + --> $DIR/non-exhaustive-match.rs:34:11 + | +LL | match *vec { + | ^^^^ pattern `[]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `[_, _, _, _]` not covered + --> $DIR/non-exhaustive-match.rs:47:11 + | +LL | match *vec { + | ^^^^ pattern `[_, _, _, _]` not covered + | + = 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/non-exhaustive-pattern-witness.rs b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs new file mode 100644 index 00000000000..4ca1cbcebcc --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.rs @@ -0,0 +1,91 @@ +#![feature(slice_patterns)] + +struct Foo { + first: bool, + second: Option<[usize; 4]> +} + +fn struct_with_a_nested_enum_and_vector() { + match (Foo { first: true, second: None }) { +//~^ ERROR non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered + Foo { first: true, second: None } => (), + Foo { first: true, second: Some(_) } => (), + Foo { first: false, second: None } => (), + Foo { first: false, second: Some([1, 2, 3, 4]) } => () + } +} + +enum Color { + Red, + Green, + CustomRGBA { a: bool, r: u8, g: u8, b: u8 } +} + +fn enum_with_single_missing_variant() { + match Color::Red { + //~^ ERROR non-exhaustive patterns: `Red` not covered + Color::CustomRGBA { .. } => (), + Color::Green => () + } +} + +enum Direction { + North, East, South, West +} + +fn enum_with_multiple_missing_variants() { + match Direction::North { + //~^ ERROR non-exhaustive patterns: `East`, `South` and `West` not covered + Direction::North => () + } +} + +enum ExcessiveEnum { + First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth +} + +fn enum_with_excessive_missing_variants() { + match ExcessiveEnum::First { + //~^ ERROR `Second`, `Third`, `Fourth` and 8 more not covered + + ExcessiveEnum::First => () + } +} + +fn enum_struct_variant() { + match Color::Red { + //~^ ERROR non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered + Color::Red => (), + Color::Green => (), + Color::CustomRGBA { a: false, r: _, g: _, b: 0 } => (), + Color::CustomRGBA { a: false, r: _, g: _, b: _ } => () + } +} + +enum Enum { + First, + Second(bool) +} + +fn vectors_with_nested_enums() { + let x: &'static [Enum] = &[Enum::First, Enum::Second(false)]; + match *x { + //~^ ERROR non-exhaustive patterns: `[Second(true), Second(false)]` not covered + [] => (), + [_] => (), + [Enum::First, _] => (), + [Enum::Second(true), Enum::First] => (), + [Enum::Second(true), Enum::Second(true)] => (), + [Enum::Second(false), _] => (), + [_, _, ref tail @ .., _] => () + } +} + +fn missing_nil() { + match ((), false) { + //~^ ERROR non-exhaustive patterns: `((), false)` not covered + ((), true) => () + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr new file mode 100644 index 00000000000..a0b497dd4c0 --- /dev/null +++ b/src/test/ui/pattern/usefulness/non-exhaustive-pattern-witness.stderr @@ -0,0 +1,95 @@ +error[E0004]: non-exhaustive patterns: `Foo { first: false, second: Some([_, _, _, _]) }` not covered + --> $DIR/non-exhaustive-pattern-witness.rs:9:11 + | +LL | / struct Foo { +LL | | first: bool, +LL | | second: Option<[usize; 4]> +LL | | } + | |_- `Foo` defined here +... +LL | match (Foo { first: true, second: None }) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pattern `Foo { first: false, second: Some([_, _, _, _]) }` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `Red` not covered + --> $DIR/non-exhaustive-pattern-witness.rs:25:11 + | +LL | / enum Color { +LL | | Red, + | | --- not covered +LL | | Green, +LL | | CustomRGBA { a: bool, r: u8, g: u8, b: u8 } +LL | | } + | |_- `Color` defined here +... +LL | match Color::Red { + | ^^^^^^^^^^ pattern `Red` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `East`, `South` and `West` not covered + --> $DIR/non-exhaustive-pattern-witness.rs:37:11 + | +LL | / enum Direction { +LL | | North, East, South, West + | | ---- ----- ---- not covered + | | | | + | | | not covered + | | not covered +LL | | } + | |_- `Direction` defined here +... +LL | match Direction::North { + | ^^^^^^^^^^^^^^^^ patterns `East`, `South` and `West` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `Second`, `Third`, `Fourth` and 8 more not covered + --> $DIR/non-exhaustive-pattern-witness.rs:48:11 + | +LL | / enum ExcessiveEnum { +LL | | First, Second, Third, Fourth, Fifth, Sixth, Seventh, Eighth, Ninth, Tenth, Eleventh, Twelfth +LL | | } + | |_- `ExcessiveEnum` defined here +... +LL | match ExcessiveEnum::First { + | ^^^^^^^^^^^^^^^^^^^^ patterns `Second`, `Third`, `Fourth` and 8 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `CustomRGBA { a: true, .. }` not covered + --> $DIR/non-exhaustive-pattern-witness.rs:56:11 + | +LL | / enum Color { +LL | | Red, +LL | | Green, +LL | | CustomRGBA { a: bool, r: u8, g: u8, b: u8 } + | | ---------- not covered +LL | | } + | |_- `Color` defined here +... +LL | match Color::Red { + | ^^^^^^^^^^ pattern `CustomRGBA { a: true, .. }` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `[Second(true), Second(false)]` not covered + --> $DIR/non-exhaustive-pattern-witness.rs:72:11 + | +LL | match *x { + | ^^ pattern `[Second(true), Second(false)]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error[E0004]: non-exhaustive patterns: `((), false)` not covered + --> $DIR/non-exhaustive-pattern-witness.rs:85:11 + | +LL | match ((), false) { + | ^^^^^^^^^^^ pattern `((), false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + +error: aborting due to 7 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/refutable-pattern-errors.rs b/src/test/ui/pattern/usefulness/refutable-pattern-errors.rs new file mode 100644 index 00000000000..d4afe17ca74 --- /dev/null +++ b/src/test/ui/pattern/usefulness/refutable-pattern-errors.rs @@ -0,0 +1,9 @@ +// ignore-tidy-linelength + +fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { } +//~^ ERROR refutable pattern in function argument: `(_, _)` not covered + +fn main() { + let (1, (Some(1), 2..=3)) = (1, (None, 2)); + //~^ ERROR refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` and `(2i32..=std::i32::MAX, _)` not covered +} diff --git a/src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr b/src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr new file mode 100644 index 00000000000..0cf5d9cd5f1 --- /dev/null +++ b/src/test/ui/pattern/usefulness/refutable-pattern-errors.stderr @@ -0,0 +1,22 @@ +error[E0005]: refutable pattern in function argument: `(_, _)` not covered + --> $DIR/refutable-pattern-errors.rs:3:9 + | +LL | fn func((1, (Some(1), 2..=3)): (isize, (Option<isize>, isize))) { } + | ^^^^^^^^^^^^^^^^^^^^^ pattern `(_, _)` not covered + +error[E0005]: refutable pattern in local binding: `(std::i32::MIN..=0i32, _)` and `(2i32..=std::i32::MAX, _)` not covered + --> $DIR/refutable-pattern-errors.rs:7:9 + | +LL | let (1, (Some(1), 2..=3)) = (1, (None, 2)); + | ^^^^^^^^^^^^^^^^^^^^^ patterns `(std::i32::MIN..=0i32, _)` and `(2i32..=std::i32::MAX, _)` 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 +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let (1, (Some(1), 2..=3)) = (1, (None, 2)) { /* */ } + | + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs b/src/test/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs new file mode 100644 index 00000000000..a2d9e1935de --- /dev/null +++ b/src/test/ui/pattern/usefulness/refutable-pattern-in-fn-arg.rs @@ -0,0 +1,5 @@ +fn main() { + let f = |3: isize| println!("hello"); + //~^ ERROR refutable pattern in function argument: `_` not covered + f(4); +} diff --git a/src/test/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr b/src/test/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr new file mode 100644 index 00000000000..8666e6bb73e --- /dev/null +++ b/src/test/ui/pattern/usefulness/refutable-pattern-in-fn-arg.stderr @@ -0,0 +1,9 @@ +error[E0005]: refutable pattern in function argument: `_` not covered + --> $DIR/refutable-pattern-in-fn-arg.rs:2:14 + | +LL | let f = |3: isize| println!("hello"); + | ^ pattern `_` not covered + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs new file mode 100644 index 00000000000..b1fc0f5ad3e --- /dev/null +++ b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.rs @@ -0,0 +1,12 @@ +enum A { + B { x: Option<isize> }, + C +} + +fn main() { + let x = A::B { x: Some(3) }; + match x { //~ ERROR non-exhaustive patterns + A::C => {} + A::B { x: None } => {} + } +} diff --git a/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr new file mode 100644 index 00000000000..d6b5af17964 --- /dev/null +++ b/src/test/ui/pattern/usefulness/struct-like-enum-nonexhaustive.stderr @@ -0,0 +1,18 @@ +error[E0004]: non-exhaustive patterns: `B { x: Some(_) }` not covered + --> $DIR/struct-like-enum-nonexhaustive.rs:8:11 + | +LL | / enum A { +LL | | B { x: Option<isize> }, + | | - not covered +LL | | C +LL | | } + | |_- `A` defined here +... +LL | match x { + | ^ pattern `B { x: Some(_) }` 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 + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/struct-pattern-match-useless.rs b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.rs new file mode 100644 index 00000000000..93f0a931761 --- /dev/null +++ b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.rs @@ -0,0 +1,15 @@ +#![deny(unreachable_patterns)] + +struct Foo { + x: isize, + y: isize, +} + +pub fn main() { + let a = Foo { x: 1, y: 2 }; + match a { + Foo { x: _x, y: _y } => (), + Foo { .. } => () //~ ERROR unreachable pattern + } + +} diff --git a/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr new file mode 100644 index 00000000000..5b0c9305448 --- /dev/null +++ b/src/test/ui/pattern/usefulness/struct-pattern-match-useless.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/struct-pattern-match-useless.rs:12:9 + | +LL | Foo { .. } => () + | ^^^^^^^^^^ + | +note: lint level defined here + --> $DIR/struct-pattern-match-useless.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs new file mode 100644 index 00000000000..76bcf3fbd4d --- /dev/null +++ b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.rs @@ -0,0 +1,9 @@ +struct Foo(isize, isize); + +fn main() { + let x = Foo(1, 2); + match x { //~ ERROR non-exhaustive + Foo(1, b) => println!("{}", b), + Foo(2, b) => println!("{}", b) + } +} diff --git a/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr new file mode 100644 index 00000000000..bbdf9ceed23 --- /dev/null +++ b/src/test/ui/pattern/usefulness/tuple-struct-nonexhaustive.stderr @@ -0,0 +1,14 @@ +error[E0004]: non-exhaustive patterns: `Foo(_, _)` not covered + --> $DIR/tuple-struct-nonexhaustive.rs:5:11 + | +LL | struct Foo(isize, isize); + | ------------------------- `Foo` defined here +... +LL | match x { + | ^ pattern `Foo(_, _)` 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 + +For more information about this error, try `rustc --explain E0004`. |
