support const zeroed() (#240)

This commit is contained in:
Tyler Ruckinger 2024-05-13 12:16:20 -04:00 committed by GitHub
parent 7ef8801cff
commit 99e95084a6
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 26 additions and 6 deletions

View File

@ -34,6 +34,8 @@ aarch64_simd = [] # MSRV 1.59.0: support aarch64 simd types
must_cast = [] # MSRV 1.57.0: support the `must` module. must_cast = [] # MSRV 1.57.0: support the `must` module.
const_zeroed = [] # MSRV 1.75.0: support const `zeroed()`
# Do not use if you can avoid it, because this is **unsound**!!!! # Do not use if you can avoid it, because this is **unsound**!!!!
unsound_ptr_pod_impl = [] unsound_ptr_pod_impl = []
@ -59,6 +61,7 @@ features = [
"min_const_generics", "min_const_generics",
"wasm_simd", "wasm_simd",
"must_cast", "must_cast",
"const_zeroed",
] ]
[package.metadata.playground] [package.metadata.playground]
@ -72,4 +75,5 @@ features = [
"min_const_generics", "min_const_generics",
"wasm_simd", "wasm_simd",
"must_cast", "must_cast",
"const_zeroed",
] ]

View File

@ -19,6 +19,7 @@ use alloc::{
vec, vec,
vec::Vec, vec::Vec,
}; };
use core::mem::ManuallyDrop;
use core::ops::{Deref, DerefMut}; use core::ops::{Deref, DerefMut};
/// As [`try_cast_box`](try_cast_box), but unwraps for you. /// As [`try_cast_box`](try_cast_box), but unwraps for you.
@ -286,7 +287,7 @@ pub fn try_cast_vec<A: NoUninit, B: AnyBitPattern>(
pub fn pod_collect_to_vec<A: NoUninit, B: NoUninit + AnyBitPattern>( pub fn pod_collect_to_vec<A: NoUninit, B: NoUninit + AnyBitPattern>(
src: &[A], src: &[A],
) -> Vec<B> { ) -> Vec<B> {
let src_size = size_of_val(src); let src_size = core::mem::size_of_val(src);
// Note(Lokathor): dst_count is rounded up so that the dest will always be at // Note(Lokathor): dst_count is rounded up so that the dest will always be at
// least as many bytes as the src. // least as many bytes as the src.
let dst_count = src_size / size_of::<B>() let dst_count = src_size / size_of::<B>()
@ -512,7 +513,7 @@ pub trait TransparentWrapperAlloc<Inner: ?Sized>:
Self: Sized, Self: Sized,
Inner: Sized, Inner: Sized,
{ {
let mut s = core::mem::ManuallyDrop::new(s); let mut s = ManuallyDrop::new(s);
let length = s.len(); let length = s.len();
let capacity = s.capacity(); let capacity = s.capacity();
@ -617,7 +618,7 @@ pub trait TransparentWrapperAlloc<Inner: ?Sized>:
Self: Sized, Self: Sized,
Inner: Sized, Inner: Sized,
{ {
let mut s = core::mem::ManuallyDrop::new(s); let mut s = ManuallyDrop::new(s);
let length = s.len(); let length = s.len();
let capacity = s.capacity(); let capacity = s.capacity();

View File

@ -83,6 +83,7 @@
//! instead of just for a select list of array lengths. //! instead of just for a select list of array lengths.
//! * `must_cast`: Provides the `must_` functions, which will compile error if //! * `must_cast`: Provides the `must_` functions, which will compile error if
//! the requested cast can't be statically verified. //! the requested cast can't be statically verified.
//! * `const_zeroed`: Provides the const [`zeroed`] function.
#[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))] #[cfg(all(target_arch = "aarch64", feature = "aarch64_simd"))]
use core::arch::aarch64; use core::arch::aarch64;
@ -93,7 +94,12 @@ use core::arch::x86;
#[cfg(target_arch = "x86_64")] #[cfg(target_arch = "x86_64")]
use core::arch::x86_64; use core::arch::x86_64;
// //
use core::{marker::*, mem::*, num::*, ptr::*}; use core::{
marker::*,
mem::{align_of, size_of},
num::*,
ptr::*,
};
// Used from macros to ensure we aren't using some locally defined name and // Used from macros to ensure we aren't using some locally defined name and
// actually are referencing libcore. This also would allow pre-2018 edition // actually are referencing libcore. This also would allow pre-2018 edition
@ -506,3 +512,12 @@ pub fn fill_zeroes<T: Zeroable>(slice: &mut [T]) {
unsafe { core::ptr::write_bytes(slice.as_mut_ptr() as *mut u8, 0u8, len) } unsafe { core::ptr::write_bytes(slice.as_mut_ptr() as *mut u8, 0u8, len) }
} }
} }
/// Initialize a zeroed `T`.
///
/// Like [`Zeroable::zeroed`], but supports const.
#[cfg(feature = "const_zeroed")]
#[inline]
pub const fn zeroed<T: Zeroable>() -> T {
unsafe { core::mem::zeroed() }
}

View File

@ -74,7 +74,7 @@ unsafe impl<T: 'static> PodInOption for NonNull<T> {}
unsafe impl<T: ?Sized + 'static> Pod for PhantomData<T> {} unsafe impl<T: ?Sized + 'static> Pod for PhantomData<T> {}
unsafe impl Pod for PhantomPinned {} unsafe impl Pod for PhantomPinned {}
unsafe impl<T: Pod> Pod for ManuallyDrop<T> {} unsafe impl<T: Pod> Pod for core::mem::ManuallyDrop<T> {}
// Note(Lokathor): MaybeUninit can NEVER be Pod. // Note(Lokathor): MaybeUninit can NEVER be Pod.

View File

@ -66,7 +66,7 @@ unsafe impl Zeroable for *const str {}
unsafe impl<T: ?Sized> Zeroable for PhantomData<T> {} unsafe impl<T: ?Sized> Zeroable for PhantomData<T> {}
unsafe impl Zeroable for PhantomPinned {} unsafe impl Zeroable for PhantomPinned {}
unsafe impl<T: Zeroable> Zeroable for ManuallyDrop<T> {} unsafe impl<T: Zeroable> Zeroable for core::mem::ManuallyDrop<T> {}
unsafe impl<T: Zeroable> Zeroable for core::cell::UnsafeCell<T> {} unsafe impl<T: Zeroable> Zeroable for core::cell::UnsafeCell<T> {}
unsafe impl<T: Zeroable> Zeroable for core::cell::Cell<T> {} unsafe impl<T: Zeroable> Zeroable for core::cell::Cell<T> {}