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