about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2020-09-18 23:38:17 +0000
committerbors <bors@rust-lang.org>2020-09-18 23:38:17 +0000
commitc6ab8e5fe0a837e06ae53bfa962e844d220ccf38 (patch)
treee65ebaefe4bfbf5a65eb554130c9cdcd60c61ef5
parentbbc677480db8da85ea302e1e89d3df1f00e435bf (diff)
parentb65937031d7c5a1ad45c847e9d3d97c822c1ac81 (diff)
downloadrust-c6ab8e5fe0a837e06ae53bfa962e844d220ccf38.tar.gz
rust-c6ab8e5fe0a837e06ae53bfa962e844d220ccf38.zip
Auto merge of #76787 - lzutao:slice_iters_new, r=lcnr
Using <Iter>::new instead of exposing internal fields

As requested in https://github.com/rust-lang/rust/pull/76311#discussion_r487685126
-rw-r--r--library/core/src/slice/iter.rs333
-rw-r--r--library/core/src/slice/mod.rs137
2 files changed, 302 insertions, 168 deletions
diff --git a/library/core/src/slice/iter.rs b/library/core/src/slice/iter.rs
index 84fa34c75e3..546edef7f57 100644
--- a/library/core/src/slice/iter.rs
+++ b/library/core/src/slice/iter.rs
@@ -8,7 +8,7 @@ use crate::cmp::Ordering;
 use crate::fmt;
 use crate::intrinsics::{assume, exact_div, unchecked_sub};
 use crate::iter::{FusedIterator, TrustedLen, TrustedRandomAccess};
-use crate::marker::{self, Send, Sized, Sync};
+use crate::marker::{PhantomData, Send, Sized, Sync};
 use crate::mem;
 use crate::ptr::NonNull;
 
@@ -62,11 +62,11 @@ fn size_from_ptr<T>(_: *const T) -> usize {
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Iter<'a, T: 'a> {
-    pub(super) ptr: NonNull<T>,
-    pub(super) end: *const T, // If T is a ZST, this is actually ptr+len.  This encoding is picked so that
+    ptr: NonNull<T>,
+    end: *const T, // If T is a ZST, this is actually ptr+len.  This encoding is picked so that
     // ptr == end is a quick test for the Iterator being empty, that works
     // for both ZST and non-ZST.
-    pub(super) _marker: marker::PhantomData<&'a T>,
+    _marker: PhantomData<&'a T>,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -82,6 +82,23 @@ unsafe impl<T: Sync> Sync for Iter<'_, T> {}
 unsafe impl<T: Sync> Send for Iter<'_, T> {}
 
 impl<'a, T> Iter<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T]) -> Self {
+        let ptr = slice.as_ptr();
+        // SAFETY: Similar to `IterMut::new`.
+        unsafe {
+            assume(!ptr.is_null());
+
+            let end = if mem::size_of::<T>() == 0 {
+                (ptr as *const u8).wrapping_add(slice.len()) as *const T
+            } else {
+                ptr.add(slice.len())
+            };
+
+            Self { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: PhantomData }
+        }
+    }
+
     /// Views the underlying data as a subslice of the original data.
     ///
     /// This has the same lifetime as the original slice, and so the
@@ -164,11 +181,11 @@ impl<T> AsRef<[T]> for Iter<'_, T> {
 /// [slices]: ../../std/primitive.slice.html
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct IterMut<'a, T: 'a> {
-    pub(super) ptr: NonNull<T>,
-    pub(super) end: *mut T, // If T is a ZST, this is actually ptr+len.  This encoding is picked so that
+    ptr: NonNull<T>,
+    end: *mut T, // If T is a ZST, this is actually ptr+len.  This encoding is picked so that
     // ptr == end is a quick test for the Iterator being empty, that works
     // for both ZST and non-ZST.
-    pub(super) _marker: marker::PhantomData<&'a mut T>,
+    _marker: PhantomData<&'a mut T>,
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -184,6 +201,38 @@ unsafe impl<T: Sync> Sync for IterMut<'_, T> {}
 unsafe impl<T: Send> Send for IterMut<'_, T> {}
 
 impl<'a, T> IterMut<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T]) -> Self {
+        let ptr = slice.as_mut_ptr();
+        // SAFETY: There are several things here:
+        //
+        // `ptr` has been obtained by `slice.as_ptr()` where `slice` is a valid
+        // reference thus it is non-NUL and safe to use and pass to
+        // `NonNull::new_unchecked` .
+        //
+        // Adding `slice.len()` to the starting pointer gives a pointer
+        // at the end of `slice`. `end` will never be dereferenced, only checked
+        // for direct pointer equality with `ptr` to check if the iterator is
+        // done.
+        //
+        // In the case of a ZST, the end pointer is just the start pointer plus
+        // the length, to also allows for the fast `ptr == end` check.
+        //
+        // See the `next_unchecked!` and `is_empty!` macros as well as the
+        // `post_inc_start` method for more informations.
+        unsafe {
+            assume(!ptr.is_null());
+
+            let end = if mem::size_of::<T>() == 0 {
+                (ptr as *mut u8).wrapping_add(slice.len()) as *mut T
+            } else {
+                ptr.add(slice.len())
+            };
+
+            Self { ptr: NonNull::new_unchecked(ptr), end, _marker: PhantomData }
+        }
+    }
+
     /// Views the underlying data as a subslice of the original data.
     ///
     /// To avoid creating `&mut` references that alias, this is forced
@@ -277,9 +326,16 @@ pub struct Split<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) v: &'a [T],
-    pub(super) pred: P,
-    pub(super) finished: bool,
+    v: &'a [T],
+    pred: P,
+    finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> Split<'a, T, P> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], pred: P) -> Self {
+        Self { v: slice, pred, finished: false }
+    }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -385,9 +441,16 @@ pub struct SplitInclusive<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) v: &'a [T],
-    pub(super) pred: P,
-    pub(super) finished: bool,
+    v: &'a [T],
+    pred: P,
+    finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusive<'a, T, P> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], pred: P) -> Self {
+        Self { v: slice, pred, finished: false }
+    }
 }
 
 #[unstable(feature = "split_inclusive", issue = "72360")]
