Add cast_init and cast_uninit methods for pointers

This commit is contained in:
ltdk 2025-07-17 23:28:24 -04:00
parent 8e62bfd311
commit d6945f6d8c
8 changed files with 74 additions and 3 deletions

View File

@ -102,6 +102,7 @@
#![feature(async_iterator)]
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(cast_maybe_uninit)]
#![feature(char_internals)]
#![feature(char_max_len)]
#![feature(clone_to_uninit)]

View File

@ -3176,7 +3176,7 @@ impl<T, A: Allocator> Vec<T, A> {
// - but the allocation extends out to `self.buf.capacity()` elements, possibly
// uninitialized
let spare_ptr = unsafe { ptr.add(self.len) };
let spare_ptr = spare_ptr.cast::<MaybeUninit<T>>();
let spare_ptr = spare_ptr.cast_uninit();
let spare_len = self.buf.capacity() - self.len;
// SAFETY:

View File

@ -195,7 +195,7 @@ impl<T, const N: usize> Buffer<T, N> {
// SAFETY: the index is valid and this is element `a` in the
// diagram above and has not been dropped yet.
unsafe { ptr::drop_in_place(to_drop.cast::<T>()) };
unsafe { ptr::drop_in_place(to_drop.cast_init()) };
}
}

View File

@ -1430,6 +1430,28 @@ impl<T: PointeeSized> *const T {
}
}
impl<T> *const T {
/// Casts from a type to its maybe-uninitialized version.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_uninit(self) -> *const MaybeUninit<T> {
self as _
}
}
impl<T> *const MaybeUninit<T> {
/// Casts from a maybe-uninitialized type to its initialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_init(self) -> *const T {
self as _
}
}
impl<T> *const [T] {
/// Returns the length of a raw slice.
///

View File

@ -1687,6 +1687,31 @@ impl<T: PointeeSized> *mut T {
}
}
impl<T> *mut T {
/// Casts from a type to its maybe-uninitialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_uninit(self) -> *mut MaybeUninit<T> {
self as _
}
}
impl<T> *mut MaybeUninit<T> {
/// Casts from a maybe-uninitialized type to its initialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_init(self) -> *mut T {
self as _
}
}
impl<T> *mut [T] {
/// Returns the length of a raw slice.
///

View File

@ -1357,6 +1357,28 @@ impl<T: PointeeSized> NonNull<T> {
}
}
impl<T> NonNull<T> {
/// Casts from a type to its maybe-uninitialized version.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_uninit(self) -> NonNull<MaybeUninit<T>> {
self.cast()
}
}
impl<T> NonNull<MaybeUninit<T>> {
/// Casts from a maybe-uninitialized type to its initialized version.
///
/// This is always safe, since UB can only occur if the pointer is read
/// before being initialized.
#[must_use]
#[inline(always)]
#[unstable(feature = "cast_maybe_uninit", issue = "145036")]
pub const fn cast_init(self) -> NonNull<T> {
self.cast()
}
}
impl<T> NonNull<[T]> {
/// Creates a non-null raw slice from a thin pointer and a length.
///

View File

@ -327,6 +327,7 @@
// tidy-alphabetical-start
#![feature(bstr)]
#![feature(bstr_internals)]
#![feature(cast_maybe_uninit)]
#![feature(char_internals)]
#![feature(clone_to_uninit)]
#![feature(core_intrinsics)]

View File

@ -1606,7 +1606,7 @@ pub fn junction_point(original: &Path, link: &Path) -> io::Result<()> {
};
unsafe {
let ptr = header.PathBuffer.as_mut_ptr();
ptr.copy_from(abs_path.as_ptr().cast::<MaybeUninit<u16>>(), abs_path.len());
ptr.copy_from(abs_path.as_ptr().cast_uninit(), abs_path.len());
let mut ret = 0;
cvt(c::DeviceIoControl(