Skip to content

Commit 73d6efc

Browse files
committed
Only emit overlapping patterns lint if the overlap is partial
1 parent 89b19cc commit 73d6efc

14 files changed

+66
-111
lines changed

src/libcore/ascii.rs

-2
Original file line numberDiff line numberDiff line change
@@ -100,8 +100,6 @@ pub fn escape_default(c: u8) -> EscapeDefault {
100100
b'\\' => ([b'\\', b'\\', 0, 0], 2),
101101
b'\'' => ([b'\\', b'\'', 0, 0], 2),
102102
b'"' => ([b'\\', b'"', 0, 0], 2),
103-
// The three arms above are in the following range
104-
#[allow(overlapping_patterns)]
105103
b'\x20' ..= b'\x7e' => ([c, 0, 0, 0], 1),
106104
_ => ([b'\\', b'x', hexify(c >> 4), hexify(c & 0xf)], 4),
107105
};

src/librustc_mir/hair/pattern/_match.rs

+34-1
Original file line numberDiff line numberDiff line change
@@ -1075,6 +1075,38 @@ impl<'tcx> IntRange<'tcx> {
10751075
None
10761076
}
10771077
}
1078+
1079+
fn suspicious_intersection(&self, other: &Self) -> bool {
1080+
let (lo, hi) = (*self.range.start(), *self.range.end());
1081+
let (other_lo, other_hi) = (*other.range.start(), *other.range.end());
1082+
1083+
// `false` in the following cases:
1084+
// 1 ----
1085+
// 2 ----------
1086+
//
1087+
// 1 ----------
1088+
// 2 ----
1089+
//
1090+
// 1 ----
1091+
// 2 ----
1092+
//
1093+
// 1 ----
1094+
// 2 ----
1095+
1096+
// `true` in the following cases:
1097+
// 1 ---------
1098+
// 2 ----------
1099+
lo < other_lo && hi > other_lo && hi < other_hi ||
1100+
// 1 ---------
1101+
// 2 ----------
1102+
lo > other_lo && lo < other_hi && hi > other_hi ||
1103+
// 1 ----
1104+
// 2 ----
1105+
lo == other_hi && other_lo < lo ||
1106+
// 1 ----
1107+
// 2 -----
1108+
hi == other_lo && lo < other_lo
1109+
}
10781110
}
10791111

