diff options
| author | bors <bors@rust-lang.org> | 2021-09-29 00:16:17 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2021-09-29 00:16:17 +0000 |
| commit | 6df1d82869d06b88ff413e63a1e8efbb311e3b5c (patch) | |
| tree | 22d0ccf49286fc65743e82737db0f731b8f504af /src/test/ui/pattern/usefulness | |
| parent | 8f8092cc32ec171becef8ceacec7dbb06c5d7d7e (diff) | |
| parent | b7e358ee17a5794603b2324858de078c4586acfc (diff) | |
| download | rust-6df1d82869d06b88ff413e63a1e8efbb311e3b5c.tar.gz rust-6df1d82869d06b88ff413e63a1e8efbb311e3b5c.zip | |
Auto merge of #88950 - Nadrieril:deconstruct-pat, r=oli-obk
Add an intermediate representation to exhaustiveness checking The exhaustiveness checking algorithm keeps deconstructing patterns into a `Constructor` and some `Fields`, but does so a bit all over the place. This PR introduces a new representation for patterns that already has that information, so we only compute it once at the start. I find this makes code easier to follow. In particular `DeconstructedPat::specialize` is a lot simpler than what happened before, and more closely matches the description of the algorithm. I'm also hoping this could help for the project of librarifying exhaustiveness for rust_analyzer since it decouples the algorithm from `rustc_middle::Pat`.
Diffstat (limited to 'src/test/ui/pattern/usefulness')
6 files changed, 95 insertions, 16 deletions
diff --git a/src/test/ui/pattern/usefulness/const-private-fields.rs b/src/test/ui/pattern/usefulness/const-private-fields.rs new file mode 100644 index 00000000000..06c832ca46a --- /dev/null +++ b/src/test/ui/pattern/usefulness/const-private-fields.rs @@ -0,0 +1,30 @@ +// check-pass +// +// Check that we don't ignore private fields in usefulness checking +#![deny(unreachable_patterns)] + +mod inner { + #[derive(PartialEq, Eq)] + pub struct PrivateField { + pub x: bool, + y: bool, + } + + pub const FOO: PrivateField = PrivateField { x: true, y: true }; + pub const BAR: PrivateField = PrivateField { x: true, y: false }; +} +use inner::*; + +fn main() { + match FOO { + FOO => {} + BAR => {} + _ => {} + } + + match FOO { + FOO => {} + PrivateField { x: true, .. } => {} + _ => {} + } +} diff --git a/src/test/ui/pattern/usefulness/consts-opaque.stderr b/src/test/ui/pattern/usefulness/consts-opaque.stderr index 68451043cf5..05c009a6f3f 100644 --- a/src/test/ui/pattern/usefulness/consts-opaque.stderr +++ b/src/test/ui/pattern/usefulness/consts-opaque.stderr @@ -7,8 +7,11 @@ LL | FOO => {} error: unreachable pattern --> $DIR/consts-opaque.rs:32:9 | +LL | FOO => {} + | --- matches any value +LL | LL | _ => {} // should not be emitting unreachable warning - | ^ + | ^ unreachable pattern | note: the lint level is defined here --> $DIR/consts-opaque.rs:6:9 @@ -25,8 +28,11 @@ LL | FOO_REF => {} error: unreachable pattern --> $DIR/consts-opaque.rs:39:9 | +LL | FOO_REF => {} + | ------- matches any value +LL | LL | Foo(_) => {} // should not be emitting unreachable warning - | ^^^^^^ + | ^^^^^^ unreachable pattern warning: to use a constant of type `Foo` in a pattern, `Foo` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/consts-opaque.rs:45:9 @@ -70,15 +76,18 @@ LL | BAR => {} error: unreachable pattern --> $DIR/consts-opaque.rs:63:9 | +LL | BAR => {} + | --- matches any value +LL | LL | Bar => {} // should not be emitting unreachable warning - | ^^^ + | ^^^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:65:9 | -LL | Bar => {} // should not be emitting unreachable warning +LL | BAR => {} | --- matches any value -LL | +... LL | _ => {} | ^ unreachable pattern @@ -97,14 +106,20 @@ LL | BAR => {} // should not be emitting unreachable warning error: unreachable pattern --> $DIR/consts-opaque.rs:72:9 | +LL | BAR => {} + | --- matches any value +LL | LL | BAR => {} // should not be emitting unreachable warning - | ^^^ + | ^^^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:75:9 | +LL | BAR => {} + | --- matches any value +... LL | _ => {} // should not be emitting unreachable warning - | ^ + | ^ unreachable pattern error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/consts-opaque.rs:80:9 @@ -115,14 +130,20 @@ LL | BAZ => {} error: unreachable pattern --> $DIR/consts-opaque.rs:82:9 | +LL | BAZ => {} + | --- matches any value +LL | LL | Baz::Baz1 => {} // should not be emitting unreachable warning - | ^^^^^^^^^ + | ^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:84:9 | +LL | BAZ => {} + | --- matches any value +... LL | _ => {} - | ^ + | ^ unreachable pattern error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/consts-opaque.rs:90:9 @@ -133,8 +154,11 @@ LL | BAZ => {} error: unreachable pattern --> $DIR/consts-opaque.rs:92:9 | +LL | BAZ => {} + | --- matches any value +LL | LL | _ => {} - | ^ + | ^ unreachable pattern error: to use a constant of type `Baz` in a pattern, `Baz` must be annotated with `#[derive(PartialEq, Eq)]` --> $DIR/consts-opaque.rs:97:9 @@ -145,20 +169,28 @@ LL | BAZ => {} error: unreachable pattern --> $DIR/consts-opaque.rs:99:9 | +LL | BAZ => {} + | --- matches any value +LL | LL | Baz::Baz2 => {} // should not be emitting unreachable warning - | ^^^^^^^^^ + | ^^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:101:9 | +LL | BAZ => {} + | --- matches any value +... LL | _ => {} // should not be emitting unreachable warning - | ^ + | ^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:127:9 | +LL | Wrap(_) => {} + | ------- matches any value LL | WRAPQUUX => {} // detected unreachable because we do inspect the `Wrap` layer - | ^^^^^^^^ + | ^^^^^^^^ unreachable pattern error: unreachable pattern --> $DIR/consts-opaque.rs:141:9 diff --git a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr index 9a02fac6a75..0ffb0ffd82a 100644 --- a/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr +++ b/src/test/ui/pattern/usefulness/integer-ranges/reachability.stderr @@ -133,8 +133,10 @@ 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 diff --git a/src/test/ui/pattern/usefulness/issue-3601.stderr b/src/test/ui/pattern/usefulness/issue-3601.stderr index c873c20cca8..48ed1491508 100644 --- a/src/test/ui/pattern/usefulness/issue-3601.stderr +++ b/src/test/ui/pattern/usefulness/issue-3601.stderr @@ -1,8 +1,8 @@ -error[E0004]: non-exhaustive patterns: `Box(_, _)` not covered +error[E0004]: non-exhaustive patterns: `box _` not covered --> $DIR/issue-3601.rs:30:44 | LL | box NodeKind::Element(ed) => match ed.kind { - | ^^^^^^^ pattern `Box(_, _)` not covered + | ^^^^^^^ pattern `box _` not covered | = help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms = note: the matched value is of type `Box<ElementKind>` diff --git a/src/test/ui/pattern/usefulness/issue-82772-match-box-as-struct.rs b/src/test/ui/pattern/usefulness/issue-82772-match-box-as-struct.rs new file mode 100644 index 00000000000..c1bfcc73402 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-82772-match-box-as-struct.rs @@ -0,0 +1,6 @@ +// This used to ICE in exhaustiveness checking. Explanation here: +// https://github.com/rust-lang/rust/issues/82772#issuecomment-905946768 +fn main() { + let Box { 1: _, .. }: Box<()>; //~ ERROR field `1` of + let Box { .. }: Box<()>; +} diff --git a/src/test/ui/pattern/usefulness/issue-82772-match-box-as-struct.stderr b/src/test/ui/pattern/usefulness/issue-82772-match-box-as-struct.stderr new file mode 100644 index 00000000000..2c8c85bb1e0 --- /dev/null +++ b/src/test/ui/pattern/usefulness/issue-82772-match-box-as-struct.stderr @@ -0,0 +1,9 @@ +error[E0451]: field `1` of struct `Box` is private + --> $DIR/issue-82772-match-box-as-struct.rs:4:15 + | +LL | let Box { 1: _, .. }: Box<()>; + | ^^^^ private field + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0451`. |
