diff --git a/src/iter_index.rs b/src/iter_index.rs index 679a88075..cf3222c9d 100644 --- a/src/iter_index.rs +++ b/src/iter_index.rs @@ -48,11 +48,17 @@ impl IteratorIndex for RangeInclusive where I: Iterator, { - type Output = Skip>; + type Output = Take>; fn index(self, iter: I) -> Self::Output { - assert_ne!(*self.end(), usize::MAX); - iter.take(self.end() + 1).skip(*self.start()) + // end - start + 1 without overflowing if possible + let length = if *self.end() == usize::MAX { + assert_ne!(*self.start(), 0); + self.end() - self.start() + 1 + } else { + (self.end() + 1).saturating_sub(*self.start()) + }; + iter.skip(*self.start()).take(length) } } diff --git a/src/lib.rs b/src/lib.rs index c45f0cd07..8d4cd1c07 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -511,7 +511,7 @@ pub trait Itertools: Iterator { /// /// Works similarly to [`slice::get`](https://doc.rust-lang.org/std/primitive.slice.html#method.get). /// - /// **Panics** if the range includes `usize::MAX`. + /// **Panics** for ranges `..=usize::MAX` and `0..=usize::MAX`. /// /// It's a generalisation of [`Iterator::take`] and [`Iterator::skip`], /// and uses these under the hood.