Skip to content

Commit 31fa301

Browse files
committed
Auto merge of #56049 - newpavlov:revert_51601, r=sfackler
Revert #51601 Closes: #55985 Specialization of `StepBy<Range(Inclusive)>` results in an incorrectly behaving code when `step_by` is combined with `skip` or `nth`. If this will get merged we probably should reopen issues previously closed by #51601 (if there was any).
2 parents 5aff307 + 6357021 commit 31fa301

File tree

2 files changed

+14
-75
lines changed

2 files changed

+14
-75
lines changed

src/libcore/iter/mod.rs

+7-75
Original file line numberDiff line numberDiff line change
@@ -319,10 +319,9 @@
319319
use cmp;
320320
use fmt;
321321
use iter_private::TrustedRandomAccess;
322-
use ops::{self, Try};
322+
use ops::Try;
323323
use usize;
324324
use intrinsics;
325-
use mem;
326325

327326
#[stable(feature = "rust1", since = "1.0.0")]
328327
pub use self::iterator::Iterator;
@@ -673,7 +672,12 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
673672

674673
#[inline]
675674
fn next(&mut self) -> Option<Self::Item> {
676-
<Self as StepBySpecIterator>::spec_next(self)
675+
if self.first_take {
676+
self.first_take = false;
677+
self.iter.next()
678+
} else {
679+
self.iter.nth(self.step)
680+
}
677681
}
678682

679683
#[inline]
@@ -733,78 +737,6 @@ impl<I> Iterator for StepBy<I> where I: Iterator {
733737
}
734738
}
735739

736-
// hidden trait for specializing iterator methods
737-
// could be generalized but is currently only used for StepBy
738-
trait StepBySpecIterator {
739-
type Item;
740-
fn spec_next(&mut self) -> Option<Self::Item>;
741-
}
742-
743-
impl<I> StepBySpecIterator for StepBy<I>
744-
where
745-
I: Iterator,
746-
{
747-
type Item = I::Item;
748-
749-
#[inline]
750-
default fn spec_next(&mut self) -> Option<I::Item> {
751-
if self.first_take {
752-
self.first_take = false;
753-
self.iter.next()
754-
} else {
755-
self.iter.nth(self.step)
756-
}
757-
}
758-
}
759-
760-
impl<T> StepBySpecIterator for StepBy<ops::Range<T>>
761-
where
762-
T: Step,
763-
{
764-
#[inline]
765-
fn spec_next(&mut self) -> Option<Self::Item> {
766-
self.first_take = false;
767-
if !(self.iter.start < self.iter.end) {
768-
return None;
769-
}
770-
// add 1 to self.step to get original step size back
771-
// it was decremented for the general case on construction
772-
if let Some(n) = self.iter.start.add_usize(self.step+1) {
773-
let next = mem::replace(&mut self.iter.start, n);
774-
Some(next)
775-
} else {
776-
let last = self.iter.start.clone();
777-
self.iter.start = self.iter.end.clone();
778-
Some(last)
779-
}
780-
}
781-
}
782-
783-
impl<T> StepBySpecIterator for StepBy<ops::RangeInclusive<T>>
784-
where
785-
T: Step,
786-
{
787-
#[inline]
788-
fn spec_next(&mut self) -> Option<Self::Item> {
789-
self.first_take = false;
790-
self.iter.compute_is_empty();
791-
if self.iter.is_empty.unwrap_or_default() {
792-
return None;
793-
}
794-
// add 1 to self.step to get original step size back
795-
// it was decremented for the general case on construction
796-
if let Some(n) = self.iter.start.add_usize(self.step+1) {
797-
self.iter.is_empty = Some(!(n <= self.iter.end));
798-
let next = mem::replace(&mut self.iter.start, n);
799-
Some(next)
800-
} else {
801-
let last = self.iter.start.clone();
802-
self.iter.is_empty = Some(true);
803-
Some(last)
804-
}
805-
}
806-
}
807-
808740
// StepBy can only make the iterator shorter, so the len will still fit.
809741
#[stable(feature = "iterator_step_by", since = "1.28.0")]
810742
impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}

src/libcore/tests/iter.rs

+7
Original file line numberDiff line numberDiff line change
@@ -1618,6 +1618,13 @@ fn test_range_step() {
16181618
assert_eq!((isize::MIN..isize::MAX).step_by(1).size_hint(), (usize::MAX, Some(usize::MAX)));
16191619
}
16201620

1621+
#[test]
1622+
fn test_step_by_skip() {
1623+
assert_eq!((0..640).step_by(128).skip(1).collect::<Vec<_>>(), [128, 256, 384, 512]);
1624+
assert_eq!((0..=50).step_by(10).nth(3), Some(30));
1625+
assert_eq!((200..=255u8).step_by(10).nth(3), Some(230));
1626+
}
1627+
16211628
#[test]
16221629
fn test_range_inclusive_step() {
16231630
assert_eq!((0..=50).step_by(10).collect::<Vec<_>>(), [0, 10, 20, 30, 40, 50]);

0 commit comments

Comments
 (0)