Add Step::forward/backward_overflowing to enable RangeInclusive loop optimizations#155114
Add Step::forward/backward_overflowing to enable RangeInclusive loop optimizations#155114pitaj wants to merge 6 commits intorust-lang:mainfrom
Step::forward/backward_overflowing to enable RangeInclusive loop optimizations#155114Conversation
but RangeInclusive loops do not
This comment has been minimized.
This comment has been minimized.
f26532b to
d0c1f8d
Compare
This comment has been minimized.
This comment has been minimized.
and optimize the RangeInclusive iterator implementation with them This changes the `exhausted` field to represent an overflow flag for the bounds, essentially acting as an extra bit for `Idx`. This was found to enable optimizations previously only applicable to the exclusive-ended Range type.
d0c1f8d to
39e74a3
Compare
|
We discussed this in the @rust-lang/libs-api meeting. The If the |
|
Right, I forgot this implements Eq even though I implemented it manually 🤦♂️. @Amanieu I'm not sure it gains much over just going back to the derive, would that be acceptable? |
|
The derive is also acceptable. We explicitly document that |
It implements DoubleEndedIterator but regardless yeah I'll change it back to the derive |
|
@rustbot ready |
|
I found a bug with this PR. fn main() {
let mut range = 255_u8..=255_u8;
let _ = range.next();
println!("{range:?}");
println!("{}", range.contains(&100_u8));
}Output of above code on nightly: Output of above code with this PR: (The desired behavior of the |
|
And here's some strange behavior that's possibly a bug: fn main() {
let mut range = 0_usize..=0_usize;
let _ = range.next_back();
println!("{range:?}");
let data = [0; 1000];
println!("{:?}", &data[range]);
}Output of above code on nightly: Output of above code with this PR: |
|
|
||
| let (n, o) = Step::forward_overflowing(self.start.clone(), 1); | ||
|
|
||
| self.exhausted |= o; |
There was a problem hiding this comment.
| self.exhausted |= o; | |
| self.exhausted = o; |
self.exhausted is always false before this line.
| } | ||
| } | ||
| self.start = plus_1; | ||
| self.exhausted |= on | o1; |
There was a problem hiding this comment.
| self.exhausted |= on | o1; | |
| self.exhausted = on | o1; |
Same thing here
change end_bound to return Excluded(start) when exhausted add contains to tests
matches From<legacy::RangeInclusive<T>> for RangeInclusive<T> and expand explanation for into_slice_range
Good find on
This is expected behavior from the new overflowing behavior. Given that the values of
I think the I also changed Nominating for libs-api approval of those changes |
|
This was discussed the @rust-lang/libs-api meeting. We're happy with the @bors try |
This comment has been minimized.
This comment has been minimized.
Add `Step::forward/backward_overflowing` to enable RangeInclusive loop optimizations
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.
|
@bors try |
This comment has been minimized.
This comment has been minimized.
Add `Step::forward/backward_overflowing` to enable RangeInclusive loop optimizations
|
@craterbot run mode=build-and-test |
|
👌 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
|
🚧 Experiment ℹ️ Crater is a tool to run experiments across parts of the Rust ecosystem. Learn more |
View all comments
ACP: rust-lang/libs-team#767
This adds new required methods to the Step trait:
It was found that using these to implement RangeInclusive's Iterator impl enabled optimizations previously only applicable to the exclusive-ended
Range.This required changing how "exhaustion" works for
RangeInclusive. I've nominated this for libs-api discussion because of one insta-stable change:The new implementations now only set
exhaustedwhen overflow occurs, andstartis now advanced pastendotherwise. I doubt anyone depends on the prior behavior, but it's probably worth a crater run.The exhaustion changes also affect
Debugbut my understanding is that debug formatting is never guaranteed stable.I have now changed the
nthimpls to use the new functions as well.r? libs