1use 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`],
6/// except that the type can allow uninit (or padding) bytes.
7/// This limits what you can do with a type of this kind, but also broadens the
8/// included types to `repr(C)` `struct`s that contain padding as well as
9/// `union`s. Notably, you can only cast *immutable* references and *owned*
10/// values into [`AnyBitPattern`] types, not *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 value
30/// 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).
51pub unsafe trait AnyBitPattern:
52 Zeroable + Sized + Copy + 'static
53{
54}
55
56unsafe impl<T: Pod> AnyBitPattern for T {}
57
58#[cfg(feature = "zeroable_maybe_uninit")]
59#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "zeroable_maybe_uninit")))]
60unsafe impl<T> AnyBitPattern for core::mem::MaybeUninit<T> where T: AnyBitPattern
61{}
62