Change:
The following snippet demonstrates the problem: It prints: I expect second iterator to produce the same result as for the third one.
Regression from 1.28.0 to 1.29.0. Introduced in
The problem is interaction between and . ignores the inner working of StepBy. Test-case reduced to using without .
From a cursory look, it seems to me that the problem is that and are out of sync. StepBy specifically allows for the underlying iterator, either or . If both and follow the same one, the bug shouldn't occur. In other words, if is specialized and overrides the default, then needs to be specialized as well.

Discussion:
use cmp; use fmt; use iter_private::TrustedRandomAccess; <del> use ops::{self, Try}; </del> <ins> use ops::Try; </ins> use usize; use intrinsics; <del> use mem; </del> #[stable(feature = "rust1", since = "1.0.0")] pub use self::iterator::Iterator;

#[inline] fn next(&mut self) -> Option<Self::Item> { <del> <Self as StepBySpecIterator>::spec_next(self) </del> <ins> if self.first_take { self.first_take = false; self.iter.next() } else { self.iter.nth(self.step) } </ins> } #[inline]

} } <del> // hidden trait for specializing iterator methods // could be generalized but is currently only used for StepBy trait StepBySpecIterator { type Item; fn spec_next(&mut self) -> Option<Self::Item>; } impl<I> StepBySpecIterator for StepBy<I> where I: Iterator, { type Item = I::Item; #[inline] default fn spec_next(&mut self) -> Option<I::Item> { if self.first_take { self.first_take = false; self.iter.next() } else { self.iter.nth(self.step) } } } impl<T> StepBySpecIterator for StepBy<ops::Range<T>> where T: Step, { #[inline] fn spec_next(&mut self) -> Option<Self::Item> { self.first_take = false; if !(self.iter.start < self.iter.end) { return None; } // add 1 to self.step to get original step size back // it was decremented for the general case on construction if let Some(n) = self.iter.start.add_usize(self.step+1) { let next = mem::replace(&mut self.iter.start, n); Some(next) } else { let last = self.iter.start.clone(); self.iter.start = self.iter.end.clone(); Some(last) } } } impl<T> StepBySpecIterator for StepBy<ops::RangeInclusive<T>> where T: Step, { #[inline] fn spec_next(&mut self) -> Option<Self::Item> { self.first_take = false; self.iter.compute_is_empty(); if self.iter.is_empty.unwrap_or_default() { return None; } // add 1 to self.step to get original step size back // it was decremented for the general case on construction if let Some(n) = self.iter.start.add_usize(self.step+1) { self.iter.is_empty = Some(!(n <= self.iter.end)); let next = mem::replace(&mut self.iter.start, n); Some(next) } else { let last = self.iter.start.clone(); self.iter.is_empty = Some(true); Some(last) } } } </del> // StepBy can only make the iterator shorter, so the len will still fit. #[stable(feature = "iterator_step_by", since = "1.28.0")] impl<I> ExactSizeIterator for StepBy<I> where I: ExactSizeIterator {}

} #[test] <ins> fn test_step_by_skip() { assert_eq!((0..640).step_by(128).skip(1).collect::<Vec<_>>(), [128, 256, 384, 512]); assert_eq!((0..=50).step_by(10).nth(3), Some(30)); assert_eq!((200..=255u8).step_by(10).nth(3), Some(230)); } #[test] </ins> fn test_range_inclusive_step() { assert_eq!((0..=50).step_by(10).collect::<Vec<_>>(), [0, 10, 20, 30, 40, 50]); assert_eq!((0..=5).step_by(1).collect::<Vec<_>>(), [0, 1, 2, 3, 4, 5]);