diff options
| author | oyvindln <oyvindln@users.noreply.github.com> | 2017-08-01 19:17:33 +0200 |
|---|---|---|
| committer | oyvindln <oyvindln@users.noreply.github.com> | 2017-08-01 19:31:50 +0200 |
| commit | 4bb9a8b4ac27b48fb7989ef2900ec12a0face475 (patch) | |
| tree | 257af90900d1f7db99edb23a55a51e7f96d71390 /src | |
| parent | c2407516ff33d03d0e24c6a4268a5581e9bc8b4d (diff) | |
Add an overflow check in the Iter::next() impl for Range<_>
This helps with vectorization in some cases, such as (0..u16::MAX).collect::<Vec<u16>>(), as LLVM is able to change the loop condition to use equality instead of less than
Diffstat (limited to 'src')
| -rw-r--r-- | src/libcore/iter/range.rs | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/src/libcore/iter/range.rs b/src/libcore/iter/range.rs index 32c32e327eb..73d518b570a 100644 --- a/src/libcore/iter/range.rs +++ b/src/libcore/iter/range.rs @@ -214,9 +214,16 @@ impl<A: Step> Iterator for ops::Range<A> { #[inline] fn next(&mut self) -> Option<A> { if self.start < self.end { - let mut n = self.start.add_one(); - mem::swap(&mut n, &mut self.start); - Some(n) + // We check for overflow here, even though it can't actually + // happen. Adding this check does however help llvm vectorize loops + // for some ranges that don't get vectorized otherwise, + // and this won't actually result in an extra check in an optimized build. + if let Some(mut n) = self.start.add_usize(1) { + mem::swap(&mut n, &mut self.start); + Some(n) + } else { + None + } } else { None } |
