Skip to content

Commit e8198f6

Browse files
committed
Auto merge of #66129 - Nadrieril:refactor-slice-pat-usefulness, r=<try>
Refactor slice pattern usefulness checking This PR changes how variable-length slice patterns are handled in usefulness checking. The objectives are: cleaning up that code to make it easier to understand, and paving the way to handling fixed-length slices more cleverly too, for #53820. Before this, variable-length slice patterns were eagerly expanded into a union of fixed-length slices. Now they have their own special constructor, which allows expanding them a bit more lazily. As a nice side-effect, this improves diagnostics. This PR shows a slight performance improvement, mostly due to 149792b. This will probably have to be reverted in some way when we implement or-patterns.
2 parents 3a1b3b3 + 9531787 commit e8198f6

16 files changed

+536
-190
lines changed

src/librustc_mir/hair/pattern/_match.rs

+281-178
Large diffs are not rendered by default.

src/test/ui/consts/const_let_refutable.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _]` not covered
1+
error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
22
--> $DIR/const_let_refutable.rs:3:16
33
|
44
LL | const fn slice([a, b]: &[i32]) -> i32 {
5-
| ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _]` not covered
5+
| ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
66

77
error[E0723]: can only call other `const fn` within a `const fn`, but `const <&i32 as std::ops::Add>::add` is not stable as `const fn`
88
--> $DIR/const_let_refutable.rs:4:5

