From 99b49b789dca6b77bf6def60d3ce3e51a01da937 Mon Sep 17 00:00:00 2001 From: Joshua Liebow-Feeser Date: Mon, 14 Oct 2024 12:42:51 -0700 Subject: [PATCH] [pointer] Rename Any -> Unknown, remove aliasing Don't implement `Aliasing` for `Unknown` - every `Ptr` always has *some* aliasing that is known at construction. --- src/pointer/invariant.rs | 23 +++++------------------ src/pointer/mod.rs | 4 ++-- src/pointer/ptr.rs | 11 +++++++---- src/util/macro_util.rs | 2 +- src/util/mod.rs | 4 ++-- 5 files changed, 17 insertions(+), 27 deletions(-) diff --git a/src/pointer/invariant.rs b/src/pointer/invariant.rs index c48e0a196c..9d7a76bd78 100644 --- a/src/pointer/invariant.rs +++ b/src/pointer/invariant.rs @@ -81,24 +81,11 @@ pub trait Validity: Sealed {} /// Exclusive`. pub trait Reference: Aliasing + Sealed {} -/// No requirement - any invariant is allowed. -pub enum Any {} -impl Aliasing for Any { - const IS_EXCLUSIVE: bool = false; +/// It is unknown whether any invariant holds. +pub enum Unknown {} - // SAFETY: Since we don't know what aliasing model this is, we have to be - // conservative. Invariance is strictly more restrictive than any other - // variance model, so this can never cause soundness issues. - // - // `fn() -> T` and `fn(T) -> ()` are covariant and contravariant in `T`, - // respectively. [1] Thus, `fn(T) -> T` is invariant in `T`. Thus, `fn(&'a - // T) -> &'a T` is invariant in `'a` and `T`. - // - // [1] https://doc.rust-lang.org/1.81.0/reference/subtyping.html#variance - type Variance<'a, T: 'a + ?Sized> = fn(&'a T) -> &'a T; -} -impl Alignment for Any {} -impl Validity for Any {} +impl Alignment for Unknown {} +impl Validity for Unknown {} /// The `Ptr<'a, T>` adheres to the aliasing rules of a `&'a T`. /// @@ -212,7 +199,7 @@ mod sealed { pub trait Sealed {} - impl Sealed for Any {} + impl Sealed for Unknown {} impl Sealed for Shared {} impl Sealed for Exclusive {} diff --git a/src/pointer/mod.rs b/src/pointer/mod.rs index ceda0c6bd0..e7b8c0e802 100644 --- a/src/pointer/mod.rs +++ b/src/pointer/mod.rs @@ -24,14 +24,14 @@ use crate::Unaligned; /// to [`TryFromBytes::is_bit_valid`]. /// /// [`TryFromBytes::is_bit_valid`]: crate::TryFromBytes::is_bit_valid -pub type Maybe<'a, T, Aliasing = invariant::Shared, Alignment = invariant::Any> = +pub type Maybe<'a, T, Aliasing = invariant::Shared, Alignment = invariant::Unknown> = Ptr<'a, T, (Aliasing, Alignment, invariant::Initialized)>; /// A semi-user-facing wrapper type representing a maybe-aligned reference, for /// use in [`TryFromBytes::is_bit_valid`]. /// /// [`TryFromBytes::is_bit_valid`]: crate::TryFromBytes::is_bit_valid -pub type MaybeAligned<'a, T, Aliasing = invariant::Shared, Alignment = invariant::Any> = +pub type MaybeAligned<'a, T, Aliasing = invariant::Shared, Alignment = invariant::Unknown> = Ptr<'a, T, (Aliasing, Alignment, invariant::Valid)>; // These methods are defined on the type alias, `MaybeAligned`, so as to bring diff --git a/src/pointer/ptr.rs b/src/pointer/ptr.rs index 78bf23d1b3..7e7d96e89d 100644 --- a/src/pointer/ptr.rs +++ b/src/pointer/ptr.rs @@ -676,7 +676,7 @@ mod _transitions { #[doc(hidden)] #[must_use] #[inline] - pub const fn forget_aligned(self) -> Ptr<'a, T, I::WithAlignment> { + pub const fn forget_aligned(self) -> Ptr<'a, T, I::WithAlignment> { // SAFETY: `Any` is less restrictive than `Aligned`. unsafe { self.assume_invariants() } } @@ -714,7 +714,7 @@ mod _casts { pub unsafe fn cast_unsized_unchecked *mut U>( self, cast: F, - ) -> Ptr<'a, U, (I::Aliasing, Any, Any)> { + ) -> Ptr<'a, U, (I::Aliasing, Unknown, Unknown)> { let ptr = cast(self.as_inner().as_non_null().as_ptr()); // SAFETY: Caller promises that `cast` returns a pointer whose @@ -784,7 +784,10 @@ mod _casts { /// - `u` has the same provenance as `p` #[doc(hidden)] #[inline] - pub unsafe fn cast_unsized(self, cast: F) -> Ptr<'a, U, (I::Aliasing, Any, Any)> + pub unsafe fn cast_unsized( + self, + cast: F, + ) -> Ptr<'a, U, (I::Aliasing, Unknown, Unknown)> where T: Read, U: 'a + ?Sized + Read, @@ -1070,7 +1073,7 @@ mod _project { pub unsafe fn project( self, projector: impl FnOnce(*mut T) -> *mut U, - ) -> Ptr<'a, U, (I::Aliasing, Any, Initialized)> { + ) -> Ptr<'a, U, (I::Aliasing, Unknown, Initialized)> { // TODO(#1122): If `cast_unsized` were able to reason that, when // casting from an `Initialized` pointer, the result is another // `Initialized` pointer, we could remove this method entirely. diff --git a/src/util/macro_util.rs b/src/util/macro_util.rs index 1064a5b76b..7a904438ee 100644 --- a/src/util/macro_util.rs +++ b/src/util/macro_util.rs @@ -520,7 +520,7 @@ pub unsafe fn transmute_mut<'dst, 'src: 'dst, Src: 'src, Dst: 'dst>( fn try_cast_or_pme( src: Ptr<'_, Src, I>, ) -> Result< - Ptr<'_, Dst, (I::Aliasing, invariant::Any, invariant::Valid)>, + Ptr<'_, Dst, (I::Aliasing, invariant::Unknown, invariant::Valid)>, ValidityError, Dst>, > where diff --git a/src/util/mod.rs b/src/util/mod.rs index b00437cd7c..dd2e5bdd61 100644 --- a/src/util/mod.rs +++ b/src/util/mod.rs @@ -99,11 +99,11 @@ impl ValidityVariance for Covariant { pub enum Invariant {} impl AlignmentVariance for Invariant { - type Applied = invariant::Any; + type Applied = invariant::Unknown; } impl ValidityVariance for Invariant { - type Applied = invariant::Any; + type Applied = invariant::Unknown; } // SAFETY: