-
Notifications
You must be signed in to change notification settings - Fork 12.9k
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
Refactor pattern-matching usefulness algorithm #65160
Conversation
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @eddyb (or someone else) soon. If any changes to this PR are deemed necessary, please add them as extra commits. This ensures that the reviewer can see what has changed since they last reviewed the code. Due to the way GitHub handles out-of-date commits, this should also make it reasonably obvious what issues have or haven't been addressed. Large or tricky changes may require several passes of review and changes. Please see the contribution instructions for more information. |
r? @pnkfelix or @nikomatsakis cc @varkor @Centril |
5c849c5
to
bae5adb
Compare
☔ The latest upstream changes (presumably #65089) made this pull request unmergeable. Please resolve the merge conflicts. |
4a1e85b
to
b1c0113
Compare
}).collect() | ||
} | ||
PatKind::Or { ref pats } => { | ||
pats.iter().flat_map(|pat| pat_constructors(tcx, param_env, pat, ty)).collect() |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Since you've familiarized yourself in-depth with this code, would you like to tackle exhaustiveness for or-patterns as well? (Hope you don't mind @dlrobertson -- then you can focus more on MIR)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah, don't mind at all. Having more eyes on the code is always better 😄
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would like to, yes !
I've started reviewing this. Let's check to see whether this affects perf at all. @bors try |
⌛ Trying commit 92bf5a2d22ffd7cdefb0ed22ceaf18e291a1cfa5 with merge 3c8eb891c46a383549ee6d6d3936bec0dee6f238... |
cc @arielb1 |
☀️ Try build successful - checks-azure |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I've left some comments. Some of them may be out of date, because I was commenting as I was looking through each commit, which often got refactored later, so ignore any that don't seem relevant any more. Overall, these changes seem really good, and make things a lot clearer ❤️ The diagnostics improvements as a result are a nice bonus, too!
Let's just check that nothing regresses, but other than that, I'm pretty happy with how things are here. You've put a lot of effort into improving this code; thank you!
@rust-timer build 3c8eb891c46a383549ee6d6d3936bec0dee6f238 |
1 similar comment
@rust-timer build 3c8eb891c46a383549ee6d6d3936bec0dee6f238 |
Queued 3c8eb891c46a383549ee6d6d3936bec0dee6f238 with parent 59a31c8, future comparison URL. |
r? @varkor |
All the constructed PatStacks end up having `head_ctors` called on them, so this does not unnecessarily precompute anything.
Stop checking that cached constructors are valid. Avoid cloning constructors when not necessary.
This reverts some of the or-patterns future-proofing, for the sake of performance.
ad6ad6b
to
fd3ec66
Compare
/AzurePipelines run |
Sorry for the noise, trying to figure out why PR builders don't work. /AzurePipelines help |
Azure Pipelines successfully started running 1 pipeline(s). |
☔ The latest upstream changes (presumably #65598) made this pull request unmergeable. Please resolve the merge conflicts. |
So the lastest merge conflict is taking a big toll on me to rebase. I also have the feeling that this PR has become so unwieldy that maintainers will struggle to find time to review it. If it is going to wait around a while (and need several more complex rebases), maybe splitting this PR up into smaller meaningful chunks could make everyone's job easier; but that would not be worth it if the PR is almost mergeable. |
@Nadrieril I would personally try to split it up; what should make it both easier to merge and review, and especially the latter is important as match checking is important for soundness. |
I think that as long as the rebases aren't requiring significant changes in how things work, and the performance issue can be resolved, it could be easier to just go for this one PR, as it's already been looked at by two of us. That said, it's up to you: if splitting up would be easier, then go for that. |
Ping from triage. |
I have decided to split this into smaller bits |
Clarify pattern-matching usefulness algorithm This PR clarifies a bit the usefulness algorithm by emphasizing that each row of the matrix can be seen as a sort of stack from which we pop constructors. It also moves code around to increase separation of concerns. This is part of my splitting of #65160 into smaller PRs.
Clarify pattern-matching usefulness algorithm This PR clarifies a bit the usefulness algorithm by emphasizing that each row of the matrix can be seen as a sort of stack from which we pop constructors. It also moves code around to increase separation of concerns. This is part of my splitting of #65160 into smaller PRs.
While working on #53820, I felt uneasy because the usefulness algorithm was quite a complex piece of code and it wasn't clear to me how the different parts interacted. The basic algorithm is clear enough and well explained at the top of the file, but additions were made to support integer ranges, slice patterns and various edge cases like private fields. Those additions made some sense individually but didn't seem to fit in a larger coherent whole.
In this PR, I propose a rework of the algorithm, that integrates advanced features like slice patterns natively. The algorithm describes different steps from the one in the paper, but it actually does the exact same work when restricted to normal constructors + wildcard patterns. This rewrite in particular removes the special-casing of the wildcard pattern, which I found added a lot of cognitive complexity to the code. This PR also largely increases separation of concerns between specialization, witness reconstruction, and handling of special features like integer ranges. I personally feel that the code is now much easier to follow.
This is a fairly large PR; I felt it only made sense as a whole, but if needed I could try splitting it up.
This is for the most part pure refactoring: a lot of the commits simply move code around. I made them small so it should be easy to see that each step preserves behaviour. The only real change in behaviour is regarding exhaustiveness diagnostics for array/slice patterns: they have been slightly altered and are no longer cut off at some arbitrary-seeming length. They have also improved when slice_patterns is enabled.
I recommend the following reading order: first read the description of the new algorithm at the top of the lastest version of
_match.rs
, then commit-by-commit. I believe tests pass after every commit.This PR is mostly me being unable to resist refactoring everything I see, so the changes may be a bit all over the place. I hope it all makes sense in the end.
Thanks for taking some time to review !