Skip to content

Commit c724b67

Browse files
committed
Auto merge of rust-lang#73490 - CAD97:range-unchecked-stepping, r=Amanieu
Use step_unchecked more liberally in range iter impls Without these `_unchecked`, these operations on iterators of `char` fail to optimize out the unreachable panicking condition on overflow. cc @cuviper rayon-rs/rayon#771 where this was discovered.
2 parents 4a689da + 7779a11 commit c724b67

File tree

1 file changed

+12
-12
lines changed

1 file changed

+12
-12
lines changed

Diff for: src/libcore/iter/range.rs

+12-12
Original file line numberDiff line numberDiff line change
@@ -504,9 +504,6 @@ impl<A: Step> Iterator for ops::Range<A> {
504504
fn next(&mut self) -> Option<A> {
505505
if self.start < self.end {
506506
// SAFETY: just checked precondition
507-
// We use the unchecked version here, because
508-
// this helps LLVM vectorize loops for some ranges
509-
// that don't get vectorized otherwise.
510507
let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
511508
Some(mem::replace(&mut self.start, n))
512509
} else {
@@ -528,7 +525,8 @@ impl<A: Step> Iterator for ops::Range<A> {
528525
fn nth(&mut self, n: usize) -> Option<A> {
529526
if let Some(plus_n) = Step::forward_checked(self.start.clone(), n) {
530527
if plus_n < self.end {
531-
self.start = Step::forward(plus_n.clone(), 1);
528+
// SAFETY: just checked precondition
529+
self.start = unsafe { Step::forward_unchecked(plus_n.clone(), 1) };
532530
return Some(plus_n);
533531
}
534532
}
@@ -589,7 +587,8 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
589587
#[inline]
590588
fn next_back(&mut self) -> Option<A> {
591589
if self.start < self.end {
592-
self.end = Step::backward(self.end.clone(), 1);
590+
// SAFETY: just checked precondition
591+
self.end = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
593592
Some(self.end.clone())
594593
} else {
595594
None
@@ -600,7 +599,8 @@ impl<A: Step> DoubleEndedIterator for ops::Range<A> {
600599
fn nth_back(&mut self, n: usize) -> Option<A> {
601600
if let Some(minus_n) = Step::backward_checked(self.end.clone(), n) {
602601
if minus_n > self.start {
603-
self.end = Step::backward(minus_n, 1);
602+
// SAFETY: just checked precondition
603+
self.end = unsafe { Step::backward_unchecked(minus_n, 1) };
604604
return Some(self.end.clone());
605605
}
606606
}
@@ -657,9 +657,6 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
657657
let is_iterating = self.start < self.end;
658658
Some(if is_iterating {
659659
// SAFETY: just checked precondition
660-
// We use the unchecked version here, because
661-
// otherwise `for _ in '\0'..=char::MAX`
662-
// does not successfully remove panicking code.
663660
let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
664661
mem::replace(&mut self.start, n)
665662
} else {
@@ -722,7 +719,8 @@ impl<A: Step> Iterator for ops::RangeInclusive<A> {
722719
let mut accum = init;
723720

724721
while self.start < self.end {
725-
let n = Step::forward(self.start.clone(), 1);
722+
// SAFETY: just checked precondition
723+
let n = unsafe { Step::forward_unchecked(self.start.clone(), 1) };
726724
let n = mem::replace(&mut self.start, n);
727725
accum = f(accum, n)?;
728726
}
@@ -775,7 +773,8 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
775773
}
776774
let is_iterating = self.start < self.end;
777775
Some(if is_iterating {
778-
let n = Step::backward(self.end.clone(), 1);
776+
// SAFETY: just checked precondition
777+
let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
779778
mem::replace(&mut self.end, n)
780779
} else {
781780
self.exhausted = true;
@@ -825,7 +824,8 @@ impl<A: Step> DoubleEndedIterator for ops::RangeInclusive<A> {
825824
let mut accum = init;
826825

827826
while self.start < self.end {
828-
let n = Step::backward(self.end.clone(), 1);
827+
// SAFETY: just checked precondition
828+
let n = unsafe { Step::backward_unchecked(self.end.clone(), 1) };
829829
let n = mem::replace(&mut self.end, n);
830830
accum = f(accum, n)?;
831831
}

0 commit comments

Comments
 (0)