]> git.lizzy.rs Git - rust.git/blobdiff - src/libcore/slice/mod.rs
Rollup merge of #51326 - sdroege:slice-iter-cleanup, r=dtolnay
[rust.git] / src / libcore / slice / mod.rs
index fdc9aa473e8b8ed2247225eecf8495ea96af1eba..c5792d62aa92c16f30d8095f10ad856d4b54896c 100644 (file)
 mod sort;
 
 #[repr(C)]
-struct Repr<T> {
-    pub data: *const T,
-    pub len: usize,
+union Repr<'a, T: 'a> {
+    rust: &'a [T],
+    rust_mut: &'a mut [T],
+    raw: FatPtr<T>,
+}
+
+#[repr(C)]
+struct FatPtr<T> {
+    data: *const T,
+    len: usize,
 }
 
 //
@@ -119,9 +126,10 @@ impl<T> [T] {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn len(&self) -> usize {
+    #[rustc_const_unstable(feature = "const_slice_len")]
+    pub const fn len(&self) -> usize {
         unsafe {
-            mem::transmute::<&[T], Repr<T>>(self).len
+            Repr { rust: self }.raw.len
         }
     }
 
@@ -135,7 +143,8 @@ pub fn len(&self) -> usize {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn is_empty(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_slice_len")]
+    pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
 
@@ -418,7 +427,8 @@ pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[inline]
-    pub fn as_ptr(&self) -> *const T {
+    #[rustc_const_unstable(feature = "const_slice_as_ptr")]
+    pub const fn as_ptr(&self) -> *const T {
         self as *const [T] as *const T
     }
 
@@ -1698,6 +1708,7 @@ pub fn swap_with_slice(&mut self, other: &mut [T]) {
     }
 
     /// Function to calculate lenghts of the middle and trailing slice for `align_to{,_mut}`.
+    #[cfg(not(stage0))]
     fn align_to_offsets<U>(&self) -> (usize, usize) {
         // What we gonna do about `rest` is figure out what multiple of `U`s we can put in a
         // lowest number of `T`s. And how many `T`s we need for each such "multiple".
@@ -1966,35 +1977,63 @@ fn slice_index_overflow_fail() -> ! {
     panic!("attempted to index slice up to maximum usize");
 }
 
+mod private_slice_index {
+    use super::ops;
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    pub trait Sealed {}
+
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for usize {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::Range<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeTo<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeFrom<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeFull {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeInclusive<usize> {}
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
+    impl Sealed for ops::RangeToInclusive<usize> {}
+}
+
 /// A helper trait used for indexing operations.
-#[unstable(feature = "slice_get_slice", issue = "35729")]
+#[stable(feature = "slice_get_slice", since = "1.28.0")]
 #[rustc_on_unimplemented = "slice indices are of type `usize` or ranges of `usize`"]
-pub trait SliceIndex<T: ?Sized> {
+pub trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
     /// The output type returned by methods.
+    #[stable(feature = "slice_get_slice", since = "1.28.0")]
     type Output: ?Sized;
 
     /// Returns a shared reference to the output at this location, if in
     /// bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn get(self, slice: &T) -> Option<&Self::Output>;
 
     /// Returns a mutable reference to the output at this location, if in
     /// bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
 
     /// Returns a shared reference to the output at this location, without
     /// performing any bounds checking.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, without
     /// performing any bounds checking.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     unsafe fn get_unchecked_mut(self, slice: &mut T) -> &mut Self::Output;
 
     /// Returns a shared reference to the output at this location, panicking
     /// if out of bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn index(self, slice: &T) -> &Self::Output;
 
     /// Returns a mutable reference to the output at this location, panicking
     /// if out of bounds.
+    #[unstable(feature = "slice_index_methods", issue = "0")]
     fn index_mut(self, slice: &mut T) -> &mut Self::Output;
 }
 
@@ -2502,6 +2541,12 @@ fn rfold<Acc, Fold>(mut self, init: Acc, mut f: Fold) -> Acc
                 accum
             }
         }
+
+        #[stable(feature = "fused", since = "1.26.0")]
+        impl<'a, T> FusedIterator for $name<'a, T> {}
+
+        #[unstable(feature = "trusted_len", issue = "37572")]
+        unsafe impl<'a, T> TrustedLen for $name<'a, T> {}
     }
 }
 
@@ -2628,12 +2673,6 @@ fn is_empty(&self) -> bool {
     }
 }
 
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a, T> FusedIterator for Iter<'a, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<'a, T> TrustedLen for Iter<'a, T> {}
-
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> Clone for Iter<'a, T> {
     fn clone(&self) -> Iter<'a, T> { Iter { ptr: self.ptr, end: self.end, _marker: self._marker } }
@@ -2695,9 +2734,7 @@ impl<'a, T> IterMut<'a, T> {
     /// View the underlying data as a subslice of the original data.
     ///
     /// To avoid creating `&mut` references that alias, this is forced
-    /// to consume the iterator. Consider using the `Slice` and
-    /// `SliceMut` implementations for obtaining slices with more
-    /// restricted lifetimes that do not consume the iterator.
+    /// to consume the iterator.
     ///
     /// # Examples
     ///
@@ -2756,13 +2793,6 @@ fn is_empty(&self) -> bool {
     }
 }
 
-#[stable(feature = "fused", since = "1.26.0")]
-impl<'a, T> FusedIterator for IterMut<'a, T> {}
-
-#[unstable(feature = "trusted_len", issue = "37572")]
-unsafe impl<'a, T> TrustedLen for IterMut<'a, T> {}
-
-
 // Return the number of elements of `T` from `start` to `end`.
 // Return the arithmetic difference if `T` is zero size.
 #[inline(always)]
@@ -3360,6 +3390,9 @@ fn next_back(&mut self) -> Option<&'a [T]> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for Windows<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for Windows<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for Windows<'a, T> {}
 
@@ -3479,6 +3512,9 @@ fn next_back(&mut self) -> Option<&'a [T]> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for Chunks<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for Chunks<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for Chunks<'a, T> {}
 
@@ -3595,6 +3631,9 @@ fn next_back(&mut self) -> Option<&'a mut [T]> {
 #[stable(feature = "rust1", since = "1.0.0")]
 impl<'a, T> ExactSizeIterator for ChunksMut<'a, T> {}
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ChunksMut<'a, T> {}
+
 #[stable(feature = "fused", since = "1.26.0")]
 impl<'a, T> FusedIterator for ChunksMut<'a, T> {}
 
@@ -3705,6 +3744,9 @@ fn is_empty(&self) -> bool {
     }
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ExactChunks<'a, T> {}
+
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> FusedIterator for ExactChunks<'a, T> {}
 
@@ -3802,6 +3844,9 @@ fn is_empty(&self) -> bool {
     }
 }
 
+#[unstable(feature = "trusted_len", issue = "37572")]
+unsafe impl<'a, T> TrustedLen for ExactChunksMut<'a, T> {}
+
 #[unstable(feature = "exact_chunks", issue = "47115")]
 impl<'a, T> FusedIterator for ExactChunksMut<'a, T> {}
 
@@ -3828,10 +3873,9 @@ fn may_have_side_effect() -> bool { false }
 /// valid for `len` elements, nor whether the lifetime inferred is a suitable
 /// lifetime for the returned slice.
 ///
-/// `p` must be non-null, even for zero-length slices, because non-zero bits
-/// are required to distinguish between a zero-length slice within `Some()`
-/// from `None`. `p` can be a bogus non-dereferencable pointer, such as `0x1`,
-/// for zero-length slices, though.
+/// `p` must be non-null and aligned, even for zero-length slices, as is
+/// required for all references. However, for zero-length slices, `p` can be
+/// a bogus non-dereferencable pointer such as [`NonNull::dangling()`].
 ///
 /// # Caveat
 ///
@@ -3853,10 +3897,12 @@ fn may_have_side_effect() -> bool { false }
 ///     let slice = slice::from_raw_parts(ptr, amt);
 /// }
 /// ```
+///
+/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
-    mem::transmute(Repr { data: p, len: len })
+pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
+    Repr { raw: FatPtr { data, len } }.rust
 }
 
 /// Performs the same functionality as `from_raw_parts`, except that a mutable
@@ -3864,16 +3910,16 @@ pub unsafe fn from_raw_parts<'a, T>(p: *const T, len: usize) -> &'a [T] {
 ///
 /// This function is unsafe for the same reasons as `from_raw_parts`, as well
 /// as not being able to provide a non-aliasing guarantee of the returned
-/// mutable slice. `p` must be non-null even for zero-length slices as with
+/// mutable slice. `p` must be non-null and aligned even for zero-length slices as with
 /// `from_raw_parts`.
 #[inline]
 #[stable(feature = "rust1", since = "1.0.0")]
-pub unsafe fn from_raw_parts_mut<'a, T>(p: *mut T, len: usize) -> &'a mut [T] {
-    mem::transmute(Repr { data: p, len: len })
+pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
+    Repr { raw: FatPtr { data, len} }.rust_mut
 }
 
 /// Converts a reference to T into a slice of length 1 (without copying).
-#[unstable(feature = "from_ref", issue = "45703")]
+#[stable(feature = "from_ref", since = "1.28.0")]
 pub fn from_ref<T>(s: &T) -> &[T] {
     unsafe {
         from_raw_parts(s, 1)
@@ -3881,8 +3927,8 @@ pub fn from_ref<T>(s: &T) -> &[T] {
 }
 
 /// Converts a reference to T into a slice of length 1 (without copying).
-#[unstable(feature = "from_ref", issue = "45703")]
-pub fn from_ref_mut<T>(s: &mut T) -> &mut [T] {
+#[stable(feature = "from_ref", since = "1.28.0")]
+pub fn from_mut<T>(s: &mut T) -> &mut [T] {
     unsafe {
         from_raw_parts_mut(s, 1)
     }