Skip to content

Commit

Permalink
[pointer] Rename Any -> Unknown, remove aliasing
Browse files Browse the repository at this point in the history
Don't implement `Aliasing` for `Unknown` - every `Ptr` always has *some*
aliasing that is known at construction.
  • Loading branch information
joshlf committed Oct 14, 2024
1 parent c938064 commit f25b7b6
Show file tree
Hide file tree
Showing 5 changed files with 17 additions and 27 deletions.
23 changes: 5 additions & 18 deletions src/pointer/invariant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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`.
///
Expand Down Expand Up @@ -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 {}
Expand Down
4 changes: 2 additions & 2 deletions src/pointer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
11 changes: 7 additions & 4 deletions src/pointer/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -676,7 +676,7 @@ mod _transitions {
#[doc(hidden)]
#[must_use]
#[inline]
pub const fn forget_aligned(self) -> Ptr<'a, T, I::WithAlignment<Any>> {
pub const fn forget_aligned(self) -> Ptr<'a, T, I::WithAlignment<Unknown>> {
// SAFETY: `Any` is less restrictive than `Aligned`.
unsafe { self.assume_invariants() }
}
Expand Down Expand Up @@ -714,7 +714,7 @@ mod _casts {
pub unsafe fn cast_unsized_unchecked<U: 'a + ?Sized, F: FnOnce(*mut T) -> *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
Expand Down Expand Up @@ -784,7 +784,10 @@ mod _casts {
/// - `u` has the same provenance as `p`
#[doc(hidden)]
#[inline]
pub unsafe fn cast_unsized<U, F, R, S>(self, cast: F) -> Ptr<'a, U, (I::Aliasing, Any, Any)>
pub unsafe fn cast_unsized<U, F, R, S>(
self,
cast: F,
) -> Ptr<'a, U, (I::Aliasing, Unknown, Unknown)>
where
T: Read<I::Aliasing, R>,
U: 'a + ?Sized + Read<I::Aliasing, S>,
Expand Down Expand Up @@ -1070,7 +1073,7 @@ mod _project {
pub unsafe fn project<U: 'a + ?Sized>(
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.
Expand Down
2 changes: 1 addition & 1 deletion src/util/macro_util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -520,7 +520,7 @@ pub unsafe fn transmute_mut<'dst, 'src: 'dst, Src: 'src, Dst: 'dst>(
fn try_cast_or_pme<Src, Dst, I, R>(
src: Ptr<'_, Src, I>,
) -> Result<
Ptr<'_, Dst, (I::Aliasing, invariant::Any, invariant::Valid)>,
Ptr<'_, Dst, (I::Aliasing, invariant::Unknown, invariant::Valid)>,
ValidityError<Ptr<'_, Src, I>, Dst>,
>
where
Expand Down
4 changes: 2 additions & 2 deletions src/util/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,11 +99,11 @@ impl<I: invariant::Validity> ValidityVariance<I> for Covariant {
pub enum Invariant {}

impl<I: invariant::Alignment> AlignmentVariance<I> for Invariant {
type Applied = invariant::Any;
type Applied = invariant::Unknown;
}

impl<I: invariant::Validity> ValidityVariance<I> for Invariant {
type Applied = invariant::Any;
type Applied = invariant::Unknown;
}

// SAFETY:
Expand Down

0 comments on commit f25b7b6

Please sign in to comment.