@@ -483,9 +546,16 @@ pub struct SplitMut<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) v: &'a mut [T],
-    pub(super) pred: P,
-    pub(super) finished: bool,
+    v: &'a mut [T],
+    pred: P,
+    finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitMut<'a, T, P> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
+        Self { v: slice, pred, finished: false }
+    }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -598,9 +668,16 @@ pub struct SplitInclusiveMut<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) v: &'a mut [T],
-    pub(super) pred: P,
-    pub(super) finished: bool,
+    v: &'a mut [T],
+    pred: P,
+    finished: bool,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitInclusiveMut<'a, T, P> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
+        Self { v: slice, pred, finished: false }
+    }
 }
 
 #[unstable(feature = "split_inclusive", issue = "72360")]
@@ -706,7 +783,14 @@ pub struct RSplit<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) inner: Split<'a, T, P>,
+    inner: Split<'a, T, P>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplit<'a, T, P> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], pred: P) -> Self {
+        Self { inner: Split::new(slice, pred) }
+    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -777,7 +861,14 @@ pub struct RSplitMut<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) inner: SplitMut<'a, T, P>,
+    inner: SplitMut<'a, T, P>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitMut<'a, T, P> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T], pred: P) -> Self {
+        Self { inner: SplitMut::new(slice, pred) }
+    }
 }
 
 #[stable(feature = "slice_rsplit", since = "1.27.0")]
@@ -840,9 +931,9 @@ impl<T, P> FusedIterator for RSplitMut<'_, T, P> where P: FnMut(&T) -> bool {}
 /// match a predicate function, splitting at most a fixed number of
 /// times.
 #[derive(Debug)]
