diff options
| author | bors <bors@rust-lang.org> | 2020-11-22 18:29:38 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-11-22 18:29:38 +0000 |
| commit | c643dd2ec8fed2852f5eee8f776d657293a6a8f2 (patch) | |
| tree | af4808d37329c7591dead286316631357f5f7947 /src/test/ui/pattern | |
| parent | 52e3cf13aa9716f6648b1cad286ccd8d37aa315f (diff) | |
| parent | 3213efcd9ab32cbe4e69c4322e6a992a9e64f0ff (diff) | |
| download | rust-c643dd2ec8fed2852f5eee8f776d657293a6a8f2.tar.gz rust-c643dd2ec8fed2852f5eee8f776d657293a6a8f2.zip | |
Auto merge of #79243 - Nadrieril:consolidate-tests, r=varkor
Consolidate exhaustiveness-related tests I hunted for tests that only exercised the match exhaustiveness algorithm and regrouped them. I also improved integer-range tests since I had found them lacking while hacking around. The interest is mainly so that one can pass `--test-args patterns` and catch most relevant tests. r? `@varkor` `@rustbot` modify labels: +A-exhaustiveness-checking
Diffstat (limited to 'src/test/ui/pattern')
66 files changed, 1524 insertions, 601 deletions
diff --git a/src/test/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs b/src/test/ui/pattern/integer-range-binding.rs index ff065882d96..ff065882d96 100644 --- a/src/test/ui/pattern/usefulness/irrefutable-exhaustive-integer-binding.rs +++ b/src/test/ui/pattern/integer-range-binding.rs diff --git a/src/test/ui/pattern/const-pat-ice.rs b/src/test/ui/pattern/usefulness/const-pat-ice.rs index abfacf3936b..abfacf3936b 100644 --- a/src/test/ui/pattern/const-pat-ice.rs +++ b/src/test/ui/pattern/usefulness/const-pat-ice.rs diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.rs b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.rs index 14040c8ada6..14040c8ada6 100644 --- a/src/test/ui/pattern/deny-irrefutable-let-patterns.rs +++ b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.rs diff --git a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr index 308a6c7c58e..308a6c7c58e 100644 --- a/src/test/ui/pattern/deny-irrefutable-let-patterns.stderr +++ b/src/test/ui/pattern/usefulness/deny-irrefutable-let-patterns.stderr diff --git a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs deleted file mode 100644 index 78cc0d28fb0..00000000000 --- a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.rs +++ /dev/null @@ -1,172 +0,0 @@ -#![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 => {} - } - - const FOO: i32 = 42; - const BAR: &i32 = &42; - match &0 { - &42 => {} - &FOO => {} //~ ERROR unreachable pattern - BAR => {} //~ ERROR unreachable pattern - _ => {} - } - - // Regression test, see https://github.com/rust-lang/rust/pull/66326#issuecomment-552889933 - match &0 { - BAR => {} // ok - _ => {} - } -} diff --git a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr b/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr deleted file mode 100644 index 9f076c50a8f..00000000000 --- a/src/test/ui/pattern/usefulness/exhaustive_integer_patterns.stderr +++ /dev/null @@ -1,146 +0,0 @@ -error: unreachable pattern - --> $DIR/exhaustive_integer_patterns.rs:23:9 - | -LL | 200 => {} - | ^^^ - | -note: the lint level is defined here - --> $DIR/exhaustive_integer_patterns.rs:3:9 - | -LL | #![deny(unreachable_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered - --> $DIR/exhaustive_integer_patterns.rs:28:11 - | -LL | match x { - | ^ pattern `128_u8..=u8::MAX` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `u8` - -error[E0004]: non-exhaustive patterns: `11_u8..=19_u8`, `31_u8..=34_u8`, `36_u8..=69_u8` and 1 more not covered - --> $DIR/exhaustive_integer_patterns.rs:33:11 - | -LL | match x { - | ^ patterns `11_u8..=19_u8`, `31_u8..=34_u8`, `36_u8..=69_u8` and 1 more not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `u8` - -error: unreachable pattern - --> $DIR/exhaustive_integer_patterns.rs:44:9 - | -LL | -2..=20 => {} - | ^^^^^^^ - -error[E0004]: non-exhaustive patterns: `i8::MIN..=-8_i8`, `-6_i8`, `121_i8..=124_i8` and 1 more not covered - --> $DIR/exhaustive_integer_patterns.rs:41:11 - | -LL | match x { - | ^ patterns `i8::MIN..=-8_i8`, `-6_i8`, `121_i8..=124_i8` and 1 more not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `i8` - -error[E0004]: non-exhaustive patterns: `i8::MIN` not covered - --> $DIR/exhaustive_integer_patterns.rs:83:11 - | -LL | match 0i8 { - | ^^^ pattern `i8::MIN` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `i8` - -error[E0004]: non-exhaustive patterns: `0_i16` not covered - --> $DIR/exhaustive_integer_patterns.rs:91:11 - | -LL | match 0i16 { - | ^^^^ pattern `0_i16` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `i16` - -error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered - --> $DIR/exhaustive_integer_patterns.rs:109:11 - | -LL | match 0u8 { - | ^^^ pattern `128_u8..=u8::MAX` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `u8` - -error[E0004]: non-exhaustive patterns: `(0_u8, Some(_))` and `(2_u8..=u8::MAX, Some(_))` not covered - --> $DIR/exhaustive_integer_patterns.rs:121:11 - | -LL | match (0u8, Some(())) { - | ^^^^^^^^^^^^^^^ patterns `(0_u8, Some(_))` and `(2_u8..=u8::MAX, Some(_))` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `(u8, Option<()>)` - -error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered - --> $DIR/exhaustive_integer_patterns.rs:126:11 - | -LL | match (0u8, true) { - | ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `(u8, bool)` - -error: multiple patterns covering the same range - --> $DIR/exhaustive_integer_patterns.rs:141:9 - | -LL | 0 .. 2 => {} - | ------ this range overlaps on `1_u8` -LL | 1 ..= 2 => {} - | ^^^^^^^ overlapping patterns - | -note: the lint level is defined here - --> $DIR/exhaustive_integer_patterns.rs:4:9 - | -LL | #![deny(overlapping_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -error[E0004]: non-exhaustive patterns: `u128::MAX` not covered - --> $DIR/exhaustive_integer_patterns.rs:146:11 - | -LL | match 0u128 { - | ^^^^^ pattern `u128::MAX` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `u128` - -error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered - --> $DIR/exhaustive_integer_patterns.rs:150:11 - | -LL | match 0u128 { - | ^^^^^ pattern `5_u128..=u128::MAX` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `u128` - -error[E0004]: non-exhaustive patterns: `0_u128..=3_u128` not covered - --> $DIR/exhaustive_integer_patterns.rs:154:11 - | -LL | match 0u128 { - | ^^^^^ pattern `0_u128..=3_u128` not covered - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `u128` - -error: unreachable pattern - --> $DIR/exhaustive_integer_patterns.rs:162:9 - | -LL | &FOO => {} - | ^^^^ - -error: unreachable pattern - --> $DIR/exhaustive_integer_patterns.rs:163:9 - | -LL | BAR => {} - | ^^^ - -error: aborting due to 16 previous errors - -For more information about this 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/floats.rs index 588fecbf10d..095f5ac9a89 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.rs +++ b/src/test/ui/pattern/usefulness/floats.rs @@ -10,4 +10,10 @@ fn main() { match 0.0 { //~ ERROR non-exhaustive patterns 0.0..=1.0 => {} } + + match 1.0f64 { + 0.01f64 ..= 6.5f64 => {} + 0.02f64 => {} //~ ERROR unreachable pattern + _ => {} + }; } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr b/src/test/ui/pattern/usefulness/floats.stderr index 4835fa86cc0..464bfbdb2c3 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-float-range-match.stderr +++ b/src/test/ui/pattern/usefulness/floats.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/non-exhaustive-float-range-match.rs:10:11 + --> $DIR/floats.rs:10:11 | LL | match 0.0 { | ^^^ pattern `_` not covered @@ -7,6 +7,18 @@ LL | match 0.0 { = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `f64` -error: aborting due to previous error +error: unreachable pattern + --> $DIR/floats.rs:16:7 + | +LL | 0.02f64 => {} + | ^^^^^^^ + | +note: the lint level is defined here + --> $DIR/floats.rs:2:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +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/guards-not-exhaustive.rs b/src/test/ui/pattern/usefulness/guards-not-exhaustive.rs deleted file mode 100644 index b74f162c0c6..00000000000 --- a/src/test/ui/pattern/usefulness/guards-not-exhaustive.rs +++ /dev/null @@ -1,18 +0,0 @@ -// 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/usefulness/guards.rs b/src/test/ui/pattern/usefulness/guards.rs new file mode 100644 index 00000000000..b15440cf608 --- /dev/null +++ b/src/test/ui/pattern/usefulness/guards.rs @@ -0,0 +1,22 @@ +#![feature(exclusive_range_pattern)] +#![deny(unreachable_patterns)] + +enum Q { R(Option<usize>) } + +pub fn main() { + match Q::R(None) { + Q::R(S) if S.is_some() => {} + _ => {} + } + + 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 + } +} diff --git a/src/test/ui/pattern/usefulness/guards.stderr b/src/test/ui/pattern/usefulness/guards.stderr new file mode 100644 index 00000000000..61f7facb330 --- /dev/null +++ b/src/test/ui/pattern/usefulness/guards.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: `128_u8..=u8::MAX` not covered + --> $DIR/guards.rs:12:11 + | +LL | match 0u8 { + | ^^^ pattern `128_u8..=u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u8` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs new file mode 100644 index 00000000000..5a44dfc28bb --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs @@ -0,0 +1,101 @@ +#![feature(exclusive_range_pattern)] +#![feature(assoc_char_consts)] +#![deny(unreachable_patterns)] + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +macro_rules! test_int { + ($s:expr, $min:path, $max:path) => { + m!($s, $min..=$max); + m!($s, $min..5 | 5..=$max); + m!($s, $min..=4 | 5..=$max); + m!($s, $min..$max | $max); + m!(($s, true), ($min..5, true) | (5..=$max, true) | ($min..=$max, false)); + } +} + +fn main() { + test_int!(0u8, u8::MIN, u8::MAX); + test_int!(0u16, u16::MIN, u16::MAX); + test_int!(0u32, u32::MIN, u32::MAX); + test_int!(0u64, u64::MIN, u64::MAX); + test_int!(0u128, u128::MIN, u128::MAX); + + test_int!(0i8, i8::MIN, i8::MAX); + test_int!(0i16, i16::MIN, i16::MAX); + test_int!(0i32, i32::MIN, i32::MAX); + test_int!(0i64, i64::MIN, i64::MAX); + test_int!(0i128, i128::MIN, i128::MAX); + + m!('a', '\u{0}'..=char::MAX); + m!('a', '\u{0}'..='\u{10_FFFF}'); + // We can get away with just covering the following two ranges, which correspond to all valid + // Unicode Scalar Values. + m!('a', '\u{0}'..='\u{D7FF}' | '\u{E000}'..=char::MAX); + m!('a', '\u{0}'..'\u{D7FF}' | '\u{D7FF}' | '\u{E000}'..=char::MAX); + + let 0..=255 = 0u8; + let -128..=127 = 0i8; + let -2147483648..=2147483647 = 0i32; + let '\u{0000}'..='\u{10FFFF}' = 'v'; + + // Almost exhaustive + m!(0u8, 0..255); //~ ERROR non-exhaustive patterns + m!(0u8, 0..=254); //~ ERROR non-exhaustive patterns + m!(0u8, 1..=255); //~ ERROR non-exhaustive patterns + m!(0u8, 0..42 | 43..=255); //~ ERROR non-exhaustive patterns + m!(0i8, -128..127); //~ ERROR non-exhaustive patterns + m!(0i8, -128..=126); //~ ERROR non-exhaustive patterns + m!(0i8, -127..=127); //~ ERROR non-exhaustive patterns + match 0i8 { //~ ERROR non-exhaustive patterns + i8::MIN ..= -1 => {} + 1 ..= i8::MAX => {} + } + const ALMOST_MAX: u128 = u128::MAX - 1; + m!(0u128, 0..=ALMOST_MAX); //~ ERROR non-exhaustive patterns + m!(0u128, 0..=4); //~ ERROR non-exhaustive patterns + m!(0u128, 1..=u128::MAX); //~ ERROR non-exhaustive patterns + + // More complicatedly (non-)exhaustive + match 0u8 { + 0 ..= 30 => {} + 20 ..= 70 => {} + 50 ..= 255 => {} + } + 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 (true, 0u8) { + (true, 0 ..= 255) => {} + (false, 0 ..= 125) => {} + (false, 128 ..= 255) => {} + (false, 125 .. 128) => {} + } + match Some(0u8) { + None => {} + Some(0 ..= 125) => {} + Some(128 ..= 255) => {} + Some(125 .. 128) => {} + } + const FOO: u8 = 41; + const BAR: &u8 = &42; + match &0u8 { + 0..41 => {} + &FOO => {} + BAR => {} + 43..=255 => {} + } + +} diff --git a/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr new file mode 100644 index 00000000000..2e0023348e4 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr @@ -0,0 +1,111 @@ +error[E0004]: non-exhaustive patterns: `u8::MAX` not covered + --> $DIR/exhaustiveness.rs:47:8 + | +LL | m!(0u8, 0..255); + | ^^^ pattern `u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u8` + +error[E0004]: non-exhaustive patterns: `u8::MAX` not covered + --> $DIR/exhaustiveness.rs:48:8 + | +LL | m!(0u8, 0..=254); + | ^^^ pattern `u8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u8` + +error[E0004]: non-exhaustive patterns: `0_u8` not covered + --> $DIR/exhaustiveness.rs:49:8 + | +LL | m!(0u8, 1..=255); + | ^^^ pattern `0_u8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u8` + +error[E0004]: non-exhaustive patterns: `42_u8` not covered + --> $DIR/exhaustiveness.rs:50:8 + | +LL | m!(0u8, 0..42 | 43..=255); + | ^^^ pattern `42_u8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u8` + +error[E0004]: non-exhaustive patterns: `i8::MAX` not covered + --> $DIR/exhaustiveness.rs:51:8 + | +LL | m!(0i8, -128..127); + | ^^^ pattern `i8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `i8` + +error[E0004]: non-exhaustive patterns: `i8::MAX` not covered + --> $DIR/exhaustiveness.rs:52:8 + | +LL | m!(0i8, -128..=126); + | ^^^ pattern `i8::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `i8` + +error[E0004]: non-exhaustive patterns: `i8::MIN` not covered + --> $DIR/exhaustiveness.rs:53:8 + | +LL | m!(0i8, -127..=127); + | ^^^ pattern `i8::MIN` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `i8` + +error[E0004]: non-exhaustive patterns: `0_i8` not covered + --> $DIR/exhaustiveness.rs:54:11 + | +LL | match 0i8 { + | ^^^ pattern `0_i8` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `i8` + +error[E0004]: non-exhaustive patterns: `u128::MAX` not covered + --> $DIR/exhaustiveness.rs:59:8 + | +LL | m!(0u128, 0..=ALMOST_MAX); + | ^^^^^ pattern `u128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u128` + +error[E0004]: non-exhaustive patterns: `5_u128..=u128::MAX` not covered + --> $DIR/exhaustiveness.rs:60:8 + | +LL | m!(0u128, 0..=4); + | ^^^^^ pattern `5_u128..=u128::MAX` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u128` + +error[E0004]: non-exhaustive patterns: `0_u128` not covered + --> $DIR/exhaustiveness.rs:61:8 + | +LL | m!(0u128, 1..=u128::MAX); + | ^^^^^ pattern `0_u128` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `u128` + +error[E0004]: non-exhaustive patterns: `(126_u8..=127_u8, false)` not covered + --> $DIR/exhaustiveness.rs:69:11 + | +LL | match (0u8, true) { + | ^^^^^^^^^^^ pattern `(126_u8..=127_u8, false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `(u8, bool)` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs new file mode 100644 index 00000000000..af720a05693 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs @@ -0,0 +1,53 @@ +#![feature(exclusive_range_pattern)] +#![deny(overlapping_patterns)] + +macro_rules! m { + ($s:expr, $t1:pat, $t2:pat) => { + match $s { + $t1 => {} + $t2 => {} + _ => {} + } + } +} + +fn main() { + m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns covering the same range + m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns covering the same range + m!(0u8, 20..=30, 31..=40); + m!(0u8, 20..=30, 29..=40); + m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns covering the same range + m!(0u8, 20.. 30, 28..=40); + m!(0u8, 20.. 30, 30..=40); + m!(0u8, 20..=30, 30..=30); + m!(0u8, 20..=30, 30..=31); //~ ERROR multiple patterns covering the same range + m!(0u8, 20..=30, 29..=30); + m!(0u8, 20..=30, 20..=20); + m!(0u8, 20..=30, 20..=21); + m!(0u8, 20..=30, 19..=20); //~ ERROR multiple patterns covering the same range + m!(0u8, 20..=30, 20); + m!(0u8, 20..=30, 25); + m!(0u8, 20..=30, 30); + m!(0u8, 20.. 30, 29); + m!(0u8, 20, 20..=30); //~ ERROR multiple patterns covering the same range + m!(0u8, 25, 20..=30); + m!(0u8, 30, 20..=30); //~ ERROR multiple patterns covering the same range + + match (0u8, true) { + (0..=10, true) => {} + (10..20, true) => {} // not detected + (10..20, false) => {} + _ => {} + } + match (true, 0u8) { + (true, 0..=10) => {} + (true, 10..20) => {} //~ ERROR multiple patterns covering the same range + (false, 10..20) => {} + _ => {} + } + match Some(0u8) { + Some(0..=10) => {} + Some(10..20) => {} //~ ERROR multiple patterns covering the same range + _ => {} + } +} diff --git a/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr new file mode 100644 index 00000000000..7bb747cdf6f --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -0,0 +1,80 @@ +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:15:22 + | +LL | m!(0u8, 20..=30, 30..=40); + | ------- ^^^^^^^ overlapping patterns + | | + | this range overlaps on `30_u8` + | +note: the lint level is defined here + --> $DIR/overlapping_range_endpoints.rs:2:9 + | +LL | #![deny(overlapping_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:16:22 + | +LL | m!(0u8, 30..=40, 20..=30); + | ------- ^^^^^^^ overlapping patterns + | | + | this range overlaps on `30_u8` + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:19:22 + | +LL | m!(0u8, 20.. 30, 29..=40); + | ------- ^^^^^^^ overlapping patterns + | | + | this range overlaps on `29_u8` + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:23:22 + | +LL | m!(0u8, 20..=30, 30..=31); + | ------- ^^^^^^^ overlapping patterns + | | + | this range overlaps on `30_u8` + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:27:22 + | +LL | m!(0u8, 20..=30, 19..=20); + | ------- ^^^^^^^ overlapping patterns + | | + | this range overlaps on `20_u8` + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:32:17 + | +LL | m!(0u8, 20, 20..=30); + | -- ^^^^^^^ overlapping patterns + | | + | this range overlaps on `20_u8` + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:34:17 + | +LL | m!(0u8, 30, 20..=30); + | -- ^^^^^^^ overlapping patterns + | | + | this range overlaps on `30_u8` + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:44:16 + | +LL | (true, 0..=10) => {} + | ------ this range overlaps on `10_u8` +LL | (true, 10..20) => {} + | ^^^^^^ overlapping patterns + +error: multiple patterns covering the same range + --> $DIR/overlapping_range_endpoints.rs:50:14 + | +LL | Some(0..=10) => {} + | ------ this range overlaps on `10_u8` +LL | Some(10..20) => {} + | ^^^^^^ overlapping patterns + +error: aborting due to 9 previous errors + diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.rs b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.rs new file mode 100644 index 00000000000..6173053cc4f --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.rs @@ -0,0 +1,38 @@ +#![feature(precise_pointer_size_matching)] +#![feature(exclusive_range_pattern)] + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +fn main() { + match 0usize { + 0 ..= usize::MAX => {} + } + + match 0isize { + isize::MIN ..= isize::MAX => {} + } + + m!(0usize, 0..=usize::MAX); + m!(0usize, 0..5 | 5..=usize::MAX); + m!(0usize, 0..usize::MAX | usize::MAX); + m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); + + m!(0isize, isize::MIN..=isize::MAX); + m!(0isize, isize::MIN..5 | 5..=isize::MAX); + m!(0isize, isize::MIN..isize::MAX | isize::MAX); + m!((0isize, true), (isize::MIN..5, true) + | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false)); + + match 0isize { + isize::MIN ..= -1 => {} + 0 => {} + 1 ..= isize::MAX => {} + } + + match 7usize {} + //~^ ERROR non-exhaustive patterns +} diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.stderr new file mode 100644 index 00000000000..0b3c65166ee --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-allow.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: type `usize` is non-empty + --> $DIR/pointer-sized-int-allow.rs:36:11 + | +LL | match 7usize {} + | ^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `usize` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.rs b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.rs new file mode 100644 index 00000000000..9292f22e09e --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.rs @@ -0,0 +1,48 @@ +#![feature(exclusive_range_pattern)] + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +fn main() { + match 0usize { + //~^ ERROR non-exhaustive patterns + 0 ..= usize::MAX => {} + } + + match 0isize { + //~^ ERROR non-exhaustive patterns + isize::MIN ..= isize::MAX => {} + } + + m!(0usize, 0..=usize::MAX); + //~^ ERROR non-exhaustive patterns + m!(0usize, 0..5 | 5..=usize::MAX); + //~^ ERROR non-exhaustive patterns + m!(0usize, 0..usize::MAX | usize::MAX); + //~^ ERROR non-exhaustive patterns + m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); + //~^ ERROR non-exhaustive patterns + + m!(0isize, isize::MIN..=isize::MAX); + //~^ ERROR non-exhaustive patterns + m!(0isize, isize::MIN..5 | 5..=isize::MAX); + //~^ ERROR non-exhaustive patterns + m!(0isize, isize::MIN..isize::MAX | isize::MAX); + //~^ ERROR non-exhaustive patterns + m!((0isize, true), (isize::MIN..5, true) + | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false)); + //~^^ ERROR non-exhaustive patterns + + match 0isize { + //~^ ERROR non-exhaustive patterns + isize::MIN ..= -1 => {} + 0 => {} + 1 ..= isize::MAX => {} + } + + match 7usize {} + //~^ ERROR non-exhaustive patterns +} diff --git a/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.stderr new file mode 100644 index 00000000000..9d566b0e775 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int-deny.stderr @@ -0,0 +1,129 @@ +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:10:11 + | +LL | match 0usize { + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `usize` + = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:15:11 + | +LL | match 0isize { + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `isize` + = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:20:8 + | +LL | m!(0usize, 0..=usize::MAX); + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `usize` + = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:22:8 + | +LL | m!(0usize, 0..5 | 5..=usize::MAX); + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `usize` + = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:24:8 + | +LL | m!(0usize, 0..usize::MAX | usize::MAX); + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `usize` + = note: `usize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching + +error[E0004]: non-exhaustive patterns: `(_, _)` not covered + --> $DIR/pointer-sized-int-deny.rs:26:8 + | +LL | m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); + | ^^^^^^^^^^^^^^ pattern `(_, _)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `(usize, bool)` + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:29:8 + | +LL | m!(0isize, isize::MIN..=isize::MAX); + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `isize` + = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:31:8 + | +LL | m!(0isize, isize::MIN..5 | 5..=isize::MAX); + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `isize` + = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:33:8 + | +LL | m!(0isize, isize::MIN..isize::MAX | isize::MAX); + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `isize` + = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching + +error[E0004]: non-exhaustive patterns: `(_, _)` not covered + --> $DIR/pointer-sized-int-deny.rs:35:8 + | +LL | m!((0isize, true), (isize::MIN..5, true) + | ^^^^^^^^^^^^^^ pattern `(_, _)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `(isize, bool)` + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int-deny.rs:39:11 + | +LL | match 0isize { + | ^^^^^^ pattern `_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `isize` + = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively + = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching + +error[E0004]: non-exhaustive patterns: type `usize` is non-empty + --> $DIR/pointer-sized-int-deny.rs:46:11 + | +LL | match 7usize {} + | ^^^^^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `usize` + +error: aborting due to 12 previous errors + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs index 0c52876e21f..a2aa655ca54 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.rs +++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs @@ -1,23 +1,18 @@ -use std::{usize, isize}; - +// This tests that the lint message explains the reason for the error. fn main() { match 0usize { - //~^ ERROR non-exhaustive patterns + //~^ ERROR non-exhaustive patterns: `_` not covered //~| NOTE pattern `_` not covered //~| NOTE the matched value is of type `usize` //~| NOTE `usize` does not have a fixed maximum value - 0 ..= usize::MAX => {} + 0..=usize::MAX => {} } match 0isize { - //~^ ERROR non-exhaustive patterns + //~^ ERROR non-exhaustive patterns: `_` not covered //~| NOTE pattern `_` not covered //~| NOTE the matched value is of type `isize` //~| NOTE `isize` does not have a fixed maximum value - isize::MIN ..= isize::MAX => {} + isize::MIN..=isize::MAX => {} } - - match 7usize {} - //~^ ERROR non-exhaustive patterns - //~| NOTE the matched value is of type `usize` } diff --git a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.stderr b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr index d0aa452fd38..37e73a68f22 100644 --- a/src/test/ui/pattern/usefulness/non-exhaustive-pattern-pointer-size-int.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:4:11 + --> $DIR/precise_pointer_matching-message.rs:3:11 | LL | match 0usize { | ^^^^^^ pattern `_` not covered @@ -10,7 +10,7 @@ LL | match 0usize { = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `usize` matching error[E0004]: non-exhaustive patterns: `_` not covered - --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:12:11 + --> $DIR/precise_pointer_matching-message.rs:11:11 | LL | match 0isize { | ^^^^^^ pattern `_` not covered @@ -20,15 +20,6 @@ LL | match 0isize { = note: `isize` does not have a fixed maximum value, so a wildcard `_` is necessary to match exhaustively = help: add `#![feature(precise_pointer_size_matching)]` to the crate attributes to enable precise `isize` matching -error[E0004]: non-exhaustive patterns: type `usize` is non-empty - --> $DIR/non-exhaustive-pattern-pointer-size-int.rs:20:11 - | -LL | match 7usize {} - | ^^^^^^ - | - = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms - = note: the matched value is of type `usize` - -error: aborting due to 3 previous errors +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/integer-ranges/reachability.rs b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs new file mode 100644 index 00000000000..9078e65f667 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs @@ -0,0 +1,112 @@ +#![feature(exclusive_range_pattern)] +#![deny(unreachable_patterns)] + +macro_rules! m { + ($s:expr, $t1:pat, $t2:pat) => { + match $s { + $t1 => {} + $t2 => {} + _ => {} + } + } +} + +fn main() { + m!(0u8, 42, 41); + m!(0u8, 42, 42); //~ ERROR unreachable pattern + m!(0u8, 42, 43); + + m!(0u8, 20..=30, 19); + m!(0u8, 20..=30, 20); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 21); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 25); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 29); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 30); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 31); + m!(0u8, 20..30, 19); + m!(0u8, 20..30, 20); //~ ERROR unreachable pattern + m!(0u8, 20..30, 21); //~ ERROR unreachable pattern + m!(0u8, 20..30, 25); //~ ERROR unreachable pattern + m!(0u8, 20..30, 29); //~ ERROR unreachable pattern + m!(0u8, 20..30, 30); + m!(0u8, 20..30, 31); + + m!(0u8, 20..=30, 20..=30); //~ ERROR unreachable pattern + m!(0u8, 20.. 30, 20.. 30); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 20.. 30); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 19..=30); + m!(0u8, 20..=30, 21..=30); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 20..=29); //~ ERROR unreachable pattern + m!(0u8, 20..=30, 20..=31); + m!('a', 'A'..='z', 'a'..='z'); //~ ERROR unreachable pattern + + match 0u8 { + 5 => {}, + 6 => {}, + 7 => {}, + 8 => {}, + 5..=8 => {}, //~ ERROR unreachable pattern + _ => {}, + } + match 0u8 { + 0..10 => {}, + 10..20 => {}, + 5..15 => {}, //~ ERROR unreachable pattern + _ => {}, + } + match 0u8 { + 0..10 => {}, + 10..20 => {}, + 20..30 => {}, + 5..25 => {}, //~ ERROR unreachable pattern + _ => {}, + } + match 0u8 { + 0..10 => {}, + 10 => {}, + 11..=23 => {}, + 19..30 => {}, + 5..25 => {}, //~ ERROR unreachable pattern + _ => {}, + } + match 0usize { + 0..10 => {}, + 10..20 => {}, + 5..15 => {}, // FIXME: should be unreachable + _ => {}, + } + // Chars between '\u{D7FF}' and '\u{E000}' are invalid even though ranges that contain them are + // allowed. + match 'a' { + _ => {}, + '\u{D7FF}'..='\u{E000}' => {}, //~ ERROR unreachable pattern + } + match 'a' { + '\u{0}'..='\u{D7FF}' => {}, + '\u{E000}'..='\u{10_FFFF}' => {}, + '\u{D7FF}'..='\u{E000}' => {}, // FIXME should be unreachable + } + + match (0u8, true) { + (0..=255, false) => {} + (0..=255, true) => {} // ok + } + match (true, 0u8) { + (false, 0..=255) => {} + (true, 0..=255) => {} // ok + } + + const FOO: i32 = 42; + const BAR: &i32 = &42; + match &0 { + &42 => {} + &FOO => {} //~ ERROR unreachable pattern + BAR => {} //~ ERROR unreachable pattern + _ => {} + } + // Regression test, see https://github.com/rust-lang/rust/pull/66326#issuecomment-552889933 + match &0 { + BAR => {} // ok + _ => {} + } +} diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr new file mode 100644 index 00000000000..8baf0d50c88 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr @@ -0,0 +1,146 @@ +error: unreachable pattern + --> $DIR/reachability.rs:16:17 + | +LL | m!(0u8, 42, 42); + | ^^ + | +note: the lint level is defined here + --> $DIR/reachability.rs:2:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:20:22 + | +LL | m!(0u8, 20..=30, 20); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:21:22 + | +LL | m!(0u8, 20..=30, 21); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:22:22 + | +LL | m!(0u8, 20..=30, 25); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:23:22 + | +LL | m!(0u8, 20..=30, 29); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:24:22 + | +LL | m!(0u8, 20..=30, 30); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:27:21 + | +LL | m!(0u8, 20..30, 20); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:28:21 + | +LL | m!(0u8, 20..30, 21); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:29:21 + | +LL | m!(0u8, 20..30, 25); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:30:21 + | +LL | m!(0u8, 20..30, 29); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:34:22 + | +LL | m!(0u8, 20..=30, 20..=30); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:35:22 + | +LL | m!(0u8, 20.. 30, 20.. 30); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:36:22 + | +LL | m!(0u8, 20..=30, 20.. 30); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:38:22 + | +LL | m!(0u8, 20..=30, 21..=30); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:39:22 + | +LL | m!(0u8, 20..=30, 20..=29); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:41:24 + | +LL | m!('a', 'A'..='z', 'a'..='z'); + | ^^^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:48:9 + | +LL | 5..=8 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:54:9 + | +LL | 5..15 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:61:9 + | +LL | 5..25 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:69:9 + | +LL | 5..25 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:82:9 + | +LL | '\u{D7FF}'..='\u{E000}' => {}, + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:103:9 + | +LL | &FOO => {} + | ^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:104:9 + | +LL | BAR => {} + | ^^^ + +error: aborting due to 23 previous errors + diff --git a/src/test/ui/pattern/irrefutable-let-patterns.rs b/src/test/ui/pattern/usefulness/irrefutable-let-patterns.rs index d400ef0bbd6..d400ef0bbd6 100644 --- a/src/test/ui/pattern/irrefutable-let-patterns.rs +++ b/src/test/ui/pattern/usefulness/irrefutable-let-patterns.rs diff --git a/src/test/ui/pattern/usefulness/issue-12116.rs b/src/test/ui/pattern/usefulness/issue-12116.rs new file mode 100644 index 00000000000..8b391cd95d7 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-12116.rs @@ -0,0 +1,21 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] +#![allow(dead_code)] +#![allow(unused_variables)] +#![deny(unreachable_patterns)] + +enum IntList { + Cons(isize, Box<IntList>), + Nil +} + +fn tail(source_list: &IntList) -> IntList { + match source_list { + &IntList::Cons(val, box ref next_list) => tail(next_list), + &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil), +//~^ ERROR unreachable pattern + _ => panic!() + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/issue-12116.stderr b/src/test/ui/pattern/usefulness/issue-12116.stderr new file mode 100644 index 00000000000..4d162eb77e7 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-12116.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/issue-12116.rs:15:9 + | +LL | &IntList::Cons(val, box IntList::Nil) => IntList::Cons(val, box IntList::Nil), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-12116.rs:5:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/usefulness/issue-12369.rs b/src/test/ui/pattern/usefulness/issue-12369.rs new file mode 100644 index 00000000000..0481c1fd9e1 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-12369.rs @@ -0,0 +1,11 @@ +#![deny(unreachable_patterns)] + +fn main() { + let sl = vec![1,2,3]; + let v: isize = match &*sl { + &[] => 0, + &[a,b,c] => 3, + &[a, ref rest @ ..] => a, + &[10,a, ref rest @ ..] => 10 //~ ERROR: unreachable pattern + }; +} diff --git a/src/test/ui/pattern/usefulness/issue-12369.stderr b/src/test/ui/pattern/usefulness/issue-12369.stderr new file mode 100644 index 00000000000..aab2be78c9a --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-12369.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/issue-12369.rs:9:9 + | +LL | &[10,a, ref rest @ ..] => 10 + | ^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-12369.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/usefulness/issue-13727.rs b/src/test/ui/pattern/usefulness/issue-13727.rs new file mode 100644 index 00000000000..7fb565ef3bf --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-13727.rs @@ -0,0 +1,15 @@ +#![allow(overflowing_literals)] +#![deny(unreachable_patterns)] + +fn test(val: u8) { + match val { + 256 => print!("0b1110\n"), + 512 => print!("0b1111\n"), + //~^ ERROR: unreachable pattern + _ => print!("fail\n"), + } +} + +fn main() { + test(1); +} diff --git a/src/test/ui/pattern/usefulness/issue-13727.stderr b/src/test/ui/pattern/usefulness/issue-13727.stderr new file mode 100644 index 00000000000..07ca56a566f --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-13727.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/issue-13727.rs:7:5 + | +LL | 512 => print!("0b1111\n"), + | ^^^ + | +note: the lint level is defined here + --> $DIR/issue-13727.rs:2:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/usefulness/issue-15129.rs b/src/test/ui/pattern/usefulness/issue-15129.rs new file mode 100644 index 00000000000..ed134c175ed --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-15129.rs @@ -0,0 +1,17 @@ +pub enum T { + T1(()), + T2(()) +} + +pub enum V { + V1(isize), + V2(bool) +} + +fn main() { + match (T::T1(()), V::V2(true)) { + //~^ ERROR non-exhaustive patterns: `(T1(()), V2(_))` not covered + (T::T1(()), V::V1(i)) => (), + (T::T2(()), V::V2(b)) => () + } +} diff --git a/src/test/ui/pattern/usefulness/issue-15129.stderr b/src/test/ui/pattern/usefulness/issue-15129.stderr new file mode 100644 index 00000000000..aa4434e72b5 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-15129.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: `(T1(()), V2(_))` not covered + --> $DIR/issue-15129.rs:12:11 + | +LL | match (T::T1(()), V::V2(true)) { + | ^^^^^^^^^^^^^^^^^^^^^^^^ pattern `(T1(()), V2(_))` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `(T, V)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-2111.rs b/src/test/ui/pattern/usefulness/issue-2111.rs new file mode 100644 index 00000000000..7e5835e8697 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-2111.rs @@ -0,0 +1,12 @@ +fn foo(a: Option<usize>, b: Option<usize>) { + match (a,b) { + //~^ ERROR: non-exhaustive patterns: `(None, None)` not covered + (Some(a), Some(b)) if a == b => { } + (Some(_), None) | + (None, Some(_)) => { } + } +} + +fn main() { + foo(None, None); +} diff --git a/src/test/ui/pattern/usefulness/issue-2111.stderr b/src/test/ui/pattern/usefulness/issue-2111.stderr new file mode 100644 index 00000000000..a39a479e078 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-2111.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: `(None, None)` not covered + --> $DIR/issue-2111.rs:2:9 + | +LL | match (a,b) { + | ^^^^^ pattern `(None, None)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `(Option<usize>, Option<usize>)` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-30240-b.rs b/src/test/ui/pattern/usefulness/issue-30240-b.rs new file mode 100644 index 00000000000..01a6e7d8cb9 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-30240-b.rs @@ -0,0 +1,15 @@ +#![deny(unreachable_patterns)] + +fn main() { + match "world" { + "hello" => {} + _ => {}, + } + + match "world" { + ref _x if false => {} + "hello" => {} + "hello" => {} //~ ERROR unreachable pattern + _ => {}, + } +} diff --git a/src/test/ui/pattern/usefulness/issue-30240-b.stderr b/src/test/ui/pattern/usefulness/issue-30240-b.stderr new file mode 100644 index 00000000000..59d64bc256b --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-30240-b.stderr @@ -0,0 +1,14 @@ +error: unreachable pattern + --> $DIR/issue-30240-b.rs:12:9 + | +LL | "hello" => {} + | ^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-30240-b.rs:1:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + diff --git a/src/test/ui/pattern/usefulness/issue-30240-rpass.rs b/src/test/ui/pattern/usefulness/issue-30240-rpass.rs new file mode 100644 index 00000000000..ab16614fd30 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-30240-rpass.rs @@ -0,0 +1,14 @@ +// run-pass +fn main() { + let &ref a = &[0i32] as &[_]; + assert_eq!(a, &[0i32] as &[_]); + + let &ref a = "hello"; + assert_eq!(a, "hello"); + + match "foo" { + "fool" => unreachable!(), + "foo" => {}, + ref _x => unreachable!() + } +} diff --git a/src/test/ui/pattern/usefulness/issue-30240.rs b/src/test/ui/pattern/usefulness/issue-30240.rs new file mode 100644 index 00000000000..a0c0d1626ec --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-30240.rs @@ -0,0 +1,10 @@ +fn main() { + match "world" { //~ ERROR non-exhaustive patterns: `&_` + "hello" => {} + } + + match "world" { //~ ERROR non-exhaustive patterns: `&_` + ref _x if false => {} + "hello" => {} + } +} diff --git a/src/test/ui/pattern/usefulness/issue-30240.stderr b/src/test/ui/pattern/usefulness/issue-30240.stderr new file mode 100644 index 00000000000..a2c58d6e051 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-30240.stderr @@ -0,0 +1,21 @@ +error[E0004]: non-exhaustive patterns: `&_` not covered + --> $DIR/issue-30240.rs:2:11 + | +LL | match "world" { + | ^^^^^^^ pattern `&_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `&str` + +error[E0004]: non-exhaustive patterns: `&_` not covered + --> $DIR/issue-30240.rs:6:11 + | +LL | match "world" { + | ^^^^^^^ pattern `&_` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `&str` + +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/issue-3096-1.rs b/src/test/ui/pattern/usefulness/issue-3096-1.rs new file mode 100644 index 00000000000..edc3b322305 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-3096-1.rs @@ -0,0 +1,3 @@ +fn main() { + match () { } //~ ERROR non-exhaustive +} diff --git a/src/test/ui/pattern/usefulness/issue-3096-1.stderr b/src/test/ui/pattern/usefulness/issue-3096-1.stderr new file mode 100644 index 00000000000..97c34755189 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-3096-1.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: type `()` is non-empty + --> $DIR/issue-3096-1.rs:2:11 + | +LL | match () { } + | ^^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `()` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-3096-2.rs b/src/test/ui/pattern/usefulness/issue-3096-2.rs new file mode 100644 index 00000000000..a26e425809f --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-3096-2.rs @@ -0,0 +1,6 @@ +enum Bottom { } + +fn main() { + let x = &() as *const () as *const Bottom; + match x { } //~ ERROR non-exhaustive patterns +} diff --git a/src/test/ui/pattern/usefulness/issue-3096-2.stderr b/src/test/ui/pattern/usefulness/issue-3096-2.stderr new file mode 100644 index 00000000000..472d1a91e6a --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-3096-2.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: type `*const Bottom` is non-empty + --> $DIR/issue-3096-2.rs:5:11 + | +LL | match x { } + | ^ + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `*const Bottom` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-31221.rs b/src/test/ui/pattern/usefulness/issue-31221.rs new file mode 100644 index 00000000000..e03f1ec5bc2 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-31221.rs @@ -0,0 +1,34 @@ +#![allow(dead_code)] +#![allow(unused_variables)] +#![allow(non_snake_case)] +#![deny(unreachable_patterns)] + +#[derive(Clone, Copy)] +enum Enum { + Var1, + Var2, +} + +fn main() { + use Enum::*; + let s = Var1; + match s { + Var1 => (), + Var3 => (), + Var2 => (), + //~^ ERROR unreachable pattern + }; + match &s { + &Var1 => (), + &Var3 => (), + &Var2 => (), + //~^ ERROR unreachable pattern + }; + let t = (Var1, Var1); + match t { + (Var1, b) => (), + (c, d) => (), + anything => () + //~^ ERROR unreachable pattern + }; +} diff --git a/src/test/ui/pattern/usefulness/issue-31221.stderr b/src/test/ui/pattern/usefulness/issue-31221.stderr new file mode 100644 index 00000000000..7d349144456 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-31221.stderr @@ -0,0 +1,32 @@ +error: unreachable pattern + --> $DIR/issue-31221.rs:18:9 + | +LL | Var3 => (), + | ---- matches any value +LL | Var2 => (), + | ^^^^ unreachable pattern + | +note: the lint level is defined here + --> $DIR/issue-31221.rs:4:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/issue-31221.rs:24:9 + | +LL | &Var3 => (), + | ----- matches any value +LL | &Var2 => (), + | ^^^^^ unreachable pattern + +error: unreachable pattern + --> $DIR/issue-31221.rs:31:9 + | +LL | (c, d) => (), + | ------ matches any value +LL | anything => () + | ^^^^^^^^ unreachable pattern + +error: aborting due to 3 previous errors + diff --git a/src/test/ui/pattern/usefulness/issue-31561.rs b/src/test/ui/pattern/usefulness/issue-31561.rs new file mode 100644 index 00000000000..813b2409cc8 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-31561.rs @@ -0,0 +1,10 @@ +enum Thing { + Foo(u8), + Bar, + Baz +} + +fn main() { + let Thing::Foo(y) = Thing::Foo(1); + //~^ ERROR refutable pattern in local binding: `Bar` and `Baz` not covered +} diff --git a/src/test/ui/pattern/usefulness/issue-31561.stderr b/src/test/ui/pattern/usefulness/issue-31561.stderr new file mode 100644 index 00000000000..2f562b23692 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-31561.stderr @@ -0,0 +1,26 @@ +error[E0005]: refutable pattern in local binding: `Bar` and `Baz` not covered + --> $DIR/issue-31561.rs:8:9 + | +LL | / enum Thing { +LL | | Foo(u8), +LL | | Bar, + | | --- not covered +LL | | Baz + | | --- not covered +LL | | } + | |_- `Thing` defined here +... +LL | let Thing::Foo(y) = Thing::Foo(1); + | ^^^^^^^^^^^^^ patterns `Bar` and `Baz` 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 `Thing` +help: you might want to use `if let` to ignore the variant that isn't matched + | +LL | if let Thing::Foo(y) = Thing::Foo(1) { /* */ } + | + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0005`. diff --git a/src/test/ui/pattern/usefulness/issue-3601.rs b/src/test/ui/pattern/usefulness/issue-3601.rs new file mode 100644 index 00000000000..e33359beccd --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-3601.rs @@ -0,0 +1,34 @@ +#![feature(box_patterns)] +#![feature(box_syntax)] + +struct HTMLImageData { + image: Option<String> +} + +struct ElementData { + kind: Box<ElementKind> +} + +enum ElementKind { + HTMLImageElement(HTMLImageData) +} + +enum NodeKind { + Element(ElementData) +} + +struct NodeData { + kind: Box<NodeKind>, +} + +fn main() { + let mut id = HTMLImageData { image: None }; + let ed = ElementData { kind: box ElementKind::HTMLImageElement(id) }; + let n = NodeData {kind : box NodeKind::Element(ed)}; + // n.b. span could be better + match n.kind { + box NodeKind::Element(ed) => match ed.kind { //~ ERROR non-exhaustive patterns + box ElementKind::HTMLImageElement(ref d) if d.image.is_some() => { true } + }, + }; +} diff --git a/src/test/ui/pattern/usefulness/issue-3601.stderr b/src/test/ui/pattern/usefulness/issue-3601.stderr new file mode 100644 index 00000000000..c873c20cca8 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-3601.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: `Box(_, _)` not covered + --> $DIR/issue-3601.rs:30:44 + | +LL | box NodeKind::Element(ed) => match ed.kind { + | ^^^^^^^ pattern `Box(_, _)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `Box<ElementKind>` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-39362.rs b/src/test/ui/pattern/usefulness/issue-39362.rs new file mode 100644 index 00000000000..ea3c8f88e0b --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-39362.rs @@ -0,0 +1,18 @@ +enum Foo { + Bar { bar: Bar, id: usize } +} + +enum Bar { + A, B, C, D, E, F +} + +fn test(f: Foo) { + match f { + //~^ ERROR non-exhaustive patterns + //~| patterns + Foo::Bar { bar: Bar::A, .. } => (), + Foo::Bar { bar: Bar::B, .. } => (), + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/issue-39362.stderr b/src/test/ui/pattern/usefulness/issue-39362.stderr new file mode 100644 index 00000000000..8c162e55619 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-39362.stderr @@ -0,0 +1,17 @@ +error[E0004]: non-exhaustive patterns: `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered + --> $DIR/issue-39362.rs:10:11 + | +LL | / enum Foo { +LL | | Bar { bar: Bar, id: usize } +LL | | } + | |_- `Foo` defined here +... +LL | match f { + | ^ patterns `Bar { bar: C, .. }`, `Bar { bar: D, .. }`, `Bar { bar: E, .. }` and 1 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `Foo` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-40221.rs b/src/test/ui/pattern/usefulness/issue-40221.rs new file mode 100644 index 00000000000..e1f7e975b80 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-40221.rs @@ -0,0 +1,16 @@ +enum P { + C(PC), +} + +enum PC { + Q, + QA, +} + +fn test(proto: P) { + match proto { //~ ERROR non-exhaustive patterns + P::C(PC::Q) => (), + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/issue-40221.stderr b/src/test/ui/pattern/usefulness/issue-40221.stderr new file mode 100644 index 00000000000..98efe805a0b --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-40221.stderr @@ -0,0 +1,18 @@ +error[E0004]: non-exhaustive patterns: `C(QA)` not covered + --> $DIR/issue-40221.rs:11:11 + | +LL | / enum P { +LL | | C(PC), + | | - not covered +LL | | } + | |_- `P` defined here +... +LL | match proto { + | ^^^^^ pattern `C(QA)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `P` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-4321.rs b/src/test/ui/pattern/usefulness/issue-4321.rs new file mode 100644 index 00000000000..9715f2eba2f --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-4321.rs @@ -0,0 +1,8 @@ +fn main() { + let tup = (true, true); + println!("foo {:}", match tup { //~ ERROR non-exhaustive patterns: `(true, false)` not covered + (false, false) => "foo", + (false, true) => "bar", + (true, true) => "baz" + }); +} diff --git a/src/test/ui/pattern/usefulness/issue-4321.stderr b/src/test/ui/pattern/usefulness/issue-4321.stderr new file mode 100644 index 00000000000..1e8852556b1 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-4321.stderr @@ -0,0 +1,12 @@ +error[E0004]: non-exhaustive patterns: `(true, false)` not covered + --> $DIR/issue-4321.rs:3:31 + | +LL | println!("foo {:}", match tup { + | ^^^ pattern `(true, false)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `(bool, bool)` + +error: aborting due to previous error + +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 deleted file mode 100644 index 349ba11a7cd..00000000000 --- a/src/test/ui/pattern/usefulness/issue-43253.rs +++ /dev/null @@ -1,47 +0,0 @@ -// 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 unreachable pattern - _ => {}, - } - - match 10 { - 5..7 => {}, - 6 => {}, //~ WARNING unreachable pattern - 1..10 => {}, - 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 deleted file mode 100644 index 04feef1706c..00000000000 --- a/src/test/ui/pattern/usefulness/issue-43253.stderr +++ /dev/null @@ -1,52 +0,0 @@ -warning: multiple patterns covering the same range - --> $DIR/issue-43253.rs:16:9 - | -LL | 1..10 => {}, - | ----- this range overlaps on `9_i32` -LL | 9..=10 => {}, - | ^^^^^^ overlapping patterns - | -note: the lint level is defined here - --> $DIR/issue-43253.rs:4:9 - | -LL | #![warn(overlapping_patterns)] - | ^^^^^^^^^^^^^^^^^^^^ - -warning: unreachable pattern - --> $DIR/issue-43253.rs:29:9 - | -LL | 9 => {}, - | ^ - | -note: the lint level is 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 => {}, - | ^ - -warning: 6 warnings emitted - diff --git a/src/test/ui/pattern/usefulness/issue-50900.rs b/src/test/ui/pattern/usefulness/issue-50900.rs new file mode 100644 index 00000000000..27135af9575 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-50900.rs @@ -0,0 +1,19 @@ +#[derive(PartialEq, Eq)] +pub struct Tag(pub Context, pub u16); + +#[derive(PartialEq, Eq)] +pub enum Context { + Tiff, + Exif, +} + +impl Tag { + const ExifIFDPointer: Tag = Tag(Context::Tiff, 34665); +} + +fn main() { + match Tag::ExifIFDPointer { + //~^ ERROR: non-exhaustive patterns: `Tag(Exif, _)` not covered + Tag::ExifIFDPointer => {} + } +} diff --git a/src/test/ui/pattern/usefulness/issue-50900.stderr b/src/test/ui/pattern/usefulness/issue-50900.stderr new file mode 100644 index 00000000000..d378b6e8efe --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-50900.stderr @@ -0,0 +1,15 @@ +error[E0004]: non-exhaustive patterns: `Tag(Exif, _)` not covered + --> $DIR/issue-50900.rs:15:11 + | +LL | pub struct Tag(pub Context, pub u16); + | ------------------------------------- `Tag` defined here +... +LL | match Tag::ExifIFDPointer { + | ^^^^^^^^^^^^^^^^^^^ pattern `Tag(Exif, _)` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `Tag` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0004`. diff --git a/src/test/ui/pattern/usefulness/issue-57472.rs b/src/test/ui/pattern/usefulness/issue-57472.rs new file mode 100644 index 00000000000..1131006374c --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-57472.rs @@ -0,0 +1,35 @@ +#![crate_type="lib"] +#![deny(unreachable_patterns)] + +mod test_struct { + // Test the exact copy of the minimal example + // posted in the issue. + pub struct Punned { + foo: [u8; 1], + bar: [u8; 1], + } + + pub fn test(punned: Punned) { + match punned { + Punned { foo: [_], .. } => println!("foo"), + Punned { bar: [_], .. } => println!("bar"), + //~^ ERROR unreachable pattern [unreachable_patterns] + } + } +} + +mod test_union { + // Test the same thing using a union. + pub union Punned { + foo: [u8; 1], + bar: [u8; 1], + } + + pub fn test(punned: Punned) { + match punned { + Punned { foo: [_] } => println!("foo"), + Punned { bar: [_] } => println!("bar"), + //~^ ERROR unreachable pattern [unreachable_patterns] + } + } +} diff --git a/src/test/ui/pattern/usefulness/issue-57472.stderr b/src/test/ui/pattern/usefulness/issue-57472.stderr new file mode 100644 index 00000000000..26efdf6dbaf --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-57472.stderr @@ -0,0 +1,20 @@ +error: unreachable pattern + --> $DIR/issue-57472.rs:15:13 + | +LL | Punned { bar: [_], .. } => println!("bar"), + | ^^^^^^^^^^^^^^^^^^^^^^^ + | +note: the lint level is defined here + --> $DIR/issue-57472.rs:2:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/issue-57472.rs:31:13 + | +LL | Punned { bar: [_] } => println!("bar"), + | ^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/pattern/issue-66501.rs b/src/test/ui/pattern/usefulness/issue-66501.rs index ffcfd4ad83e..ffcfd4ad83e 100644 --- a/src/test/ui/pattern/issue-66501.rs +++ b/src/test/ui/pattern/usefulness/issue-66501.rs diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs b/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs deleted file mode 100644 index 37c4ccda0f5..00000000000 --- a/src/test/ui/pattern/usefulness/match-range-fail-dominate.rs +++ /dev/null @@ -1,49 +0,0 @@ -#![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 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 - //~| WARNING this was previously accepted by the compiler - 0.02f64 => {} //~ ERROR unreachable pattern - //~^ 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 - _ => {} - }; -} diff --git a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr b/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr deleted file mode 100644 index 6922170fccb..00000000000 --- a/src/test/ui/pattern/usefulness/match-range-fail-dominate.stderr +++ /dev/null @@ -1,93 +0,0 @@ -error: unreachable pattern - --> $DIR/match-range-fail-dominate.rs:6:7 - | -LL | 5 ..= 6 => { } - | ^^^^^^^ - | -note: the lint level is 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:42: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:42: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> - -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:42: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: aborting due to 5 previous errors; 6 warnings emitted - diff --git a/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.rs b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.rs new file mode 100644 index 00000000000..cb44c1da76b --- /dev/null +++ b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.rs @@ -0,0 +1,36 @@ +#[deny(unreachable_patterns)] + +fn parse_data1(data: &[u8]) -> u32 { + match data { + b"" => 1, + _ => 2, + } +} + +fn parse_data2(data: &[u8]) -> u32 { + match data { //~ ERROR non-exhaustive patterns: `&[_, ..]` not covered + b"" => 1, + } +} + +fn parse_data3(data: &[u8; 0]) -> u8 { + match data { + b"" => 1, + } +} + +fn parse_data4(data: &[u8]) -> u8 { + match data { //~ ERROR non-exhaustive patterns + b"aaa" => 0, + [_, _, _] => 1, + } +} + +fn parse_data5(data: &[u8; 3]) -> u8 { + match data { + b"aaa" => 0, + [_, _, _] => 1, + } +} + +fn main() {} diff --git a/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr new file mode 100644 index 00000000000..6ce53a4f21e --- /dev/null +++ b/src/test/ui/pattern/usefulness/type_polymorphic_byte_str_literals.stderr @@ -0,0 +1,21 @@ +error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered + --> $DIR/type_polymorphic_byte_str_literals.rs:11:11 + | +LL | match data { + | ^^^^ pattern `&[_, ..]` not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `&[u8]` + +error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 1 more not covered + --> $DIR/type_polymorphic_byte_str_literals.rs:23:11 + | +LL | match data { + | ^^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 1 more not covered + | + = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms + = note: the matched value is of type `&[u8]` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0004`. |
