Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 11 additions & 11 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ assert_unaligned!(bool);
// pattern 0x01.
const _: () = unsafe {
unsafe_impl!(=> TryFromBytes for bool; |byte| {
let byte = byte.transmute_with::<u8, invariant::Valid, CastSizedExact, _>();
let byte = byte.transmute_with::<u8, invariant::Safe, CastSizedExact, _>();
*byte.unaligned_as_ref() < 2
})
};
Expand Down Expand Up @@ -138,7 +138,7 @@ const _: () = unsafe { unsafe_impl!(char: Immutable, FromZeros, IntoBytes) };
// `char`.
const _: () = unsafe {
unsafe_impl!(=> TryFromBytes for char; |c| {
let c = c.transmute_with::<Unalign<u32>, invariant::Valid, CastSizedExact, _>();
let c = c.transmute_with::<Unalign<u32>, invariant::Safe, CastSizedExact, _>();
let c = c.read_unaligned().into_inner();
char::from_u32(c).is_some()
});
Expand Down Expand Up @@ -171,7 +171,7 @@ const _: () = unsafe { unsafe_impl!(str: Immutable, FromZeros, IntoBytes, Unalig
// Returns `Err` if the slice is not UTF-8.
const _: () = unsafe {
unsafe_impl!(=> TryFromBytes for str; |c| {
let c = c.transmute_with::<[u8], invariant::Valid, CastUnsized, _>();
let c = c.transmute_with::<[u8], invariant::Safe, CastUnsized, _>();
let c = c.unaligned_as_ref();
core::str::from_utf8(c).is_ok()
})
Expand All @@ -181,7 +181,7 @@ macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
($($nonzero:ident[$prim:ty]),*) => {
$(
unsafe_impl!(=> TryFromBytes for $nonzero; |n| {
let n = n.transmute_with::<Unalign<$prim>, invariant::Valid, CastSizedExact, _>();
let n = n.transmute_with::<Unalign<$prim>, invariant::Safe, CastSizedExact, _>();
$nonzero::new(n.read_unaligned().into_inner()).is_some()
});
)*
Expand Down Expand Up @@ -419,15 +419,15 @@ mod atomics {
($($($tyvar:ident)? => $atomic:ty [$prim:ty]),*) => {{
crate::util::macros::__unsafe();

use crate::pointer::{SizeEq, TransmuteFrom, invariant::Valid};
use crate::pointer::{SizeEq, TransmuteFrom, invariant::Safe};

$(
// SAFETY: The caller promised that `$atomic` and `$prim` have
// the same size and bit validity.
unsafe impl<$($tyvar)?> TransmuteFrom<$atomic, Valid, Valid> for $prim {}
unsafe impl<$($tyvar)?> TransmuteFrom<$atomic, Safe, Safe> for $prim {}
// SAFETY: The caller promised that `$atomic` and `$prim` have
// the same size and bit validity.
unsafe impl<$($tyvar)?> TransmuteFrom<$prim, Valid, Valid> for $atomic {}
unsafe impl<$($tyvar)?> TransmuteFrom<$prim, Safe, Safe> for $atomic {}

impl<$($tyvar)?> SizeEq<$atomic> for $prim {
type CastFrom = $crate::pointer::cast::CastSizedExact;
Expand All @@ -445,9 +445,9 @@ mod atomics {
// `UnsafeCell<T>` has the same in-memory representation as
// its inner type `T`. A consequence of this guarantee is that
// it is possible to convert between `T` and `UnsafeCell<T>`.
unsafe impl<$($tyvar)?> TransmuteFrom<$atomic, Valid, Valid> for core::cell::UnsafeCell<$prim> {}
unsafe impl<$($tyvar)?> TransmuteFrom<$atomic, Safe, Safe> for core::cell::UnsafeCell<$prim> {}
// SAFETY: See previous safety comment.
unsafe impl<$($tyvar)?> TransmuteFrom<core::cell::UnsafeCell<$prim>, Valid, Valid> for $atomic {}
unsafe impl<$($tyvar)?> TransmuteFrom<core::cell::UnsafeCell<$prim>, Safe, Safe> for $atomic {}
)*
}};
}
Expand Down Expand Up @@ -1125,7 +1125,7 @@ mod tuples {
// SAFETY: See comments on items.
unsafe impl<Aliasing, Alignment, $($AllT),+> crate::ProjectField<
(),
(Aliasing, Alignment, crate::invariant::Valid),
(Aliasing, Alignment, crate::invariant::Safe),
{ crate::STRUCT_VARIANT_ID },
{ crate::ident_id!($CurrI)}
> for ($($AllT,)+)
Expand All @@ -1142,7 +1142,7 @@ mod tuples {
// SAFETY: Tuples are product types whose fields are
// well-aligned, so projection preserves both the alignment and
// validity invariants of the outer pointer.
type Invariants = (Aliasing, Alignment, crate::invariant::Valid);
type Invariants = (Aliasing, Alignment, crate::invariant::Safe);

// SAFETY: Tuples are product types and so projection is infallible;
type Error = core::convert::Infallible;
Expand Down
8 changes: 4 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1231,9 +1231,9 @@ where
// cannot be used to discriminate between variants.
ValidityKind::Uninit | ValidityKind::Initialized => true,
// The projectability of an enum field from an
// `AsInitialized` or `Valid` state is a dynamic
// `AsInitialized` or `Safe` state is a dynamic
// property of its tag.
ValidityKind::AsInitialized | ValidityKind::Valid => false,
ValidityKind::AsInitialized | ValidityKind::Safe => false,
}
}
};
Expand Down Expand Up @@ -3096,8 +3096,8 @@ unsafe fn try_read_from<S, T: TryFromBytes>(

fn _assert_same_size_and_validity<T>()
where
Wrapping<T>: pointer::TransmuteFrom<T, invariant::Valid, invariant::Valid>,
T: pointer::TransmuteFrom<Wrapping<T>, invariant::Valid, invariant::Valid>,
Wrapping<T>: pointer::TransmuteFrom<T, invariant::Safe, invariant::Safe>,
T: pointer::TransmuteFrom<Wrapping<T>, invariant::Safe, invariant::Safe>,
{
}

Expand Down
14 changes: 7 additions & 7 deletions src/pointer/invariant.rs
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ pub enum ValidityKind {
Uninit,
AsInitialized,
Initialized,
Valid,
Safe,
}

/// An [`Aliasing`] invariant which is either [`Shared`] or [`Exclusive`].
Expand Down Expand Up @@ -195,13 +195,13 @@ unsafe impl Validity for Initialized {
const KIND: ValidityKind = ValidityKind::Initialized;
}

/// The referent of a `Ptr<T>` is valid for `T`, upholding bit validity and any
/// The referent of a `Ptr<T>` is safe for `T`, upholding bit validity and any
/// library safety invariants.
pub enum Valid {}
// SAFETY: `Valid`'s validity is well-defined for all `T: ?Sized`, and is not a
pub enum Safe {}
// SAFETY: `Safe`'s validity is well-defined for all `T: ?Sized`, and is not a
// function of any property of `T` other than its bit validity.
unsafe impl Validity for Valid {
const KIND: ValidityKind = ValidityKind::Valid;
unsafe impl Validity for Safe {
const KIND: ValidityKind = ValidityKind::Safe;
}

/// # Safety
Expand Down Expand Up @@ -261,7 +261,7 @@ mod sealed {
impl Sealed for Uninit {}
impl Sealed for AsInitialized {}
impl Sealed for Initialized {}
impl Sealed for Valid {}
impl Sealed for Safe {}

impl<A: Sealed, AA: Sealed, V: Sealed> Sealed for (A, AA, V) {}

Expand Down
56 changes: 28 additions & 28 deletions src/pointer/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ mod _conversions {
use crate::pointer::cast::CastSized;

/// `&'a T` → `Ptr<'a, T>`
impl<'a, T> Ptr<'a, T, (Shared, Aligned, Valid)>
impl<'a, T> Ptr<'a, T, (Shared, Aligned, Safe)>
where
T: 'a + ?Sized,
{
Expand All @@ -178,7 +178,7 @@ mod _conversions {
// 1. `ptr`, by invariant on `&'a T`, conforms to the alignment
// invariant of `Aligned`.
// 2. `ptr`'s referent, by invariant on `&'a T`, is a bit-valid `T`.
// This satisfies the requirement that a `Ptr<T, (_, _, Valid)>`
// This satisfies the requirement that a `Ptr<T, (_, _, Safe)>`
// point to a bit-valid `T`. Even if `T` permits interior
// mutation, this invariant guarantees that the returned `Ptr`
// can only ever be used to modify the referent to store
Expand All @@ -191,7 +191,7 @@ mod _conversions {
}

/// `&'a mut T` → `Ptr<'a, T>`
impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)>
impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Safe)>
where
T: 'a + ?Sized,
{
Expand All @@ -207,7 +207,7 @@ mod _conversions {
// invariant of `Aligned`.
// 2. `ptr`'s referent, by invariant on `&'a mut T`, is a bit-valid
// `T`. This satisfies the requirement that a `Ptr<T, (_, _,
// Valid)>` point to a bit-valid `T`. This invariant guarantees
// Safe)>` point to a bit-valid `T`. This invariant guarantees
// that the returned `Ptr` can only ever be used to modify the
// referent to store bit-valid `T`s, which ensures that the
// returned `Ptr` cannot be used to violate the soundness of the
Expand All @@ -220,7 +220,7 @@ mod _conversions {
impl<'a, T, I> Ptr<'a, T, I>
where
T: 'a + ?Sized,
I: Invariants<Alignment = Aligned, Validity = Valid>,
I: Invariants<Alignment = Aligned, Validity = Safe>,
I::Aliasing: Reference,
{
/// Converts `self` to a shared reference.
Expand Down Expand Up @@ -258,7 +258,7 @@ mod _conversions {
//
// 3. The pointer must point to a validly-initialized instance of
// `T`. This is ensured by-contract on `Ptr`, because the
// `I::Validity` is `Valid`.
// `I::Validity` is `Safe`.
//
// 4. You must enforce Rust’s aliasing rules. This is ensured by
// contract on `Ptr`, because `I::Aliasing: Reference`. Either it
Expand Down Expand Up @@ -326,7 +326,7 @@ mod _conversions {
}

/// `Ptr<'a, T>` → `&'a mut T`
impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Valid)>
impl<'a, T> Ptr<'a, T, (Exclusive, Aligned, Safe)>
where
T: 'a + ?Sized,
{
Expand Down Expand Up @@ -361,7 +361,7 @@ mod _conversions {
//
// 3. The pointer must point to a validly-initialized instance of
// `T`. This is ensured by-contract on `Ptr`, because the
// validity invariant is `Valid`.
// validity invariant is `Safe`.
//
// 4. You must enforce Rust’s aliasing rules. This is ensured by
// contract on `Ptr`, because the `ALIASING_INVARIANT` is
Expand Down Expand Up @@ -536,7 +536,7 @@ mod _conversions {
impl<'a, T, I> Ptr<'a, T, I>
where
T: ?Sized,
I: Invariants<Validity = Valid>,
I: Invariants<Validity = Safe>,
I::Aliasing: Reference,
{
/// Reads the referent.
Expand Down Expand Up @@ -751,19 +751,19 @@ mod _transitions {
unsafe { self.assume_validity::<Initialized>() }
}

/// A shorthand for `self.assume_validity<Valid>()`.
/// A shorthand for `self.assume_validity<Safe>()`.
///
/// # Safety
///
/// The caller promises to uphold the safety preconditions of
/// `self.assume_validity<Valid>()`.
/// `self.assume_validity<Safe>()`.
#[doc(hidden)]
#[must_use]
#[inline]
pub unsafe fn assume_valid(self) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Valid)> {
pub unsafe fn assume_safe(self) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Safe)> {
// SAFETY: The caller has promised to uphold the safety
// preconditions.
unsafe { self.assume_validity::<Valid>() }
unsafe { self.assume_validity::<Safe>() }
}

/// Recalls that `self`'s referent is initialized.
Expand All @@ -777,11 +777,11 @@ mod _transitions {
) -> Ptr<'a, T, (I::Aliasing, I::Alignment, Initialized)>
where
T: crate::IntoBytes + crate::FromBytes,
I: Invariants<Validity = Valid>,
I: Invariants<Validity = Safe>,
{
// SAFETY: The `T: IntoBytes + FromBytes` bound ensures that `T`'s
// bit validity is equivalent to `[u8]`. In other words, the set of
// allowed referents for a `Ptr<T, (_, _, Valid)>` is the set of
// allowed referents for a `Ptr<T, (_, _, Safe)>` is the set of
// initialized bit patterns. The same is true of the set of allowed
// referents for any `Ptr<_, (_, _, Initialized)>`. Thus, this call
// does not change the set of allowed values in the referent.
Expand All @@ -799,12 +799,12 @@ mod _transitions {
) -> Ptr<'a, T, (Shared, I::Alignment, Initialized)>
where
T: crate::IntoBytes + crate::Immutable,
I: Invariants<Aliasing = Shared, Validity = Valid>,
I: Invariants<Aliasing = Shared, Validity = Safe>,
{
// SAFETY: Let `O` (for "old") be the set of allowed bit patterns in
// `self`'s referent, and let `N` (for "new") be the set of allowed
// bit patterns in the referent of the returned `Ptr`. `T:
// IntoBytes` and `I: Invariants<Validity = Valid>` ensures that `O`
// IntoBytes` and `I: Invariants<Validity = Safe>` ensures that `O`
// cannot contain any uninitialized bit patterns. Since the returned
// `Ptr` has validity `Initialized`, `N` is equal to the set of all
// initialized bit patterns. Thus, `O` is a subset of `N`, and so
Expand All @@ -820,7 +820,7 @@ mod _transitions {
}

/// Checks that `self`'s referent is validly initialized for `T`,
/// returning a `Ptr` with `Valid` on success.
/// returning a `Ptr` with `Safe` on success.
///
/// # Panics
///
Expand All @@ -834,11 +834,11 @@ mod _transitions {
#[inline]
pub(crate) fn try_into_valid<R, S>(
mut self,
) -> Result<Ptr<'a, T, (I::Aliasing, I::Alignment, Valid)>, ValidityError<Self, T>>
) -> Result<Ptr<'a, T, (I::Aliasing, I::Alignment, Safe)>, ValidityError<Self, T>>
where
T: TryFromBytes
+ Read<I::Aliasing, R>
+ TryTransmuteFromPtr<T, I::Aliasing, I::Validity, Valid, S>,
+ TryTransmuteFromPtr<T, I::Aliasing, I::Validity, Safe, S>,
I::Aliasing: Reference,
I: Invariants<Validity = Initialized>,
{
Expand All @@ -848,11 +848,11 @@ mod _transitions {
if T::is_bit_valid(self.reborrow().forget_aligned()) {
// SAFETY: If `T::is_bit_valid`, code may assume that `self`
// contains a bit-valid instance of `T`. By `T:
// TryTransmuteFromPtr<T, I::Aliasing, I::Validity, Valid>`, so
// long as `self`'s referent conforms to the `Valid` validity
// TryTransmuteFromPtr<T, I::Aliasing, I::Validity, Safe>`, so
// long as `self`'s referent conforms to the `Safe` validity
// for `T` (which we just confirmed), then this transmute is
// sound.
Ok(unsafe { self.assume_valid() })
Ok(unsafe { self.assume_safe() })
} else {
Err(ValidityError::new(self))
}
Expand Down Expand Up @@ -985,14 +985,14 @@ mod _casts {
#[allow(clippy::wrong_self_convention)]
#[must_use]
#[inline]
pub fn as_bytes<R>(self) -> Ptr<'a, [u8], (I::Aliasing, Aligned, Valid)>
pub fn as_bytes<R>(self) -> Ptr<'a, [u8], (I::Aliasing, Aligned, Safe)>
where
T: Read<I::Aliasing, R>,
[u8]: Read<I::Aliasing, R>,
I::Aliasing: Reference,
{
let ptr = self.cast::<_, AsBytesCast, _>();
ptr.bikeshed_recall_aligned().recall_validity::<Valid, (_, (_, _))>()
ptr.bikeshed_recall_aligned().recall_validity::<Safe, (_, (_, _))>()
}
}

Expand Down Expand Up @@ -1042,7 +1042,7 @@ mod _casts {
/// alignment of `[u8]` is 1.
impl<'a, I> Ptr<'a, [u8], I>
where
I: Invariants<Validity = Valid>,
I: Invariants<Validity = Safe>,
{
/// Attempts to cast `self` to a `U` using the given cast type.
///
Expand Down Expand Up @@ -1101,7 +1101,7 @@ mod _casts {
// it is derived from `try_cast_into`, which promises that the
// object described by `target` is validly aligned for `U`.
// 2. By trait bound, `self` - and thus `target` - is a bit-valid
// `[u8]`. `Ptr<[u8], (_, _, Valid)>` and `Ptr<_, (_, _,
// `[u8]`. `Ptr<[u8], (_, _, Safe)>` and `Ptr<_, (_, _,
// Initialized)>` have the same bit validity, and so neither
// `self` nor `res` can be used to write a value to the referent
// which violates the other's validity invariant.
Expand All @@ -1112,7 +1112,7 @@ mod _casts {
// have `UnsafeCell`s at the same locations. Type casting does
// not affect aliasing.
// 1. `[u8]` has no alignment requirement.
// 2. `self` has validity `Valid` and has type `[u8]`. Since
// 2. `self` has validity `Safe` and has type `[u8]`. Since
// `remainder` references a subset of `self`'s referent, it is
// also a bit-valid `[u8]`. Thus, neither `self` nor `remainder`
// can be used to write a value to the referent which violates
Expand Down
8 changes: 4 additions & 4 deletions src/pointer/transmute.rs
Original file line number Diff line number Diff line change
Expand Up @@ -301,17 +301,17 @@ impl<T: ?Sized> SizeEq<T> for T {
// SAFETY: Since `Src: IntoBytes`, the set of valid `Src`'s is the set of
// initialized bit patterns, which is exactly the set allowed in the referent of
// any `Initialized` `Ptr`.
unsafe impl<Src, Dst> TransmuteFrom<Src, Valid, Initialized> for Dst
unsafe impl<Src, Dst> TransmuteFrom<Src, Safe, Initialized> for Dst
where
Src: IntoBytes + ?Sized,
Dst: ?Sized,
{
}

// SAFETY: Since `Dst: FromBytes`, any initialized bit pattern may appear in the
// referent of a `Ptr<Dst, (_, _, Valid)>`. This is exactly equal to the set of
// referent of a `Ptr<Dst, (_, _, Safe)>`. This is exactly equal to the set of
// bit patterns which may appear in the referent of any `Initialized` `Ptr`.
unsafe impl<Src, Dst> TransmuteFrom<Src, Initialized, Valid> for Dst
unsafe impl<Src, Dst> TransmuteFrom<Src, Initialized, Safe> for Dst
where
Src: ?Sized,
Dst: FromBytes + ?Sized,
Expand Down Expand Up @@ -446,7 +446,7 @@ impl_transitive_transmute_from!(T: ?Sized => UnsafeCell<T> => T => Cell<T>);
// explicitly guaranteed, but it's obvious from `MaybeUninit`'s documentation
// that this is the intention:
// https://doc.rust-lang.org/1.85.0/core/mem/union.MaybeUninit.html
unsafe impl<T> TransmuteFrom<T, Uninit, Valid> for MaybeUninit<T> {}
unsafe impl<T> TransmuteFrom<T, Uninit, Safe> for MaybeUninit<T> {}

impl<T> SizeEq<T> for MaybeUninit<T> {
type CastFrom = cast::CastSizedExact;
Expand Down
Loading
Loading