Skip to content

Commit

Permalink
run cargo fmt (#120)
Browse files Browse the repository at this point in the history
  • Loading branch information
WaffleLapkin committed Jul 24, 2022
1 parent d75942c commit 331762b
Show file tree
Hide file tree
Showing 6 changed files with 177 additions and 141 deletions.
57 changes: 27 additions & 30 deletions src/allocation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,13 @@ pub fn zeroed_box<T: Zeroable>() -> Box<T> {
try_zeroed_box().unwrap()
}

/// Allocates a `Vec<T>` of length and capacity exactly equal to `length` and all elements zeroed.
///
/// Allocates a `Vec<T>` of length and capacity exactly equal to `length` and
/// all elements zeroed.
///
/// ## Failure
///
/// This fails if the allocation fails, or if a layout cannot be calculated for the allocation.
/// This fails if the allocation fails, or if a layout cannot be calculated for
/// the allocation.
pub fn try_zeroed_vec<T: Zeroable>(length: usize) -> Result<Vec<T>, ()> {
if length == 0 {
Ok(Vec::new())
Expand All @@ -121,7 +123,8 @@ pub fn zeroed_vec<T: Zeroable>(length: usize) -> Vec<T> {
///
/// ## Failure
///
/// This fails if the allocation fails, or if a layout cannot be calculated for the allocation.
/// This fails if the allocation fails, or if a layout cannot be calculated for
/// the allocation.
#[inline]
pub fn try_zeroed_slice_box<T: Zeroable>(
length: usize,
Expand All @@ -145,7 +148,7 @@ pub fn try_zeroed_slice_box<T: Zeroable>(
let slice =
unsafe { core::slice::from_raw_parts_mut(ptr as *mut T, length) };
Ok(unsafe { Box::<[T]>::from_raw(slice) })
}
}
}

/// As [`try_zeroed_slice_box`](try_zeroed_slice_box), but unwraps for you.
Expand Down Expand Up @@ -313,12 +316,14 @@ pub fn pod_collect_to_vec<
}

/// An extension trait for `TransparentWrapper` and alloc types.
pub trait TransparentWrapperAlloc<Inner: ?Sized>: TransparentWrapper<Inner> {
pub trait TransparentWrapperAlloc<Inner: ?Sized>:
TransparentWrapper<Inner>
{
/// Convert a vec of the inner type into a vec of the wrapper type.
fn wrap_vec(s: Vec<Inner>) -> Vec<Self>
where
Self: Sized,
Inner: Sized
Inner: Sized,
{
let mut s = core::mem::ManuallyDrop::new(s);

Expand All @@ -331,11 +336,7 @@ pub trait TransparentWrapperAlloc<Inner: ?Sized>: TransparentWrapper<Inner> {
// * ptr comes from Vec (and will not be double-dropped)
// * the two types have the identical representation
// * the len and capacity fields are valid
Vec::from_raw_parts(
ptr as *mut Self,
length,
capacity
)
Vec::from_raw_parts(ptr as *mut Self, length, capacity)
}
}

Expand All @@ -350,12 +351,12 @@ pub trait TransparentWrapperAlloc<Inner: ?Sized>: TransparentWrapper<Inner> {
// the vtables match (because of the `?Sized` restriction relaxation).
// A `transmute` doesn't work because the sizes are unspecified.
//
// SAFETY:
// * The unsafe contract requires that pointers to Inner and Self
// have identical representations
// * Box is guaranteed to have representation identical to a
// (non-null) pointer
// * The pointer comes from a box (and thus satisfies all safety
// SAFETY:
// * The unsafe contract requires that pointers to Inner and Self have
// identical representations
// * Box is guaranteed to have representation identical to a (non-null)
// pointer
// * The pointer comes from a box (and thus satisfies all safety
// requirements of Box)
let inner_ptr: *mut Inner = Box::into_raw(s);
let wrapper_ptr: *mut Self = transmute!(inner_ptr);
Expand All @@ -367,7 +368,7 @@ pub trait TransparentWrapperAlloc<Inner: ?Sized>: TransparentWrapper<Inner> {
fn peel_vec(s: Vec<Self>) -> Vec<Inner>
where
Self: Sized,
Inner: Sized
Inner: Sized,
{
let mut s = core::mem::ManuallyDrop::new(s);

Expand All @@ -380,11 +381,7 @@ pub trait TransparentWrapperAlloc<Inner: ?Sized>: TransparentWrapper<Inner> {
// * ptr comes from Vec (and will not be double-dropped)
// * the two types have the identical representation
// * the len and capacity fields are valid
Vec::from_raw_parts(
ptr as *mut Inner,
length,
capacity
)
Vec::from_raw_parts(ptr as *mut Inner, length, capacity)
}
}

Expand All @@ -399,12 +396,12 @@ pub trait TransparentWrapperAlloc<Inner: ?Sized>: TransparentWrapper<Inner> {
// the vtables match (because of the `?Sized` restriction relaxation).
// A `transmute` doesn't work because the sizes are unspecified.
//
// SAFETY:
// * The unsafe contract requires that pointers to Inner and Self
// have identical representations
// * Box is guaranteed to have representation identical to a
// (non-null) pointer
// * The pointer comes from a box (and thus satisfies all safety
// SAFETY:
// * The unsafe contract requires that pointers to Inner and Self have
// identical representations
// * Box is guaranteed to have representation identical to a (non-null)
// pointer
// * The pointer comes from a box (and thus satisfies all safety
// requirements of Box)
let wrapper_ptr: *mut Self = Box::into_raw(s);
let inner_ptr: *mut Inner = transmute!(wrapper_ptr);
Expand Down
50 changes: 28 additions & 22 deletions src/anybitpattern.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,46 +5,52 @@ use crate::{Pod, Zeroable};
/// 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.
/// 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 ]
/// [`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.
/// 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.
/// 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.
/// * 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 {}
pub unsafe trait AnyBitPattern:
Zeroable + Sized + Copy + 'static
{
}

unsafe impl<T: Pod> AnyBitPattern for T {}

0 comments on commit 331762b

Please sign in to comment.