-pub(super) struct GenericSplitN<I> {
-    pub(super) iter: I,
-    pub(super) count: usize,
+struct GenericSplitN<I> {
+    iter: I,
+    count: usize,
 }
 
 impl<T, I: SplitIter<Item = T>> Iterator for GenericSplitN<I> {
@@ -882,7 +973,14 @@ pub struct SplitN<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) inner: GenericSplitN<Split<'a, T, P>>,
+    inner: GenericSplitN<Split<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitN<'a, T, P> {
+    #[inline]
+    pub(super) fn new(s: Split<'a, T, P>, n: usize) -> Self {
+        Self { inner: GenericSplitN { iter: s, count: n } }
+    }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -908,7 +1006,14 @@ pub struct RSplitN<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) inner: GenericSplitN<RSplit<'a, T, P>>,
+    inner: GenericSplitN<RSplit<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitN<'a, T, P> {
+    #[inline]
+    pub(super) fn new(s: RSplit<'a, T, P>, n: usize) -> Self {
+        Self { inner: GenericSplitN { iter: s, count: n } }
+    }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -933,7 +1038,14 @@ pub struct SplitNMut<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) inner: GenericSplitN<SplitMut<'a, T, P>>,
+    inner: GenericSplitN<SplitMut<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> SplitNMut<'a, T, P> {
+    #[inline]
+    pub(super) fn new(s: SplitMut<'a, T, P>, n: usize) -> Self {
+        Self { inner: GenericSplitN { iter: s, count: n } }
+    }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -959,7 +1071,14 @@ pub struct RSplitNMut<'a, T: 'a, P>
 where
     P: FnMut(&T) -> bool,
 {
-    pub(super) inner: GenericSplitN<RSplitMut<'a, T, P>>,
+    inner: GenericSplitN<RSplitMut<'a, T, P>>,
+}
+
+impl<'a, T: 'a, P: FnMut(&T) -> bool> RSplitNMut<'a, T, P> {
+    #[inline]
+    pub(super) fn new(s: RSplitMut<'a, T, P>, n: usize) -> Self {
+        Self { inner: GenericSplitN { iter: s, count: n } }
+    }
 }
 
 #[stable(feature = "core_impl_debug", since = "1.9.0")]
@@ -986,8 +1105,15 @@ forward_iterator! { RSplitNMut: T, &'a mut [T] }
 #[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Windows<'a, T: 'a> {
-    pub(super) v: &'a [T],
-    pub(super) size: usize,
+    v: &'a [T],
+    size: usize,
+}
+
+impl<'a, T: 'a> Windows<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+        Self { v: slice, size }
+    }
 }
 
 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
@@ -1118,8 +1244,15 @@ unsafe impl<'a, T> TrustedRandomAccess for Windows<'a, T> {
 #[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct Chunks<'a, T: 'a> {
-    pub(super) v: &'a [T],
-    pub(super) chunk_size: usize,
+    v: &'a [T],
+    chunk_size: usize,
+}
+
+impl<'a, T: 'a> Chunks<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+        Self { v: slice, chunk_size: size }
+    }
 }
 
 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
@@ -1272,8 +1405,15 @@ unsafe impl<'a, T> TrustedRandomAccess for Chunks<'a, T> {
 #[derive(Debug)]
 #[stable(feature = "rust1", since = "1.0.0")]
 pub struct ChunksMut<'a, T: 'a> {
-    pub(super) v: &'a mut [T],
-    pub(super) chunk_size: usize,
+    v: &'a mut [T],
+    chunk_size: usize,
+}
+
+impl<'a, T: 'a> ChunksMut<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
+        Self { v: slice, chunk_size: size }
+    }
 }
 
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -1425,12 +1565,21 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksMut<'a, T> {
 #[derive(Debug)]
 #[stable(feature = "chunks_exact", since = "1.31.0")]
 pub struct ChunksExact<'a, T: 'a> {
-    pub(super) v: &'a [T],
-    pub(super) rem: &'a [T],
-    pub(super) chunk_size: usize,
+    v: &'a [T],
+    rem: &'a [T],
+    chunk_size: usize,
 }
 
 impl<'a, T> ChunksExact<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
+        let rem = slice.len() % chunk_size;
+        let fst_len = slice.len() - rem;
+        // SAFETY: 0 <= fst_len <= slice.len() by construction above
+        let (fst, snd) = unsafe { slice.split_at_unchecked(fst_len) };
+        Self { v: fst, rem: snd, chunk_size }
+    }
+
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
@@ -1565,12 +1714,21 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExact<'a, T> {
 #[derive(Debug)]
 #[stable(feature = "chunks_exact", since = "1.31.0")]
 pub struct ChunksExactMut<'a, T: 'a> {
-    pub(super) v: &'a mut [T],
-    pub(super) rem: &'a mut [T],
-    pub(super) chunk_size: usize,
+    v: &'a mut [T],
+    rem: &'a mut [T],
+    chunk_size: usize,
 }
 
 impl<'a, T> ChunksExactMut<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
