diff --git a/src/lib.rs b/src/lib.rs index f5bf22770d..68678c378c 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1022,7 +1022,9 @@ pub unsafe trait TryFromBytes { /// [`UnsafeCell`]: core::cell::UnsafeCell /// [`Shared`]: invariant::Shared #[doc(hidden)] - fn is_bit_valid(candidate: Maybe<'_, Self, A>) -> bool; + fn is_bit_valid>( + candidate: Maybe<'_, Self, A>, + ) -> bool; /// Attempts to interpret a byte slice as a `Self`. /// @@ -3768,7 +3770,9 @@ unsafe impl TryFromBytes for UnsafeCell { } #[inline] - fn is_bit_valid(candidate: Maybe<'_, Self, A>) -> bool { + fn is_bit_valid>( + candidate: Maybe<'_, Self, A>, + ) -> bool { // The only way to implement this function is using an exclusive-aliased // pointer. `UnsafeCell`s cannot be read via shared-aliased pointers // (other than by using `unsafe` code, which we can't use since we can't @@ -7954,7 +7958,10 @@ mod tests { pub(super) trait TestIsBitValidShared { #[allow(clippy::needless_lifetimes)] - fn test_is_bit_valid_shared<'ptr, A: invariant::at_least::Shared>( + fn test_is_bit_valid_shared< + 'ptr, + A: invariant::Aliasing + invariant::AtLeast, + >( &self, candidate: Maybe<'ptr, T, A>, ) -> Option; @@ -7962,7 +7969,10 @@ mod tests { impl TestIsBitValidShared for AutorefWrapper { #[allow(clippy::needless_lifetimes)] - fn test_is_bit_valid_shared<'ptr, A: invariant::at_least::Shared>( + fn test_is_bit_valid_shared< + 'ptr, + A: invariant::Aliasing + invariant::AtLeast, + >( &self, candidate: Maybe<'ptr, T, A>, ) -> Option { @@ -8066,7 +8076,7 @@ mod tests { #[allow(unused, non_local_definitions)] impl AutorefWrapper<$ty> { #[allow(clippy::needless_lifetimes)] - fn test_is_bit_valid_shared<'ptr, A: invariant::at_least::Shared>( + fn test_is_bit_valid_shared<'ptr, A: invariant::Aliasing + invariant::AtLeast>( &mut self, candidate: Maybe<'ptr, $ty, A>, ) -> Option { diff --git a/src/macros.rs b/src/macros.rs index 83fa618ca6..e844e3e55c 100644 --- a/src/macros.rs +++ b/src/macros.rs @@ -140,7 +140,7 @@ macro_rules! unsafe_impl { fn only_derive_is_allowed_to_implement_this_trait() {} #[inline] - fn is_bit_valid(candidate: Maybe<'_, Self, AA>) -> bool { + fn is_bit_valid>(candidate: Maybe<'_, Self, AA>) -> bool { // SAFETY: // - The argument to `cast_unsized` is `|p| p as *mut _` as required // by that method's safety precondition. @@ -162,7 +162,7 @@ macro_rules! unsafe_impl { fn only_derive_is_allowed_to_implement_this_trait() {} #[inline] - fn is_bit_valid(candidate: Maybe<'_, Self, AA>) -> bool { + fn is_bit_valid>(candidate: Maybe<'_, Self, AA>) -> bool { // SAFETY: // - The argument to `cast_unsized` is `|p| p as *mut _` as required // by that method's safety precondition. @@ -184,7 +184,7 @@ macro_rules! unsafe_impl { (@method TryFromBytes) => { #[allow(clippy::missing_inline_in_public_items)] fn only_derive_is_allowed_to_implement_this_trait() {} - #[inline(always)] fn is_bit_valid(_: Maybe<'_, Self, A>) -> bool { true } + #[inline(always)] fn is_bit_valid>(_: Maybe<'_, Self, A>) -> bool { true } }; (@method $trait:ident) => { #[allow(clippy::missing_inline_in_public_items)] @@ -357,7 +357,7 @@ macro_rules! impl_for_transparent_wrapper { // TryFromBytes)` macro arm for an explanation of why this is a sound // implementation of `is_bit_valid`. #[inline] - fn is_bit_valid(candidate: Maybe<'_, Self, A>) -> bool { + fn is_bit_valid>(candidate: Maybe<'_, Self, A>) -> bool { TryFromBytes::is_bit_valid(candidate.transparent_wrapper_into_inner()) } }; diff --git a/src/pointer/mod.rs b/src/pointer/mod.rs index 2d14f85ab3..94f0dd9ce1 100644 --- a/src/pointer/mod.rs +++ b/src/pointer/mod.rs @@ -33,7 +33,7 @@ pub type MaybeAligned<'a, T, Aliasing = invariant::Shared, Alignment = invariant impl<'a, T, Aliasing, Alignment> MaybeAligned<'a, T, Aliasing, Alignment> where T: 'a + ?Sized, - Aliasing: invariant::at_least::Shared, + Aliasing: invariant::Aliasing + invariant::AtLeast, Alignment: invariant::Alignment, { /// Reads the value from `MaybeAligned`. @@ -68,7 +68,7 @@ pub(crate) fn is_zeroed(ptr: Ptr<'_, T, I>) -> bool where T: crate::Immutable, I: invariant::Invariants, - I::Aliasing: invariant::at_least::Shared, + I::Aliasing: invariant::AtLeast, { ptr.as_bytes().as_ref().iter().all(|&byte| byte == 0) } diff --git a/src/pointer/ptr.rs b/src/pointer/ptr.rs index 080db0d904..f9b3e96b7c 100644 --- a/src/pointer/ptr.rs +++ b/src/pointer/ptr.rs @@ -112,22 +112,6 @@ mod def { Self { ptr, _invariants: PhantomData } } - /// Constructs a `Ptr` from another `Ptr`, possibly with different - /// parameterized safety invariants. - /// - /// # Safety - /// - /// The caller promises that `ptr` conforms to the invariants of `I`. - pub(super) unsafe fn from_ptr(ptr: Ptr<'a, T, H>) -> Self - where - H: Invariants, - { - // SAFETY: The caller has promised to satisfy all parameterized - // invariants of `Ptr`. `Ptr`'s other invariants are satisfied - // by-contract by the source `Ptr`. - unsafe { Self::new(ptr.as_non_null()) } - } - /// Converts this `Ptr` to a [`NonNull`]. /// /// Note that this method does not consume `self`. The caller should @@ -149,6 +133,13 @@ macro_rules! define_system { $( $(#[$elem_attr:meta])* $elem:ident $(< $($stronger_elem:ident)|*)?,)* })* }) => { + /// No requirement - any invariant is allowed. + #[allow(missing_copy_implementations, missing_debug_implementations)] + pub enum Any {} + + /// `Self` imposes a requirement at least as strict as `I`. + pub trait AtLeast {} + mod sealed { pub trait Sealed {} @@ -219,48 +210,21 @@ macro_rules! define_system { )* )* - /// Groupings of invariants at least as strict as the given invariant. - pub mod at_least { - $($( - // This `$()?` corresponds to `$(< $($stronger_elem:ident)|*)?` - // from the match rule. By having it wrap the entire block - // (instead of just the trailing, repeating impl block), we - // ensure that we don't define `at_least` traits that only have - // a trivial implementation (e.g., `at_least::Exclusive for - // Exclusive`, etc). - $( - #[doc = concat!( - "[", - stringify!($set), - "][super::", - stringify!($set), - "] at least as strict as [`", - stringify!($elem), - "`][super::", - stringify!($elem), - "]." - )] - pub trait $elem: super::$set {} - impl $elem for super::$elem {} - - $(impl $elem for super::$stronger_elem {})* - )? - )*)* - } + $($( + impl AtLeast for $elem {} + impl AtLeast<$elem> for $elem {} + + $($(impl AtLeast<$elem> for $stronger_elem {})*)? + )*)* }; } /// The parameterized invariants of a [`Ptr`]. /// -/// Invariants are encoded as ([`Aliasing`][invariant::Aliasing], -/// [`Alignment`][invariant::Alignment], [`Validity`][invariant::Validity]) +/// Invariants are encoded as ([`Aliasing`], [`Alignment`], [`Validity`]) /// triples implementing the [`Invariants`] trait. #[doc(hidden)] pub mod invariant { - /// No requirement - any invariant is allowed. - #[allow(missing_copy_implementations, missing_debug_implementations)] - pub enum Any {} - define_system! { /// The invariants of a [`Ptr`][super::Ptr]. Invariants { @@ -341,7 +305,7 @@ pub mod invariant { } } -pub(crate) use invariant::Invariants; +pub(crate) use invariant::*; /// External trait implementations on [`Ptr`]. mod _external { @@ -355,7 +319,8 @@ mod _external { impl<'a, T, I> Copy for Ptr<'a, T, I> where T: 'a + ?Sized, - I: Invariants, + I: Invariants, + Shared: AtLeast, { } @@ -366,7 +331,8 @@ mod _external { impl<'a, T, I> Clone for Ptr<'a, T, I> where T: 'a + ?Sized, - I: Invariants, + I: Invariants, + Shared: AtLeast, { #[inline] fn clone(&self) -> Self { @@ -392,7 +358,7 @@ mod _conversions { use crate::util::{AlignmentVariance, Covariant, TransparentWrapper, ValidityVariance}; /// `&'a T` → `Ptr<'a, T>` - impl<'a, T> Ptr<'a, T, (invariant::Shared, invariant::Aligned, invariant::Valid)> + impl<'a, T> Ptr<'a, T, (Shared, Aligned, Valid)> where T: 'a + ?Sized, { @@ -415,11 +381,11 @@ mod _conversions { // least `'a`. // 6. `T: 'a`. // 7. `ptr`, by invariant on `&'a T`, conforms to the aliasing - // invariant of `invariant::Shared`. + // invariant of `Shared`. // 8. `ptr`, by invariant on `&'a T`, conforms to the alignment - // invariant of `invariant::Aligned`. + // invariant of `Aligned`. // 9. `ptr`, by invariant on `&'a T`, conforms to the validity - // invariant of `invariant::Valid`. + // invariant of `Valid`. // 10. The referents of `Ptr` and `&T` have `UnsafeCell`s at // identical ranges. Both `Ptr` and `&T` prevent loads and // stores which treat other byte ranges as having `UnsafeCell`s. @@ -429,7 +395,7 @@ mod _conversions { } /// `&'a mut T` → `Ptr<'a, T>` - impl<'a, T> Ptr<'a, T, (invariant::Exclusive, invariant::Aligned, invariant::Valid)> + impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)> where T: 'a + ?Sized, { @@ -451,11 +417,11 @@ mod _conversions { // 5. `A`, by invariant on `&'a mut T`, is guaranteed to live for at // least `'a`. // 6. `ptr`, by invariant on `&'a mut T`, conforms to the aliasing - // invariant of `invariant::Exclusive`. + // invariant of `Exclusive`. // 7. `ptr`, by invariant on `&'a mut T`, conforms to the alignment - // invariant of `invariant::Aligned`. + // invariant of `Aligned`. // 8. `ptr`, by invariant on `&'a mut T`, conforms to the validity - // invariant of `invariant::Valid`. + // invariant of `Valid`. unsafe { Self::new(ptr) } } } @@ -464,10 +430,10 @@ mod _conversions { impl<'a, T, I> Ptr<'a, T, I> where T: 'a + ?Sized, - I: Invariants, - I::Aliasing: invariant::at_least::Shared, + I: Invariants, + I::Aliasing: AtLeast, { - /// Converts the `Ptr` to a shared reference. + /// Converts `self` to a shared reference. // This consumes `self`, not `&self`, because `self` is, logically, a // pointer. For `I::Aliasing = invariant::Shared`, `Self: Copy`, and so // this doesn't prevent the caller from still using the pointer after @@ -496,7 +462,7 @@ mod _conversions { // // 4. You must enforce Rust’s aliasing rules. This is ensured by // contract on `Ptr`, because the `I::Aliasing` is - // `at_least::Shared`. Either it is `Shared` or `Exclusive`. In + // `AtLeast`. Either it is `Shared` or `Exclusive`. In // both cases, other references may not mutate the referent // outside of `UnsafeCell`s. // @@ -510,9 +476,9 @@ mod _conversions { where T: 'a + ?Sized, I: Invariants, - I::Aliasing: invariant::at_least::Shared, + I::Aliasing: AtLeast, { - /// Reborrows this `Ptr`, producing another `Ptr`. + /// Reborrows `self`, producing another `Ptr`. /// /// Since `self` is borrowed immutably, this prevents any mutable /// methods from being called on `self` as long as the returned `Ptr` @@ -546,9 +512,8 @@ mod _conversions { // memory which treats `UnsafeCell`s as existing at different // ranges than they exist in `T`. // - // For aliasing (6 above), since `I::Aliasing: - // invariant::at_least::Shared`, there are two cases for - // `I::Aliasing`: + // For aliasing (6 above), since `I::Aliasing: AtLeast`, + // there are two cases for `I::Aliasing`: // - For `invariant::Shared`: `'a` outlives `'b`, and so the // returned `Ptr` does not permit accessing the referent any // longer than is possible via `self`. For shared aliasing, it is @@ -569,11 +534,11 @@ mod _conversions { } /// `Ptr<'a, T>` → `&'a mut T` - impl<'a, T> Ptr<'a, T, (invariant::Exclusive, invariant::Aligned, invariant::Valid)> + impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)> where T: 'a + ?Sized, { - /// Converts the `Ptr` to a mutable reference. + /// Converts `self` to a mutable reference. #[allow(clippy::wrong_self_convention)] pub(crate) fn as_mut(self) -> &'a mut T { let mut raw = self.as_non_null(); @@ -612,7 +577,7 @@ mod _conversions { T: 'a + TransparentWrapper + ?Sized, I: Invariants, { - /// Converts the `Ptr` to a transparent wrapper type into a `Ptr` to the + /// Converts `self` to a transparent wrapper type into a `Ptr` to the /// wrapped inner type. pub(crate) fn transparent_wrapper_into_inner( self, @@ -670,17 +635,15 @@ mod _transitions { #[inline] pub(crate) fn into_exclusive_or_post_monomorphization_error( self, - ) -> Ptr<'a, T, (invariant::Exclusive, I::Alignment, I::Validity)> { - trait AliasingExt: invariant::Aliasing { + ) -> Ptr<'a, T, (Exclusive, I::Alignment, I::Validity)> { + trait AliasingExt: Aliasing { const IS_EXCLUSIVE: bool; } - impl AliasingExt for A { + impl AliasingExt for A { const IS_EXCLUSIVE: bool = { - let is_exclusive = strs_are_equal( - ::NAME, - ::NAME, - ); + let is_exclusive = + strs_are_equal(::NAME, ::NAME); const_assert!(is_exclusive); true }; @@ -718,59 +681,71 @@ mod _transitions { unsafe { self.assume_exclusive() } } - /// Assumes that `Ptr` satisfies the aliasing requirement of `A`. + /// Assumes that `self` satisfies the invariants `H`. + /// + /// # Safety + /// + /// The caller promises that `self` satisfies the invariants `H`. + pub(super) unsafe fn assume_invariants(self) -> Ptr<'a, T, H> { + // SAFETY: The caller has promised to satisfy all parameterized + // invariants of `Ptr`. `Ptr`'s other invariants are satisfied + // by-contract by the source `Ptr`. + unsafe { Ptr::new(self.as_non_null()) } + } + + /// Assumes that `self` satisfies the aliasing requirement of `A`. /// /// # Safety /// - /// The caller promises that `Ptr` satisfies the aliasing requirement of - /// `A`. + /// The caller promises that `self` satisfies the aliasing requirement + /// of `A`. #[inline] - pub(crate) unsafe fn assume_aliasing( + pub(crate) unsafe fn assume_aliasing( self, ) -> Ptr<'a, T, (A, I::Alignment, I::Validity)> { // SAFETY: The caller promises that `self` satisfies the aliasing // requirements of `A`. - unsafe { Ptr::from_ptr(self) } + unsafe { self.assume_invariants() } } - /// Assumes that `Ptr` satisfies the aliasing requirement of [`Exclusive`]. + /// Assumes `self` satisfies the aliasing requirement of [`Exclusive`]. /// /// # Safety /// - /// The caller promises that `Ptr` satisfies the aliasing requirement of - /// `Exclusive`. + /// The caller promises that `self` satisfies the aliasing requirement + /// of `Exclusive`. /// /// [`Exclusive`]: invariant::Exclusive #[inline] pub(crate) unsafe fn assume_exclusive( self, - ) -> Ptr<'a, T, (invariant::Exclusive, I::Alignment, I::Validity)> { + ) -> Ptr<'a, T, (Exclusive, I::Alignment, I::Validity)> { // SAFETY: The caller promises that `self` satisfies the aliasing // requirements of `Exclusive`. - unsafe { self.assume_aliasing::() } + unsafe { self.assume_aliasing::() } } - /// Assumes that `Ptr`'s referent is validly-aligned for `T` if required - /// by `A`. + /// Assumes that `self`'s referent is validly-aligned for `T` if + /// required by `A`. /// /// # Safety /// - /// The caller promises that `Ptr`'s referent conforms to the alignment + /// The caller promises that `self`'s referent conforms to the alignment /// invariant of `T` if required by `A`. #[inline] - pub(crate) unsafe fn assume_alignment( + pub(crate) unsafe fn assume_alignment( self, ) -> Ptr<'a, T, (I::Aliasing, A, I::Validity)> { // SAFETY: The caller promises that `self`'s referent is // well-aligned for `T` if required by `A` . - unsafe { Ptr::from_ptr(self) } + unsafe { self.assume_invariants() } } - /// Checks the `Ptr`'s alignment at runtime, returning an aligned `Ptr` + /// Checks the `self`'s alignment at runtime, returning an aligned `Ptr` /// on success. pub(crate) fn bikeshed_try_into_aligned( self, - ) -> Option> + ) -> Option> where T: Sized, { @@ -779,40 +754,40 @@ mod _transitions { } // SAFETY: We just checked the alignment. - Some(unsafe { self.assume_alignment::() }) + Some(unsafe { self.assume_alignment::() }) } - /// Recalls that `Ptr`'s referent is validly-aligned for `T`. + /// Recalls that `self`'s referent is validly-aligned for `T`. #[inline] // TODO(#859): Reconsider the name of this method before making it // public. pub(crate) fn bikeshed_recall_aligned( self, - ) -> Ptr<'a, T, (I::Aliasing, invariant::Aligned, I::Validity)> + ) -> Ptr<'a, T, (I::Aliasing, Aligned, I::Validity)> where T: crate::Unaligned, { // SAFETY: The bound `T: Unaligned` ensures that `T` has no // non-trivial alignment requirement. - unsafe { self.assume_alignment::() } + unsafe { self.assume_alignment::() } } - /// Assumes that `Ptr`'s referent conforms to the validity requirement + /// Assumes that `self`'s referent conforms to the validity requirement /// of `V`. /// /// # Safety /// - /// The caller promises that `Ptr`'s referent conforms to the validity + /// The caller promises that `self`'s referent conforms to the validity /// requirement of `V`. #[doc(hidden)] #[must_use] #[inline] - pub unsafe fn assume_validity( + pub unsafe fn assume_validity( self, ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, V)> { // SAFETY: The caller promises that `self`'s referent conforms to // the validity requirement of `V`. - unsafe { Ptr::from_ptr(self) } + unsafe { self.assume_invariants() } } /// A shorthand for `self.assume_validity()`. @@ -826,39 +801,35 @@ mod _transitions { #[inline] pub unsafe fn assume_initialized( self, - ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, invariant::Initialized)> { + ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Initialized)> { // SAFETY: The caller has promised to uphold the safety // preconditions. - unsafe { self.assume_validity::() } + unsafe { self.assume_validity::() } } - /// A shorthand for `self.assume_validity()`. + /// A shorthand for `self.assume_validity()`. /// /// # Safety /// /// The caller promises to uphold the safety preconditions of - /// `self.assume_validity()`. + /// `self.assume_validity()`. #[doc(hidden)] #[must_use] #[inline] - pub unsafe fn assume_valid( - self, - ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, invariant::Valid)> { + pub unsafe fn assume_valid(self) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Valid)> { // SAFETY: The caller has promised to uphold the safety // preconditions. - unsafe { self.assume_validity::() } + unsafe { self.assume_validity::() } } - /// Recalls that `Ptr`'s referent is bit-valid for `T`. + /// Recalls that `self`'s referent is bit-valid for `T`. #[inline] // TODO(#859): Reconsider the name of this method before making it // public. - pub(crate) fn bikeshed_recall_valid( - self, - ) -> Ptr<'a, T, (I::Aliasing, I::Alignment, invariant::Valid)> + pub(crate) fn bikeshed_recall_valid(self) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Valid)> where T: crate::FromBytes, - I: Invariants, + I: Invariants, { // SAFETY: The bound `T: FromBytes` ensures that any initialized // sequence of bytes is bit-valid for `T`. `I: Invariants Option> + ) -> Option> where T: TryFromBytes, - I::Aliasing: invariant::at_least::Shared, - I: Invariants, + I::Aliasing: AtLeast, + I: Invariants, { // This call may panic. If that happens, it doesn't cause any soundness // issues, as we have not generated any invalid state which we need to @@ -895,26 +866,26 @@ mod _transitions { } } - /// Forgets that `Ptr`'s referent exclusively references `T`, + /// Forgets that `self`'s referent exclusively references `T`, /// downgrading to a shared reference. #[doc(hidden)] #[must_use] #[inline] - pub fn forget_exclusive(self) -> Ptr<'a, T, (invariant::Shared, I::Alignment, I::Validity)> + pub fn forget_exclusive(self) -> Ptr<'a, T, (Shared, I::Alignment, I::Validity)> where - I::Aliasing: invariant::at_least::Shared, + I::Aliasing: AtLeast, { // SAFETY: `I::Aliasing` is at least as restrictive as `Shared`. - unsafe { Ptr::from_ptr(self) } + unsafe { self.assume_invariants() } } - /// Forgets that `Ptr`'s referent is validly-aligned for `T`. + /// Forgets that `self`'s referent is validly-aligned for `T`. #[doc(hidden)] #[must_use] #[inline] - pub fn forget_aligned(self) -> Ptr<'a, T, (I::Aliasing, invariant::Any, I::Validity)> { + pub fn forget_aligned(self) -> Ptr<'a, T, (I::Aliasing, Any, I::Validity)> { // SAFETY: `Any` is less restrictive than `Aligned`. - unsafe { Ptr::from_ptr(self) } + unsafe { self.assume_invariants() } } } } @@ -969,7 +940,7 @@ mod _casts { pub unsafe fn cast_unsized *mut U>( self, cast: F, - ) -> Ptr<'a, U, (I::Aliasing, invariant::Any, invariant::Any)> { + ) -> Ptr<'a, U, (I::Aliasing, Any, Any)> { let ptr = cast(self.as_non_null().as_ptr()); // SAFETY: Caller promises that `cast` is just a cast. We call @@ -1015,14 +986,12 @@ mod _casts { impl<'a, T, I> Ptr<'a, T, I> where T: 'a, - I: Invariants, + I: Invariants, T: Immutable, { /// 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, invariant::Aligned, invariant::Valid)> { + pub(crate) fn as_bytes(self) -> Ptr<'a, [u8], (I::Aliasing, Aligned, Valid)> { // SAFETY: We ensure that: // - `cast(p)` is implemented as an invocation to // `slice_from_raw_parts_mut`. @@ -1044,7 +1013,7 @@ mod _casts { // type is then casted to `[u8]`, whose only validity invariant is // that its bytes are initialized. This validity invariant is // satisfied by the `Initialized` invariant on the starting `ptr`. - unsafe { ptr.assume_validity::() } + unsafe { ptr.assume_validity::() } } } @@ -1112,7 +1081,7 @@ mod _casts { /// alignment of `[u8]` is 1. impl<'a, I> Ptr<'a, [u8], I> where - I: Invariants, + I: Invariants, { /// Attempts to cast `self` to a `U` using the given cast type. /// @@ -1133,8 +1102,7 @@ mod _casts { pub(crate) fn try_cast_into( &self, cast_type: CastType, - ) -> Option<(Ptr<'a, U, (I::Aliasing, invariant::Aligned, invariant::Initialized)>, usize)> - { + ) -> Option<(Ptr<'a, U, (I::Aliasing, Aligned, Initialized)>, usize)> { crate::util::assert_dst_is_not_zst::(); // PANICS: By invariant, the byte range addressed by `self.ptr` does @@ -1234,7 +1202,7 @@ mod _casts { #[inline(always)] pub(crate) fn try_cast_into_no_leftover( &self, - ) -> Option> { + ) -> Option> { // TODO(#67): Remove this allow. See NonNulSlicelExt for more // details. #[allow(unstable_name_collisions)] @@ -1253,7 +1221,7 @@ mod _project { impl<'a, T, I> Ptr<'a, T, I> where T: 'a + ?Sized, - I: Invariants, + I: Invariants, { /// Projects a field from `self`. /// @@ -1280,7 +1248,7 @@ mod _project { pub unsafe fn project( self, projector: impl FnOnce(*mut T) -> *mut U, - ) -> Ptr<'a, U, (I::Aliasing, invariant::Any, invariant::Initialized)> { + ) -> Ptr<'a, U, (I::Aliasing, Any, Initialized)> { // SAFETY: `projector` is provided with `self` casted to a raw // pointer. let field = projector(self.as_non_null().as_ptr()); @@ -1524,11 +1492,7 @@ mod tests { // SAFETY: The bytes in `slf` must be initialized. unsafe fn validate_and_get_len( - slf: Ptr< - '_, - T, - (invariant::Shared, invariant::Aligned, invariant::Initialized), - >, + slf: Ptr<'_, T, (Shared, Aligned, Initialized)>, ) -> usize { let t = slf.bikeshed_recall_valid().as_ref(); @@ -1618,13 +1582,13 @@ mod tests { // Test that the correct invariant relationships hold. use super::invariant::*; - assert_not_impl_any!(Any: at_least::Shared); - assert_impl_all!(Shared: at_least::Shared); - assert_impl_all!(Exclusive: at_least::Shared); + assert_not_impl_any!(Any: AtLeast); + assert_impl_all!(Shared: AtLeast); + assert_impl_all!(Exclusive: AtLeast); - assert_not_impl_any!(Any: at_least::AsInitialized); - assert_impl_all!(AsInitialized: at_least::AsInitialized); - assert_impl_all!(Initialized: at_least::AsInitialized); - assert_impl_all!(Valid: at_least::AsInitialized); + assert_not_impl_any!(Any: AtLeast); + assert_impl_all!(AsInitialized: AtLeast); + assert_impl_all!(Initialized: AtLeast); + assert_impl_all!(Valid: AtLeast); } } diff --git a/zerocopy-derive/src/lib.rs b/zerocopy-derive/src/lib.rs index 00d32c3981..fe3f9f966c 100644 --- a/zerocopy-derive/src/lib.rs +++ b/zerocopy-derive/src/lib.rs @@ -378,7 +378,7 @@ fn derive_try_from_bytes_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_m // validity of a struct is just the composition of the bit // validities of its fields, so this is a sound implementation of // `is_bit_valid`. - fn is_bit_valid( + fn is_bit_valid>( mut candidate: ::zerocopy::Maybe ) -> bool { true #(&& { @@ -427,7 +427,7 @@ fn derive_try_from_bytes_union(ast: &DeriveInput, unn: &DataUnion) -> proc_macro // bit validity of a union is not yet well defined in Rust, but it // is guaranteed to be no more strict than this definition. See #696 // for a more in-depth discussion. - fn is_bit_valid( + fn is_bit_valid>( mut candidate: ::zerocopy::Maybe ) -> bool { false #(|| { @@ -539,7 +539,7 @@ fn derive_try_from_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2: // SAFETY: We use `is_bit_valid` to validate that the bit pattern // corresponds to one of the field-less enum's variant discriminants. // Thus, this is a sound implementation of `is_bit_valid`. - fn is_bit_valid( + fn is_bit_valid>( candidate: ::zerocopy::Ptr< '_, Self,