2022-03-29 23:01:02 +00:00
|
|
|
use crate::{Pod, Zeroable};
|
|
|
|
|
|
|
|
/// Marker trait for "plain old data" types that are valid for any bit pattern.
|
|
|
|
///
|
|
|
|
/// The requirements for this is very similar to [`Pod`],
|
2022-05-19 17:47:54 +00:00
|
|
|
/// except that the type can allow uninit (or padding) bytes.
|
2022-03-29 23:01:02 +00:00
|
|
|
/// This limits what you can do with a type of this kind, but also broadens the
|
2022-07-24 15:27:49 +00:00
|
|
|
/// included types to `repr(C)` `struct`s that contain padding as well as
|
|
|
|
/// `union`s. Notably, you can only cast *immutable* references and *owned*
|
|
|
|
/// values into [`AnyBitPattern`] types, not *mutable* references.
|
2022-03-29 23:01:02 +00:00
|
|
|
///
|
|
|
|
/// [`Pod`] is a subset of [`AnyBitPattern`], meaning that any `T: Pod` is also
|
|
|
|
/// [`AnyBitPattern`] but any `T: AnyBitPattern` is not necessarily [`Pod`].
|
|
|
|
///
|
2022-07-24 15:27:49 +00:00
|
|
|
/// [`AnyBitPattern`] is a subset of [`Zeroable`], meaning that any `T:
|
|
|
|
/// AnyBitPattern` is also [`Zeroable`], but any `T: Zeroable` is not
|
2024-01-25 02:58:00 +00:00
|
|
|
/// necessarily [`AnyBitPattern`]
|
2022-03-29 23:01:02 +00:00
|
|
|
///
|
|
|
|
/// # Derive
|
|
|
|
///
|
2022-07-24 15:27:49 +00:00
|
|
|
/// A `#[derive(AnyBitPattern)]` macro is provided under the `derive` feature
|
|
|
|
/// flag which will automatically validate the requirements of this trait and
|
|
|
|
/// implement the trait for you for both structs and enums. This is the
|
|
|
|
/// recommended method for implementing the trait, however it's also possible to
|
|
|
|
/// do manually. If you implement it manually, you *must* carefully follow the
|
|
|
|
/// below safety rules.
|
2022-03-29 23:01:02 +00:00
|
|
|
///
|
|
|
|
/// * *NOTE: even `C-style`, fieldless enums are intentionally **excluded** from
|
|
|
|
/// this trait, since it is **unsound** for an enum to have a discriminant value
|
|
|
|
/// that is not one of its defined variants.
|
2022-07-24 15:27:49 +00:00
|
|
|
///
|
2022-03-29 23:01:02 +00:00
|
|
|
/// # Safety
|
|
|
|
///
|
2022-07-24 15:27:49 +00:00
|
|
|
/// Similar to [`Pod`] except we disregard the rule about it must not contain
|
|
|
|
/// uninit bytes. Still, this is a quite strong guarantee about a type, so *be
|
|
|
|
/// careful* when implementing it manually.
|
2022-03-29 23:01:02 +00:00
|
|
|
///
|
|
|
|
/// * The type must be inhabited (eg: no
|
|
|
|
/// [Infallible](core::convert::Infallible)).
|
|
|
|
/// * The type must be valid for any bit pattern of its backing memory.
|
|
|
|
/// * Structs need to have all fields also be `AnyBitPattern`.
|
2022-07-24 15:27:49 +00:00
|
|
|
/// * It is disallowed for types to contain pointer types, `Cell`, `UnsafeCell`,
|
|
|
|
/// atomics, and any other forms of interior mutability.
|
|
|
|
/// * More precisely: A shared reference to the type must allow reads, and
|
|
|
|
/// *only* reads. RustBelt's separation logic is based on the notion that a
|
|
|
|
/// type is allowed to define a sharing predicate, its own invariant that must
|
|
|
|
/// hold for shared references, and this predicate is the reasoning that allow
|
|
|
|
/// it to deal with atomic and cells etc. We require the sharing predicate to
|
|
|
|
/// be trivial and permit only read-only access.
|
2022-03-29 23:01:02 +00:00
|
|
|
/// * There's probably more, don't mess it up (I mean it).
|
2022-07-24 15:27:49 +00:00
|
|
|
pub unsafe trait AnyBitPattern:
|
|
|
|
Zeroable + Sized + Copy + 'static
|
|
|
|
{
|
|
|
|
}
|
2022-03-29 23:01:02 +00:00
|
|
|
|
|
|
|
unsafe impl<T: Pod> AnyBitPattern for T {}
|
2023-01-11 07:24:05 +00:00
|
|
|
|
|
|
|
#[cfg(feature = "zeroable_maybe_uninit")]
|
2023-09-05 19:39:41 +00:00
|
|
|
#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "zeroable_maybe_uninit")))]
|
2023-01-11 07:24:05 +00:00
|
|
|
unsafe impl<T> AnyBitPattern for core::mem::MaybeUninit<T> where T: AnyBitPattern
|
|
|
|
{}
|