Skip to content

Commit 7b9a12f

Browse files
joshlfjswrenn
andcommitted
[WIP] Generalize SizeEq to SizeCompat
Co-authored-by: Jack Wrenn <[email protected]> gherrit-pr-id: I6c793a9620ad75bdc0d26ab7c7cd1a0c7bef1b8b
1 parent 38c910a commit 7b9a12f

File tree

6 files changed

+184
-119
lines changed

6 files changed

+184
-119
lines changed

src/impls.rs

Lines changed: 33 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,8 @@ const _: () = unsafe {
109109
*byte.unaligned_as_ref() < 2
110110
})
111111
};
112-
impl_size_eq!(bool, u8);
112+
113+
impl_size_compat!(bool, u8);
113114

114115
// SAFETY:
115116
// - `Immutable`: `char` self-evidently does not contain any `UnsafeCell`s.
@@ -140,7 +141,7 @@ const _: () = unsafe {
140141
});
141142
};
142143

143-
impl_size_eq!(char, Unalign<u32>);
144+
impl_size_compat!(char, Unalign<u32>);
144145

145146
// SAFETY: Per the Reference [1], `str` has the same layout as `[u8]`.
146147
// - `Immutable`: `[u8]` does not contain any `UnsafeCell`s.
@@ -173,14 +174,13 @@ const _: () = unsafe {
173174
})
174175
};
175176

176-
impl_size_eq!(str, [u8]);
177+
impl_size_compat!(str, [u8]);
177178