src/test/ui/pattern/usefulness/match-byte-array-patterns-2.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ LL | match buf {
66
|
77
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
88

9-
error[E0004]: non-exhaustive patterns: `&[]`, `&[_]`, `&[_, _]` and 3 more not covered
9+
error[E0004]: non-exhaustive patterns: `&[..]` not covered
1010
--> $DIR/match-byte-array-patterns-2.rs:10:11
1111
|
1212
LL | match buf {
13-
| ^^^ patterns `&[]`, `&[_]`, `&[_, _]` and 3 more not covered
13+
| ^^^ pattern `&[..]` not covered
1414
|
1515
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
1616

src/test/ui/pattern/usefulness/match-slice-patterns.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
fn check(list: &[Option<()>]) {
44
match list {
5-
//~^ ERROR `&[_, Some(_), None, _]` not covered
5+
//~^ ERROR `&[_, Some(_), .., None, _]` not covered
66
&[] => {},
77
&[_] => {},
88
&[_, _] => {},

src/test/ui/pattern/usefulness/match-slice-patterns.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
1-
error[E0004]: non-exhaustive patterns: `&[_, Some(_), None, _]` not covered
1+
error[E0004]: non-exhaustive patterns: `&[_, Some(_), .., None, _]` not covered
22
--> $DIR/match-slice-patterns.rs:4:11
33
|
44
LL | match list {
5-
| ^^^^ pattern `&[_, Some(_), None, _]` not covered
5+
| ^^^^ pattern `&[_, Some(_), .., None, _]` not covered
66
|
77
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
88

src/test/ui/pattern/usefulness/non-exhaustive-match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ fn main() {
4444
}
4545
let vec = vec![0.5f32];
4646
let vec: &[f32] = &vec;
47-
match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered
47+
match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _, ..]` not covered
4848
[0.1, 0.2, 0.3] => (),
4949
[0.1, 0.2] => (),
5050
[0.1] => (),

src/test/ui/pattern/usefulness/non-exhaustive-match.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ LL | match *vec {
6666
|
6767
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
6868

69-
error[E0004]: non-exhaustive patterns: `[_, _, _, _]` not covered
69+
error[E0004]: non-exhaustive patterns: `[_, _, _, _, ..]` not covered
7070
--> $DIR/non-exhaustive-match.rs:47:11
7171
|
7272
LL | match *vec {
73-
| ^^^^ pattern `[_, _, _, _]` not covered
73+
| ^^^^ pattern `[_, _, _, _, ..]` not covered
7474
|
7575
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
7676

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,110 @@
1+
#![feature(slice_patterns)]
2+
#![deny(unreachable_patterns)]
3+
4+
fn main() {
5+
let s: &[bool] = &[true; 0];
6+
let s0: &[bool; 0] = &[];
7+
let s1: &[bool; 1] = &[false; 1];
8+
let s2: &[bool; 2] = &[false; 2];
9+
let s3: &[bool; 3] = &[false; 3];
10+
11+
let [] = s0;
12+
let [_] = s1;
13+
let [_, _] = s2;
14+
15+
let [..] = s;
16+
let [..] = s0;
17+
let [..] = s1;
18+
let [..] = s2;
19+
let [..] = s3;
20+
21+
let [_, _, ..] = s2;
22+
let [_, .., _] = s2;
23+
let [.., _, _] = s2;
24+
25+
match s1 {
26+
[true, ..] => {}
27+
[.., false] => {}
28+
}
29+
match s2 {
30+
//~^ ERROR `&[false, true]` not covered
31+
[true, ..] => {}
32+
[.., false] => {}
33+
}
34+
match s3 {
35+
//~^ ERROR `&[false, _, true]` not covered
36+
[true, ..] => {}
37+
[.., false] => {}
38+
}
39+
match s {
40+
//~^ ERROR `&[false, .., true]` not covered
41+
[] => {}
42+
[true, ..] => {}
43+
[.., false] => {}
44+
}
45+
46+
match s3 {
47+
//~^ ERROR `&[false, _, _]` not covered
48+
[true, .., true] => {}
49+
}
50+
match s {
51+
//~^ ERROR `&[_, ..]` not covered
52+
[] => {}
53+
}
54+
match s {
55+
//~^ ERROR `&[_, _, ..]` not covered
56+
[] => {}
57+
[_] => {}
58+
}
59+
match s {
60+
//~^ ERROR `&[false, ..]` not covered
61+
[] => {}
62+
[true, ..] => {}
63+
}
64+
match s {
65+
//~^ ERROR `&[false, _, ..]` not covered
66+
[] => {}
67+
[_] => {}
68+
[true, ..] => {}
69+
}
70+
match s {
71+
//~^ ERROR `&[_, .., false]` not covered
72+
[] => {}
73+
[_] => {}
74+
[.., true] => {}
75+
}
76+
77+
match s {
78+
[true, ..] => {}
79+
[true, ..] => {} //~ ERROR unreachable pattern
80+
[true] => {} //~ ERROR unreachable pattern
81+
[..] => {}
82+
}
83+
match s {
84+
[.., true] => {}
85+
[.., true] => {} //~ ERROR unreachable pattern
86+
[true] => {} //~ ERROR unreachable pattern
87+
[..] => {}
88+
}
89+
match s {
90+
[false, .., true] => {}
91+
[false, .., true] => {} //~ ERROR unreachable pattern
92+
[false, true] => {} //~ ERROR unreachable pattern
93+
[false] => {}
94+
[..] => {}
95+
}
96+
match s {
97+
//~^ ERROR `&[_, _, .., true]` not covered
98+
[] => {}
99+
[_] => {}
100+
[_, _] => {}
101+
[.., false] => {}
102+
}
103+
match s {
104+
//~^ ERROR `&[true, _, .., _]` not covered
105+
[] => {}
106+
[_] => {}
107+
[_, _] => {}
108+
[false, .., false] => {}
109+
}
110+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
2+
--> $DIR/slice-patterns.rs:29:11
3+
|
4+
LL | match s2 {
5+
| ^^ pattern `&[false, true]` not covered
6+
|
7+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
8+
9+
error[E0004]: non-exhaustive patterns: `&[false, _, true]` not covered
10+
--> $DIR/slice-patterns.rs:34:11
11+
|
12+
LL | match s3 {
13+
| ^^ pattern `&[false, _, true]` not covered
14+
|
15+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
16+
17+
error[E0004]: non-exhaustive patterns: `&[false, .., true]` not covered
18+
--> $DIR/slice-patterns.rs:39:11
19+
|
20+
LL | match s {
21+
| ^ pattern `&[false, .., true]` not covered
22+
|
23+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
24+
25+
error[E0004]: non-exhaustive patterns: `&[false, _, _]` not covered
26+
--> $DIR/slice-patterns.rs:46:11
27+
|
28+
LL | match s3 {
29+
| ^^ pattern `&[false, _, _]` not covered
30+
|
31+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
32+
33+
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
34+
--> $DIR/slice-patterns.rs:50:11
35+
|
36+
LL | match s {
37+
| ^ pattern `&[_, ..]` not covered
38+
|
39+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
40+
41+
error[E0004]: non-exhaustive patterns: `&[_, _, ..]` not covered
42+
--> $DIR/slice-patterns.rs:54:11
43+
|
44+
LL | match s {
45+
| ^ pattern `&[_, _, ..]` not covered
46+
|
47+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
48+
49+
error[E0004]: non-exhaustive patterns: `&[false, ..]` not covered
50+
--> $DIR/slice-patterns.rs:59:11
51+
|
52+
LL | match s {
53+
| ^ pattern `&[false, ..]` not covered
54+
|
55+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
56+
57+
error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
58+
--> $DIR/slice-patterns.rs:64:11
59+
|
60+
LL | match s {
61+
| ^ pattern `&[false, _, ..]` not covered
62+
|
63+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
64+
65+
error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
66+
--> $DIR/slice-patterns.rs:70:11
67+
|
68+
LL | match s {
69+
| ^ pattern `&[_, .., false]` not covered
70+
|
71+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
72+
73+
error: unreachable pattern
74+
--> $DIR/slice-patterns.rs:79:9
75+
|
76+
LL | [true, ..] => {}
77+
| ^^^^^^^^^^
78+
|
79+
note: lint level defined here
80+
--> $DIR/slice-patterns.rs:2:9
81+
|
82+
LL | #![deny(unreachable_patterns)]
83+
| ^^^^^^^^^^^^^^^^^^^^
84+
85+
error: unreachable pattern
86+
--> $DIR/slice-patterns.rs:80:9
87+
|
88+
LL | [true] => {}
89+
| ^^^^^^
90+
91+
error: unreachable pattern
92+
--> $DIR/slice-patterns.rs:85:9
93+
|
94+
LL | [.., true] => {}
95+
| ^^^^^^^^^^
96+
97+
error: unreachable pattern
98+
--> $DIR/slice-patterns.rs:86:9
99+
|
100+
LL | [true] => {}
101+
| ^^^^^^
102+
103+
error: unreachable pattern
104+
--> $DIR/slice-patterns.rs:91:9
105+
|
106+
LL | [false, .., true] => {}
107+
| ^^^^^^^^^^^^^^^^^
108+
109+
error: unreachable pattern
110+
--> $DIR/slice-patterns.rs:92:9
111+
|
112+
LL | [false, true] => {}
113+
| ^^^^^^^^^^^^^
114+
115+
error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
116+
--> $DIR/slice-patterns.rs:96:11
117+
|
118+
LL | match s {
119+
| ^ pattern `&[_, _, .., true]` not covered
120+
|
121+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
122+
123+
error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
124+
--> $DIR/slice-patterns.rs:103:11
125+
|
126+
LL | match s {
127+
| ^ pattern `&[true, _, .., _]` not covered
128+
|
129+
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
130+
131+
error: aborting due to 17 previous errors
132+
133+
For more information about this error, try `rustc --explain E0004`.

src/test/ui/uninhabited/uninhabited-matches-feature-gated.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -30,11 +30,11 @@ LL | let _ = match x {};
3030
|
3131
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
3232

33-
error[E0004]: non-exhaustive patterns: `&[_]` not covered
33+
error[E0004]: non-exhaustive patterns: `&[_, ..]` not covered
3434
--> $DIR/uninhabited-matches-feature-gated.rs:21:19
3535
|
3636
LL | let _ = match x {
37-
| ^ pattern `&[_]` not covered
37+
| ^ pattern `&[_, ..]` not covered
3838
|
3939
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms
4040

0 commit comments

Comments
 (0)