Skip to content

Commit dddcbcf

Browse files
committed
Fix range performance regression
A recent change to the implementation of range iterators meant that, even when stepping by 1, the iterators *always* involved checked arithmetic. This commit reverts to the earlier behavior (while retaining the refactoring into traits). Fixes #24095 cc #24014
1 parent 9f37ba6 commit dddcbcf

File tree

2 files changed

+24
-24
lines changed

2 files changed

+24
-24
lines changed

src/libcore/iter.rs

+23-24
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ use self::MinMaxResult::*;
6060

6161
use clone::Clone;
6262
use cmp;
63-
use cmp::Ord;
63+
use cmp::{Ord, PartialOrd, PartialEq};
6464
use default::Default;
6565
use marker;
6666
use mem;
@@ -2431,7 +2431,7 @@ impl<A, St, F> Iterator for Unfold<St, F> where F: FnMut(&mut St) -> Option<A> {
24312431
/// two `Step` objects.
24322432
#[unstable(feature = "step_trait",
24332433
reason = "likely to be replaced by finer-grained traits")]
2434-
pub trait Step: Ord {
2434+
pub trait Step: PartialOrd {
24352435
/// Steps `self` if possible.
24362436
fn step(&self, by: &Self) -> Option<Self>;
24372437

@@ -2598,7 +2598,10 @@ pub fn range_inclusive<A>(start: A, stop: A) -> RangeInclusive<A>
25982598

25992599
#[unstable(feature = "core",
26002600
reason = "likely to be replaced by range notation and adapters")]
2601-
impl<A: Step + One + Clone> Iterator for RangeInclusive<A> {
2601+
impl<A> Iterator for RangeInclusive<A> where
2602+
A: PartialEq + Step + One + Clone,
2603+
for<'a> &'a A: Add<&'a A, Output = A>
2604+
{
26022605
type Item = A;
26032606

26042607
#[inline]
@@ -2628,9 +2631,10 @@ impl<A: Step + One + Clone> Iterator for RangeInclusive<A> {
26282631

26292632
#[unstable(feature = "core",
26302633
reason = "likely to be replaced by range notation and adapters")]
2631-
impl<A> DoubleEndedIterator for RangeInclusive<A>
2632-
where A: Step + One + Clone,
2633-
for<'a> &'a A: Sub<Output=A>
2634+
impl<A> DoubleEndedIterator for RangeInclusive<A> where
2635+
A: PartialEq + Step + One + Clone,
2636+
for<'a> &'a A: Add<&'a A, Output = A>,
2637+
for<'a> &'a A: Sub<Output=A>
26342638
{
26352639
#[inline]
26362640
fn next_back(&mut self) -> Option<A> {
@@ -2758,24 +2762,17 @@ macro_rules! range_exact_iter_impl {
27582762

27592763
#[stable(feature = "rust1", since = "1.0.0")]
27602764
#[allow(deprecated)]
2761-
impl<A: Step + One + Clone> Iterator for ops::Range<A> {
2765+
impl<A: Step + One> Iterator for ops::Range<A> where
2766+
for<'a> &'a A: Add<&'a A, Output = A>
2767+
{
27622768
type Item = A;
27632769

27642770
#[inline]
27652771
fn next(&mut self) -> Option<A> {
27662772
if self.start < self.end {
2767-
match self.start.step(&A::one()) {
2768-
Some(mut n) => {
2769-
mem::swap(&mut n, &mut self.start);
2770-
Some(n)
2771-
},
2772-
None => {
2773-
let mut n = self.end.clone();
2774-
mem::swap(&mut n, &mut self.start);
2775-
Some(n)
2776-
2777-
}
2778-
}
2773+
let mut n = &self.start + &A::one();
2774+
mem::swap(&mut n, &mut self.start);
2775+
Some(n)
27792776
} else {
27802777
None
27812778
}
@@ -2797,6 +2794,7 @@ range_exact_iter_impl!(usize u8 u16 u32 isize i8 i16 i32);
27972794
#[stable(feature = "rust1", since = "1.0.0")]
27982795
#[allow(deprecated)]
27992796
impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
2797+
for<'a> &'a A: Add<&'a A, Output = A>,
28002798
for<'a> &'a A: Sub<&'a A, Output = A>
28012799
{
28022800
#[inline]
@@ -2812,15 +2810,16 @@ impl<A: Step + One + Clone> DoubleEndedIterator for ops::Range<A> where
28122810

28132811
#[stable(feature = "rust1", since = "1.0.0")]
28142812
#[allow(deprecated)]
2815-
impl<A: Step + One> Iterator for ops::RangeFrom<A> {
2813+
impl<A: Step + One> Iterator for ops::RangeFrom<A> where
2814+
for<'a> &'a A: Add<&'a A, Output = A>
2815+
{
28162816
type Item = A;
28172817

28182818
#[inline]
28192819
fn next(&mut self) -> Option<A> {
2820-
self.start.step(&A::one()).map(|mut n| {
2821-
mem::swap(&mut n, &mut self.start);
2822-
n
2823-
})
2820+
let mut n = &self.start + &A::one();
2821+
mem::swap(&mut n, &mut self.start);
2822+
Some(n)
28242823
}
28252824
}
28262825

src/test/compile-fail/range-1.rs

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ pub fn main() {
1919
for i in false..true {}
2020
//~^ ERROR the trait
2121
//~^^ ERROR the trait
22+
//~^^^ ERROR the trait
2223

2324
// Unsized type.
2425
let arr: &[_] = &[1, 2, 3];

0 commit comments

Comments
 (0)