Skip to content
Closed
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
30 changes: 9 additions & 21 deletions src/impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,7 @@ const _: () = unsafe {
*byte.unaligned_as_ref() < 2
})
};
impl_size_eq!(bool, u8);
impl_size_compat!(bool, u8);

// SAFETY:
// - `Immutable`: `char` self-evidently does not contain any `UnsafeCell`s.
Expand Down Expand Up @@ -144,7 +144,7 @@ const _: () = unsafe {
});
};

impl_size_eq!(char, Unalign<u32>);
impl_size_compat!(char, Unalign<u32>);

// SAFETY: Per the Reference [1], `str` has the same layout as `[u8]`.
// - `Immutable`: `[u8]` does not contain any `UnsafeCell`s.
Expand Down Expand Up @@ -179,13 +179,13 @@ const _: () = unsafe {
})
};

impl_size_eq!(str, [u8]);
impl_size_compat!(str, [u8]);

macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
($($nonzero:ident[$prim:ty]),*) => {
$(
unsafe_impl!(=> TryFromBytes for $nonzero; |n| {
impl_size_eq!($nonzero, Unalign<$prim>);
impl_size_compat!($nonzero, Unalign<$prim>);

let n = n.transmute::<Unalign<$prim>, invariant::Valid, _>();
$nonzero::new(n.read_unaligned().into_inner()).is_some()
Expand Down Expand Up @@ -426,7 +426,7 @@ mod atomics {
crate::util::macros::__unsafe();

use core::cell::UnsafeCell;
use crate::pointer::{SizeEq, TransmuteFrom, invariant::Valid};
use crate::pointer::{SizeCompat, TransmuteFrom, invariant::Valid};

$(
// SAFETY: The caller promised that `$atomic` and `$prim` have
Expand All @@ -436,28 +436,16 @@ mod atomics {
// the same size and bit validity.
unsafe impl<$($tyvar)?> TransmuteFrom<$prim, Valid, Valid> for $atomic {}

// SAFETY: The caller promised that `$atomic` and `$prim` have
// the same size.
unsafe impl<$($tyvar)?> SizeEq<$atomic> for $prim {
impl<$($tyvar)?> SizeCompat<$atomic> for $prim {
type CastFrom = $crate::pointer::cast::CastSized;
}
// SAFETY: See previous safety comment.
unsafe impl<$($tyvar)?> SizeEq<$prim> for $atomic {
impl<$($tyvar)?> SizeCompat<$prim> for $atomic {
type CastFrom = $crate::pointer::cast::CastSized;
}
// SAFETY: The caller promised that `$atomic` and `$prim` have
// the same size. `UnsafeCell<T>` has the same size as `T` [1].
//
// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
//
// `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)?> SizeEq<$atomic> for UnsafeCell<$prim> {
impl<$($tyvar)?> SizeCompat<$atomic> for UnsafeCell<$prim> {
type CastFrom = $crate::pointer::cast::CastSized;
}
// SAFETY: See previous safety comment.
unsafe impl<$($tyvar)?> SizeEq<UnsafeCell<$prim>> for $atomic {
impl<$($tyvar)?> SizeCompat<UnsafeCell<$prim>> for $atomic {
type CastFrom = $crate::pointer::cast::CastSized;
}

Expand Down
4 changes: 2 additions & 2 deletions src/macros.rs
Original file line number Diff line number Diff line change
Expand Up @@ -674,7 +674,7 @@ macro_rules! try_transmute_ref {
// the value returned from this branch.
let u;

$crate::assert_size_eq!(t, u);
$crate::assert_size_compat!(t, u);
$crate::assert_align_gt_eq!(t, u);

Ok(&u)
Expand Down Expand Up @@ -783,7 +783,7 @@ macro_rules! try_transmute_mut {
// u)` as the value returned from this branch.
let u;

$crate::assert_size_eq!(t, u);
$crate::assert_size_compat!(t, u);
$crate::assert_align_gt_eq!(t, u);

Ok(&mut u)
Expand Down
19 changes: 10 additions & 9 deletions src/pointer/ptr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use crate::{
pointer::{
inner::PtrInner,
invariant::*,
transmute::{MutationCompatible, SizeEq, TransmuteFromPtr},
transmute::{MutationCompatible, SizeCompat, TransmuteFromPtr},
},
AlignmentError, CastError, CastType, KnownLayout, SizeError, TryFromBytes, ValidityError,
};
Expand Down Expand Up @@ -381,10 +381,10 @@ mod _conversions {
pub(crate) fn transmute<U, V, R>(self) -> Ptr<'a, U, (I::Aliasing, Unaligned, V)>
where
V: Validity,
U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, R> + SizeEq<T> + ?Sized,
U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, R> + SizeCompat<T> + ?Sized,
{
// SAFETY:
// - By `SizeEq::CastFrom: Cast`, `SizeEq::CastFrom` preserves
// - By `SizeCompat::CastFrom: Cast`, `SizeCompat::CastFrom` preserves
// referent address, and so we don't need to consider projections
// in the following safety arguments.
// - If aliasing is `Shared`, then by `U: TransmuteFromPtr<T>`, at
Expand All @@ -396,7 +396,7 @@ mod _conversions {
// operate on these references simultaneously
// - By `U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V>`, it is
// sound to perform this transmute.
unsafe { self.project_transmute_unchecked::<_, _, <U as SizeEq<T>>::CastFrom>() }
unsafe { self.project_transmute_unchecked::<_, _, <U as SizeCompat<T>>::CastFrom>() }
}

#[doc(hidden)]
Expand All @@ -408,15 +408,16 @@ mod _conversions {
T: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, R>,
{
// SAFETY:
// - By `SizeEq::CastFrom: Cast`, `SizeEq::CastFrom` preserves
// referent address, and so we don't need to consider projections
// in the following safety arguments.
// - By `SizeCompat::CastFrom: Cast`, `SizeCompat::CastFrom`
// preserves referent address, and so we don't need to consider
// projections in the following safety arguments.
// - It is trivially sound to have multiple `&T` referencing the
// same referent simultaneously
// - By `T: TransmuteFromPtr<T, I::Aliasing, I::Validity, V>`, it is
// sound to perform this transmute.
let ptr =
unsafe { self.project_transmute_unchecked::<_, _, <T as SizeEq<T>>::CastFrom>() };
let ptr = unsafe {
self.project_transmute_unchecked::<_, _, <T as SizeCompat<T>>::CastFrom>()
};
// SAFETY: `self` and `ptr` have the same address and referent type.
// Therefore, if `self` satisfies `I::Alignment`, then so does
// `ptr`.
Expand Down
Loading
Loading