Skip to content

Commit c59cc85

Browse files
huonwOliver Schneider
authored andcommitted
Work-around optimiser deficiencies in Range iterator.
The conditional mutation of the previous implementation resulted in poor code, making it unconditional makes `Range` less well behaved as an Iterator (but still legal) but also makes it fast. The intention is that this change will be reverted when rustc/LLVM handle the best-behaved implementation better. cc rust-lang#24660
1 parent 4806210 commit c59cc85

File tree

2 files changed

+18
-3
lines changed

2 files changed

+18
-3
lines changed

src/libcore/iter.rs

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2896,9 +2896,17 @@ impl<A: Step + One> Iterator for ops::Range<A> where
28962896

28972897
#[inline]
28982898
fn next(&mut self) -> Option<A> {
2899-
if self.start < self.end {
2900-
let mut n = &self.start + &A::one();
2901-
mem::swap(&mut n, &mut self.start);
2899+
// FIXME #24660: this may start returning Some after returning
2900+
// None if the + overflows. This is OK per Iterator's
2901+
// definition, but it would be really nice for a core iterator
2902+
// like `x..y` to be as well behaved as
2903+
// possible. Unfortunately, for types like `i32`, LLVM
2904+
// mishandles the version that places the mutation inside the
2905+
// `if`: it seems to optimise the `Option<i32>` in a way that
2906+
// confuses it.
2907+
let mut n = &self.start + &A::one();
2908+
mem::swap(&mut n, &mut self.start);
2909+
if n < self.end {
29022910
Some(n)
29032911
} else {
29042912
None

src/libcoretest/iter.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1167,3 +1167,10 @@ fn bench_max(b: &mut Bencher) {
11671167
it.map(scatter).max()
11681168
})
11691169
}
1170+
1171+
#[bench]
1172+
fn bench_range_constant_fold(b: &mut Bencher) {
1173+
// this should be constant-folded to just '1000', and so this
1174+
// benchmark should run quickly...
1175+
b.iter(|| (0..1000).count())
1176+
}

0 commit comments

Comments
 (0)