Skip to content

Commit

Permalink
Auto merge of #66129 - Nadrieril:refactor-slice-pat-usefulness, r=<try>
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
bors committed Nov 5, 2019
2 parents 3a1b3b3 + 9531787 commit e8198f6
Show file tree
Hide file tree
Showing 16 changed files with 536 additions and 190 deletions.
459 changes: 281 additions & 178 deletions src/librustc_mir/hair/pattern/_match.rs

Large diffs are not rendered by default.

4 changes: 2 additions & 2 deletions src/test/ui/consts/const_let_refutable.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _]` not covered
error[E0005]: refutable pattern in function argument: `&[]`, `&[_]` and `&[_, _, _, ..]` not covered
--> $DIR/const_let_refutable.rs:3:16
|
LL | const fn slice([a, b]: &[i32]) -> i32 {
| ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _]` not covered
| ^^^^^^ patterns `&[]`, `&[_]` and `&[_, _, _, ..]` not covered

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`
--> $DIR/const_let_refutable.rs:4:5
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ LL | match buf {
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

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

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/pattern/usefulness/match-slice-patterns.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

fn check(list: &[Option<()>]) {
match list {
//~^ ERROR `&[_, Some(_), None, _]` not covered
//~^ ERROR `&[_, Some(_), .., None, _]` not covered
&[] => {},
&[_] => {},
&[_, _] => {},
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/pattern/usefulness/match-slice-patterns.stderr
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
error[E0004]: non-exhaustive patterns: `&[_, Some(_), None, _]` not covered
error[E0004]: non-exhaustive patterns: `&[_, Some(_), .., None, _]` not covered
--> $DIR/match-slice-patterns.rs:4:11
|
LL | match list {
| ^^^^ pattern `&[_, Some(_), None, _]` not covered
| ^^^^ pattern `&[_, Some(_), .., None, _]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

