From 698f8c2f01ea549d77d7dc3338a12e04c11057b9 Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Wed, 17 Apr 2024 14:02:58 +0200 Subject: Adding upstream version 1.64.0+dfsg1. Signed-off-by: Daniel Baumann --- .../usefulness/integer-ranges/exhaustiveness.rs | 101 ++++++++++++ .../integer-ranges/exhaustiveness.stderr | 149 ++++++++++++++++++ .../integer-ranges/overlapping_range_endpoints.rs | 59 +++++++ .../overlapping_range_endpoints.stderr | 89 +++++++++++ .../integer-ranges/pointer-sized-int.allow.stderr | 17 +++ .../integer-ranges/pointer-sized-int.deny.stderr | 170 +++++++++++++++++++++ .../usefulness/integer-ranges/pointer-sized-int.rs | 50 ++++++ .../precise_pointer_matching-message.rs | 18 +++ .../precise_pointer_matching-message.stderr | 33 ++++ .../usefulness/integer-ranges/reachability.rs | 113 ++++++++++++++ .../usefulness/integer-ranges/reachability.stderr | 154 +++++++++++++++++++ 11 files changed, 953 insertions(+) create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.allow.stderr create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.rs create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/reachability.rs create mode 100644 src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr (limited to 'src/test/ui/pattern/usefulness/integer-ranges') 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 000000000..0f5f49c4c --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.rs @@ -0,0 +1,101 @@ +#![feature(exclusive_range_pattern)] +#![allow(overlapping_range_endpoints)] +#![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 000000000..f30ba05df --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/exhaustiveness.stderr @@ -0,0 +1,149 @@ +error[E0004]: non-exhaustive patterns: `u8::MAX` not covered + --> $DIR/exhaustiveness.rs:47:8 + | +LL | m!(0u8, 0..255); + | ^^^ pattern `u8::MAX` not covered + | + = note: the matched value is of type `u8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, u8::MAX => todo!() } + | ++++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `u8::MAX` not covered + --> $DIR/exhaustiveness.rs:48:8 + | +LL | m!(0u8, 0..=254); + | ^^^ pattern `u8::MAX` not covered + | + = note: the matched value is of type `u8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, u8::MAX => todo!() } + | ++++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `0_u8` not covered + --> $DIR/exhaustiveness.rs:49:8 + | +LL | m!(0u8, 1..=255); + | ^^^ pattern `0_u8` not covered + | + = note: the matched value is of type `u8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, 0_u8 => todo!() } + | +++++++++++++++++ + +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 + | + = note: the matched value is of type `u8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, 42_u8 => todo!() } + | ++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `i8::MAX` not covered + --> $DIR/exhaustiveness.rs:51:8 + | +LL | m!(0i8, -128..127); + | ^^^ pattern `i8::MAX` not covered + | + = note: the matched value is of type `i8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, i8::MAX => todo!() } + | ++++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `i8::MAX` not covered + --> $DIR/exhaustiveness.rs:52:8 + | +LL | m!(0i8, -128..=126); + | ^^^ pattern `i8::MAX` not covered + | + = note: the matched value is of type `i8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, i8::MAX => todo!() } + | ++++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `i8::MIN` not covered + --> $DIR/exhaustiveness.rs:53:8 + | +LL | m!(0i8, -127..=127); + | ^^^ pattern `i8::MIN` not covered + | + = note: the matched value is of type `i8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, i8::MIN => todo!() } + | ++++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `0_i8` not covered + --> $DIR/exhaustiveness.rs:54:11 + | +LL | match 0i8 { + | ^^^ pattern `0_i8` not covered + | + = note: the matched value is of type `i8` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ 1 ..= i8::MAX => {} +LL + 0_i8 => todo!() + | + +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 + | + = note: the matched value is of type `u128` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, u128::MAX => todo!() } + | ++++++++++++++++++++++ + +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 + | + = note: the matched value is of type `u128` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, 5_u128..=u128::MAX => todo!() } + | +++++++++++++++++++++++++++++++ + +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 + | + = note: the matched value is of type `u128` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, 0_u128 => todo!() } + | +++++++++++++++++++ + +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 + | + = note: the matched value is of type `(u8, bool)` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ (0 ..= 255, true) => {} +LL + (126_u8..=127_u8, false) => todo!() + | + +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 000000000..5ea92b070 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.rs @@ -0,0 +1,59 @@ +#![feature(exclusive_range_pattern)] +#![deny(overlapping_range_endpoints)] + +macro_rules! m { + ($s:expr, $t1:pat, $t2:pat) => { + match $s { + $t1 => {} + $t2 => {} + _ => {} + } + } +} + +fn main() { + m!(0u8, 20..=30, 30..=40); //~ ERROR multiple patterns overlap on their endpoints + m!(0u8, 30..=40, 20..=30); //~ ERROR multiple patterns overlap on their endpoints + m!(0u8, 20..=30, 31..=40); + m!(0u8, 20..=30, 29..=40); + m!(0u8, 20.. 30, 29..=40); //~ ERROR multiple patterns overlap on their endpoints + 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 overlap on their endpoints + 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 overlap on their endpoints + 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); + m!(0u8, 25, 20..=30); + m!(0u8, 30, 20..=30); + + match 0u8 { + 0..=10 => {} + 20..=30 => {} + 10..=20 => {} //~ ERROR multiple patterns overlap on their endpoints + _ => {} + } + 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 overlap on their endpoints + (false, 10..20) => {} + _ => {} + } + match Some(0u8) { + Some(0..=10) => {} + Some(10..20) => {} //~ ERROR multiple patterns overlap on their endpoints + _ => {} + } +} 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 000000000..24c0419e1 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/overlapping_range_endpoints.stderr @@ -0,0 +1,89 @@ +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:15:22 + | +LL | m!(0u8, 20..=30, 30..=40); + | ------- ^^^^^^^ ... with this range + | | + | this range overlaps on `30_u8`... + | +note: the lint level is defined here + --> $DIR/overlapping_range_endpoints.rs:2:9 + | +LL | #![deny(overlapping_range_endpoints)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: you likely meant to write mutually exclusive ranges + +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:16:22 + | +LL | m!(0u8, 30..=40, 20..=30); + | ------- ^^^^^^^ ... with this range + | | + | this range overlaps on `30_u8`... + | + = note: you likely meant to write mutually exclusive ranges + +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:19:22 + | +LL | m!(0u8, 20.. 30, 29..=40); + | ------- ^^^^^^^ ... with this range + | | + | this range overlaps on `29_u8`... + | + = note: you likely meant to write mutually exclusive ranges + +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:23:22 + | +LL | m!(0u8, 20..=30, 30..=31); + | ------- ^^^^^^^ ... with this range + | | + | this range overlaps on `30_u8`... + | + = note: you likely meant to write mutually exclusive ranges + +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:27:22 + | +LL | m!(0u8, 20..=30, 19..=20); + | ------- ^^^^^^^ ... with this range + | | + | this range overlaps on `20_u8`... + | + = note: you likely meant to write mutually exclusive ranges + +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:39:9 + | +LL | 0..=10 => {} + | ------ this range overlaps on `10_u8`... +LL | 20..=30 => {} + | ------- this range overlaps on `20_u8`... +LL | 10..=20 => {} + | ^^^^^^^ ... with this range + | + = note: you likely meant to write mutually exclusive ranges + +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:50:16 + | +LL | (true, 0..=10) => {} + | ------ this range overlaps on `10_u8`... +LL | (true, 10..20) => {} + | ^^^^^^ ... with this range + | + = note: you likely meant to write mutually exclusive ranges + +error: multiple patterns overlap on their endpoints + --> $DIR/overlapping_range_endpoints.rs:56:14 + | +LL | Some(0..=10) => {} + | ------ this range overlaps on `10_u8`... +LL | Some(10..20) => {} + | ^^^^^^ ... with this range + | + = note: you likely meant to write mutually exclusive ranges + +error: aborting due to 8 previous errors + 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 000000000..9f277fa1e --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.allow.stderr @@ -0,0 +1,17 @@ +error[E0004]: non-exhaustive patterns: type `usize` is non-empty + --> $DIR/pointer-sized-int.rs:48:11 + | +LL | match 7usize {} + | ^^^^^^ + | + = note: the matched value is of type `usize` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match 7usize { +LL + _ => todo!(), +LL + } + | + +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.stderr b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr new file mode 100644 index 000000000..e3eb98ccd --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.deny.stderr @@ -0,0 +1,170 @@ +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:12:11 + | +LL | match 0usize { + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ 0 ..= usize::MAX => {} +LL + _ => todo!() + | + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:17:11 + | +LL | match 0isize { + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ isize::MIN ..= isize::MAX => {} +LL + _ => todo!() + | + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:22:8 + | +LL | m!(0usize, 0..=usize::MAX); + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, _ => todo!() } + | ++++++++++++++ + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:24:8 + | +LL | m!(0usize, 0..5 | 5..=usize::MAX); + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, _ => todo!() } + | ++++++++++++++ + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:26:8 + | +LL | m!(0usize, 0..usize::MAX | usize::MAX); + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, _ => todo!() } + | ++++++++++++++ + +error[E0004]: non-exhaustive patterns: `(_, _)` not covered + --> $DIR/pointer-sized-int.rs:28:8 + | +LL | m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); + | ^^^^^^^^^^^^^^ pattern `(_, _)` not covered + | + = note: the matched value is of type `(usize, bool)` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, (_, _) => todo!() } + | +++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:31:8 + | +LL | m!(0isize, isize::MIN..=isize::MAX); + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, _ => todo!() } + | ++++++++++++++ + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:33:8 + | +LL | m!(0isize, isize::MIN..5 | 5..=isize::MAX); + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, _ => todo!() } + | ++++++++++++++ + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:35:8 + | +LL | m!(0isize, isize::MIN..isize::MAX | isize::MAX); + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, _ => todo!() } + | ++++++++++++++ + +error[E0004]: non-exhaustive patterns: `(_, _)` not covered + --> $DIR/pointer-sized-int.rs:37:8 + | +LL | m!((0isize, true), (isize::MIN..5, true) + | ^^^^^^^^^^^^^^ pattern `(_, _)` not covered + | + = note: the matched value is of type `(isize, bool)` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL | match $s { $($t)+ => {}, (_, _) => todo!() } + | +++++++++++++++++++ + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/pointer-sized-int.rs:41:11 + | +LL | match 0isize { + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ 1 ..= isize::MAX => {} +LL + _ => todo!() + | + +error[E0004]: non-exhaustive patterns: type `usize` is non-empty + --> $DIR/pointer-sized-int.rs:48:11 + | +LL | match 7usize {} + | ^^^^^^ + | + = note: the matched value is of type `usize` +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern as shown + | +LL ~ match 7usize { +LL + _ => todo!(), +LL + } + | + +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/pointer-sized-int.rs b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.rs new file mode 100644 index 000000000..1ed18c267 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/pointer-sized-int.rs @@ -0,0 +1,50 @@ +// revisions: allow deny +#![feature(exclusive_range_pattern)] +#![cfg_attr(allow, feature(precise_pointer_size_matching))] + +macro_rules! m { + ($s:expr, $($t:tt)+) => { + match $s { $($t)+ => {} } + } +} + +fn main() { + match 0usize { + //[deny]~^ ERROR non-exhaustive patterns + 0 ..= usize::MAX => {} + } + + match 0isize { + //[deny]~^ ERROR non-exhaustive patterns + isize::MIN ..= isize::MAX => {} + } + + m!(0usize, 0..=usize::MAX); + //[deny]~^ ERROR non-exhaustive patterns + m!(0usize, 0..5 | 5..=usize::MAX); + //[deny]~^ ERROR non-exhaustive patterns + m!(0usize, 0..usize::MAX | usize::MAX); + //[deny]~^ ERROR non-exhaustive patterns + m!((0usize, true), (0..5, true) | (5..=usize::MAX, true) | (0..=usize::MAX, false)); + //[deny]~^ ERROR non-exhaustive patterns + + m!(0isize, isize::MIN..=isize::MAX); + //[deny]~^ ERROR non-exhaustive patterns + m!(0isize, isize::MIN..5 | 5..=isize::MAX); + //[deny]~^ ERROR non-exhaustive patterns + m!(0isize, isize::MIN..isize::MAX | isize::MAX); + //[deny]~^ ERROR non-exhaustive patterns + m!((0isize, true), (isize::MIN..5, true) + | (5..=isize::MAX, true) | (isize::MIN..=isize::MAX, false)); + //[deny]~^^ ERROR non-exhaustive patterns + + match 0isize { + //[deny]~^ 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/precise_pointer_matching-message.rs b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs new file mode 100644 index 000000000..a2aa655ca --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.rs @@ -0,0 +1,18 @@ +// This tests that the lint message explains the reason for the error. +fn main() { + match 0usize { + //~^ 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 => {} + } + + match 0isize { + //~^ 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 => {} + } +} diff --git a/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr new file mode 100644 index 000000000..30492c982 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/precise_pointer_matching-message.stderr @@ -0,0 +1,33 @@ +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/precise_pointer_matching-message.rs:3:11 + | +LL | match 0usize { + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ 0..=usize::MAX => {} +LL + _ => todo!() + | + +error[E0004]: non-exhaustive patterns: `_` not covered + --> $DIR/precise_pointer_matching-message.rs:11:11 + | +LL | match 0isize { + | ^^^^^^ pattern `_` not covered + | + = 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 +help: ensure that all possible cases are being handled by adding a match arm with a wildcard pattern or an explicit pattern as shown + | +LL ~ isize::MIN..=isize::MAX => {} +LL + _ => todo!() + | + +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 000000000..fb4d59b05 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.rs @@ -0,0 +1,113 @@ +#![feature(exclusive_range_pattern)] +#![allow(overlapping_range_endpoints)] +#![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 => {}, //~ ERROR unreachable pattern + _ => {}, + } + // 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 000000000..0ffb0ffd8 --- /dev/null +++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr @@ -0,0 +1,154 @@ +error: unreachable pattern + --> $DIR/reachability.rs:17:17 + | +LL | m!(0u8, 42, 42); + | ^^ + | +note: the lint level is defined here + --> $DIR/reachability.rs:3:9 + | +LL | #![deny(unreachable_patterns)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:21:22 + | +LL | m!(0u8, 20..=30, 20); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:22:22 + | +LL | m!(0u8, 20..=30, 21); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:23:22 + | +LL | m!(0u8, 20..=30, 25); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:24:22 + | +LL | m!(0u8, 20..=30, 29); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:25:22 + | +LL | m!(0u8, 20..=30, 30); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:28:21 + | +LL | m!(0u8, 20..30, 20); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:29:21 + | +LL | m!(0u8, 20..30, 21); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:30:21 + | +LL | m!(0u8, 20..30, 25); + | ^^ + +error: unreachable pattern + --> $DIR/reachability.rs:31:21 + | +LL | m!(0u8, 20..30, 29); + | ^^ + +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:37:22 + | +LL | m!(0u8, 20..=30, 20.. 30); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:39:22 + | +LL | m!(0u8, 20..=30, 21..=30); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:40:22 + | +LL | m!(0u8, 20..=30, 20..=29); + | ^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:42:24 + | +LL | m!('a', 'A'..='z', 'a'..='z'); + | ^^^^^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:49:9 + | +LL | 5..=8 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:55:9 + | +LL | 5..15 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:62:9 + | +LL | 5..25 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:70:9 + | +LL | 5..25 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:76:9 + | +LL | 5..15 => {}, + | ^^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:83:9 + | +LL | _ => {}, + | - matches any value +LL | '\u{D7FF}'..='\u{E000}' => {}, + | ^^^^^^^^^^^^^^^^^^^^^^^ unreachable pattern + +error: unreachable pattern + --> $DIR/reachability.rs:104:9 + | +LL | &FOO => {} + | ^^^^ + +error: unreachable pattern + --> $DIR/reachability.rs:105:9 + | +LL | BAR => {} + | ^^^ + +error: aborting due to 24 previous errors + -- cgit v1.2.3