aboutsummaryrefslogtreecommitdiff
path: root/vendor/bytemuck/src/anybitpattern.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/bytemuck/src/anybitpattern.rs')
-rw-r--r--vendor/bytemuck/src/anybitpattern.rs61
1 files changed, 61 insertions, 0 deletions
diff --git a/vendor/bytemuck/src/anybitpattern.rs b/vendor/bytemuck/src/anybitpattern.rs
new file mode 100644
index 0000000..a759738
--- /dev/null
+++ b/vendor/bytemuck/src/anybitpattern.rs
@@ -0,0 +1,61 @@
+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`],
+/// except that the type can allow uninit (or padding) bytes.
+/// This limits what you can do with a type of this kind, but also broadens the
+/// 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.
+///
+/// [`Pod`] is a subset of [`AnyBitPattern`], meaning that any `T: Pod` is also
+/// [`AnyBitPattern`] but any `T: AnyBitPattern` is not necessarily [`Pod`].
+///
+/// [`AnyBitPattern`] is a subset of [`Zeroable`], meaning that any `T:
+/// AnyBitPattern` is also [`Zeroable`], but any `T: Zeroable` is not
+/// necessarily [`AnyBitPattern ]
+///
+/// # Derive
+///
+/// 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.
+///
+/// * *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.
+///
+/// # Safety
+///
+/// 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.
+///
+/// * 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`.
+/// * 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.
+/// * There's probably more, don't mess it up (I mean it).
+pub unsafe trait AnyBitPattern:
+ Zeroable + Sized + Copy + 'static
+{
+}
+
+unsafe impl<T: Pod> AnyBitPattern for T {}
+
+#[cfg(feature = "zeroable_maybe_uninit")]
+#[cfg_attr(feature = "nightly_docs", doc(cfg(feature = "zeroable_maybe_uninit")))]
+unsafe impl<T> AnyBitPattern for core::mem::MaybeUninit<T> where T: AnyBitPattern
+{}