diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs index 419bf0e292ae1..39cfef73efc6a 100644 --- a/library/core/src/slice/iter.rs +++ b/library/core/src/slice/iter.rs @@ -11,7 +11,6 @@ use crate::intrinsics::{assume, exact_div, unchecked_sub}; use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess, TrustedRandomAccessNoCoerce}; use crate::marker::{PhantomData, Send, Sized, Sync}; use crate::mem; -use crate::num::NonZeroUsize; use crate::ptr::NonNull; use super::{from_raw_parts, from_raw_parts_mut}; @@ -1193,12 +1192,12 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] } #[stable(feature = "rust1", since = "1.0.0")] pub struct Windows<'a, T: 'a> { v: &'a [T], - size: NonZeroUsize, + size: usize, } impl<'a, T: 'a> Windows<'a, T> { #[inline] - pub(super) fn new(slice: &'a [T], size: NonZeroUsize) -> Self { + pub(super) fn new(slice: &'a [T], size: usize) -> Self { Self { v: slice, size } } } @@ -1217,10 +1216,10 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn next(&mut self) -> Option<&'a [T]> { - if self.size.get() > self.v.len() { + if self.size > self.v.len() { None } else { - let ret = Some(&self.v[..self.size.get()]); + let ret = Some(&self.v[..self.size]); self.v = &self.v[1..]; ret } @@ -1228,10 +1227,10 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn size_hint(&self) -> (usize, Option<usize>) { - if self.size.get() > self.v.len() { + if self.size > self.v.len() { (0, Some(0)) } else { - let size = self.v.len() - self.size.get() + 1; + let size = self.v.len() - self.size + 1; (size, Some(size)) } } @@ -1243,7 +1242,7 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn nth(&mut self, n: usize) -> Option<Self::Item> { - let (end, overflow) = self.size.get().overflowing_add(n); + let (end, overflow) = self.size.overflowing_add(n); if end > self.v.len() || overflow { self.v = &[]; None @@ -1256,10 +1255,10 @@ impl<'a, T> Iterator for Windows<'a, T> { #[inline] fn last(self) -> Option<Self::Item> { - if self.size.get() > self.v.len() { + if self.size > self.v.len() { None } else { - let start = self.v.len() - self.size.get(); + let start = self.v.len() - self.size; Some(&self.v[start..]) } } @@ -1270,7 +1269,7 @@ impl<'a, T> Iterator for Windows<'a, T> { // which means that `i` cannot overflow an `isize`, and the // slice created by `from_raw_parts` is a subslice of `self.v` // thus is guaranteed to be valid for the lifetime `'a` of `self.v`. - unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size.get()) } + unsafe { from_raw_parts(self.v.as_ptr().add(idx), self.size) } } } @@ -1278,10 +1277,10 @@ impl<'a, T> Iterator for Windows<'a, T> { impl<'a, T> DoubleEndedIterator for Windows<'a, T> { #[inline] fn next_back(&mut self) -> Option<&'a [T]> { - if self.size.get() > self.v.len() { + if self.size > self.v.len() { None } else { - let ret = Some(&self.v[self.v.len() - self.size.get()..]); + let ret = Some(&self.v[self.v.len() - self.size..]); self.v = &self.v[..self.v.len() - 1]; ret } @@ -1290,11 +1289,11 @@ impl<'a, T> DoubleEndedIterator for Windows<'a, T> { #[inline] fn nth_back(&mut self, n: usize) -> Option<Self::Item> { let (end, overflow) = self.v.len().overflowing_sub(n); - if end < self.size.get() || overflow { + if end < self.size || overflow { self.v = &[]; None } else { - let ret = &self.v[end - self.size.get()..end]; + let ret = &self.v[end - self.size..end]; self.v = &self.v[..end - 1]; Some(ret) } @@ -1995,7 +1994,7 @@ pub struct ArrayWindows<'a, T: 'a, const N: usize> { impl<'a, T: 'a, const N: usize> ArrayWindows<'a, T, N> { #[inline] pub(super) fn new(slice: &'a [T]) -> Self { - let num_windows = slice.len().saturating_sub(N - 1); + let num_windows = (slice.len() + 1).saturating_sub(N); Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData } } } diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs index 67eecab99d89a..aece1a9865e06 100644 --- a/library/core/src/slice/mod.rs +++ b/library/core/src/slice/mod.rs @@ -11,7 +11,6 @@ use crate::cmp::Ordering::{self, Greater, Less}; use crate::marker::Copy; use crate::mem; -use crate::num::NonZeroUsize; use crate::ops::{FnMut, Range, RangeBounds}; use crate::option::Option; use crate::option::Option::{None, Some}; @@ -725,13 +724,9 @@ impl<T> [T] { } /// Returns an iterator over all contiguous windows of length - /// `size`. The windows overlap. If the slice is shorter than + /// `size`. The windows may overlap. If the slice is shorter than /// `size`, the iterator returns no values. /// - /// # Panics - /// - /// Panics if `size` is 0. - /// /// # Examples /// /// ``` @@ -753,7 +748,6 @@ impl<T> [T] { #[stable(feature = "rust1", since = "1.0.0")] #[inline] pub fn windows(&self, size: usize) -> Windows<'_, T> { - let size = NonZeroUsize::new(size).expect("size is zero"); Windows::new(self, size) } @@ -1199,11 +1193,6 @@ impl<T> [T] { /// /// If `N` is greater than the size of the slice, it will return no windows. /// - /// # Panics - /// - /// Panics if `N` is 0. This check will most probably get changed to a compile time - /// error before this method gets stabilized. - /// /// # Examples /// /// ``` @@ -1220,7 +1209,6 @@ impl<T> [T] { #[unstable(feature = "array_windows", issue = "75027")] #[inline] pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> { - assert_ne!(N, 0); ArrayWindows::new(self) } diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs index 240b894057c3e..ca5b8d08db3e2 100644 --- a/library/core/tests/slice.rs +++ b/library/core/tests/slice.rs @@ -726,6 +726,18 @@ fn test_array_windows_infer() { assert_eq!(total, 3 + 6 + 9 + 12 + 15); } +#[test] +fn test_array_windows_zero() { + let v: &[i32] = &[0, 1, 2]; + let mut iter = v.array_windows::<0>(); + + assert_eq!(iter.next(), Some(&[])); + assert_eq!(iter.next(), Some(&[])); + assert_eq!(iter.next(), Some(&[])); + assert_eq!(iter.next(), Some(&[])); + assert_eq!(iter.next(), None); +} + #[test] fn test_array_windows_count() { let v: &[i32] = &[0, 1, 2, 3, 4, 5]; @@ -739,6 +751,10 @@ fn test_array_windows_count() { let v3: &[i32] = &[]; let c3 = v3.array_windows::<2>(); assert_eq!(c3.count(), 0); + + let v4: &[i32] = &[0, 1, 2]; + let c4 = c4.array_windows::<0>(); + assert_eq!(c4.count(), 4); } #[test] @@ -1050,6 +1066,10 @@ fn test_windows_count() { let v3: &[i32] = &[]; let c3 = v3.windows(2); assert_eq!(c3.count(), 0); + + let v4: &[i32] = &[0, 1, 2, 3, 4]; + let c4 = v4.windows(0); + assert_eq!(c4.count(), 6); } #[test]