Rollup merge of #149110 - Paladynee:acp/ptr_cast_slice, r=jhpratt
Implement `cast_slice` for raw pointer types Tracking issue: https://github.com/rust-lang/rust/issues/149103 This PR implements the method `cast_slice` that defers to the respective `slice_from_raw_parts` call for `*const T`, `*mut T` and `NonNull<T>`, and copies over their documentation. ```rust impl<T> *const T { pub const fn cast_slice(self, len: usize) -> *const [T]; } impl<T> *mut T { pub const fn cast_slice(self, len: usize) -> *mut [T]; } impl<T> NonNull<T> { pub const fn cast_slice(self, len: usize) -> NonNull<[T]>; } ```
This commit is contained in:
commit
034b53c863
3 changed files with 111 additions and 0 deletions
|
|
@ -1386,6 +1386,43 @@ impl<T> *const T {
|
|||
pub const fn cast_uninit(self) -> *const MaybeUninit<T> {
|
||||
self as _
|
||||
}
|
||||
|
||||
/// Forms a raw slice from a pointer and a length.
|
||||
///
|
||||
/// The `len` argument is the number of **elements**, not the number of bytes.
|
||||
///
|
||||
/// This function is safe, but actually using the return value is unsafe.
|
||||
/// See the documentation of [`slice::from_raw_parts`] for slice safety requirements.
|
||||
///
|
||||
/// [`slice::from_raw_parts`]: crate::slice::from_raw_parts
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(ptr_cast_slice)]
|
||||
/// // create a slice pointer when starting out with a pointer to the first element
|
||||
/// let x = [5, 6, 7];
|
||||
/// let raw_pointer = x.as_ptr();
|
||||
/// let slice = raw_pointer.cast_slice(3);
|
||||
/// assert_eq!(unsafe { &*slice }[2], 7);
|
||||
/// ```
|
||||
///
|
||||
/// You must ensure that the pointer is valid and not null before dereferencing
|
||||
/// the raw slice. A slice reference must never have a null pointer, even if it's empty.
|
||||
///
|
||||
/// ```rust,should_panic
|
||||
/// #![feature(ptr_cast_slice)]
|
||||
/// use std::ptr;
|
||||
/// let danger: *const [u8] = ptr::null::<u8>().cast_slice(0);
|
||||
/// unsafe {
|
||||
/// danger.as_ref().expect("references must not be null");
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "ptr_cast_slice", issue = "149103")]
|
||||
pub const fn cast_slice(self, len: usize) -> *const [T] {
|
||||
slice_from_raw_parts(self, len)
|
||||
}
|
||||
}
|
||||
impl<T> *const MaybeUninit<T> {
|
||||
/// Casts from a maybe-uninitialized type to its initialized version.
|
||||
|
|
|
|||
|
|
@ -1655,6 +1655,51 @@ impl<T> *mut T {
|
|||
pub const fn cast_uninit(self) -> *mut MaybeUninit<T> {
|
||||
self as _
|
||||
}
|
||||
|
||||
/// Forms a raw mutable slice from a pointer and a length.
|
||||
///
|
||||
/// The `len` argument is the number of **elements**, not the number of bytes.
|
||||
///
|
||||
/// Performs the same functionality as [`cast_slice`] on a `*const T`, except that a
|
||||
/// raw mutable slice is returned, as opposed to a raw immutable slice.
|
||||
///
|
||||
/// This function is safe, but actually using the return value is unsafe.
|
||||
/// See the documentation of [`slice::from_raw_parts_mut`] for slice safety requirements.
|
||||
///
|
||||
/// [`slice::from_raw_parts_mut`]: crate::slice::from_raw_parts_mut
|
||||
/// [`cast_slice`]: pointer::cast_slice
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(ptr_cast_slice)]
|
||||
///
|
||||
/// let x = &mut [5, 6, 7];
|
||||
/// let slice = x.as_mut_ptr().cast_slice(3);
|
||||
///
|
||||
/// unsafe {
|
||||
/// (*slice)[2] = 99; // assign a value at an index in the slice
|
||||
/// };
|
||||
///
|
||||
/// assert_eq!(unsafe { &*slice }[2], 99);
|
||||
/// ```
|
||||
///
|
||||
/// You must ensure that the pointer is valid and not null before dereferencing
|
||||
/// the raw slice. A slice reference must never have a null pointer, even if it's empty.
|
||||
///
|
||||
/// ```rust,should_panic
|
||||
/// #![feature(ptr_cast_slice)]
|
||||
/// use std::ptr;
|
||||
/// let danger: *mut [u8] = ptr::null_mut::<u8>().cast_slice(0);
|
||||
/// unsafe {
|
||||
/// danger.as_mut().expect("references must not be null");
|
||||
/// }
|
||||
/// ```
|
||||
#[inline]
|
||||
#[unstable(feature = "ptr_cast_slice", issue = "149103")]
|
||||
pub const fn cast_slice(self, len: usize) -> *mut [T] {
|
||||
slice_from_raw_parts_mut(self, len)
|
||||
}
|
||||
}
|
||||
impl<T> *mut MaybeUninit<T> {
|
||||
/// Casts from a maybe-uninitialized type to its initialized version.
|
||||
|
|
|
|||
|
|
@ -1377,6 +1377,35 @@ impl<T> NonNull<T> {
|
|||
pub const fn cast_uninit(self) -> NonNull<MaybeUninit<T>> {
|
||||
self.cast()
|
||||
}
|
||||
|
||||
/// Creates a non-null raw slice from a thin pointer and a length.
|
||||
///
|
||||
/// The `len` argument is the number of **elements**, not the number of bytes.
|
||||
///
|
||||
/// This function is safe, but dereferencing the return value is unsafe.
|
||||
/// See the documentation of [`slice::from_raw_parts`] for slice safety requirements.
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// ```rust
|
||||
/// #![feature(ptr_cast_slice)]
|
||||
/// use std::ptr::NonNull;
|
||||
///
|
||||
/// // create a slice pointer when starting out with a pointer to the first element
|
||||
/// let mut x = [5, 6, 7];
|
||||
/// let nonnull_pointer = NonNull::new(x.as_mut_ptr()).unwrap();
|
||||
/// let slice = nonnull_pointer.cast_slice(3);
|
||||
/// assert_eq!(unsafe { slice.as_ref()[2] }, 7);
|
||||
/// ```
|
||||
///
|
||||
/// (Note that this example artificially demonstrates a use of this method,
|
||||
/// but `let slice = NonNull::from(&x[..]);` would be a better way to write code like this.)
|
||||
#[inline]
|
||||
#[must_use]
|
||||
#[unstable(feature = "ptr_cast_slice", issue = "149103")]
|
||||
pub const fn cast_slice(self, len: usize) -> NonNull<[T]> {
|
||||
NonNull::slice_from_raw_parts(self, len)
|
||||
}
|
||||
}
|
||||
impl<T> NonNull<MaybeUninit<T>> {
|
||||
/// Casts from a maybe-uninitialized type to its initialized version.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue