Skip to content
/ rust Public
forked from rust-lang/rust

Commit f836c83

Browse files
authored
Rollup merge of rust-lang#155114 - pitaj:rangeinclusiveiter-optimize, r=Mark-Simulacrum
Add `Step::forward/backward_overflowing` to enable RangeInclusive loop optimizations ACP: rust-lang/libs-team#767 This adds new required methods to the Step trait: ```rust trait Step: ... { // ... existing functions // New required functions fn forward_overflowing(start: Self, count: usize) -> (Self, bool); fn backward_overflowing(start: Self, count: usize) -> (Self, bool); } ``` 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 `exhausted` when overflow occurs, and `start` is now advanced past `end` otherwise. I doubt anyone depends on the prior behavior, but it's probably worth a crater run. The exhaustion changes also affect `Debug` but my understanding is that debug formatting is never guaranteed stable. I have now changed the `nth` impls to use the new functions as well. r? libs
2 parents 071adf5 + c83fca5 commit f836c83

12 files changed

Lines changed: 429 additions & 144 deletions

compiler/rustc_abi/src/lib.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -990,6 +990,13 @@ impl Step for Size {
990990
u64::forward_checked(start.bytes(), count).map(Self::from_bytes)
991991
}
992992

993+
#[inline]
994+
#[cfg(not(bootstrap))]
995+
fn forward_overflowing(start: Self, count: usize) -> (Self, bool) {
996+
let (s, o) = u64::forward_overflowing(start.bytes(), count);
997+
(Self::from_bytes(s), o)
998+
}
999+
9931000
#[inline]
9941001
fn forward(start: Self, count: usize) -> Self {
9951002
Self::from_bytes(u64::forward(start.bytes(), count))
@@ -1005,6 +1012,13 @@ impl Step for Size {
10051012
u64::backward_checked(start.bytes(), count).map(Self::from_bytes)
10061013
}
10071014

1015+
#[inline]
1016+
#[cfg(not(bootstrap))]
1017+
fn backward_overflowing(start: Self, count: usize) -> (Self, bool) {
1018+
let (s, o) = u64::backward_overflowing(start.bytes(), count);
1019+
(Self::from_bytes(s), o)
1020+
}
1021+
10081022
#[inline]
10091023
fn backward(start: Self, count: usize) -> Self {
10101024
Self::from_bytes(u64::backward(start.bytes(), count))

compiler/rustc_index_macros/src/newtype.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,20 @@ impl Parse for Newtype {
136136
fn backward_checked(start: Self, u: usize) -> Option<Self> {
137137
Self::index(start).checked_sub(u).map(Self::from_usize)
138138
}
139+
140+
#[inline]
141+
#[cfg(not(bootstrap))]
142+
fn forward_overflowing(start: Self, u: usize) -> (Self, bool) {
143+
let (s, o) = Self::index(start).overflowing_add(u);
144+
(Self::from_usize(s), o)
145+
}
146+
147+
#[inline]
148+
#[cfg(not(bootstrap))]
149+
fn backward_overflowing(start: Self, u: usize) -> (Self, bool) {
150+
let (s, o) = Self::index(start).overflowing_sub(u);
151+
(Self::from_usize(s), o)
152+
}
139153
}
140154
impl ::std::cmp::Ord for #name {
141155
fn cmp(&self, other: &Self) -> std::cmp::Ordering {

0 commit comments

Comments
 (0)