+        let rem = slice.len() % chunk_size;
+        let fst_len = slice.len() - rem;
+        // SAFETY: 0 <= fst_len <= slice.len() by construction above
+        let (fst, snd) = unsafe { slice.split_at_mut_unchecked(fst_len) };
+        Self { v: fst, rem: snd, chunk_size }
+    }
+
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
@@ -1697,9 +1855,17 @@ unsafe impl<'a, T> TrustedRandomAccess for ChunksExactMut<'a, T> {
 #[derive(Debug, Clone, Copy)]
 #[unstable(feature = "array_windows", issue = "75027")]
 pub struct ArrayWindows<'a, T: 'a, const N: usize> {
-    pub(crate) slice_head: *const T,
-    pub(crate) num: usize,
-    pub(crate) marker: marker::PhantomData<&'a [T; N]>,
+    slice_head: *const T,
+    num: usize,
+    marker: PhantomData<&'a [T; N]>,
+}
+
+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);
+        Self { slice_head: slice.as_ptr(), num: num_windows, marker: PhantomData }
+    }
 }
 
 #[unstable(feature = "array_windows", issue = "75027")]
@@ -1802,11 +1968,22 @@ impl<T, const N: usize> ExactSizeIterator for ArrayWindows<'_, T, N> {
 #[derive(Debug)]
 #[unstable(feature = "array_chunks", issue = "74985")]
 pub struct ArrayChunks<'a, T: 'a, const N: usize> {
-    pub(super) iter: Iter<'a, [T; N]>,
-    pub(super) rem: &'a [T],
+    iter: Iter<'a, [T; N]>,
+    rem: &'a [T],
 }
 
 impl<'a, T, const N: usize> ArrayChunks<'a, T, N> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T]) -> Self {
+        let len = slice.len() / N;
+        let (fst, snd) = slice.split_at(len * N);
+        // SAFETY: We cast a slice of `len * N` elements into
+        // a slice of `len` many `N` elements chunks.
+        let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) };
+
+        Self { iter: array_slice.iter(), rem: snd }
+    }
+
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `N-1`
     /// elements.
@@ -1909,11 +2086,23 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunks<'a, T, N>
 #[derive(Debug)]
 #[unstable(feature = "array_chunks", issue = "74985")]
 pub struct ArrayChunksMut<'a, T: 'a, const N: usize> {
-    pub(super) iter: IterMut<'a, [T; N]>,
-    pub(super) rem: &'a mut [T],
+    iter: IterMut<'a, [T; N]>,
+    rem: &'a mut [T],
 }
 
 impl<'a, T, const N: usize> ArrayChunksMut<'a, T, N> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T]) -> Self {
+        let len = slice.len() / N;
+        let (fst, snd) = slice.split_at_mut(len * N);
+        // SAFETY: We cast a slice of `len * N` elements into
+        // a slice of `len` many `N` elements chunks.
+        unsafe {
+            let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len);
+            Self { iter: array_slice.iter_mut(), rem: snd }
+        }
+    }
+
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `N-1`
     /// elements.
@@ -2006,8 +2195,15 @@ unsafe impl<'a, T, const N: usize> TrustedRandomAccess for ArrayChunksMut<'a, T,
 #[derive(Debug)]
 #[stable(feature = "rchunks", since = "1.31.0")]
 pub struct RChunks<'a, T: 'a> {
-    pub(super) v: &'a [T],
-    pub(super) chunk_size: usize,
+    v: &'a [T],
+    chunk_size: usize,
+}
+
+impl<'a, T: 'a> RChunks<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], size: usize) -> Self {
+        Self { v: slice, chunk_size: size }
+    }
 }
 
 // FIXME(#26925) Remove in favor of `#[derive(Clone)]`
@@ -2156,8 +2352,15 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunks<'a, T> {
 #[derive(Debug)]
 #[stable(feature = "rchunks", since = "1.31.0")]
 pub struct RChunksMut<'a, T: 'a> {
-    pub(super) v: &'a mut [T],
-    pub(super) chunk_size: usize,
+    v: &'a mut [T],
+    chunk_size: usize,
+}
+
+impl<'a, T: 'a> RChunksMut<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T], size: usize) -> Self {
+        Self { v: slice, chunk_size: size }
+    }
 }
 
 #[stable(feature = "rchunks", since = "1.31.0")]
