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