-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Refactor pattern-matching usefulness algorithm #65160
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Closed
Closed
Changes from all commits
Commits
Show all changes
87 commits
Select commit
Hold shift + click to select a range
c9b33ee
Run `rustfmt`
Nadrieril 3ea9c9c
Remove mention of old slice pattern syntax
Nadrieril f983460
Clarify and fix the explanation of the algorithm
Nadrieril 77e3a95
Abstract out pattern stacks to make the code more legible
Nadrieril e1b7627
Remove some redundancy
Nadrieril a075db8
Remove duplicate logic in compute_missing_constructors
Nadrieril 7ee9cb7
Extract constructor application as a Constructor method
Nadrieril a150d97
Refactor "wild constructor" construction
Nadrieril f0e8c78
Clarify some variable names
Nadrieril 8a2274b
`specialize` conceptually operates on a single pattern
Nadrieril 0f5e02e
Wording
Nadrieril c95b7ae
Add some slice-pattern exhaustiveness tests
Nadrieril ea3fe4e
Rename Constructor::Slice to FixedLenSlice
Nadrieril d4cc125
IntRange::from_pat is redundant with pat_constructors
Nadrieril 501cf3a
split_grouped_constructors only needs access to the list of used cons…
Nadrieril b2ae93c
Share computation of used_ctors
Nadrieril 89df721
Rework the exhaustiveness algorithm to better integrate meta-construc…
Nadrieril 1bd18d2
Define a MissingConstructors struct for cleanliness
Nadrieril ad28919
Move is_non_exhaustive into MissingConstructors
Nadrieril ec57a89
Allow Constructor::apply to return more than one pattern
Nadrieril 6d9a35d
Define MissingConstructors meta-constructor and use it for witness re…
Nadrieril 6e392f0
Match constructor first instead of type first in various functions
Nadrieril d9871b8
Move constructor_sub_pattern_tys into wildcard_subpatterns
Nadrieril cf90304
Replace wildcard-specific code paths with generalized specialization
Nadrieril 931d7a9
Factor out some bits
Nadrieril 142df8b
Extract constructor splitting as a Constructor method
Nadrieril cb4715d
Rename pop_constructor back to specialize
Nadrieril a1b3800
Add Wildcard meta-constructor
Nadrieril 6337864
pat_constructors now returns Wildcard when relevant
Nadrieril c0359ce
Avoid allocating in the common case of a single pattern
Nadrieril 33273f2
Invert condition for clarity
Nadrieril cb3452c
Clarify handling of uninhabited types
Nadrieril ad78eff
Gather together usefulness tests
Nadrieril a91cdd4
MatchCheckCtxt::byte_array_map is unused since 7df1d9f6564cafca3758e5…
Nadrieril 8e89f3c
No need to mutate MatchCheckCtxt anymore
Nadrieril 9ae4c52
Add comment about non_exhaustive feature
Nadrieril b3de6fd
Use Wildcard instead of MissingConstructors when relevant
Nadrieril 4be3802
Make IntRange::subtract_from work on a single constructor
Nadrieril d12b172
Factor out constructor subtraction
Nadrieril 2687140
subtract_meta_constructor: match on constructor first
Nadrieril 1f8d93c
Extract constructor_intersects_pattern function
Nadrieril 1b65bec
Inline constructor_covered_by_range and IntRange::from_pat
Nadrieril 12bb3b7
Use question mark instead of custom macro
Nadrieril 022c620
Regroup similar code paths
Nadrieril 0ab764b
Add a few more slice pattern usefulness tests
Nadrieril 956838d
Add variable-length slice metaconstructor
Nadrieril 1793ad5
Don't use max_slice_length when subtracting from VarLenSlice
Nadrieril 527fe65
Faster code path for subtracting from FixedLenSlice
Nadrieril 0d58ead
Faster code path for subtracting from VarLenSlice
Nadrieril 0b353b3
Make exhaustiveness error message more consistent for slice patterns
Nadrieril cf4dc88
Prepare return types for or-patterns
Nadrieril 1e43487
MissingConstructors should not be compared for equality, but we need …
Nadrieril c8ac41e
Add example run of the algorithm
Nadrieril 244ac8d
Tidy up
Nadrieril ad09cc5
Store both prefix and suffix length in VarLenSlice
Nadrieril 47ee628
max_slice_length only needs to look at constructors
Nadrieril c6d1cad
Inline max_slice_length
Nadrieril 0c0fe9f
Add some test cases
Nadrieril 6b4426a
Splitting variable-length slices now respects the required invariant
Nadrieril 72c3a68
PatCtxt is not useful anymore
Nadrieril f5d833f
Cleanup comments
Nadrieril 94227f5
Store Const in ConstantRange
Nadrieril 60021ce
Cleanup constructor_intersects_pattern
Nadrieril 3d0945d
Implement nnethercote's suggestion
Nadrieril 5badbb7
Implement Centril's suggestion
Nadrieril defc66d
Incorporate varkor's review
Nadrieril d8b71d4
Be more consistent in terminology
Nadrieril 66dac52
Move range exhaustiveness check to IntRange::intersection
Nadrieril b85e4be
Introduce IntRange meta-constructor
Nadrieril eea0b79
We no longer construct any ConstantValue or ConstantRange for non-int…
Nadrieril 34b0774
Remove some unnecessary conversions between Constructor and IntRange
Nadrieril 087adfe
Ungate improved slice patterns diagnostics
Nadrieril a66dcd5
Simplify slice subtraction as suggested by arielb1
Nadrieril a2624f2
Rewrite constructor_intersects_pattern as a match
Nadrieril 79efdb4
Remove unnecessary Const conversion
Nadrieril 1f6a5a5
Clarify why the naive algorithm may not terminate
Nadrieril 455095a
Remove unneeded lifetime extensions
Nadrieril d379a43
Use special `Captures` trait to solve issues with impl Iterator
Nadrieril 1de1683
`pat_constructors` doesn't need a `ty` parameter
Nadrieril 3aa5fb3
Extract head constructors construction
Nadrieril c956c65
Name the field of PatStack
Nadrieril 368c71b
Cache `pat_constructors` invocations
Nadrieril 6df1815
Compute constructors on PatStack construction
Nadrieril ed3ea67
Restore performance
Nadrieril 9c3682f
Don't rebuild the same matrix twice
Nadrieril b052036
Don't use SmallVec when we could use Option
Nadrieril fd3ec66
Integrate comment fixes suggested by arielb1
Nadrieril File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
6 changes: 3 additions & 3 deletions
6
...test/ui/match/match-argm-statics-2.stderr → ...ern/usefulness/match-arm-statics-2.stderr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
4 changes: 2 additions & 2 deletions
4
...test/ui/match/match-slice-patterns.stderr → ...rn/usefulness/match-slice-patterns.stderr
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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] => {} | ||
} | ||
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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`. |
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.