10801112
// A request for missing constructor data in terms of either:
@@ -1718,7 +1750,8 @@ fn split_grouped_constructors<'p, 'tcx>(
17181750
})
17191751
.flat_map(|(range, row_len)| {
17201752
let intersection = ctor_range.intersection(&range);
1721-
if let (Some(range), 1) = (&intersection, row_len) {
1753+
let should_lint = ctor_range.suspicious_intersection(&range);
1754+
if let (Some(range), 1, true) = (&intersection, row_len, should_lint) {
17221755
// FIXME: for now, only check for overlapping ranges on simple range
17231756
// patterns. Otherwise with the current logic the following is detected
17241757
// as overlapping:

src/librustc_target/abi/mod.rs

-2
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,6 @@ impl Integer {
488488

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

501500
/// Finds the smallest Integer type which can represent the unsigned value.
502501
pub fn fit_unsigned(x: u128) -> Integer {
503-
#[cfg_attr(not(stage0), allow(overlapping_patterns))]
504502
match x {
505503
0..=0x0000_0000_0000_00ff => I8,
506504
0..=0x0000_0000_0000_ffff => I16,

src/test/ui/check_match/issue-43253.stderr

-18
Original file line numberDiff line numberDiff line change
@@ -24,14 +24,6 @@ note: lint level defined here
2424
LL | #![warn(unreachable_patterns)]
2525
| ^^^^^^^^^^^^^^^^^^^^
2626

27-
warning: multiple patterns covering the same range
28-
--> $DIR/issue-43253.rs:35:9
29-
|
30-
LL | 1..10 => {},
31-
| ----- this range overlaps on `8i32..=9i32`
32-
LL | 8..=9 => {},
33-
| ^^^^^ overlapping patterns
34-
3527
warning: unreachable pattern
3628
--> $DIR/issue-43253.rs:35:9
3729
|
@@ -44,16 +36,6 @@ warning: unreachable pattern
4436
LL | 6 => {},
4537
| ^
4638

47-
warning: multiple patterns covering the same range
48-
--> $DIR/issue-43253.rs:42:9
49-
|
50-
LL | 5..7 => {},
51-
| ---- this range overlaps on `5i32..=6i32`
52-
LL | 6 => {},
53-
| - this range overlaps on `6i32`
54-
LL | 1..10 => {},
55-
| ^^^^^ overlapping patterns
56-
5739
warning: unreachable pattern
5840
--> $DIR/issue-43253.rs:43:9
5941
|

src/test/ui/exhaustive_integer_patterns.rs

-1
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,6 @@ fn main() {
4343
-5..=120 => {}
4444
-2..=20 => {}
4545
//~^ ERROR unreachable pattern
46-
//~| ERROR multiple patterns covering the same range
4746
125 => {}
4847
}
4948

src/test/ui/exhaustive_integer_patterns.stderr

+10-18
Original file line numberDiff line numberDiff line change
@@ -40,14 +40,6 @@ LL | match x {
4040
|
4141
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
4242

43-
error: multiple patterns covering the same range
44-
--> $DIR/exhaustive_integer_patterns.rs:44:9
45-
|
46-
LL | -5..=120 => {}
47-
| -------- this range overlaps on `-2i8..=20i8`
48-
LL | -2..=20 => {}
49-
| ^^^^^^^ overlapping patterns
50-
5143
error: unreachable pattern
5244
--> $DIR/exhaustive_integer_patterns.rs:44:9
5345
|
@@ -63,77 +55,77 @@ LL | match x {
6355
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
6456

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

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

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

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

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

10597
error: multiple patterns covering the same range
106-
--> $DIR/exhaustive_integer_patterns.rs:142:9
98+
--> $DIR/exhaustive_integer_patterns.rs:141:9
10799
|
108100
LL | 0 .. 2 => {}
109101
| ------ this range overlaps on `1u8`
110102
LL | 1 ..= 2 => {}
111103
| ^^^^^^^ overlapping patterns
112104

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

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

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

137-
error: aborting due to 16 previous errors
129+
error: aborting due to 15 previous errors
138130

139131
For more information about this error, try `rustc --explain E0004`.

src/test/ui/issues/issue-13867.rs

+1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
// run-pass
22
// Test that codegen works correctly when there are multiple refutable
33
// patterns in match expression.
4+
#![allow(overlapping_patterns)]
45

56

67
enum Foo {

src/test/ui/issues/issue-21475.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// run-pass
2-
#![allow(unused_imports)]
2+
#![allow(unused_imports, overlapping_patterns)]
33
// pretty-expanded FIXME #23616
44

55
use m::{START, END};

src/test/ui/issues/issue-26251.rs

+2
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
// run-pass
2+
#![allow(overlapping_patterns)]
3+
24
fn main() {
35
let x = 'a';
46

src/test/ui/match/match-range-fail-dominate.rs

-4
Original file line numberDiff line numberDiff line change
@@ -5,31 +5,27 @@ fn main() {
55
1 ..= 10 => { }
66
5 ..= 6 => { }
77
//~^ ERROR unreachable pattern
8-
//~| ERROR multiple patterns covering the same range
98
_ => {}
109
};
1110

1211
match 5 {
1312
3 ..= 6 => { }
1413
4 ..= 6 => { }
1514
//~^ ERROR unreachable pattern
16-
//~| ERROR multiple patterns covering the same range
1715
_ => {}
1816
};
1917

2018
match 5 {
2119
4 ..= 6 => { }
2220
4 ..= 6 => { }
2321
//~^ ERROR unreachable pattern
24-
//~| ERROR multiple patterns covering the same range
2522
_ => {}
2623
};
2724

2825
match 'c' {
2926
'A' ..= 'z' => {}
3027
'a' ..= 'z' => {}
3128
//~^ ERROR unreachable pattern
32-
//~| ERROR multiple patterns covering the same range
3329
_ => {}
3430
};
3531

Original file line numberDiff line numberDiff line change
@@ -1,17 +1,3 @@
1-
error: multiple patterns covering the same range
2-
--> $DIR/match-range-fail-dominate.rs:6:7
3-
|
4-
LL | 1 ..= 10 => { }
5-
| -------- this range overlaps on `5i32..=6i32`
6-
LL | 5 ..= 6 => { }
7-
| ^^^^^^^ overlapping patterns
8-
|
9-
note: lint level defined here
10-
--> $DIR/match-range-fail-dominate.rs:1:31
11-
|
12-
LL | #![deny(unreachable_patterns, overlapping_patterns)]
13-
| ^^^^^^^^^^^^^^^^^^^^
14-
151
error: unreachable pattern
162
--> $DIR/match-range-fail-dominate.rs:6:7
173
|
@@ -24,50 +10,26 @@ note: lint level defined here
2410
LL | #![deny(unreachable_patterns, overlapping_patterns)]
2511
| ^^^^^^^^^^^^^^^^^^^^
2612

27-
error: multiple patterns covering the same range
28-
--> $DIR/match-range-fail-dominate.rs:14:7
29-
|
30-
LL | 3 ..= 6 => { }
31-
| ------- this range overlaps on `4i32..=6i32`
32-
LL | 4 ..= 6 => { }
33-
| ^^^^^^^ overlapping patterns
34-
3513
error: unreachable pattern
36-
--> $DIR/match-range-fail-dominate.rs:14:7
14+
--> $DIR/match-range-fail-dominate.rs:13:7
3715
|
3816
LL | 4 ..= 6 => { }
3917
| ^^^^^^^
4018

41-
error: multiple patterns covering the same range
42-
--> $DIR/match-range-fail-dominate.rs:22:7
43-
|
44-
LL | 4 ..= 6 => { }
45-
| ------- this range overlaps on `4i32..=6i32`
46-
LL | 4 ..= 6 => { }
47-
| ^^^^^^^ overlapping patterns
48-
4919
error: unreachable pattern
50-
--> $DIR/match-range-fail-dominate.rs:22:7
20+
--> $DIR/match-range-fail-dominate.rs:20:7
5121
|
5222
LL | 4 ..= 6 => { }
5323
| ^^^^^^^
5424

55-
error: multiple patterns covering the same range
56-
--> $DIR/match-range-fail-dominate.rs:30:7
57-
|
58-
LL | 'A' ..= 'z' => {}
59-
| ----------- this range overlaps on `'a'..='z'`
60-
LL | 'a' ..= 'z' => {}
61-
| ^^^^^^^^^^^ overlapping patterns
62-
6325
error: unreachable pattern
64-
--> $DIR/match-range-fail-dominate.rs:30:7
26+
--> $DIR/match-range-fail-dominate.rs:27:7
6527
|
6628
LL | 'a' ..= 'z' => {}
6729
| ^^^^^^^^^^^
6830

6931
warning: floating-point types cannot be used in patterns
70-
--> $DIR/match-range-fail-dominate.rs:37:7
32+
--> $DIR/match-range-fail-dominate.rs:33:7
7133
|
7234
LL | 0.01f64 ..= 6.5f64 => {}
7335
| ^^^^^^^
@@ -77,7 +39,7 @@ LL | 0.01f64 ..= 6.5f64 => {}
7739
= note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
7840

7941
warning: floating-point types cannot be used in patterns
80-
--> $DIR/match-range-fail-dominate.rs:37:19
42+
--> $DIR/match-range-fail-dominate.rs:33:19
8143
|
8244
LL | 0.01f64 ..= 6.5f64 => {}
8345
| ^^^^^^
@@ -86,7 +48,7 @@ LL | 0.01f64 ..= 6.5f64 => {}
8648
= note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
8749

8850
warning: floating-point types cannot be used in patterns
89-
--> $DIR/match-range-fail-dominate.rs:44:7
51+
--> $DIR/match-range-fail-dominate.rs:40:7
9052
|
9153
LL | 0.02f64 => {}
9254
| ^^^^^^^
@@ -95,19 +57,19 @@ LL | 0.02f64 => {}
9557
= note: for more information, see issue #41620 <https://github.com/rust-lang/rust/issues/41620>
9658

9759
error: unreachable pattern
98-
--> $DIR/match-range-fail-dominate.rs:44:7
60+
--> $DIR/match-range-fail-dominate.rs:40:7
9961
|
10062
LL | 0.02f64 => {}
10163
| ^^^^^^^
10264

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

112-
error: aborting due to 9 previous errors
74+
error: aborting due to 5 previous errors
11375

src/test/ui/precise_pointer_size_matching.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ fn main() {
2323

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

2929
match 0usize { //~ ERROR non-exhaustive patterns

0 commit comments

Comments
 (0)