// ignore-tidy-filelength
+// ignore-tidy-undocumented-unsafe
//! Slice management and manipulation.
//!
/// assert_eq!(a.len(), 3);
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[cfg_attr(not(bootstrap), rustc_const_stable(feature = "const_slice_len", since = "1.32.0"))]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
#[allow(unused_attributes)]
/// assert!(!a.is_empty());
/// ```
#[stable(feature = "rust1", since = "1.0.0")]
+ #[cfg_attr(
+ not(bootstrap),
+ rustc_const_stable(feature = "const_slice_is_empty", since = "1.32.0"),
+ )]
#[inline]
pub const fn is_empty(&self) -> bool {
self.len() == 0
///
/// [`as_mut_ptr`]: #method.as_mut_ptr
#[stable(feature = "rust1", since = "1.0.0")]
+ #[cfg_attr(
+ not(bootstrap),
+ rustc_const_stable(feature = "const_slice_as_ptr", since = "1.32.0"),
+ )]
#[inline]
pub const fn as_ptr(&self) -> *const T {
self as *const [T] as *const T
///
/// # Safety
///
-/// This function is unsafe as there is no guarantee that the given pointer is
-/// valid for `len` elements, nor whether the lifetime inferred is a suitable
-/// lifetime for the returned slice.
+/// Behavior is undefined if any of the following conditions are violated:
///
-/// `data` must be non-null and aligned, even for zero-length slices. One
-/// reason for this is that enum layout optimizations may rely on references
-/// (including slices of any length) being aligned and non-null to distinguish
-/// them from other data. You can obtain a pointer that is usable as `data`
-/// for zero-length slices using [`NonNull::dangling()`].
+/// * `data` must be [valid] for reads for `len * mem::size_of::<T>()` many bytes,
+/// and it must be properly aligned. This means in particular:
///
-/// The total size of the slice must be no larger than `isize::MAX` **bytes**
-/// in memory. See the safety documentation of [`pointer::offset`].
+/// * The entire memory range of this slice must be contained within a single allocated object!
+/// Slices can never span across multiple allocated objects.
+/// * `data` must be non-null and aligned even for zero-length slices. One
+/// reason for this is that enum layout optimizations may rely on references
+/// (including slices of any length) being aligned and non-null to distinguish
+/// them from other data. You can obtain a pointer that is usable as `data`
+/// for zero-length slices using [`NonNull::dangling()`].
+///
+/// * The memory referenced by the returned slice must not be mutated for the duration
+/// of lifetime `'a`, except inside an `UnsafeCell`.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+/// See the safety documentation of [`pointer::offset`].
///
/// # Caveat
///
/// assert_eq!(slice[0], 42);
/// ```
///
+/// [valid]: ../../std/ptr/index.html#safety
/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
#[inline]
pub unsafe fn from_raw_parts<'a, T>(data: *const T, len: usize) -> &'a [T] {
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
- "attempt to create slice covering half the address space");
+ "attempt to create slice covering at least half the address space");
&*ptr::slice_from_raw_parts(data, len)
}
/// Performs the same functionality as [`from_raw_parts`], except that a
/// mutable slice is returned.
///
-/// 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. `data` must be non-null and aligned even for zero-length
-/// slices as with [`from_raw_parts`]. The total size of the slice must be no
-/// larger than `isize::MAX` **bytes** in memory.
+/// # Safety
+///
+/// Behavior is undefined if any of the following conditions are violated:
+///
+/// * `data` must be [valid] for writes for `len * mem::size_of::<T>()` many bytes,
+/// and it must be properly aligned. This means in particular:
///
-/// See the documentation of [`from_raw_parts`] for more details.
+/// * The entire memory range of this slice must be contained within a single allocated object!
+/// Slices can never span across multiple allocated objects.
+/// * `data` must be non-null and aligned even for zero-length slices. One
+/// reason for this is that enum layout optimizations may rely on references
+/// (including slices of any length) being aligned and non-null to distinguish
+/// them from other data. You can obtain a pointer that is usable as `data`
+/// for zero-length slices using [`NonNull::dangling()`].
///
+/// * The memory referenced by the returned slice must not be accessed through any other pointer
+/// (not derived from the return value) for the duration of lifetime `'a`.
+/// Both read and write accesses are forbidden.
+///
+/// * The total size `len * mem::size_of::<T>()` of the slice must be no larger than `isize::MAX`.
+/// See the safety documentation of [`pointer::offset`].
+///
+/// [valid]: ../../std/ptr/index.html#safety
+/// [`NonNull::dangling()`]: ../../std/ptr/struct.NonNull.html#method.dangling
+/// [`pointer::offset`]: ../../std/primitive.pointer.html#method.offset
/// [`from_raw_parts`]: ../../std/slice/fn.from_raw_parts.html
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub unsafe fn from_raw_parts_mut<'a, T>(data: *mut T, len: usize) -> &'a mut [T] {
debug_assert!(is_aligned_and_not_null(data), "attempt to create unaligned or null slice");
debug_assert!(mem::size_of::<T>().saturating_mul(len) <= isize::MAX as usize,
- "attempt to create slice covering half the address space");
+ "attempt to create slice covering at least half the address space");
&mut *ptr::slice_from_raw_parts_mut(data, len)
}