#[unstable(feature = "slice_range", issue = "76393")]
pub use index::range;
+#[unstable(feature = "inherent_ascii_escape", issue = "77174")]
+pub use ascii::EscapeAscii;
+
#[lang = "slice"]
#[cfg(not(test))]
impl<T> [T] {
/// ```
#[doc(alias = "length")]
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_slice_len", since = "1.39.0")]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
#[rustc_allow_const_fn_unstable(const_fn_union)]
pub const fn len(&self) -> usize {
- #[cfg(bootstrap)]
- {
- // SAFETY: this is safe because `&[T]` and `FatPtr<T>` have the same layout.
- // Only `std` can make this guarantee.
- unsafe { crate::ptr::Repr { rust: self }.raw.len }
- }
- #[cfg(not(bootstrap))]
- {
- // FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable.
- // As of this writing this causes a "Const-stable functions can only call other
- // const-stable functions" error.
-
- // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
- // and PtrComponents<T> have the same memory layouts. Only std can make this
- // guarantee.
- unsafe { crate::ptr::PtrRepr { const_ptr: self }.components.metadata }
- }
+ // FIXME: Replace with `crate::ptr::metadata(self)` when that is const-stable.
+ // As of this writing this causes a "Const-stable functions can only call other
+ // const-stable functions" error.
+
+ // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
+ // and PtrComponents<T> have the same memory layouts. Only std can make this
+ // guarantee.
+ unsafe { crate::ptr::PtrRepr { const_ptr: self }.components.metadata }
}
/// Returns `true` if the slice has a length of 0.
/// assert!(!a.is_empty());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
- #[rustc_const_stable(feature = "const_slice_is_empty", since = "1.32.0")]
+ #[rustc_const_stable(feature = "const_slice_is_empty", since = "1.39.0")]
#[inline]
pub const fn is_empty(&self) -> bool {
self.len() == 0
/// assert_eq!(None, w.first());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn first(&self) -> Option<&T> {
+ pub const fn first(&self) -> Option<&T> {
if let [first, ..] = self { Some(first) } else { None }
}
/// assert_eq!(x, &[5, 1, 2]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn first_mut(&mut self) -> Option<&mut T> {
+ pub const fn first_mut(&mut self) -> Option<&mut T> {
if let [first, ..] = self { Some(first) } else { None }
}
/// }
/// ```
#[stable(feature = "slice_splits", since = "1.5.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn split_first(&self) -> Option<(&T, &[T])> {
+ pub const fn split_first(&self) -> Option<(&T, &[T])> {
if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
}
/// assert_eq!(x, &[3, 4, 5]);
/// ```
#[stable(feature = "slice_splits", since = "1.5.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+ pub const fn split_first_mut(&mut self) -> Option<(&mut T, &mut [T])> {
if let [first, tail @ ..] = self { Some((first, tail)) } else { None }
}
/// }
/// ```
#[stable(feature = "slice_splits", since = "1.5.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn split_last(&self) -> Option<(&T, &[T])> {
+ pub const fn split_last(&self) -> Option<(&T, &[T])> {
if let [init @ .., last] = self { Some((last, init)) } else { None }
}
/// assert_eq!(x, &[4, 5, 3]);
/// ```
#[stable(feature = "slice_splits", since = "1.5.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
+ pub const fn split_last_mut(&mut self) -> Option<(&mut T, &mut [T])> {
if let [init @ .., last] = self { Some((last, init)) } else { None }
}
/// assert_eq!(None, w.last());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn last(&self) -> Option<&T> {
+ pub const fn last(&self) -> Option<&T> {
if let [.., last] = self { Some(last) } else { None }
}
/// assert_eq!(x, &[0, 1, 10]);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[rustc_const_unstable(feature = "const_slice_first_last", issue = "83570")]
#[inline]
- pub fn last_mut(&mut self) -> Option<&mut T> {
+ pub const fn last_mut(&mut self) -> Option<&mut T> {
if let [.., last] = self { Some(last) } else { None }
}
/// Returns a mutable reference to an element or subslice depending on the
/// type of index (see [`get`]) or `None` if the index is out of bounds.
///
- /// [`get`]: #method.get
+ /// [`get`]: slice::get
///
/// # Examples
///
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
/// even if the resulting reference is not used.
///
- /// [`get`]: #method.get
+ /// [`get`]: slice::get
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
/// Calling this method with an out-of-bounds index is *[undefined behavior]*
/// even if the resulting reference is not used.
///
- /// [`get_mut`]: #method.get_mut
+ /// [`get_mut`]: slice::get_mut
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
/// }
/// ```
///
- /// [`as_mut_ptr`]: #method.as_mut_ptr
+ /// [`as_mut_ptr`]: slice::as_mut_ptr
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0")]
#[inline]
/// assert!(!a.as_ptr_range().contains(&y));
/// ```
///
- /// [`as_ptr`]: #method.as_ptr
+ /// [`as_ptr`]: slice::as_ptr
#[stable(feature = "slice_ptr_range", since = "1.48.0")]
#[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
#[inline]
/// use two pointers to refer to a range of elements in memory, as is
/// common in C++.
///
- /// [`as_mut_ptr`]: #method.as_mut_ptr
+ /// [`as_mut_ptr`]: slice::as_mut_ptr
#[stable(feature = "slice_ptr_range", since = "1.48.0")]
#[rustc_const_unstable(feature = "const_ptr_offset", issue = "71499")]
#[inline]
/// assert!(iter.next().is_none());
/// ```
///
- /// [`chunks_exact`]: #method.chunks_exact
- /// [`rchunks`]: #method.rchunks
+ /// [`chunks_exact`]: slice::chunks_exact
+ /// [`rchunks`]: slice::rchunks
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn chunks(&self, chunk_size: usize) -> Chunks<'_, T> {
/// assert_eq!(v, &[1, 1, 2, 2, 3]);
/// ```
///
- /// [`chunks_exact_mut`]: #method.chunks_exact_mut
- /// [`rchunks_mut`]: #method.rchunks_mut
+ /// [`chunks_exact_mut`]: slice::chunks_exact_mut
+ /// [`rchunks_mut`]: slice::rchunks_mut
#[stable(feature = "rust1", since = "1.0.0")]
#[inline]
pub fn chunks_mut(&mut self, chunk_size: usize) -> ChunksMut<'_, T> {
/// assert_eq!(iter.remainder(), &['m']);
/// ```
///
- /// [`chunks`]: #method.chunks
- /// [`rchunks_exact`]: #method.rchunks_exact
+ /// [`chunks`]: slice::chunks
+ /// [`rchunks_exact`]: slice::rchunks_exact
#[stable(feature = "chunks_exact", since = "1.31.0")]
#[inline]
pub fn chunks_exact(&self, chunk_size: usize) -> ChunksExact<'_, T> {
/// assert_eq!(v, &[1, 1, 2, 2, 0]);
/// ```
///
- /// [`chunks_mut`]: #method.chunks_mut
- /// [`rchunks_exact_mut`]: #method.rchunks_exact_mut
+ /// [`chunks_mut`]: slice::chunks_mut
+ /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
#[stable(feature = "chunks_exact", since = "1.31.0")]
#[inline]
pub fn chunks_exact_mut(&mut self, chunk_size: usize) -> ChunksExactMut<'_, T> {
/// assert_eq!(iter.remainder(), &['m']);
/// ```
///
- /// [`chunks_exact`]: #method.chunks_exact
+ /// [`chunks_exact`]: slice::chunks_exact
#[unstable(feature = "array_chunks", issue = "74985")]
#[inline]
pub fn array_chunks<const N: usize>(&self) -> ArrayChunks<'_, T, N> {
/// assert_eq!(v, &[1, 1, 2, 2, 0]);
/// ```
///
- /// [`chunks_exact_mut`]: #method.chunks_exact_mut
+ /// [`chunks_exact_mut`]: slice::chunks_exact_mut
#[unstable(feature = "array_chunks", issue = "74985")]
#[inline]
pub fn array_chunks_mut<const N: usize>(&mut self) -> ArrayChunksMut<'_, T, N> {
/// assert!(iter.next().is_none());
/// ```
///
- /// [`windows`]: #method.windows
+ /// [`windows`]: slice::windows
#[unstable(feature = "array_windows", issue = "75027")]
#[inline]
pub fn array_windows<const N: usize>(&self) -> ArrayWindows<'_, T, N> {
/// assert!(iter.next().is_none());
/// ```
///
- /// [`rchunks_exact`]: #method.rchunks_exact
- /// [`chunks`]: #method.chunks
+ /// [`rchunks_exact`]: slice::rchunks_exact
+ /// [`chunks`]: slice::chunks
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks(&self, chunk_size: usize) -> RChunks<'_, T> {
/// assert_eq!(v, &[3, 2, 2, 1, 1]);
/// ```
///
- /// [`rchunks_exact_mut`]: #method.rchunks_exact_mut
- /// [`chunks_mut`]: #method.chunks_mut
+ /// [`rchunks_exact_mut`]: slice::rchunks_exact_mut
+ /// [`chunks_mut`]: slice::chunks_mut
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks_mut(&mut self, chunk_size: usize) -> RChunksMut<'_, T> {
/// assert_eq!(iter.remainder(), &['l']);
/// ```
///
- /// [`chunks`]: #method.chunks
- /// [`rchunks`]: #method.rchunks
- /// [`chunks_exact`]: #method.chunks_exact
+ /// [`chunks`]: slice::chunks
+ /// [`rchunks`]: slice::rchunks
+ /// [`chunks_exact`]: slice::chunks_exact
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks_exact(&self, chunk_size: usize) -> RChunksExact<'_, T> {
/// assert_eq!(v, &[0, 2, 2, 1, 1]);
/// ```
///
- /// [`chunks_mut`]: #method.chunks_mut
- /// [`rchunks_mut`]: #method.rchunks_mut
- /// [`chunks_exact_mut`]: #method.chunks_exact_mut
+ /// [`chunks_mut`]: slice::chunks_mut
+ /// [`rchunks_mut`]: slice::rchunks_mut
+ /// [`chunks_exact_mut`]: slice::chunks_exact_mut
#[stable(feature = "rchunks", since = "1.31.0")]
#[inline]
pub fn rchunks_exact_mut(&mut self, chunk_size: usize) -> RChunksExactMut<'_, T> {
/// even if the resulting reference is not used. The caller has to ensure that
/// `0 <= mid <= self.len()`.
///
- /// [`split_at`]: #method.split_at
+ /// [`split_at`]: slice::split_at
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
/// even if the resulting reference is not used. The caller has to ensure that
/// `0 <= mid <= self.len()`.
///
- /// [`split_at_mut`]: #method.split_at_mut
+ /// [`split_at_mut`]: slice::split_at_mut
/// [undefined behavior]: https://doc.rust-lang.org/reference/behavior-considered-undefined.html
///
/// # Examples
///
/// See also [`binary_search_by`], [`binary_search_by_key`], and [`partition_point`].
///
- /// [`binary_search_by`]: #method.binary_search_by
- /// [`binary_search_by_key`]: #method.binary_search_by_key
- /// [`partition_point`]: #method.partition_point
+ /// [`binary_search_by`]: slice::binary_search_by
+ /// [`binary_search_by_key`]: slice::binary_search_by_key
+ /// [`partition_point`]: slice::partition_point
///
/// # Examples
///
///
/// See also [`binary_search`], [`binary_search_by_key`], and [`partition_point`].
///
- /// [`binary_search`]: #method.binary_search
- /// [`binary_search_by_key`]: #method.binary_search_by_key
- /// [`partition_point`]: #method.partition_point
+ /// [`binary_search`]: slice::binary_search
+ /// [`binary_search_by_key`]: slice::binary_search_by_key
+ /// [`partition_point`]: slice::partition_point
///
/// # Examples
///
} else if cmp == Greater {
right = mid;
} else {
+ // SAFETY: same as the `get_unchecked` above
+ unsafe { crate::intrinsics::assume(mid < self.len()) };
return Ok(mid);
}
///
/// See also [`binary_search`], [`binary_search_by`], and [`partition_point`].
///
- /// [`sort_by_key`]: #method.sort_by_key
- /// [`binary_search`]: #method.binary_search
- /// [`binary_search_by`]: #method.binary_search_by
- /// [`partition_point`]: #method.partition_point
+ /// [`sort_by_key`]: slice::sort_by_key
+ /// [`binary_search`]: slice::binary_search
+ /// [`binary_search_by`]: slice::binary_search_by
+ /// [`partition_point`]: slice::partition_point
///
/// # Examples
///
/// let r = s.binary_search_by_key(&1, |&(a, b)| b);
/// assert!(match r { Ok(1..=4) => true, _ => false, });
/// ```
+ // Lint rustdoc::broken_intra_doc_links is allowed as `slice::sort_by_key` is
+ // in crate `alloc`, and as such doesn't exists yet when building `core`.
+ // links to downstream crate: #74481. Since primitives are only documented in
+ // libstd (#73423), this never leads to broken links in practice.
+ #[allow(rustdoc::broken_intra_doc_links)]
#[stable(feature = "slice_binary_search_by_key", since = "1.10.0")]
#[inline]
pub fn binary_search_by_key<'a, B, F>(&'a self, b: &B, mut f: F) -> Result<usize, usize>
/// The current algorithm is based on the quickselect portion of the same quicksort algorithm
/// used for [`sort_unstable`].
///
- /// [`sort_unstable`]: #method.sort_unstable
+ /// [`sort_unstable`]: slice::sort_unstable
///
/// # Panics
///
/// The current algorithm is based on the quickselect portion of the same quicksort algorithm
/// used for [`sort_unstable`].
///
- /// [`sort_unstable`]: #method.sort_unstable
+ /// [`sort_unstable`]: slice::sort_unstable
///
/// # Panics
///
/// The current algorithm is based on the quickselect portion of the same quicksort algorithm
/// used for [`sort_unstable`].
///
- /// [`sort_unstable`]: #method.sort_unstable
+ /// [`sort_unstable`]: slice::sort_unstable
///
/// # Panics
///
/// trait to generate values, you can pass [`Default::default`] as the
/// argument.
///
- /// [`fill`]: #method.fill
+ /// [`fill`]: slice::fill
///
/// # Examples
///
/// assert_eq!(slice, [4, 5, 3, 4, 5]);
/// ```
///
- /// [`copy_from_slice`]: #method.copy_from_slice
- /// [`split_at_mut`]: #method.split_at_mut
+ /// [`copy_from_slice`]: slice::copy_from_slice
+ /// [`split_at_mut`]: slice::split_at_mut
#[stable(feature = "clone_from_slice", since = "1.7.0")]
pub fn clone_from_slice(&mut self, src: &[T])
where
/// assert_eq!(slice, [4, 5, 3, 4, 5]);
/// ```
///
- /// [`clone_from_slice`]: #method.clone_from_slice
- /// [`split_at_mut`]: #method.split_at_mut
+ /// [`clone_from_slice`]: slice::clone_from_slice
+ /// [`split_at_mut`]: slice::split_at_mut
#[doc(alias = "memcpy")]
#[stable(feature = "copy_from_slice", since = "1.9.0")]
pub fn copy_from_slice(&mut self, src: &[T])
/// assert_eq!(slice, [4, 5, 3, 1, 2]);
/// ```
///
- /// [`split_at_mut`]: #method.split_at_mut
+ /// [`split_at_mut`]: slice::split_at_mut
#[stable(feature = "swap_with_slice", since = "1.27.0")]
pub fn swap_with_slice(&mut self, other: &mut [T]) {
assert!(self.len() == other.len(), "destination and source slices have different lengths");
/// function to determine the ordering of two elements. Apart from that, it's equivalent to
/// [`is_sorted`]; see its documentation for more information.
///
- /// [`is_sorted`]: #method.is_sorted
+ /// [`is_sorted`]: slice::is_sorted
#[unstable(feature = "is_sorted", reason = "new API", issue = "53485")]
pub fn is_sorted_by<F>(&self, mut compare: F) -> bool
where
/// elements, as determined by `f`. Apart from that, it's equivalent to [`is_sorted`]; see its
/// documentation for more information.
///
- /// [`is_sorted`]: #method.is_sorted
+ /// [`is_sorted`]: slice::is_sorted
///
/// # Examples
///
///
/// See also [`binary_search`], [`binary_search_by`], and [`binary_search_by_key`].
///
- /// [`binary_search`]: #method.binary_search
- /// [`binary_search_by`]: #method.binary_search_by
- /// [`binary_search_by_key`]: #method.binary_search_by_key
+ /// [`binary_search`]: slice::binary_search
+ /// [`binary_search_by`]: slice::binary_search_by
+ /// [`binary_search_by_key`]: slice::binary_search_by_key
///
/// # Examples
///