Expand Down
2 changes: 1 addition & 1 deletion src/test/ui/pattern/usefulness/non-exhaustive-match.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ fn main() {
}
let vec = vec![0.5f32];
let vec: &[f32] = &vec;
match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _]` not covered
match *vec { //~ ERROR non-exhaustive patterns: `[_, _, _, _, ..]` not covered
[0.1, 0.2, 0.3] => (),
[0.1, 0.2] => (),
[0.1] => (),
Expand Down
4 changes: 2 additions & 2 deletions src/test/ui/pattern/usefulness/non-exhaustive-match.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,11 @@ LL | match *vec {
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

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

Expand Down
File renamed without changes.
110 changes: 110 additions & 0 deletions src/test/ui/pattern/usefulness/slice-patterns.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#![feature(slice_patterns)]
#![deny(unreachable_patterns)]

fn main() {
let s: &[bool] = &[true; 0];
let s0: &[bool; 0] = &[];
let s1: &[bool; 1] = &[false; 1];
let s2: &[bool; 2] = &[false; 2];
let s3: &[bool; 3] = &[false; 3];

let [] = s0;
let [_] = s1;
let [_, _] = s2;

let [..] = s;
let [..] = s0;
let [..] = s1;
let [..] = s2;
let [..] = s3;

let [_, _, ..] = s2;
let [_, .., _] = s2;
let [.., _, _] = s2;

match s1 {
[true, ..] => {}
[.., false] => {}
}
match s2 {
//~^ ERROR `&[false, true]` not covered
[true, ..] => {}
[.., false] => {}
}
match s3 {
//~^ ERROR `&[false, _, true]` not covered
[true, ..] => {}
[.., false] => {}
}
match s {
//~^ ERROR `&[false, .., true]` not covered
[] => {}
[true, ..] => {}
[.., false] => {}
}

match s3 {
//~^ ERROR `&[false, _, _]` not covered
[true, .., true] => {}
}
match s {
//~^ ERROR `&[_, ..]` not covered
[] => {}
}
match s {
//~^ ERROR `&[_, _, ..]` not covered
[] => {}
[_] => {}
}
match s {
//~^ ERROR `&[false, ..]` not covered
[] => {}
[true, ..] => {}
}
match s {
//~^ ERROR `&[false, _, ..]` not covered
[] => {}
[_] => {}
[true, ..] => {}
}
match s {
//~^ ERROR `&[_, .., false]` not covered
[] => {}
[_] => {}
[.., true] => {}
}

match s {
[true, ..] => {}
[true, ..] => {} //~ ERROR unreachable pattern
[true] => {} //~ ERROR unreachable pattern
[..] => {}
}
match s {
[.., true] => {}
[.., true] => {} //~ ERROR unreachable pattern
[true] => {} //~ ERROR unreachable pattern
[..] => {}
}
match s {
[false, .., true] => {}
[false, .., true] => {} //~ ERROR unreachable pattern
[false, true] => {} //~ ERROR unreachable pattern
[false] => {}
[..] => {}
}
match s {
//~^ ERROR `&[_, _, .., true]` not covered
[] => {}
[_] => {}
[_, _] => {}
[.., false] => {}
}
match s {
//~^ ERROR `&[true, _, .., _]` not covered
[] => {}
[_] => {}
[_, _] => {}
[false, .., false] => {}
}
}
133 changes: 133 additions & 0 deletions src/test/ui/pattern/usefulness/slice-patterns.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,133 @@
error[E0004]: non-exhaustive patterns: `&[false, true]` not covered
--> $DIR/slice-patterns.rs:29:11
|
LL | match s2 {
| ^^ pattern `&[false, true]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `&[false, _, true]` not covered
--> $DIR/slice-patterns.rs:34:11
|
LL | match s3 {
| ^^ pattern `&[false, _, true]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

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

error[E0004]: non-exhaustive patterns: `&[false, _, _]` not covered
--> $DIR/slice-patterns.rs:46:11
|
LL | match s3 {
| ^^ pattern `&[false, _, _]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

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

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

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

error[E0004]: non-exhaustive patterns: `&[false, _, ..]` not covered
--> $DIR/slice-patterns.rs:64:11
|
LL | match s {
| ^ pattern `&[false, _, ..]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `&[_, .., false]` not covered
--> $DIR/slice-patterns.rs:70:11
|
LL | match s {
| ^ pattern `&[_, .., false]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error: unreachable pattern
--> $DIR/slice-patterns.rs:79:9
|
LL | [true, ..] => {}
| ^^^^^^^^^^
|
note: lint level defined here
--> $DIR/slice-patterns.rs:2:9
|
LL | #![deny(unreachable_patterns)]
| ^^^^^^^^^^^^^^^^^^^^

error: unreachable pattern
--> $DIR/slice-patterns.rs:80:9
|
LL | [true] => {}
| ^^^^^^

error: unreachable pattern
--> $DIR/slice-patterns.rs:85:9
|
LL | [.., true] => {}
| ^^^^^^^^^^

error: unreachable pattern
--> $DIR/slice-patterns.rs:86:9
|
LL | [true] => {}
| ^^^^^^

error: unreachable pattern
--> $DIR/slice-patterns.rs:91:9
|
LL | [false, .., true] => {}
| ^^^^^^^^^^^^^^^^^

error: unreachable pattern
--> $DIR/slice-patterns.rs:92:9
|
LL | [false, true] => {}
| ^^^^^^^^^^^^^

error[E0004]: non-exhaustive patterns: `&[_, _, .., true]` not covered
--> $DIR/slice-patterns.rs:96:11
|
LL | match s {
| ^ pattern `&[_, _, .., true]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error[E0004]: non-exhaustive patterns: `&[true, _, .., _]` not covered
--> $DIR/slice-patterns.rs:103:11
|
LL | match s {
| ^ pattern `&[true, _, .., _]` not covered
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

error: aborting due to 17 previous errors

For more information about this error, try `rustc --explain E0004`.
Original file line number Diff line number Diff line change
Expand Up @@ -30,11 +30,11 @@ LL | let _ = match x {};
|
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms

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

Expand Down

0 comments on commit e8198f6

Please sign in to comment.