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