@@ -2306,12 +2509,20 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksMut<'a, T> {
 #[derive(Debug)]
 #[stable(feature = "rchunks", since = "1.31.0")]
 pub struct RChunksExact<'a, T: 'a> {
-    pub(super) v: &'a [T],
-    pub(super) rem: &'a [T],
-    pub(super) chunk_size: usize,
+    v: &'a [T],
+    rem: &'a [T],
+    chunk_size: usize,
 }
 
 impl<'a, T> RChunksExact<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a [T], chunk_size: usize) -> Self {
+        let rem = slice.len() % chunk_size;
+        // SAFETY: 0 <= rem <= slice.len() by construction above
+        let (fst, snd) = unsafe { slice.split_at_unchecked(rem) };
+        Self { v: snd, rem: fst, chunk_size }
+    }
+
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
@@ -2451,12 +2662,20 @@ unsafe impl<'a, T> TrustedRandomAccess for RChunksExact<'a, T> {
 #[derive(Debug)]
 #[stable(feature = "rchunks", since = "1.31.0")]
 pub struct RChunksExactMut<'a, T: 'a> {
-    pub(super) v: &'a mut [T],
-    pub(super) rem: &'a mut [T],
-    pub(super) chunk_size: usize,
+    v: &'a mut [T],
+    rem: &'a mut [T],
+    chunk_size: usize,
 }
 
 impl<'a, T> RChunksExactMut<'a, T> {
+    #[inline]
+    pub(super) fn new(slice: &'a mut [T], chunk_size: usize) -> Self {
+        let rem = slice.len() % chunk_size;
+        // SAFETY: 0 <= rem <= slice.len() by construction above
+        let (fst, snd) = unsafe { slice.split_at_mut_unchecked(rem) };
+        Self { v: snd, rem: fst, chunk_size }
+    }
+
     /// Returns the remainder of the original slice that is not going to be
     /// returned by the iterator. The returned slice has at most `chunk_size-1`
     /// elements.
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 8e9d1eb98a8..fd98f60c3dd 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -9,13 +9,12 @@
 #![stable(feature = "rust1", since = "1.0.0")]
 
 use crate::cmp::Ordering::{self, Equal, Greater, Less};
-use crate::intrinsics::assume;
-use crate::marker::{self, Copy};
+use crate::marker::Copy;
 use crate::mem;
 use crate::ops::{FnMut, Range, RangeBounds};
 use crate::option::Option;
 use crate::option::Option::{None, Some};
-use crate::ptr::{self, NonNull};
+use crate::ptr;
 use crate::result::Result;
 use crate::result::Result::{Err, Ok};
 
@@ -35,8 +34,6 @@ mod raw;
 mod rotate;
 mod sort;
 
-use iter::GenericSplitN;
-
 #[stable(feature = "rust1", since = "1.0.0")]
 pub use iter::{Chunks, ChunksMut, Windows};
 #[stable(feature = "rust1", since = "1.0.0")]
@@ -681,34 +678,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn iter(&self) -> Iter<'_, T> {
-        let ptr = self.as_ptr();
-        // SAFETY: There are several things here:
-        //
-        // `ptr` has been obtained by `self.as_ptr()` where `self` is a valid
-        // reference thus it is non-NUL and safe to use and pass to
-        // `NonNull::new_unchecked` .
-        //
-        // Adding `self.len()` to the starting pointer gives a pointer
-        // at the end of `self`. `end` will never be dereferenced, only checked
-        // for direct pointer equality with `ptr` to check if the iterator is
-        // done.
-        //
-        // In the case of a ZST, the end pointer is just the start pointer plus
-        // the length, to also allows for the fast `ptr == end` check.
-        //
-        // See the `next_unchecked!` and `is_empty!` macros as well as the
-        // `post_inc_start` method for more informations.
-        unsafe {
-            assume(!ptr.is_null());
-
-            let end = if mem::size_of::<T>() == 0 {
-                (ptr as *const u8).wrapping_add(self.len()) as *const T
-            } else {
-                ptr.add(self.len())
-            };
-
-            Iter { ptr: NonNull::new_unchecked(ptr as *mut T), end, _marker: marker::PhantomData }
-        }
+        Iter::new(self)
     }
 
     /// Returns an iterator that allows modifying each value.
@@ -725,34 +695,7 @@ impl<T> [T] {
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
     pub fn iter_mut(&mut self) -> IterMut<'_, T> {
-        let ptr = self.as_mut_ptr();
-        // SAFETY: There are several things here:
-        //
-        // `ptr` has been obtained by `self.as_ptr()` where `self` is a valid
-        // reference thus it is non-NUL and safe to use and pass to
-        // `NonNull::new_unchecked` .
-        //
-        // Adding `self.len()` to the starting pointer gives a pointer
-        // at the end of `self`. `end` will never be dereferenced, only checked
-        // for direct pointer equality with `ptr` to check if the iterator is
-        // done.
-        //
-        // In the case of a ZST, the end pointer is just the start pointer plus
-        // the length, to also allows for the fast `ptr == end` check.
-        //
-        // See the `next_unchecked!` and `is_empty!` macros as well as the
-        // `post_inc_start` method for more informations.
-        unsafe {
-            assume(!ptr.is_null());
-
-            let end = if mem::size_of::<T>() == 0 {
-                (ptr as *mut u8).wrapping_add(self.len()) as *mut T
-            } else {
-                ptr.add(self.len())
-            };
-
-            IterMut { ptr: NonNull::new_unchecked(ptr), end, _marker: marker::PhantomData }
-        }
+        IterMut::new(self)
     }
 
     /// Returns an iterator over all contiguous windows of length
@@ -785,7 +728,7 @@ impl<T> [T] {
     #[inline]
     pub fn windows(&self, size: usize) -> Windows<'_, T> {
         assert_ne!(size, 0);
-        Windows { v: self, size }
+        Windows::new(self, size)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -819,7 +762,7 @@ impl<T> [T] {
     #[inline]
     pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
         assert_ne!(chunk_size, 0);
-        Chunks { v: self, chunk_size }
+        Chunks::new(self, chunk_size)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -857,7 +800,7 @@ impl<T> [T] {
     #[inline]
     pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
         assert_ne!(chunk_size, 0);
-        ChunksMut { v: self, chunk_size }
+        ChunksMut::new(self, chunk_size)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -894,11 +837,7 @@ impl<T> [T] {
     #[inline]
     pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
         assert_ne!(chunk_size, 0);
-        let rem = self.len() % chunk_size;
-        let fst_len = self.len() - rem;
-        // SAFETY: 0 <= fst_len <= self.len() by construction above
-        let (fst, snd) = unsafe { self.split_at_unchecked(fst_len) };
-        ChunksExact { v: fst, rem: snd, chunk_size }
+        ChunksExact::new(self, chunk_size)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -940,11 +879,7 @@ impl<T> [T] {
     #[inline]
     pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
         assert_ne!(chunk_size, 0);
-        let rem = self.len() % chunk_size;
-        let fst_len = self.len() - rem;
-        // SAFETY: 0 <= fst_len <= self.len() by construction above
-        let (fst, snd) = unsafe { self.split_at_mut_unchecked(fst_len) };
-        ChunksExactMut { v: fst, rem: snd, chunk_size }
+        ChunksExactMut::new(self, chunk_size)
     }
 
     /// Returns an iterator over `N` elements of the slice at a time, starting at the
@@ -978,12 +913,7 @@ impl<T> [T] {
     #[inline]
     pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
         assert_ne!(N, 0);
-        let len = self.len() / N;
-        let (fst, snd) = self.split_at(len * N);
-        // SAFETY: We cast a slice of `len * N` elements into
-        // a slice of `len` many `N` elements chunks.
-        let array_slice: &[[T; N]] = unsafe { from_raw_parts(fst.as_ptr().cast(), len) };
-        ArrayChunks { iter: array_slice.iter(), rem: snd }
+        ArrayChunks::new(self)
     }
 
     /// Returns an iterator over `N` elements of the slice at a time, starting at the
@@ -1019,14 +949,7 @@ impl<T> [T] {
     #[inline]
     pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
         assert_ne!(N, 0);
-        let len = self.len() / N;
-        let (fst, snd) = self.split_at_mut(len * N);
-        // SAFETY: We cast a slice of `len * N` elements into
-        // a slice of `len` many `N` elements chunks.
-        unsafe {
-            let array_slice: &mut [[T; N]] = from_raw_parts_mut(fst.as_mut_ptr().cast(), len);
-            ArrayChunksMut { iter: array_slice.iter_mut(), rem: snd }
-        }
+        ArrayChunksMut::new(self)
     }
 
     /// Returns an iterator over overlapping windows of `N` elements of  a slice,
@@ -1058,9 +981,7 @@ impl<T> [T] {
     #[inline]
     pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
         assert_ne!(N, 0);
-
-        let num_windows = self.len().saturating_sub(N - 1);
-        ArrayWindows { slice_head: self.as_ptr(), num: num_windows, marker: marker::PhantomData }
+        ArrayWindows::new(self)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@@ -1094,7 +1015,7 @@ impl<T> [T] {
     #[inline]
     pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
         assert!(chunk_size != 0);
-        RChunks { v: self, chunk_size }
+        RChunks::new(self, chunk_size)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@@ -1132,7 +1053,7 @@ impl<T> [T] {
     #[inline]
     pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
         assert!(chunk_size != 0);
-        RChunksMut { v: self, chunk_size }
+        RChunksMut::new(self, chunk_size)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the
@@ -1171,10 +1092,7 @@ impl<T> [T] {
     #[inline]
     pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
         assert!(chunk_size != 0);
-        let rem = self.len() % chunk_size;
-        // SAFETY: 0 <= rem <= self.len() by construction above
-        let (fst, snd) = unsafe { self.split_at_unchecked(rem) };
-        RChunksExact { v: snd, rem: fst, chunk_size }
+        RChunksExact::new(self, chunk_size)
     }
 
     /// Returns an iterator over `chunk_size` elements of the slice at a time, starting at the end
@@ -1217,10 +1135,7 @@ impl<T> [T] {
     #[inline]
     pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
         assert!(chunk_size != 0);
-        let rem = self.len() % chunk_size;
-        // SAFETY: 0 <= rem <= self.len() by construction above
-        let (fst, snd) = unsafe { self.split_at_mut_unchecked(rem) };
-        RChunksExactMut { v: snd, rem: fst, chunk_size }
+        RChunksExactMut::new(self, chunk_size)
     }
 
     /// Divides one slice into two at an index.
@@ -1439,7 +1354,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        Split { v: self, pred, finished: false }
+        Split::new(self, pred)
     }
 
     /// Returns an iterator over mutable subslices separated by elements that
@@ -1461,7 +1376,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        SplitMut { v: self, pred, finished: false }
+        SplitMut::new(self, pred)
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1499,7 +1414,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        SplitInclusive { v: self, pred, finished: false }
+        SplitInclusive::new(self, pred)
     }
 
     /// Returns an iterator over mutable subslices separated by elements that
@@ -1524,7 +1439,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        SplitInclusiveMut { v: self, pred, finished: false }
+        SplitInclusiveMut::new(self, pred)
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1560,7 +1475,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        RSplit { inner: self.split(pred) }
+        RSplit::new(self, pred)
     }
 
     /// Returns an iterator over mutable subslices separated by elements that
@@ -1586,7 +1501,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        RSplitMut { inner: self.split_mut(pred) }
+        RSplitMut::new(self, pred)
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1614,7 +1529,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        SplitN { inner: GenericSplitN { iter: self.split(pred), count: n } }
+        SplitN::new(self.split(pred), n)
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1640,7 +1555,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        SplitNMut { inner: GenericSplitN { iter: self.split_mut(pred), count: n } }
+        SplitNMut::new(self.split_mut(pred), n)
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1669,7 +1584,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        RSplitN { inner: GenericSplitN { iter: self.rsplit(pred), count: n } }
+        RSplitN::new(self.rsplit(pred), n)
     }
 
     /// Returns an iterator over subslices separated by elements that match
@@ -1696,7 +1611,7 @@ impl<T> [T] {
     where
         F: FnMut(&T) -> bool,
     {
-        RSplitNMut { inner: GenericSplitN { iter: self.rsplit_mut(pred), count: n } }
+        RSplitNMut::new(self.rsplit_mut(pred), n)
     }
 
     /// Returns `true` if the slice contains an element with the given value.