diff --git a/src/pointer/inner.rs b/src/pointer/inner.rs index 5287ccb944..2f8b94a680 100644 --- a/src/pointer/inner.rs +++ b/src/pointer/inner.rs @@ -6,7 +6,7 @@ // This file may not be copied, modified, or distributed except according to // those terms. -use core::{marker::PhantomData, ops::Range, ptr::NonNull}; +use core::{marker::PhantomData, mem, ops::Range, ptr::NonNull}; #[allow(unused_imports)] use crate::util::polyfills::NumExt as _; @@ -89,7 +89,9 @@ mod _def { /// Rust allocation, `A`. /// 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live /// for at least `'a`. - pub(crate) const unsafe fn new(ptr: NonNull) -> PtrInner<'a, T> { + #[inline(always)] + #[must_use] + pub const unsafe fn new(ptr: NonNull) -> PtrInner<'a, T> { // SAFETY: The caller has promised to satisfy all safety invariants // of `PtrInner`. Self { ptr, _marker: PhantomData } @@ -160,6 +162,39 @@ impl<'a, T: ?Sized> PtrInner<'a, T> { // single allocated object. unsafe { Self::new(ptr) } } + + #[must_use] + #[inline(always)] + pub fn cast_sized(self) -> PtrInner<'a, U> + where + T: Sized, + { + static_assert!(T, U => mem::size_of::() >= mem::size_of::()); + // SAFETY: By the preceding assert, `U` is no larger than `T`, which is + // the size of `self`'s referent. + unsafe { self.cast() } + } + + /// # Safety + /// + /// `U` must not be larger than the size of `self`'s referent. + #[must_use] + #[inline(always)] + pub unsafe fn cast(self) -> PtrInner<'a, U> { + let ptr = self.as_non_null().cast::(); + + // SAFETY: The caller promises that `U` is no larger than `self`'s + // referent. Thus, `ptr` addresses a subset of the bytes addressed by + // `self`. + // + // 0. By invariant on `self`, if `self`'s referent is not zero sized, + // then `self` has valid provenance for its referent, which is + // entirely contained in some Rust allocation, `A`. Thus, the same + // holds of `ptr`. + // 1. By invariant on `self`, if `self`'s referent is not zero sized, + // then `A` is guaranteed to live for at least `'a`. + unsafe { PtrInner::new(ptr) } + } } #[allow(clippy::needless_lifetimes)] @@ -216,6 +251,37 @@ where // zero sized, then `A` is guaranteed to live for at least `'a`. unsafe { PtrInner::new(raw) } } + + pub(crate) fn as_bytes(self) -> PtrInner<'a, [u8]> { + let ptr = self.as_non_null(); + let bytes = match T::size_of_val_raw(ptr) { + Some(bytes) => bytes, + // SAFETY: `KnownLayout::size_of_val_raw` promises to always + // return `Some` so long as the resulting size fits in a + // `usize`. By invariant on `PtrInner`, `self` refers to a range + // of bytes whose size fits in an `isize`, which implies that it + // also fits in a `usize`. + None => unsafe { core::hint::unreachable_unchecked() }, + }; + + let ptr = core::ptr::slice_from_raw_parts_mut(ptr.cast::().as_ptr(), bytes); + + // SAFETY: `ptr` has the same address as `ptr = self.as_non_null()`, + // which is non-null by construction. + let ptr = unsafe { NonNull::new_unchecked(ptr) }; + + // SAFETY: `ptr` points to `bytes` `u8`s starting at the same address as + // `self`'s referent. Since `bytes` is the length of `self`'s referent, + // `ptr` addresses the same byte range as `self`. Thus, by invariant on + // `self` (as a `PtrInner`): + // + // 0. If `ptr`'s referent is not zero sized, then `ptr` has valid + // provenance for its referent, which is entirely contained in some + // Rust allocation, `A`. + // 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live + // for at least `'a`. + unsafe { PtrInner::new(ptr) } + } } #[allow(clippy::needless_lifetimes)] diff --git a/src/pointer/ptr.rs b/src/pointer/ptr.rs index 375420f352..254d4f1c6f 100644 --- a/src/pointer/ptr.rs +++ b/src/pointer/ptr.rs @@ -9,7 +9,6 @@ use core::{ fmt::{Debug, Formatter}, marker::PhantomData, - ptr::NonNull, }; use crate::{ @@ -50,6 +49,7 @@ mod def { /// /// `Ptr<'a, T>` is [covariant] in `'a` and invariant in `T`. /// + /// [`NonNull`]: core::ptr::NonNull /// [covariant]: https://doc.rust-lang.org/reference/subtyping.html pub struct Ptr<'a, T, I> where @@ -74,32 +74,6 @@ mod def { T: 'a + ?Sized, I: Invariants, { - /// Constructs a `Ptr` from a [`NonNull`]. - /// - /// # Safety - /// - /// The caller promises that: - /// - /// 0. If `ptr`'s referent is not zero sized, then `ptr` has valid - /// provenance for its referent, which is entirely contained in some - /// Rust allocation, `A`. - /// 1. If `ptr`'s referent is not zero sized, `A` is guaranteed to live - /// for at least `'a`. - /// 2. `ptr` conforms to the aliasing invariant of - /// [`I::Aliasing`](invariant::Aliasing). - /// 3. `ptr` conforms to the alignment invariant of - /// [`I::Alignment`](invariant::Alignment). - /// 4. `ptr` conforms to the validity invariant of - /// [`I::Validity`](invariant::Validity). - pub(super) unsafe fn new(ptr: NonNull) -> Ptr<'a, T, I> { - // SAFETY: The caller has promised (in 0 - 1) to satisfy all safety - // invariants of `PtrInner::new`. - let ptr = unsafe { PtrInner::new(ptr) }; - // SAFETY: The caller has promised (in 2 - 4) to satisfy all safety - // invariants of `Ptr`. - Self { ptr, _invariants: PhantomData } - } - /// Constructs a new `Ptr` from a [`PtrInner`]. /// /// # Safety @@ -402,7 +376,7 @@ mod _conversions { // operate on these references simultaneously // - By `U: TransmuteFromPtr`, it is // sound to perform this transmute. - unsafe { self.transmute_unchecked(|ptr| SizeEq::cast_from_raw(ptr).as_non_null()) } + unsafe { self.transmute_unchecked(SizeEq::cast_from_raw) } } #[doc(hidden)] @@ -420,7 +394,7 @@ mod _conversions { // referent simultaneously // - By `T: TransmuteFromPtr`, it is // sound to perform this transmute. - let ptr = unsafe { self.transmute_unchecked(|t| t.as_non_null()) }; + let ptr = unsafe { self.transmute_unchecked(SizeEq::cast_from_raw) }; // SAFETY: `self` and `ptr` have the same address and referent type. // Therefore, if `self` satisfies `I::Alignment`, then so does // `ptr`. @@ -450,12 +424,6 @@ mod _conversions { /// `I::Aliasing`, `I::Validity`, and `V`, and may depend upon the /// presence, absence, or specific location of `UnsafeCell`s in `T` /// and/or `U`. See [`Validity`] for more details. - /// - /// `transmute_unchecked` guarantees that the pointer passed to `cast` - /// will reference a byte sequence which is either contained inside a - /// single allocated object or is zero sized. In either case, this means - /// that its size will fit in an `isize` and it will not wrap around the - /// address space. #[doc(hidden)] #[inline] pub unsafe fn transmute_unchecked( @@ -464,25 +432,18 @@ mod _conversions { ) -> Ptr<'a, U, (I::Aliasing, Unaligned, V)> where V: Validity, - F: FnOnce(PtrInner<'_, T>) -> NonNull, + F: FnOnce(PtrInner<'a, T>) -> PtrInner<'a, U>, { - // SAFETY: By invariant on `self`, `self.as_inner().as_non_null()` - // either references a zero-sized byte range, or else it references - // a byte range contained inside of a single allocated objection. let ptr = cast(self.as_inner()); // SAFETY: // - // Lemma 1: `ptr` has the same provenance as `self`. The caller - // promises that `cast` preserves provenance, and we call it with - // `self.as_inner().as_non_null()`. + // The following safety arguments rely on the fact that the caller + // promises that `cast` returns a `PtrInner` which addresses a + // prefix of the bytes of `*self`, and so properties that hold of + // `*self` also hold of `*ptr`. // - // 0. By invariant, if `self`'s referent is not zero sized, then - // `self` has valid provenance for its entire referent, which is - // entirely contained in `A`. By Lemma 1, so does `ptr`. - // 1. By invariant on `self`, if `self`'s referent is not zero - // sized, then `A` is guaranteed to live for at least `'a`. - // 2. `ptr` conforms to the aliasing invariant of `I::Aliasing`: + // 0. `ptr` conforms to the aliasing invariant of `I::Aliasing`: // - `Exclusive`: `self` is the only `Ptr` or reference which is // permitted to read or modify the referent for the lifetime // `'a`. Since we consume `self` by value, the returned pointer @@ -499,10 +460,10 @@ mod _conversions { // of `UnsafeCell`s is unsound, this must be impossible using // `&T` and `&U`. // - `Inaccessible`: There are no restrictions we need to uphold. - // 3. `ptr` trivially satisfies the alignment invariant `Unaligned`. - // 4. The caller promises that `ptr` conforms to the validity + // 1. `ptr` trivially satisfies the alignment invariant `Unaligned`. + // 2. The caller promises that `ptr` conforms to the validity // invariant `V` with respect to its referent type, `U`. - unsafe { Ptr::new(ptr) } + unsafe { Ptr::from_inner(ptr) } } } @@ -533,10 +494,7 @@ mod _conversions { // and the returned `Ptr` permit the same set of bit patterns in // their referents, and so neither can be used to violate the // validity of the other. - let ptr = unsafe { - #[allow(clippy::as_conversions)] - self.transmute_unchecked(|ptr| ptr.as_non_null().cast::>()) - }; + let ptr = unsafe { self.transmute_unchecked(PtrInner::cast_sized) }; ptr.bikeshed_recall_aligned() } } @@ -911,7 +869,7 @@ mod _casts { /// around the address space. #[doc(hidden)] #[inline] - pub unsafe fn cast_unsized_unchecked) -> NonNull>( + pub unsafe fn cast_unsized_unchecked) -> PtrInner<'a, U>>( self, cast: F, ) -> Ptr<'a, U, (I::Aliasing, Unaligned, I::Validity)> @@ -959,7 +917,7 @@ mod _casts { where T: MutationCompatible, U: 'a + ?Sized + CastableFrom, - F: FnOnce(PtrInner<'_, T>) -> NonNull, + F: FnOnce(PtrInner<'a, T>) -> PtrInner<'a, U>, { // SAFETY: Because `T: MutationCompatible`, one // of the following holds: @@ -982,40 +940,18 @@ mod _casts { { /// Casts this pointer-to-initialized into a pointer-to-bytes. #[allow(clippy::wrong_self_convention)] - pub(crate) fn as_bytes(self) -> Ptr<'a, [u8], (I::Aliasing, Aligned, Valid)> + #[must_use] + #[inline] + pub fn as_bytes(self) -> Ptr<'a, [u8], (I::Aliasing, Aligned, Valid)> where T: Read, I::Aliasing: Reference, { - let bytes = match T::size_of_val_raw(self.as_inner().as_non_null()) { - Some(bytes) => bytes, - // SAFETY: `KnownLayout::size_of_val_raw` promises to always - // return `Some` so long as the resulting size fits in a - // `usize`. By invariant on `Ptr`, `self` refers to a range of - // bytes whose size fits in an `isize`, which implies that it - // also fits in a `usize`. - None => unsafe { core::hint::unreachable_unchecked() }, - }; - - // SAFETY: - // - `slice_from_raw_parts_mut` and `.cast` both preserve the - // pointer's address, and `bytes` is the length of `p`, so the - // returned pointer addresses the same bytes as `p` - // - `slice_from_raw_parts_mut` and `.cast` both preserve provenance - let ptr: Ptr<'a, [u8], _> = unsafe { - self.cast_unsized(|p: PtrInner<'_, T>| { - let ptr = core::ptr::slice_from_raw_parts_mut( - p.as_non_null().cast::().as_ptr(), - bytes, - ); - // SAFETY: `ptr` has the same address as `p`, which is - // non-null. - core::ptr::NonNull::new_unchecked(ptr) - }) - }; - - let ptr = ptr.bikeshed_recall_aligned(); - ptr.recall_validity::<_, (_, (_, _))>() + // SAFETY: `PtrInner::as_bytes` returns a pointer which addresses + // the same byte range as its argument, and which has the same + // provenance. + let ptr = unsafe { self.cast_unsized(PtrInner::as_bytes) }; + ptr.bikeshed_recall_aligned().recall_validity::() } } @@ -1234,7 +1170,7 @@ mod _casts { // inner type `T`. A consequence of this guarantee is that it is // possible to convert between `T` and `UnsafeCell`. #[allow(clippy::as_conversions)] - let ptr = unsafe { self.transmute_unchecked(|ptr| cast!(ptr).as_non_null()) }; + let ptr = unsafe { self.transmute_unchecked(|ptr| cast!(ptr)) }; // SAFETY: `UnsafeCell` has the same alignment as `T` [1], // and so if `self` is guaranteed to be aligned, then so is the diff --git a/src/util/macro_util.rs b/src/util/macro_util.rs index 4e331062fc..affa65c044 100644 --- a/src/util/macro_util.rs +++ b/src/util/macro_util.rs @@ -516,8 +516,7 @@ where // because we assert above that the size of `Dst` equal to the size of // `Src`. // - `p as *mut Dst` is a provenance-preserving cast - #[allow(clippy::as_conversions)] - let c_ptr = unsafe { src.cast_unsized(|ptr| ptr.as_non_null().cast::()) }; + let c_ptr = unsafe { src.cast_unsized(|p| cast!(p)) }; match c_ptr.try_into_valid() { Ok(ptr) => Ok(ptr), @@ -530,8 +529,7 @@ where // `ptr`, because we assert above that the size of `Dst` is equal // to the size of `Src`. // - `p as *mut Src` is a provenance-preserving cast - #[allow(clippy::as_conversions)] - let ptr = unsafe { ptr.cast_unsized(|ptr| ptr.as_non_null().cast::()) }; + let ptr = unsafe { ptr.cast_unsized(|p| cast!(p)) }; // SAFETY: `ptr` is `src`, and has the same alignment invariant. let ptr = unsafe { ptr.assume_alignment::() }; // SAFETY: `ptr` is `src` and has the same validity invariant. @@ -586,7 +584,7 @@ where // ABI as `T` let ptr: Ptr<'_, Dst, _> = unsafe { ptr.cast_unsized(|ptr: crate::pointer::PtrInner<'_, mem::MaybeUninit>| { - ptr.as_non_null().cast() + ptr.cast_sized() }) }; diff --git a/src/util/macros.rs b/src/util/macros.rs index 78a4ebf2ac..35211bdb74 100644 --- a/src/util/macros.rs +++ b/src/util/macros.rs @@ -677,22 +677,21 @@ macro_rules! static_assert_dst_is_not_zst { }} } +/// # Safety +/// +/// The caller must ensure that the cast does not grow the size of the referent. +/// Preserving or shrinking the size of the referent are both acceptable. macro_rules! cast { - () => { - |p| { - // SAFETY: `NonNull::as_ptr` returns a non-null pointer, so the - // argument to `NonNull::new_unchecked` is also non-null. - #[allow(clippy::as_conversions, unused_unsafe)] - #[allow(clippy::undocumented_unsafe_blocks)] // Clippy false positive - return unsafe { - core::ptr::NonNull::new_unchecked(core::ptr::NonNull::as_ptr(p) as *mut _) - }; - } - }; ($p:expr) => {{ let ptr: crate::pointer::PtrInner<'_, _> = $p; let ptr = ptr.as_non_null(); - let ptr = cast!()(ptr); + let ptr = ptr.as_ptr(); + #[allow(clippy::as_conversions)] + let ptr = ptr as *mut _; + #[allow(unused_unsafe)] + // SAFETY: `NonNull::as_ptr` returns a non-null pointer, so the argument + // to `NonNull::new_unchecked` is also non-null. + let ptr = unsafe { core::ptr::NonNull::new_unchecked(ptr) }; // SAFETY: The caller promises that the cast preserves or shrinks // referent size. By invariant on `$p: PtrInner` (guaranteed by type // annotation above), `$p` refers to a byte range entirely contained diff --git a/zerocopy-derive/src/enum.rs b/zerocopy-derive/src/enum.rs index cc3a30c17a..50e632d383 100644 --- a/zerocopy-derive/src/enum.rs +++ b/zerocopy-derive/src/enum.rs @@ -264,7 +264,7 @@ pub(crate) fn derive_is_bit_valid( let variant = unsafe { variants.cast_unsized_unchecked( |p: #zerocopy_crate::pointer::PtrInner<'_, ___ZerocopyVariants #ty_generics>| { - p.as_non_null().cast::<#variant_struct_ident #ty_generics>() + p.cast_sized::<#variant_struct_ident #ty_generics>() } ) }; @@ -325,7 +325,7 @@ pub(crate) fn derive_is_bit_valid( // primitive integer. let tag_ptr = unsafe { candidate.reborrow().cast_unsized_unchecked(|p: #zerocopy_crate::pointer::PtrInner<'_, Self>| { - p.as_non_null().cast::<___ZerocopyTagPrimitive>() + p.cast_sized::<___ZerocopyTagPrimitive>() }) }; // SAFETY: `tag_ptr` is casted from `candidate`, whose referent @@ -347,7 +347,7 @@ pub(crate) fn derive_is_bit_valid( // `UnsafeCell`s. let raw_enum = unsafe { candidate.cast_unsized_unchecked(|p: #zerocopy_crate::pointer::PtrInner<'_, Self>| { - p.as_non_null().cast::<___ZerocopyRawEnum #ty_generics>() + p.cast_sized::<___ZerocopyRawEnum #ty_generics>() }) }; // SAFETY: `cast_unsized_unchecked` removes the initialization @@ -364,13 +364,15 @@ pub(crate) fn derive_is_bit_valid( // subfield pointer just points to a smaller portion of the // overall struct. let variants = unsafe { - raw_enum.cast_unsized_unchecked( |p: #zerocopy_crate::pointer::PtrInner<'_, ___ZerocopyRawEnum #ty_generics>| { + use #zerocopy_crate::pointer::PtrInner; + raw_enum.cast_unsized_unchecked(|p: PtrInner<'_, ___ZerocopyRawEnum #ty_generics>| { let p = p.as_non_null().as_ptr(); let ptr = core_reexport::ptr::addr_of_mut!((*p).variants); // SAFETY: `ptr` is a projection into `p`, which is // `NonNull`, and guaranteed not to wrap around the address // space. Thus, `ptr` cannot be null. - unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) }; + unsafe { PtrInner::new(ptr) } }) }; diff --git a/zerocopy-derive/src/lib.rs b/zerocopy-derive/src/lib.rs index c32af9135f..51c760b05f 100644 --- a/zerocopy-derive/src/lib.rs +++ b/zerocopy-derive/src/lib.rs @@ -758,6 +758,7 @@ fn derive_try_from_bytes_struct( ___ZerocopyAliasing: #zerocopy_crate::pointer::invariant::Reference, { use #zerocopy_crate::util::macro_util::core_reexport; + use #zerocopy_crate::pointer::PtrInner; true #(&& { // SAFETY: @@ -768,7 +769,7 @@ fn derive_try_from_bytes_struct( // the same byte ranges in the returned pointer's referent // as they do in `*slf` let field_candidate = unsafe { - let project = |slf: #zerocopy_crate::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).#field_names); // SAFETY: `cast_unsized_unchecked` promises that @@ -778,7 +779,18 @@ fn derive_try_from_bytes_struct( // object. In either case, this guarantees that // field projection will not wrap around the address // space, and so `field` will be non-null. - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + // SAFETY: + // 0. `ptr` addresses a subset of the bytes of + // `slf`, so by invariant on `slf: PtrInner`, + // if `ptr`'s referent is not zero sized, + // then `ptr` has valid provenance for its + // referent, which is entirely contained in + // some Rust allocation, `A`. + // 1. By invariant on `slf: PtrInner`, if + // `ptr`'s referent is not zero sized, `A` is + // guaranteed to live for at least `'a`. + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) @@ -829,6 +841,7 @@ fn derive_try_from_bytes_union( ___ZerocopyAliasing: #zerocopy_crate::pointer::invariant::Reference, { use #zerocopy_crate::util::macro_util::core_reexport; + use #zerocopy_crate::pointer::PtrInner; false #(|| { // SAFETY: @@ -839,7 +852,7 @@ fn derive_try_from_bytes_union( // `self_type_trait_bounds`, neither `*slf` nor the // returned pointer's referent contain any `UnsafeCell`s let field_candidate = unsafe { - let project = |slf: #zerocopy_crate::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).#field_names); // SAFETY: `cast_unsized_unchecked` promises that @@ -849,7 +862,18 @@ fn derive_try_from_bytes_union( // object. In either case, this guarantees that // field projection will not wrap around the address // space, and so `field` will be non-null. - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + // SAFETY: + // 0. `ptr` addresses a subset of the bytes of + // `slf`, so by invariant on `slf: PtrInner`, + // if `ptr`'s referent is not zero sized, + // then `ptr` has valid provenance for its + // referent, which is entirely contained in + // some Rust allocation, `A`. + // 1. By invariant on `slf: PtrInner`, if + // `ptr`'s referent is not zero sized, `A` is + // guaranteed to live for at least `'a`. + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) diff --git a/zerocopy-derive/src/output_tests.rs b/zerocopy-derive/src/output_tests.rs index acb9f90f86..eb991c5b23 100644 --- a/zerocopy-derive/src/output_tests.rs +++ b/zerocopy-derive/src/output_tests.rs @@ -304,6 +304,7 @@ fn test_try_from_bytes() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true } } @@ -329,6 +330,7 @@ fn test_from_zeros() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true } } @@ -536,6 +538,7 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + #[repr(u8)] #[allow(dead_code, non_camel_case_types)] enum ___ZerocopyTag { @@ -593,13 +596,15 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).0); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -608,60 +613,66 @@ fn test_try_from_bytes_enum() { > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).1); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).2); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).3); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).4); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).5); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).6); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -703,13 +714,15 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).0); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -718,30 +731,33 @@ fn test_try_from_bytes_enum() { > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).1); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).2); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).3); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -750,10 +766,11 @@ fn test_try_from_bytes_enum() { ) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).4); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -779,20 +796,22 @@ fn test_try_from_bytes_enum() { } let tag = { let tag_ptr = unsafe { - candidate.reborrow().cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.as_non_null().cast::<___ZerocopyTagPrimitive>() }) + candidate.reborrow().cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.cast_sized::<___ZerocopyTagPrimitive>() }) }; let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.recall_validity::<_, (_, (_, _))>().read_unaligned::<::zerocopy::BecauseImmutable>() }; let raw_enum = unsafe { - candidate.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.as_non_null().cast::<___ZerocopyRawEnum<'a, N, X, Y>>() }) + candidate.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.cast_sized::<___ZerocopyRawEnum<'a, N, X, Y>>() }) }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { - raw_enum.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyRawEnum<'a, N, X, Y>>| { + use ::zerocopy::pointer::PtrInner; + raw_enum.cast_unsized_unchecked(|p: PtrInner<'_, ___ZerocopyRawEnum<'a, N, X, Y>>| { let p = p.as_non_null().as_ptr(); let ptr = core_reexport::ptr::addr_of_mut!((*p).variants); - unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) }; + unsafe { PtrInner::new(ptr) } }) }; #[allow(non_upper_case_globals)] @@ -801,7 +820,7 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_StructLike => { let variant = unsafe { variants.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyVariants<'a, N, X, Y>>| { - p.as_non_null().cast::<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>() + p.cast_sized::<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>() }) }; let variant = unsafe { variant.assume_initialized() }; @@ -811,7 +830,7 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_TupleLike => { let variant = unsafe { variants.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyVariants<'a, N, X, Y>>| { - p.as_non_null().cast::<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>() + p.cast_sized::<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>() }) }; let variant = unsafe { variant.assume_initialized() }; @@ -860,6 +879,7 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + #[repr(u32)] #[allow(dead_code, non_camel_case_types)] enum ___ZerocopyTag { @@ -917,13 +937,15 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).0); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -932,60 +954,66 @@ fn test_try_from_bytes_enum() { > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).1); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).2); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).3); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).4); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).5); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).6); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1027,13 +1055,15 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).0); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1042,30 +1072,33 @@ fn test_try_from_bytes_enum() { > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).1); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).2); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).3); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1074,10 +1107,11 @@ fn test_try_from_bytes_enum() { ) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).4); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1103,20 +1137,22 @@ fn test_try_from_bytes_enum() { } let tag = { let tag_ptr = unsafe { - candidate.reborrow().cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.as_non_null().cast::<___ZerocopyTagPrimitive> ()}) + candidate.reborrow().cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.cast_sized::<___ZerocopyTagPrimitive> ()}) }; let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.recall_validity::<_, (_, (_, _))>().read_unaligned::<::zerocopy::BecauseImmutable>() }; let raw_enum = unsafe { - candidate.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.as_non_null().cast::<___ZerocopyRawEnum<'a, N, X, Y>> ()}) + candidate.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.cast_sized::<___ZerocopyRawEnum<'a, N, X, Y>> ()}) }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { - raw_enum.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyRawEnum<'a, N, X, Y>>| { + use ::zerocopy::pointer::PtrInner; + raw_enum.cast_unsized_unchecked(|p: PtrInner<'_, ___ZerocopyRawEnum<'a, N, X, Y>>| { let p = p.as_non_null().as_ptr(); let ptr = core_reexport::ptr::addr_of_mut!((*p).variants); - unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) }; + unsafe { PtrInner::new(ptr) } }) }; #[allow(non_upper_case_globals)] @@ -1125,7 +1161,7 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_StructLike => { let variant = unsafe { variants.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyVariants<'a, N, X, Y>>| { - p.as_non_null().cast::<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>() + p.cast_sized::<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>() }) }; let variant = unsafe { variant.assume_initialized() }; @@ -1135,7 +1171,7 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_TupleLike => { let variant = unsafe { variants.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyVariants<'a, N, X, Y>>| { - p.as_non_null().cast::<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>() + p.cast_sized::<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>() }) }; let variant = unsafe { variant.assume_initialized() }; @@ -1184,6 +1220,7 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + #[repr(C)] #[allow(dead_code, non_camel_case_types)] enum ___ZerocopyTag { @@ -1241,13 +1278,15 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).0); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1256,60 +1295,66 @@ fn test_try_from_bytes_enum() { > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).1); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).2); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).3); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).4); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).5); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).6); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1351,13 +1396,15 @@ fn test_try_from_bytes_enum() { ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; + use ::zerocopy::pointer::PtrInner; true && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).0); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1366,30 +1413,33 @@ fn test_try_from_bytes_enum() { > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).1); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).2); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).3); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1398,10 +1448,11 @@ fn test_try_from_bytes_enum() { ) } && { let field_candidate = unsafe { - let project = |slf: ::zerocopy::pointer::PtrInner<'_, Self>| { + let project = |slf: PtrInner<'_, Self>| { let slf = slf.as_non_null().as_ptr(); let field = core_reexport::ptr::addr_of_mut!((*slf).4); - unsafe { core_reexport::ptr::NonNull::new_unchecked(field) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(field) }; + unsafe { PtrInner::new(ptr) } }; candidate.reborrow().cast_unsized_unchecked(project) }; @@ -1427,20 +1478,22 @@ fn test_try_from_bytes_enum() { } let tag = { let tag_ptr = unsafe { - candidate.reborrow().cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.as_non_null().cast::<___ZerocopyTagPrimitive> ()}) + candidate.reborrow().cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.cast_sized::<___ZerocopyTagPrimitive> ()}) }; let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.recall_validity::<_, (_, (_, _))>().read_unaligned::<::zerocopy::BecauseImmutable>() }; let raw_enum = unsafe { - candidate.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.as_non_null().cast::<___ZerocopyRawEnum<'a, N, X, Y>> ()}) + candidate.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, Self>| { p.cast_sized::<___ZerocopyRawEnum<'a, N, X, Y>> ()}) }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { - raw_enum.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyRawEnum<'a, N, X, Y>>| { + use ::zerocopy::pointer::PtrInner; + raw_enum.cast_unsized_unchecked(|p: PtrInner<'_, ___ZerocopyRawEnum<'a, N, X, Y>>| { let p = p.as_non_null().as_ptr(); let ptr = core_reexport::ptr::addr_of_mut!((*p).variants); - unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) } + let ptr = unsafe { core_reexport::ptr::NonNull::new_unchecked(ptr) }; + unsafe { PtrInner::new(ptr) } }) }; #[allow(non_upper_case_globals)] @@ -1449,7 +1502,7 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_StructLike => { let variant = unsafe { variants.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyVariants<'a, N, X, Y>>| { - p.as_non_null().cast::<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>() + p.cast_sized::<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>() }) }; let variant = unsafe { variant.assume_initialized() }; @@ -1459,7 +1512,7 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_TupleLike => { let variant = unsafe { variants.cast_unsized_unchecked(|p: ::zerocopy::pointer::PtrInner<'_, ___ZerocopyVariants<'a, N, X, Y>>| { - p.as_non_null().cast::<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>() + p.cast_sized::<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>() }) }; let variant = unsafe { variant.assume_initialized() }; diff --git a/zerocopy-derive/tests/include.rs b/zerocopy-derive/tests/include.rs index d5c3de52ff..01a370c322 100644 --- a/zerocopy-derive/tests/include.rs +++ b/zerocopy-derive/tests/include.rs @@ -123,7 +123,7 @@ pub mod util { // SAFETY: `T` and `MaybeUninit` have the same layout, so this is a // size-preserving cast. It is also a provenance-preserving cast. - let ptr = unsafe { ptr.cast_unsized_unchecked(|p| p.as_non_null().cast()) }; + let ptr = unsafe { ptr.cast_unsized_unchecked(|p| p.cast_sized()) }; assert!(::is_bit_valid(ptr)); } } diff --git a/zerocopy-derive/tests/struct_try_from_bytes.rs b/zerocopy-derive/tests/struct_try_from_bytes.rs index 57d1727d4f..2224d38bc5 100644 --- a/zerocopy-derive/tests/struct_try_from_bytes.rs +++ b/zerocopy-derive/tests/struct_try_from_bytes.rs @@ -78,7 +78,7 @@ fn two_bad() { // the same bytes as `c`. // - The cast preserves provenance. // - Neither the input nor output types contain any `UnsafeCell`s. - let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.as_non_null().cast::()) }; + let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.cast::()) }; // SAFETY: `candidate`'s referent is as-initialized as `Two`. let candidate = unsafe { candidate.assume_initialized() }; @@ -110,7 +110,9 @@ fn un_sized() { // - Neither the input nor output types contain any `UnsafeCell`s. let candidate = unsafe { candidate.cast_unsized_unchecked(|p| { - imp::core::ptr::NonNull::new_unchecked(p.as_non_null().as_ptr() as *mut Unsized) + let ptr = + imp::core::ptr::NonNull::new_unchecked(p.as_non_null().as_ptr() as *mut Unsized); + ::zerocopy::pointer::PtrInner::new(ptr) }) }; @@ -168,9 +170,8 @@ fn test_maybe_from_bytes() { // the same bytes as `c`. // - The cast preserves provenance. // - Neither the input nor output types contain any `UnsafeCell`s. - let candidate = unsafe { - candidate.cast_unsized_unchecked(|p| p.as_non_null().cast::>()) - }; + let candidate = + unsafe { candidate.cast_unsized_unchecked(|p| p.cast::>()) }; // SAFETY: `[u8]` consists entirely of initialized bytes. let candidate = unsafe { candidate.assume_initialized() }; diff --git a/zerocopy-derive/tests/union_try_from_bytes.rs b/zerocopy-derive/tests/union_try_from_bytes.rs index 044e1e3fd5..80bae235ba 100644 --- a/zerocopy-derive/tests/union_try_from_bytes.rs +++ b/zerocopy-derive/tests/union_try_from_bytes.rs @@ -73,7 +73,7 @@ fn two_bad() { // the same bytes as `c`. // - The cast preserves provenance. // - Neither the input nor output types contain any `UnsafeCell`s. - let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.as_non_null().cast::()) }; + let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.cast::()) }; // SAFETY: `candidate`'s referent is as-initialized as `Two`. let candidate = unsafe { candidate.assume_initialized() }; @@ -102,8 +102,7 @@ fn bool_and_zst() { // the same bytes as `c`. // - The cast preserves provenance. // - Neither the input nor output types contain any `UnsafeCell`s. - let candidate = - unsafe { candidate.cast_unsized_unchecked(|p| p.as_non_null().cast::()) }; + let candidate = unsafe { candidate.cast_unsized_unchecked(|p| p.cast::()) }; // SAFETY: `candidate`'s referent is fully initialized. let candidate = unsafe { candidate.assume_initialized() }; @@ -132,9 +131,8 @@ fn test_maybe_from_bytes() { // the same bytes as `c`. // - The cast preserves provenance. // - Neither the input nor output types contain any `UnsafeCell`s. - let candidate = unsafe { - candidate.cast_unsized_unchecked(|p| p.as_non_null().cast::>()) - }; + let candidate = + unsafe { candidate.cast_unsized_unchecked(|p| p.cast::>()) }; // SAFETY: `[u8]` consists entirely of initialized bytes. let candidate = unsafe { candidate.assume_initialized() };