178179
macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
179180
($($nonzero:ident[$prim:ty]),*) => {
180181
$(
181182
unsafe_impl!(=> TryFromBytes for $nonzero; |n| {
182-
impl_size_eq!($nonzero, Unalign<$prim>);
183-
183+
impl_size_compat!($nonzero, Unalign<$prim>);
184184
let n = n.transmute::<Unalign<$prim>, invariant::Valid, _>();
185185
$nonzero::new(n.read_unaligned().into_inner()).is_some()
186186
});
@@ -396,63 +396,72 @@ mod atomics {
396396
($($($tyvar:ident)? => $atomic:ty [$prim:ty]),*) => {{
397397
crate::util::macros::__unsafe();
398398

399-
use core::cell::UnsafeCell;
400-
use crate::pointer::{PtrInner, SizeEq, TransmuteFrom, invariant::Valid};
399+
use core::{cell::UnsafeCell};
400+
use crate::pointer::{TransmuteFrom, PtrInner, SizeCompat, invariant::Valid};
401401

402402
$(
403-
// SAFETY: The caller promised that `$atomic` and `$prim` have
404-
// the same size and bit validity.
403+
// SAFETY: The caller promised that `$atomic` and `$prim`
404+
// have the same size and bit validity. As a result of size
405+
// equality, both impls of `SizeCompat::cast_from_raw`
406+
// preserve referent size exactly.
405407
unsafe impl<$($tyvar)?> TransmuteFrom<$atomic, Valid, Valid> for $prim {}
406-
// SAFETY: The caller promised that `$atomic` and `$prim` have
407-
// the same size and bit validity.
408+
// SAFETY: The caller promised that `$atomic` and `$prim`
409+
// have the same size and bit validity. As a result of size
410+
// equality, both impls of `SizeCompat::cast_from_raw`
411+
// preserve referent size exactly.
408412
unsafe impl<$($tyvar)?> TransmuteFrom<$prim, Valid, Valid> for $atomic {}
409413

410-
// SAFETY: The caller promised that `$atomic` and `$prim` have
411-
// the same size.
412-
unsafe impl<$($tyvar)?> SizeEq<$atomic> for $prim {
414+
// SAFETY: See inline safety comment.
415+
unsafe impl<$($tyvar)?> SizeCompat<$atomic> for $prim {
413416
#[inline]
414417
fn cast_from_raw(a: PtrInner<'_, $atomic>) -> PtrInner<'_, $prim> {
415-
// SAFETY: The caller promised that `$atomic` and
416-
// `$prim` have the same size. Thus, this cast preserves
418+
// SAFETY: The caller promised that `$atomic` and `$prim`
419+
// have the same size. Thus, this cast preserves
417420
// address, referent size, and provenance.
418421
unsafe { cast!(a) }
419422
}
420423
}
421424
// SAFETY: See previous safety comment.
422-
unsafe impl<$($tyvar)?> SizeEq<$prim> for $atomic {
425+
unsafe impl<$($tyvar)?> SizeCompat<$prim> for $atomic {
423426
#[inline]
424427
fn cast_from_raw(p: PtrInner<'_, $prim>) -> PtrInner<'_, $atomic> {
425428
// SAFETY: See previous safety comment.
426429
unsafe { cast!(p) }
427430
}
428431
}
429-
// SAFETY: The caller promised that `$atomic` and `$prim` have
430-
// the same size. `UnsafeCell<T>` has the same size as `T` [1].
432+
433+
// SAFETY: The caller promised that `$atomic` and `$prim`
434+
// have the same size. `UnsafeCell<T>` has the same size as
435+
// `T` [1]. Thus, this cast preserves address, referent
436+
// size, and provenance.
431437
//
432438
// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
433439
//
434440
// `UnsafeCell<T>` has the same in-memory representation as
435441
// its inner type `T`. A consequence of this guarantee is that
436442
// it is possible to convert between `T` and `UnsafeCell<T>`.
437-
unsafe impl<$($tyvar)?> SizeEq<$atomic> for UnsafeCell<$prim> {
443+
unsafe impl<$($tyvar)?> SizeCompat<$atomic> for UnsafeCell<$prim> {
438444
#[inline]
439445
fn cast_from_raw(a: PtrInner<'_, $atomic>) -> PtrInner<'_, UnsafeCell<$prim>> {
440446
// SAFETY: See previous safety comment.
441447
unsafe { cast!(a) }
442448
}
443449
}
444450
// SAFETY: See previous safety comment.
445-
unsafe impl<$($tyvar)?> SizeEq<UnsafeCell<$prim>> for $atomic {
451+
unsafe impl<$($tyvar)?> SizeCompat<UnsafeCell<$prim>> for $atomic {
446452
#[inline]
447453
fn cast_from_raw(p: PtrInner<'_, UnsafeCell<$prim>>) -> PtrInner<'_, $atomic> {
448454
// SAFETY: See previous safety comment.
449455
unsafe { cast!(p) }
450456
}
451457
}
452458

453-
// SAFETY: The caller promised that `$atomic` and `$prim` have
454-
// the same bit validity. `UnsafeCell<T>` has the same bit
455-
// validity as `T` [1].
459+
// SAFETY: The caller promised that `$atomic` and `$prim`
460+
// have the same bit validity. `UnsafeCell<T>` has the same
461+
// bit validity as `T` [1]. `UnsafeCell<T>` also has the
462+
// same size as `T` [1], and so both impls of
463+
// `SizeCompat::cast_from_raw` preserve referent size
464+
// exactly.
456465
//
457466
// [1] Per https://doc.rust-lang.org/1.85.0/std/cell/struct.UnsafeCell.html#memory-layout:
458467
//

src/layout.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -612,15 +612,15 @@ pub(crate) use cast_from_raw::cast_from_raw;
612612
mod cast_from_raw {
613613
use crate::{pointer::PtrInner, *};
614614

615-
/// Implements [`<Dst as SizeEq<Src>>::cast_from_raw`][cast_from_raw].
615+
/// Implements [`<Dst as SizeCompat<Src>>::cast_from_raw`][cast_from_raw].
616616
///
617617
/// # PME
618618
///
619619
/// Generates a post-monomorphization error if it is not possible to satisfy
620-
/// the soundness conditions of [`SizeEq::cast_from_raw`][cast_from_raw]
620+
/// the soundness conditions of [`SizeCompat::cast_from_raw`][cast_from_raw]
621621
/// for `Src` and `Dst`.
622622
///
623-
/// [cast_from_raw]: crate::pointer::SizeEq::cast_from_raw
623+
/// [cast_from_raw]: crate::pointer::SizeCompat::cast_from_raw
624624
//
625625
// TODO(#1817): Support Sized->Unsized and Unsized->Sized casts
626626
pub(crate) fn cast_from_raw<Src, Dst>(src: PtrInner<'_, Src>) -> PtrInner<'_, Dst>

src/pointer/ptr.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use crate::{
1616
pointer::{
1717
inner::PtrInner,
1818
invariant::*,
19-
transmute::{MutationCompatible, SizeEq, TransmuteFromPtr},
19+
transmute::{MutationCompatible, SizeCompat, TransmuteFromPtr},
2020
},
2121
AlignmentError, CastError, CastType, KnownLayout, SizeError, TryFromBytes, ValidityError,
2222
};
@@ -388,10 +388,10 @@ mod _conversions {
388388
pub(crate) fn transmute<U, V, R>(self) -> Ptr<'a, U, (I::Aliasing, Unaligned, V)>
389389
where
390390
V: Validity,
391-
U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, R> + SizeEq<T> + ?Sized,
391+
U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V, R> + SizeCompat<T> + ?Sized,
392392
{
393393
// SAFETY:
394-
// - `SizeEq::cast_from_raw` promises to preserve address,
394+
// - `SizeCompat::cast_from_raw` promises to preserve address,
395395
// provenance, and the number of bytes in the referent
396396
// - If aliasing is `Shared`, then by `U: TransmuteFromPtr<T>`, at
397397
// least one of the following holds:
@@ -402,7 +402,7 @@ mod _conversions {
402402
// operate on these references simultaneously
403403
// - By `U: TransmuteFromPtr<T, I::Aliasing, I::Validity, V>`, it is
404404
// sound to perform this transmute.
405-
unsafe { self.transmute_unchecked(|ptr| SizeEq::cast_from_raw(ptr).as_non_null()) }
405+
unsafe { self.transmute_unchecked(|ptr| SizeCompat::cast_from_raw(ptr).as_non_null()) }
406406
}
407407

408408
#[doc(hidden)]

0 commit comments

Comments
 (0)