-
Notifications
You must be signed in to change notification settings - Fork 12.7k
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
Turn type inhabitedness into a query to fix exhaustive_patterns
perf
#79670
Conversation
r? @estebank (rust-highfive has picked a reviewer for you, use r? to override) |
@bors try @rust-timer queue |
Awaiting bors try build completion |
⌛ Trying commit e4c3571 with merge eae765f378d0f787f681b2b627b79583c4920d53... |
☀️ Try build successful - checks-actions |
Queued eae765f378d0f787f681b2b627b79583c4920d53 with parent 1f95c91, future comparison URL. |
Finished benchmarking try commit (eae765f378d0f787f681b2b627b79583c4920d53): comparison url. Benchmarking this pull request likely means that it is perf-sensitive, so we're automatically marking it as not fit for rolling up. Please note that if the perf results are neutral, you should likely undo the rollup=never given below by specifying Importantly, though, if the results of this run are non-neutral do not roll this PR up -- it will mask other regressions or improvements in the roll up. @bors rollup=never |
Wow, very impressive @Nadrieril! Very significant reductions in instruction counts on the stress tests, and significant improvements for ripgrep, cargo, and syn! |
Should this be relnotes-perf? |
merge conflict - sent to author |
Holy hell! Those perf numbers! Sorry I was away for all of December. Reviewing now. I wish I had reviewed before conflicts cropped up. |
error[E0004]: non-exhaustive patterns: type `u8` is non-empty | ||
--> $DIR/empty-match.rs:78:20 | ||
| | ||
LL | Some(_) => {} | ||
| ^^^^^^^ | ||
|
||
error: unreachable pattern | ||
--> $DIR/empty-match.rs:87:9 | ||
LL | match_no_arms!(0u8); | ||
| ^^^ | ||
| | ||
LL | Some(_) => {} | ||
| ^^^^^^^ | ||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms | ||
= note: the matched value is of type `u8` |
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.
This is not introduced by this PR, but we have simultaneously redundant info (we mention the type u8
twice in two different places), and use "weird jargon" (u8
is non-empty). I would like to reword these errors (after landing this PR, probably).
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.
Somehow I felt that there was an issue for that already, but I can't find it. Could have confused it with #78123 .
error[E0004]: non-exhaustive patterns: type `NonEmptyStruct1` is non-empty | ||
--> $DIR/empty-match.rs:79:20 | ||
| | ||
LL | match_empty!(0u8); | ||
| ^^^ | ||
LL | struct NonEmptyStruct1; | ||
| ----------------------- `NonEmptyStruct1` defined here | ||
... | ||
LL | match_no_arms!(NonEmptyStruct1); | ||
| ^^^^^^^^^^^^^^^ | ||
| | ||
= help: ensure that all possible cases are being handled, possibly by adding wildcards or more match arms | ||
= note: the matched value is of type `u8` | ||
= note: the matched value is of type `NonEmptyStruct1` |
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 us to handle this case in particular (matching on an empty struct) explicitly in the diagnostic output as it might not be obvious to a newcomer.
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.
Ended up spending more time going over the output than the actual code, as it looks good to me (thank you for the easy to follow commits!). r=me after fixing the merge conflict.
I feel a bit confused about e4c3571: I thought |
@camelid correct. Given e4c3571#diff-ab398df590486c873907d006df0eec96f9fdeb86131a756f5d25a29401de4dcaR110-R113 I would wonder if fiddling with |
Yes, but the smallvec in question needed to be behind an |
Since `DefIdForest` contains 0 or 1 elements the large majority of the time, by allocating only in the >1 case we avoid almost all allocations, compared to `Arc<SmallVec<[DefId;1]>>`. This shaves off 0.2% on the benchmark that stresses uninhabitedness checking.
e4c3571
to
e608d8f
Compare
Heh, the conflict was just a typo fix. @bors r=estebank rollup=never |
📌 Commit e608d8f has been approved by |
☀️ Test successful - checks-actions |
We measured in #79394 that enabling the
exhaustive_patterns
feature causes significant perf degradation. It was conjectured that the culprit is type inhabitedness checking, and I hypothesized that turning this computation into a query would solve most of the problem.This PR turns
tcx.is_ty_uninhabited_from
into a query, and I measured a 25% perf gain on the benchmark that stress-testsexhaustiveness_patterns
. This more than compensates for the 30% perf hit I measured when creating it. We'll have to measure enabling the feature again, but I suspect this fixes the perf regression entirely.I'd like a perf run on this PR obviously.
I made small atomic commits to help reviewing. The first one is just me discovering the "revisions" feature of the testing framework.
I believe there's a push to move things out of
rustc_middle
because it's huge. I guessinhabitedness/mod.rs
could be moved out, but it's quite small.DefIdForest
might be movable somewhere too. I don't know what the policy is for that.Ping @camelid since you were interested in following along
@rustbot modify labels: +A-exhaustiveness-checking