Skip to content

Commit

Permalink
impl Zeroable for Atomic* (Lokathor#157)
Browse files Browse the repository at this point in the history
* `impl Zeroable for Atomic*`

fixes Lokathor#74

* added feature flag for `zeroable_atomics`

Added documentation for some feature flags on the `Zeroable` trait.
Also fixed some invalid references in doc-comments.
  • Loading branch information
nolanderc authored Dec 21, 2022
1 parent 02c1a14 commit 3a3dc18
Show file tree
Hide file tree
Showing 3 changed files with 54 additions and 2 deletions.
3 changes: 3 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ derive = ["bytemuck_derive"]
extern_crate_alloc = []
extern_crate_std = ["extern_crate_alloc"]
zeroable_maybe_uninit = []
zeroable_atomics = []
min_const_generics = []
wasm_simd = [] # Until >= 1.54.0 is MSRV this is an off-by-default feature.
aarch64_simd = [] # Until >= 1.59.0 is MSRV this is an off-by-default feature.
Expand All @@ -38,6 +39,7 @@ features = [
"extern_crate_alloc",
"extern_crate_std",
"zeroable_maybe_uninit",
"zeroable_atomics",
"min_const_generics",
"wasm_simd",
]
Expand All @@ -49,6 +51,7 @@ features = [
"extern_crate_alloc",
"extern_crate_std",
"zeroable_maybe_uninit",
"zeroable_atomics",
"min_const_generics",
"wasm_simd",
]
8 changes: 6 additions & 2 deletions src/checked.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,11 +211,15 @@ impl_checked_for_nonzero! {
#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
pub enum CheckedCastError {
/// An error occurred during a true-[`Pod`] cast
///
/// [`Pod`]: crate::Pod
PodCastError(crate::PodCastError),
/// When casting to a [`CheckedBitPattern`] type, it is possible that the
/// original data contains an invalid bit pattern. If so, the cast will
/// fail and this error will be returned. Will never happen on casts
/// between [`Pod`] types.
///
/// [`Pod`]: crate::Pod
InvalidBitPattern,
}

Expand Down Expand Up @@ -338,7 +342,7 @@ pub fn try_cast_ref<A: NoUninit, B: CheckedBitPattern>(

/// Try to convert a `&mut T` into `&mut U`.
///
/// As [`checked_cast_ref`], but `mut`.
/// As [`try_cast_ref`], but `mut`.
#[inline]
pub fn try_cast_mut<
A: NoUninit + AnyBitPattern,
Expand Down Expand Up @@ -390,7 +394,7 @@ pub fn try_cast_slice<A: NoUninit, B: CheckedBitPattern>(
/// Try to convert `&mut [A]` into `&mut [B]` (possibly with a change in
/// length).
///
/// As [`checked_cast_slice`], but `&mut`.
/// As [`try_cast_slice`], but `&mut`.
#[inline]
pub fn try_cast_slice_mut<
A: NoUninit + AnyBitPattern,
Expand Down
45 changes: 45 additions & 0 deletions src/zeroable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,16 @@ use super::*;
/// [Infallible](core::convert::Infallible)).
/// * Your type must be allowed to be an "all zeroes" bit pattern (eg: no
/// [`NonNull<T>`](core::ptr::NonNull)).
///
/// ## Features
///
/// Some `impl`s are feature gated due to the MSRV policy:
///
/// * `MaybeUninit<T>` was not available in 1.34.0, but is available under the
/// `zeroable_maybe_uninit` feature flag.
/// * `Atomic*` types require Rust 1.60.0 or later to work on certain platforms, but is available
/// under the `zeroable_atomics` feature flag.
/// * `[T; N]` for arbitrary `N` requires the `min_const_generics` feature flag.
pub unsafe trait Zeroable: Sized {
/// Calls [`zeroed`](core::mem::zeroed).
///
Expand Down Expand Up @@ -51,6 +61,41 @@ unsafe impl<T: Zeroable> Zeroable for ManuallyDrop<T> {}
unsafe impl<T: Zeroable> Zeroable for core::cell::UnsafeCell<T> {}
unsafe impl<T: Zeroable> Zeroable for core::cell::Cell<T> {}

#[cfg(feature = "zeroable_atomics")]
mod atomic_impls {
use super::Zeroable;

#[cfg(target_has_atomic = "8")]
unsafe impl Zeroable for core::sync::atomic::AtomicBool {}
#[cfg(target_has_atomic = "8")]
unsafe impl Zeroable for core::sync::atomic::AtomicU8 {}
#[cfg(target_has_atomic = "8")]
unsafe impl Zeroable for core::sync::atomic::AtomicI8 {}

#[cfg(target_has_atomic = "16")]
unsafe impl Zeroable for core::sync::atomic::AtomicU16 {}
#[cfg(target_has_atomic = "16")]
unsafe impl Zeroable for core::sync::atomic::AtomicI16 {}

#[cfg(target_has_atomic = "32")]
unsafe impl Zeroable for core::sync::atomic::AtomicU32 {}
#[cfg(target_has_atomic = "32")]
unsafe impl Zeroable for core::sync::atomic::AtomicI32 {}

#[cfg(target_has_atomic = "64")]
unsafe impl Zeroable for core::sync::atomic::AtomicU64 {}
#[cfg(target_has_atomic = "64")]
unsafe impl Zeroable for core::sync::atomic::AtomicI64 {}

#[cfg(target_has_atomic = "ptr")]
unsafe impl Zeroable for core::sync::atomic::AtomicUsize {}
#[cfg(target_has_atomic = "ptr")]
unsafe impl Zeroable for core::sync::atomic::AtomicIsize {}

#[cfg(target_has_atomic = "ptr")]
unsafe impl<T> Zeroable for core::sync::atomic::AtomicPtr<T> {}
}

#[cfg(feature = "zeroable_maybe_uninit")]
unsafe impl<T> Zeroable for core::mem::MaybeUninit<T> {}

Expand Down

0 comments on commit 3a3dc18

Please sign in to comment.