Skip to content

Commit

Permalink
Only emit overlapping patterns lint if the overlap is partial
Browse files Browse the repository at this point in the history
  • Loading branch information
estebank committed Oct 16, 2019
1 parent 89b19cc commit 73d6efc
Show file tree
Hide file tree
Showing 14 changed files with 66 additions and 111 deletions.
2 changes: 0 additions & 2 deletions src/libcore/ascii.rs
Expand Up @@ -100,8 +100,6 @@ pub fn escape_default(c: u8) -> EscapeDefault {
b'\\' => ([b'\\', b'\\', 0, 0], 2),
b'\'' => ([b'\\', b'\'', 0, 0], 2),
b'"' => ([b'\\', b'"', 0, 0], 2),
// The three arms above are in the following range
#[allow(overlapping_patterns)]
b'\x20' ..= b'\x7e' => ([c, 0, 0, 0], 1),
_ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
};
Expand Down
35 changes: 34 additions & 1 deletion src/librustc_mir/hair/pattern/_match.rs
Expand Up @@ -1075,6 +1075,38 @@ impl<'tcx> IntRange<'tcx> {
None
}
}

fn suspicious_intersection(&self, other: &Self) -> bool {
let (lo, hi) = (*self.range.start(), *self.range.end());
let (other_lo, other_hi) = (*other.range.start(), *other.range.end());

// `false` in the following cases:
// 1 ----
// 2 ----------
//
// 1 ----------
// 2 ----
//
// 1 ----
// 2 ----
//
// 1 ----
// 2 ----

// `true` in the following cases:
// 1 ---------
// 2 ----------
lo < other_lo && hi > other_lo && hi < other_hi ||
// 1 ---------
// 2 ----------
lo > other_lo && lo < other_hi && hi > other_hi ||
// 1 ----
// 2 ----
lo == other_hi && other_lo < lo ||
// 1 ----
// 2 -----
hi == other_lo && lo < other_lo
}
}

