From 331762b0144c6338eed6b521a69b35d32473e6b2 Mon Sep 17 00:00:00 2001 From: Waffle Maybe Date: Sun, 24 Jul 2022 19:27:49 +0400 Subject: [PATCH] run `cargo fmt` (#120) --- src/allocation.rs | 57 +++++++++++----------- src/anybitpattern.rs | 50 ++++++++++--------- src/checked.rs | 111 +++++++++++++++++++++++++++---------------- src/internal.rs | 14 ++++-- src/no_uninit.rs | 70 +++++++++++++-------------- tests/transparent.rs | 14 ++++-- 6 files changed, 176 insertions(+), 140 deletions(-) diff --git a/src/allocation.rs b/src/allocation.rs index 888d3c1..93664bf 100644 --- a/src/allocation.rs +++ b/src/allocation.rs @@ -93,11 +93,13 @@ pub fn zeroed_box() -> Box { try_zeroed_box().unwrap() } -/// Allocates a `Vec` of length and capacity exactly equal to `length` and all elements zeroed. -/// +/// Allocates a `Vec` 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(length: usize) -> Result, ()> { if length == 0 { Ok(Vec::new()) @@ -121,7 +123,8 @@ pub fn zeroed_vec(length: usize) -> Vec { /// /// ## 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( length: usize, @@ -145,7 +148,7 @@ pub fn try_zeroed_slice_box( 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. @@ -313,12 +316,14 @@ pub fn pod_collect_to_vec< } /// An extension trait for `TransparentWrapper` and alloc types. -pub trait TransparentWrapperAlloc: TransparentWrapper { +pub trait TransparentWrapperAlloc: + TransparentWrapper +{ /// Convert a vec of the inner type into a vec of the wrapper type. fn wrap_vec(s: Vec) -> Vec where Self: Sized, - Inner: Sized + Inner: Sized, { let mut s = core::mem::ManuallyDrop::new(s); @@ -331,11 +336,7 @@ pub trait TransparentWrapperAlloc: TransparentWrapper { // * 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) } } @@ -350,12 +351,12 @@ pub trait TransparentWrapperAlloc: TransparentWrapper { // 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); @@ -367,7 +368,7 @@ pub trait TransparentWrapperAlloc: TransparentWrapper { fn peel_vec(s: Vec) -> Vec where Self: Sized, - Inner: Sized + Inner: Sized, { let mut s = core::mem::ManuallyDrop::new(s); @@ -380,11 +381,7 @@ pub trait TransparentWrapperAlloc: TransparentWrapper { // * 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) } } @@ -399,12 +396,12 @@ pub trait TransparentWrapperAlloc: TransparentWrapper { // 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); diff --git a/src/anybitpattern.rs b/src/anybitpattern.rs index 5e1fb88..3a55e62 100644 --- a/src/anybitpattern.rs +++ b/src/anybitpattern.rs @@ -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 AnyBitPattern for T {} diff --git a/src/checked.rs b/src/checked.rs index 6ac36c8..112abf0 100644 --- a/src/checked.rs +++ b/src/checked.rs @@ -1,32 +1,40 @@ //! Checked versions of the casting functions exposed in crate root //! that support [`CheckedBitPattern`] types. -use crate::{internal::{self, something_went_wrong}, NoUninit, AnyBitPattern}; +use crate::{ + internal::{self, something_went_wrong}, + AnyBitPattern, NoUninit, +}; -/// A marker trait that allows types that have some invalid bit patterns to be used -/// in places that otherwise require [`AnyBitPattern`] or [`Pod`] types by performing -/// a runtime check on a perticular set of bits. This is particularly -/// useful for types like fieldless ('C-style') enums, [`char`], bool, and structs containing them. +/// A marker trait that allows types that have some invalid bit patterns to be +/// used in places that otherwise require [`AnyBitPattern`] or [`Pod`] types by +/// performing a runtime check on a perticular set of bits. This is particularly +/// useful for types like fieldless ('C-style') enums, [`char`], bool, and +/// structs containing them. /// /// To do this, we define a `Bits` type which is a type with equivalent layout /// to `Self` other than the invalid bit patterns which disallow `Self` from -/// being [`AnyBitPattern`]. This `Bits` type must itself implement [`AnyBitPattern`]. -/// Then, we implement a function that checks wheter a certain instance -/// of the `Bits` is also a valid bit pattern of `Self`. If this check passes, then we -/// can allow casting from the `Bits` to `Self` (and therefore, any type which -/// is able to be cast to `Bits` is also able to be cast to `Self`). +/// being [`AnyBitPattern`]. This `Bits` type must itself implement +/// [`AnyBitPattern`]. Then, we implement a function that checks wheter a +/// certain instance of the `Bits` is also a valid bit pattern of `Self`. If +/// this check passes, then we can allow casting from the `Bits` to `Self` (and +/// therefore, any type which is able to be cast to `Bits` is also able to be +/// cast to `Self`). /// -/// [`AnyBitPattern`] is a subset of [`CheckedBitPattern`], meaning that any `T: AnyBitPattern` is also -/// [`CheckedBitPattern`]. This means you can also use any [`AnyBitPattern`] type in the checked versions -/// of casting functions in this module. If it's possible, prefer implementing [`AnyBitPattern`] for your -/// type directly instead of [`CheckedBitPattern`] as it gives greater flexibility. +/// [`AnyBitPattern`] is a subset of [`CheckedBitPattern`], meaning that any `T: +/// AnyBitPattern` is also [`CheckedBitPattern`]. This means you can also use +/// any [`AnyBitPattern`] type in the checked versions of casting functions in +/// this module. If it's possible, prefer implementing [`AnyBitPattern`] for +/// your type directly instead of [`CheckedBitPattern`] as it gives greater +/// flexibility. /// /// # Derive /// -/// A `#[derive(CheckedBitPattern)]` 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 enums and structs. This is the recommended method for -/// implementing the trait, however it's also possible to do manually. +/// A `#[derive(CheckedBitPattern)]` 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 enums and structs. This is +/// the recommended method for implementing the trait, however it's also +/// possible to do manually. /// /// # Example /// @@ -53,7 +61,7 @@ use crate::{internal::{self, something_went_wrong}, NoUninit, AnyBitPattern}; /// } /// } /// } -/// +/// /// // It is often useful to also implement `NoUninit` on our `CheckedBitPattern` types. /// // This will allow us to do casting of mutable references (and mutable slices). /// // It is not always possible to do so, but in this case we have no padding so it is. @@ -92,7 +100,7 @@ use crate::{internal::{self, something_went_wrong}, NoUninit, AnyBitPattern}; /// let bytes = bytes_of(&100u32); /// let result = checked::try_from_bytes::(bytes); /// assert!(result.is_err()); -/// +/// /// // Since we implemented NoUninit, we can also cast mutably from an original type /// // that is `NoUninit + AnyBitPattern`: /// let mut my_u32 = 2u32; @@ -107,25 +115,28 @@ use crate::{internal::{self, something_went_wrong}, NoUninit, AnyBitPattern}; /// # Safety /// /// * `Self` *must* have the same layout as the specified `Bits` except for -/// the possible invalid bit patterns being checked during [`is_valid_bit_pattern`]. +/// the possible invalid bit patterns being checked during +/// [`is_valid_bit_pattern`]. /// * This almost certainly means your type must be `#[repr(C)]` or a similar -/// specified repr, but if you think you know better, you probably don't. If you -/// still think you know better, be careful and have fun. And don't mess it up -/// (I mean it). -/// * If [`is_valid_bit_pattern`] returns true, then the bit pattern contained in -/// `bits` must also be valid for an instance of `Self`. +/// specified repr, but if you think you know better, you probably don't. If +/// you still think you know better, be careful and have fun. And don't mess +/// it up (I mean it). +/// * If [`is_valid_bit_pattern`] returns true, then the bit pattern contained +/// in `bits` must also be valid for an instance of `Self`. /// * Probably more, don't mess it up (I mean it 2.0) /// /// [`is_valid_bit_pattern`]: CheckedBitPattern::is_valid_bit_pattern /// [`Pod`]: crate::Pod pub unsafe trait CheckedBitPattern: Copy { /// `Self` *must* have the same layout as the specified `Bits` except for - /// the possible invalid bit patterns being checked during [`is_valid_bit_pattern`]. + /// the possible invalid bit patterns being checked during + /// [`is_valid_bit_pattern`]. /// /// [`is_valid_bit_pattern`]: CheckedBitPattern::is_valid_bit_pattern type Bits: AnyBitPattern; - /// If this function returns true, then it must be valid to reinterpret `bits` as `&Self`. + /// If this function returns true, then it must be valid to reinterpret `bits` + /// as `&Self`. fn is_valid_bit_pattern(bits: &Self::Bits) -> bool; } @@ -159,15 +170,16 @@ unsafe impl CheckedBitPattern for bool { } } -/// The things that can go wrong when casting between [`CheckedBitPattern`] data forms. +/// The things that can go wrong when casting between [`CheckedBitPattern`] data +/// forms. #[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] pub enum CheckedCastError { /// An error occurred during a true-[`Pod`] cast PodCastError(crate::PodCastError), - /// When casting to a [`CheckedBitPattern`] type, it is possible that the original - /// data contains an invalid bit pattern. If so, the cast will fail and - /// this error will be returned. Will never happen on casts between - /// [`Pod`] types. + /// When casting to a [`CheckedBitPattern`] type, it is possible that the + /// original data contains an invalid bit pattern. If so, the cast will + /// fail and this error will be returned. Will never happen on casts + /// between [`Pod`] types. InvalidBitPattern, } @@ -232,7 +244,9 @@ pub fn try_from_bytes_mut( /// * If the `bytes` length is not equal to `size_of::()`. /// * If the slice contains an invalid bit pattern for `T` #[inline] -pub fn try_pod_read_unaligned(bytes: &[u8]) -> Result { +pub fn try_pod_read_unaligned( + bytes: &[u8], +) -> Result { let pod = unsafe { internal::try_pod_read_unaligned(bytes) }?; if ::is_valid_bit_pattern(pod) { @@ -290,7 +304,10 @@ pub fn try_cast_ref( /// /// As [`checked_cast_ref`], but `mut`. #[inline] -pub fn try_cast_mut( +pub fn try_cast_mut< + A: NoUninit + AnyBitPattern, + B: CheckedBitPattern + NoUninit, +>( a: &mut A, ) -> Result<&mut B, CheckedCastError> { let pod = unsafe { internal::try_cast_mut(a) }?; @@ -317,7 +334,8 @@ pub fn try_cast_mut( a: &[A], @@ -338,7 +356,10 @@ pub fn try_cast_slice( /// /// As [`checked_cast_slice`], but `&mut`. #[inline] -pub fn try_cast_slice_mut( +pub fn try_cast_slice_mut< + A: NoUninit + AnyBitPattern, + B: CheckedBitPattern + NoUninit, +>( a: &mut [A], ) -> Result<&mut [B], CheckedCastError> { let pod = unsafe { internal::try_cast_slice_mut(a) }?; @@ -409,7 +430,12 @@ pub fn cast(a: A) -> B { /// /// This is [`try_cast_mut`] but will panic on error. #[inline] -pub fn cast_mut(a: &mut A) -> &mut B { +pub fn cast_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + CheckedBitPattern, +>( + a: &mut A, +) -> &mut B { match try_cast_mut(a) { Ok(t) => t, Err(e) => something_went_wrong("cast_mut", e), @@ -448,9 +474,14 @@ pub fn cast_slice(a: &[A]) -> &[B] { /// /// This is [`try_cast_slice_mut`] but will panic on error. #[inline] -pub fn cast_slice_mut(a: &mut [A]) -> &mut [B] { +pub fn cast_slice_mut< + A: NoUninit + AnyBitPattern, + B: NoUninit + CheckedBitPattern, +>( + a: &mut [A], +) -> &mut [B] { match try_cast_slice_mut(a) { Ok(t) => t, Err(e) => something_went_wrong("cast_slice_mut", e), } -} \ No newline at end of file +} diff --git a/src/internal.rs b/src/internal.rs index ab90be3..f5b85ca 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -1,7 +1,7 @@ //! Internal implementation of casting functions not bound by marker traits -//! and therefore marked as unsafe. This is used so that we don't need to duplicate -//! the business logic contained in these functions between the versions exported in -//! the crate root, `checked`, and `relaxed` modules. +//! and therefore marked as unsafe. This is used so that we don't need to +//! duplicate the business logic contained in these functions between the +//! versions exported in the crate root, `checked`, and `relaxed` modules. #![allow(unused_unsafe)] use crate::PodCastError; @@ -22,7 +22,9 @@ possibility code branch. /// Immediately panics. #[cold] #[inline(never)] -pub(crate) fn something_went_wrong(_src: &str, _err: D) -> ! { +pub(crate) fn something_went_wrong( + _src: &str, _err: D, +) -> ! { // Note(Lokathor): Keeping the panic here makes the panic _formatting_ go // here too, which helps assembly readability and also helps keep down // the inline pressure. @@ -100,7 +102,9 @@ pub(crate) unsafe fn from_bytes_mut(s: &mut [u8]) -> &mut T { /// ## Failure /// * If the `bytes` length is not equal to `size_of::()`. #[inline] -pub(crate) unsafe fn try_pod_read_unaligned(bytes: &[u8]) -> Result { +pub(crate) unsafe fn try_pod_read_unaligned( + bytes: &[u8], +) -> Result { if bytes.len() != size_of::() { Err(PodCastError::SizeMismatch) } else { diff --git a/src/no_uninit.rs b/src/no_uninit.rs index 620886d..5fda0c9 100644 --- a/src/no_uninit.rs +++ b/src/no_uninit.rs @@ -1,68 +1,62 @@ use crate::Pod; use core::num::{ - NonZeroU8, - NonZeroI8, - NonZeroU16, - NonZeroI16, - NonZeroU32, - NonZeroI32, - NonZeroU64, - NonZeroI64, - NonZeroU128, - NonZeroI128, - NonZeroUsize, - NonZeroIsize, + NonZeroI128, NonZeroI16, NonZeroI32, NonZeroI64, NonZeroI8, NonZeroIsize, + NonZeroU128, NonZeroU16, NonZeroU32, NonZeroU64, NonZeroU8, NonZeroUsize, }; /// Marker trait for "plain old data" types with no uninit (or padding) bytes. /// /// The requirements for this is very similar to [`Pod`], -/// except that it doesn't require that all bit patterns of the type are valid, i.e. -/// it does not require the type to be [`Zeroable`][crate::Zeroable]. +/// except that it doesn't require that all bit patterns of the type are valid, +/// i.e. it does not require the type to be [`Zeroable`][crate::Zeroable]. /// This limits what you can do with a type of this kind, but also broadens the /// included types to things like C-style enums. Notably, you can only cast from -/// *immutable* references to a [`NoUninit`] type into *immutable* references of any other -/// type, no casting of mutable references or mutable references to slices etc. +/// *immutable* references to a [`NoUninit`] type into *immutable* references of +/// any other type, no casting of mutable references or mutable references to +/// slices etc. /// /// [`Pod`] is a subset of [`NoUninit`], meaning that any `T: Pod` is also /// [`NoUninit`] but any `T: NoUninit` is not necessarily [`Pod`]. If possible, -/// prefer implementing [`Pod`] directly. To get more [`Pod`]-like functionality for -/// a type that is only [`NoUninit`], consider also implementing [`CheckedBitPattern`][crate::CheckedBitPattern]. +/// prefer implementing [`Pod`] directly. To get more [`Pod`]-like functionality +/// for a type that is only [`NoUninit`], consider also implementing +/// [`CheckedBitPattern`][crate::CheckedBitPattern]. /// /// # Derive /// -/// A `#[derive(NoUninit)]` 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 enums and structs. 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(NoUninit)]` 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 enums and structs. 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. /// /// # Safety /// /// The same as [`Pod`] except we disregard the rule about it must -/// allow any bit pattern (i.e. it does not need to be [`Zeroable`][crate::Zeroable]). -/// Still, this is a quite strong guarantee about a type, so *be careful* whem -/// implementing it manually. +/// allow any bit pattern (i.e. it does not need to be +/// [`Zeroable`][crate::Zeroable]). Still, this is a quite strong guarantee +/// about a type, so *be careful* whem implementing it manually. /// /// * The type must be inhabited (eg: no /// [Infallible](core::convert::Infallible)). -/// * The type must not contain any uninit (or padding) bytes, either in the middle or on -/// the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has padding in the -/// middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which has padding on -/// the end). +/// * The type must not contain any uninit (or padding) bytes, either in the +/// middle or on the end (eg: no `#[repr(C)] struct Foo(u8, u16)`, which has +/// padding in the middle, and also no `#[repr(C)] struct Foo(u16, u8)`, which +/// has padding on the end). /// * Structs need to have all fields also be `NoUninit`. /// * Structs need to be `repr(C)` or `repr(transparent)`. In the case of /// `repr(C)`, the `packed` and `align` repr modifiers can be used as long as /// all other rules end up being followed. /// * Enums need to have an explicit `#[repr(Int)]` /// * Enums must have only fieldless variants -/// * 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 NoUninit: Sized + Copy + 'static {} @@ -83,4 +77,4 @@ unsafe impl NoUninit for NonZeroI64 {} unsafe impl NoUninit for NonZeroU128 {} unsafe impl NoUninit for NonZeroI128 {} unsafe impl NoUninit for NonZeroUsize {} -unsafe impl NoUninit for NonZeroIsize {} \ No newline at end of file +unsafe impl NoUninit for NonZeroIsize {} diff --git a/tests/transparent.rs b/tests/transparent.rs index ad3435f..9bcbac8 100644 --- a/tests/transparent.rs +++ b/tests/transparent.rs @@ -21,11 +21,15 @@ fn test_transparent_wrapper() { unsafe impl bytemuck::Pod for Wrapper {} impl PartialEq for Foreign { - fn eq(&self, &other: &u8) -> bool { self.0 == other } + fn eq(&self, &other: &u8) -> bool { + self.0 == other + } } - + impl PartialEq for Wrapper { - fn eq(&self, &other: &u8) -> bool { self.0 == other } + fn eq(&self, &other: &u8) -> bool { + self.0 == other + } } let _: u8 = bytemuck::cast(Wrapper::wrap(Foreign::default())); @@ -75,7 +79,7 @@ fn test_transparent_wrapper() { use bytemuck::allocation::TransparentWrapperAlloc; let a: Vec = vec![Foreign::default(); 2]; - + let b: Vec = Wrapper::wrap_vec(a); assert_eq!(b, [0, 0]); @@ -83,7 +87,7 @@ fn test_transparent_wrapper() { assert_eq!(c, [0, 0]); let d: Box = Box::new(Foreign::default()); - + let e: Box = Wrapper::wrap_box(d); assert_eq!(&*e, &0); let f: Box = Wrapper::peel_box(e);