-
Notifications
You must be signed in to change notification settings - Fork 12.8k
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
EscapeAscii no longer panics due to incorrect ExactSizeIterator #99913
EscapeAscii no longer panics due to incorrect ExactSizeIterator #99913
Conversation
Hey! It looks like you've submitted a new PR for the library teams! If this PR contains changes to any Examples of
|
Thanks for the pull request, and welcome! The Rust team is excited to review your changes, and you should hear from @Mark-Simulacrum (or someone else) soon. Please see the contribution instructions for more information. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
library/core/src/slice/ascii.rs
Outdated
@@ -174,6 +176,9 @@ impl_fn_for_zst! { | |||
#[must_use = "iterators are lazy and do nothing unless consumed"] | |||
pub struct EscapeAscii<'a> { | |||
inner: iter::FlatMap<super::Iter<'a, u8>, ascii::EscapeDefault, EscapeByte>, | |||
|
|||
/// Cached length of the iterator to implement `ExactSizeIterator`. | |||
len: usize, |
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.
you can't cache the value because len() must be updated every time an item is consumed from the iterator.
https://doc.rust-lang.org/std/iter/trait.Iterator.html#method.size_hint
Returns the bounds on the remaining length of the iterator.
This was also recently clarified for ExactsizeIterator, as you can see in the nightly docs
Returns the exact remaining length of the iterator.
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.
Thank you for pointing out my oversight. I will recommit.
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.
Well, caching may still be cheaper than recomputing it every time, but you'll at least have to update the cached value every time an item is consumed.
But the problem with that is that it makes every call to next()
more expensive, so which approach is beneficial depends on how often len() is called.
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 feel caching is the better choice even with the extra overhead of an decrement each next()
or next_back()
and an extra usize
for each EscapeAscii
. Caching avoids degenerate worst cases like users calling len()
or size_hint()
after each byte received from a slow source.
It's unfortunately to even have to go through the source iterator more than once but there isn't any other way to implement ExactSizeIterator
correctly and it can't be removed because it's been released in a stable version.
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.
and it can't be removed because it's been released in a stable version.
The stability policy does have exceptions for accidental stabilizations and critical bugfixes. So removing it is an option. The crater run in #99880 will tell us whether it's worthwhile taking that option.
Hmm, it's a bit weird that I guess that now that we've done it, we should precompute it and keep track of it. Although personally I should have probably just not implemented it for the slice version of I'm wondering what we should do here: since |
A minor technicality that might not matter: Empty iterators would not panic. |
Crater answers the age-old question: if a change breaks in the forest and no one is around to notice, is it really a breaking change? No, says crater. |
Pull request #99913 has been updated to remove the implementation of Also, thank you to those who created and run crater, without it there would be much more uncertainty about a potentially breaking change to stable versions. |
Will we want to push a patch release for this just to let people know this wasn't supposed to be stable? Or is it fine to let it slide until next version? |
Can it get into 1.63, scheduled for August 11? |
Would need a beta backport, but that seems reasonable. Not sure who's following this PR who can help coordinate that though! |
The timeline is pretty short here, and I think we'd want an FCP or similar before dropping stable support for something like this. If it was about to land on stable we could slip it in, but otherwise I don't think it's worth it. |
I think this PR can be closed, in the last libs-api meeting the team decided to try landing #99880 |
Fixes #99878
The ExactSizeIterator implementation for EscapeAscii was causing a panic because the length of the iterator was not explicitly available. This commit precalculates the length to use as an exact
size_hint
.Supersedes #99880