Skip to content

Commit

Permalink
Auto merge of #46074 - scottmcm:unspecialize-nth, r=bluss
Browse files Browse the repository at this point in the history
Undo the Sized specialization from Iterator::nth

I just added this as part of #45595, but I'm now afraid there's a specialization issue with it, since I tried to add [another similar specialization](https://github.com/rust-lang/rust/compare/master...scottmcm:faster-iter-by-ref?expand=1#diff-1398f322bc563592215b583e9b0ba936R2390), and ended up getting really disturbing test failures like
```
thread 'iter::test_by_ref_folds' panicked at 'assertion failed: `(left == right)`
  left: `15`,
 right: `15`', src\libcore\../libcore/tests\iter.rs:1720:4
```

So since this wasn't the most critical part of the change and a new beta is branching within a week, I think putting this part back to what it was before is the best option.
  • Loading branch information
bors committed Nov 19, 2017
2 parents c5c70ef + cef45b3 commit d8d5b61
Showing 1 changed file with 6 additions and 26 deletions.
32 changes: 6 additions & 26 deletions src/libcore/iter/iterator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -253,8 +253,12 @@ pub trait Iterator {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
fn nth(&mut self, n: usize) -> Option<Self::Item> {
self.spec_nth(n)
fn nth(&mut self, mut n: usize) -> Option<Self::Item> {
for x in self {
if n == 0 { return Some(x) }
n -= 1;
}
None
}

/// Creates an iterator starting at the same point, but stepping by
Expand Down Expand Up @@ -2381,27 +2385,3 @@ impl<'a, I: Iterator + ?Sized> Iterator for &'a mut I {
(**self).nth(n)
}
}


trait SpecIterator : Iterator {
fn spec_nth(&mut self, n: usize) -> Option<Self::Item>;
}

impl<I: Iterator + ?Sized> SpecIterator for I {
default fn spec_nth(&mut self, mut n: usize) -> Option<Self::Item> {
for x in self {
if n == 0 { return Some(x) }
n -= 1;
}
None
}
}

impl<I: Iterator + Sized> SpecIterator for I {
fn spec_nth(&mut self, n: usize) -> Option<Self::Item> {
self.try_fold(n, move |i, x| {
if i == 0 { LoopState::Break(x) }
else { LoopState::Continue(i - 1) }
}).break_value()
}
}

0 comments on commit d8d5b61

Please sign in to comment.