-
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
panic early when TrustedLen
indicates a length > usize::MAX
#83726
Conversation
r? @kennytm (rust-highfive has picked a reviewer for you, use r? to override) |
@rustbot label T-libs since it also touches visible docs, not just implementation |
Error: Label since can only be set by Rust team members Please let |
@bors try @rust-timer queue |
Awaiting bors try build completion. @rustbot label: +S-waiting-on-perf |
⌛ Trying commit ad3a791 with merge fd6d76150a587f8fbfa740e956a61774c1e85edc... |
☀️ Try build successful - checks-actions |
Queued fd6d76150a587f8fbfa740e956a61774c1e85edc with parent 4fdac23, future comparison URL. |
Finished benchmarking try commit (fd6d76150a587f8fbfa740e956a61774c1e85edc): 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 |
@bors r+ |
📌 Commit ad3a791 has been approved by |
☀️ Test successful - checks-actions |
This.. surprisingly to me, at least, ended up being a pretty nice perf win, of up to 8%: https://perf.rust-lang.org/compare.html?start=49e1ec09952c5ab7798addd29532d44dc020283f&end=803ddb83598838fb9de308d283b759ba463e5e80&stat=instructions:u. Largely this looks to be driven by incremental benchmark improvements, but not completely. |
Some I haven't actually looked at the generated IR, but that's the theory that motivated this change. |
@@ -47,7 +47,12 @@ where | |||
}); |
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.
Why does the above code seemed to have the same condition written twice? See 10 lines above.
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.
One checks that high == low. the other checks that it's finite.
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.
No, I mean
if let Some(high_value) = high {
debug_assert_eq!(
low,
high_value,
"TrustedLen iterator's size hint is not exact: {:?}",
(low, high)
);
}
if let Some(additional) = high {
self.reserve(additional);
...
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.
idk, probably just an historic artifact of code being moved around and redundant conditions not being merged. Someone just has to clean it up.
Merge same condition branch in vec spec_extend Follow up of rust-lang#83726 (comment)
Changes
TrustedLen
specializations to immediately panic whensize_hint().1 == None
.As far as I can tell this is
not a changea minimal change in observable behavior for anything except ZSTs because the fallback path would go throughextend_desugared()
which tries toreserve(lower_bound)
which already isusize::MAX
and that would also lead to a panic. Before it might have popped somewhere between zero and a few elements from the iterator before panicking while it now panics immediately.Overall this should reduce codegen by eliminating the fallback paths.
While looking into the
with_capacity()
behavior I also noticed that its documentation didn't have a Panics section, so I added that.