// A request for missing constructor data in terms of either:
Expand Down Expand Up @@ -1718,7 +1750,8 @@ fn split_grouped_constructors<'p, 'tcx>(
})
.flat_map(|(range, row_len)| {
let intersection = ctor_range.intersection(&range);
if let (Some(range), 1) = (&intersection, row_len) {
let should_lint = ctor_range.suspicious_intersection(&range);
if let (Some(range), 1, true) = (&intersection, row_len, should_lint) {
// FIXME: for now, only check for overlapping ranges on simple range
// patterns. Otherwise with the current logic the following is detected
// as overlapping:
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_target/abi/mod.rs
Expand Up @@ -488,7 +488,6 @@ impl Integer {

/// Finds the smallest Integer type which can represent the signed value.
pub fn fit_signed(x: i128) -> Integer {
#[cfg_attr(not(stage0), allow(overlapping_patterns))]
match x {
-0x0000_0000_0000_0080..=0x0000_0000_0000_007f => I8,
-0x0000_0000_0000_8000..=0x0000_0000_0000_7fff => I16,
Expand All @@ -500,7 +499,6 @@ impl Integer {

/// Finds the smallest Integer type which can represent the unsigned value.
pub fn fit_unsigned(x: u128) -> Integer {
#[cfg_attr(not(stage0), allow(overlapping_patterns))]
match x {
0..=0x0000_0000_0000_00ff => I8,
0..=0x0000_0000_0000_ffff => I16,
Expand Down
18 changes: 0 additions & 18 deletions src/test/ui/check_match/issue-43253.stderr
Expand Up @@ -24,14 +24,6 @@ note: lint level defined here
LL | #![warn(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^

warning: multiple patterns covering the same range
--> $DIR/issue-43253.rs:35:9
|
LL | 1..10 => {},
| ----- this range overlaps on `8i32..=9i32`
LL | 8..=9 => {},
| ^^^^^ overlapping patterns

warning: unreachable pattern
--> $DIR/issue-43253.rs:35:9
|
Expand All @@ -44,16 +36,6 @@ warning: unreachable pattern
LL | 6 => {},
| ^

warning: multiple patterns covering the same range
--> $DIR/issue-43253.rs:42:9
|
LL | 5..7 => {},
| ---- this range overlaps on `5i32..=6i32`
LL | 6 => {},
| - this range overlaps on `6i32`
LL | 1..10 => {},
| ^^^^^ overlapping patterns

warning: unreachable pattern
--> $DIR/issue-43253.rs:43:9
|
Expand Down
1 change: 0 additions & 1 deletion src/test/ui/exhaustive_integer_patterns.rs
Expand Up @@ -43,7 +43,6 @@ fn main() {
-5..=120 => {}
-2..=20 => {}
//~^ ERROR unreachable pattern
//~| ERROR multiple patterns covering the same range
125 => {}
}

Expand Down
28 changes: 10 additions & 18 deletions src/test/ui/exhaustive_integer_patterns.stderr
Expand Up @@ -40,14 +40,6 @@ LL | match x {
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error: multiple patterns covering the same range
--> $DIR/exhaustive_integer_patterns.rs:44:9
|
LL | -5..=120 => {}
| -------- this range overlaps on `-2i8..=20i8`
LL | -2..=20 => {}
| ^^^^^^^ overlapping patterns

error: unreachable pattern
--> $DIR/exhaustive_integer_patterns.rs:44:9
|
Expand All @@ -63,77 +55,77 @@ LL | match x {
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `std::i8::MIN` not covered
--> $DIR/exhaustive_integer_patterns.rs:84:11
--> $DIR/exhaustive_integer_patterns.rs:83:11
|
LL | match 0i8 {
| ^^^ pattern `std::i8::MIN` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `0i16` not covered
--> $DIR/exhaustive_integer_patterns.rs:92:11
--> $DIR/exhaustive_integer_patterns.rs:91:11
|
LL | match 0i16 {
| ^^^^ pattern `0i16` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `128u8..=std::u8::MAX` not covered
--> $DIR/exhaustive_integer_patterns.rs:110:11
--> $DIR/exhaustive_integer_patterns.rs:109:11
|
LL | match 0u8 {
| ^^^ pattern `128u8..=std::u8::MAX` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `(0u8, Some(_))` and `(2u8..=std::u8::MAX, Some(_))` not covered
--> $DIR/exhaustive_integer_patterns.rs:122:11
--> $DIR/exhaustive_integer_patterns.rs:121:11
|
LL | match (0u8, Some(())) {
| ^^^^^^^^^^^^^^^ patterns `(0u8, Some(_))` and `(2u8..=std::u8::MAX, Some(_))` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `(126u8..=127u8, false)` not covered
--> $DIR/exhaustive_integer_patterns.rs:127:11
--> $DIR/exhaustive_integer_patterns.rs:126:11
|
LL | match (0u8, true) {
| ^^^^^^^^^^^ pattern `(126u8..=127u8, false)` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error: multiple patterns covering the same range
--> $DIR/exhaustive_integer_patterns.rs:142:9
--> $DIR/exhaustive_integer_patterns.rs:141:9
|
LL | 0 .. 2 => {}
| ------ this range overlaps on `1u8`
LL | 1 ..= 2 => {}
| ^^^^^^^ overlapping patterns

error[E0004]: non-exhaustive patterns: `std::u128::MAX` not covered
--> $DIR/exhaustive_integer_patterns.rs:147:11
--> $DIR/exhaustive_integer_patterns.rs:146:11
|
LL | match 0u128 {
| ^^^^^ pattern `std::u128::MAX` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `5u128..=std::u128::MAX` not covered
--> $DIR/exhaustive_integer_patterns.rs:151:11
--> $DIR/exhaustive_integer_patterns.rs:150:11
|
LL | match 0u128 {
| ^^^^^ pattern `5u128..=std::u128::MAX` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `0u128..=3u128` not covered
--> $DIR/exhaustive_integer_patterns.rs:155:11
--> $DIR/exhaustive_integer_patterns.rs:154:11
|
LL | match 0u128 {
| ^^^^^ pattern `0u128..=3u128` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error: aborting due to 16 previous errors
error: aborting due to 15 previous errors

For more information about this error, try `rustc --explain E0004`.
1 change: 1 addition & 0 deletions src/test/ui/issues/issue-13867.rs
@@ -1,6 +1,7 @@
// run-pass
// Test that codegen works correctly when there are multiple refutable
// patterns in match expression.
#![allow(overlapping_patterns)]


enum Foo {
Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/issues/issue-21475.rs
@@ -1,5 +1,5 @@
// run-pass
#![allow(unused_imports)]
#![allow(unused_imports, overlapping_patterns)]
// pretty-expanded FIXME #23616

use m::{START, END};
Expand Down
2 changes: 2 additions & 0 deletions src/test/ui/issues/issue-26251.rs
@@ -1,4 +1,6 @@
// run-pass
#![allow(overlapping_patterns)]

fn main() {
let x = 'a';

Expand Down
4 changes: 0 additions & 4 deletions src/test/ui/match/match-range-fail-dominate.rs
Expand Up @@ -5,31 +5,27 @@ fn main() {
1 ..= 10 => { }
5 ..= 6 => { }
//~^ ERROR unreachable pattern
//~| ERROR multiple patterns covering the same range
_ => {}
};

match 5 {
3 ..= 6 => { }
4 ..= 6 => { }
//~^ ERROR unreachable pattern
//~| ERROR multiple patterns covering the same range
_ => {}
};

match 5 {
4 ..= 6 => { }
4 ..= 6 => { }
//~^ ERROR unreachable pattern
//~| ERROR multiple patterns covering the same range
_ => {}
};

match 'c' {
'A' ..= 'z' => {}
'a' ..= 'z' => {}
//~^ ERROR unreachable pattern
//~| ERROR multiple patterns covering the same range
_ => {}
};

Expand Down
56 changes: 9 additions & 47 deletions src/test/ui/match/match-range-fail-dominate.stderr
@@ -1,17 +1,3 @@
error: multiple patterns covering the same range
--> $DIR/match-range-fail-dominate.rs:6:7
|
LL | 1 ..= 10 => { }
| -------- this range overlaps on `5i32..=6i32`
LL | 5 ..= 6 => { }
| ^^^^^^^ overlapping patterns
|
note: lint level defined here
--> $DIR/match-range-fail-dominate.rs:1:31
|
LL | #![deny(unreachable_patterns, overlapping_patterns)]
| ^^^^^^^^^^^^^^^^^^^^

error: unreachable pattern
--> $DIR/match-range-fail-dominate.rs:6:7
|
Expand All @@ -24,50 +10,26 @@ note: lint level defined here
LL | #![deny(unreachable_patterns, overlapping_patterns)]
| ^^^^^^^^^^^^^^^^^^^^

error: multiple patterns covering the same range
--> $DIR/match-range-fail-dominate.rs:14:7
|
LL | 3 ..= 6 => { }
| ------- this range overlaps on `4i32..=6i32`
LL | 4 ..= 6 => { }
| ^^^^^^^ overlapping patterns

error: unreachable pattern
--> $DIR/match-range-fail-dominate.rs:14:7
--> $DIR/match-range-fail-dominate.rs:13:7
|
LL | 4 ..= 6 => { }
| ^^^^^^^

error: multiple patterns covering the same range
--> $DIR/match-range-fail-dominate.rs:22:7
|
LL | 4 ..= 6 => { }
| ------- this range overlaps on `4i32..=6i32`
LL | 4 ..= 6 => { }
| ^^^^^^^ overlapping patterns

error: unreachable pattern
--> $DIR/match-range-fail-dominate.rs:22:7
--> $DIR/match-range-fail-dominate.rs:20:7
|
LL | 4 ..= 6 => { }
| ^^^^^^^

error: multiple patterns covering the same range
--> $DIR/match-range-fail-dominate.rs:30:7
|
LL | 'A' ..= 'z' => {}
| ----------- this range overlaps on `'a'..='z'`
LL | 'a' ..= 'z' => {}
| ^^^^^^^^^^^ overlapping patterns

error: unreachable pattern
--> $DIR/match-range-fail-dominate.rs:30:7
--> $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:37:7
--> $DIR/match-range-fail-dominate.rs:33:7
|
LL | 0.01f64 ..= 6.5f64 => {}
| ^^^^^^^
Expand All @@ -77,7 +39,7 @@ LL | 0.01f64 ..= 6.5f64 => {}
= 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:37:19
--> $DIR/match-range-fail-dominate.rs:33:19
|
LL | 0.01f64 ..= 6.5f64 => {}
| ^^^^^^
Expand All @@ -86,7 +48,7 @@ LL | 0.01f64 ..= 6.5f64 => {}
= 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:44:7
--> $DIR/match-range-fail-dominate.rs:40:7
|
LL | 0.02f64 => {}
| ^^^^^^^
Expand All @@ -95,19 +57,19 @@ LL | 0.02f64 => {}
= note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>

error: unreachable pattern
--> $DIR/match-range-fail-dominate.rs:44:7
--> $DIR/match-range-fail-dominate.rs:40:7
|
LL | 0.02f64 => {}
| ^^^^^^^

warning: floating-point types cannot be used in patterns
--> $DIR/match-range-fail-dominate.rs:37:7
--> $DIR/match-range-fail-dominate.rs:33:7
|
LL | 0.01f64 ..= 6.5f64 => {}
| ^^^^^^^
|
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>

error: aborting due to 9 previous errors
error: aborting due to 5 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/precise_pointer_size_matching.rs
Expand Up @@ -23,7 +23,7 @@ fn main() {

match 0isize { //~ ERROR non-exhaustive patterns
1 ..= 8 => {}
-5 ..= 20 => {} //~ ERROR multiple patterns covering the same range
-5 ..= 20 => {}
}

match 0usize { //~ ERROR non-exhaustive patterns
Expand Down

0 comments on commit 73d6efc

Please sign in to comment.