Skip to content

Commit 61235a0

Browse files
committed
[pointer] Add generic projection/cast framework
Add `unsafe trait Project` and `unsafe trait Cast: Project`. `Cast` is implemented for any address-preserving cast, while `Project` generalizes to conversions which may not preserve the address of the referent (ie, field projections). Use these (mostly `Cast`, but some `Project`) to unify `PtrInner`/`Ptr` casts, field projections, and `SizeEq` casts. Replace a good amount of unsafe derive-generated code with uses of this machinery. gherrit-pr-id: G57b42ad4ff767a765f9b4ac149aa1c19d3796711
1 parent b99b86d commit 61235a0

File tree

17 files changed

+4254
-4058
lines changed

17 files changed

+4254
-4058
lines changed

src/impls.rs

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -426,7 +426,7 @@ mod atomics {
426426
crate::util::macros::__unsafe();
427427

428428
use core::cell::UnsafeCell;
429-
use crate::pointer::{PtrInner, SizeEq, TransmuteFrom, invariant::Valid};
429+
use crate::pointer::{SizeEq, TransmuteFrom, invariant::Valid};
430430

431431
$(
432432
// SAFETY: The caller promised that `$atomic` and `$prim` have
@@ -439,21 +439,11 @@ mod atomics {
439439
// SAFETY: The caller promised that `$atomic` and `$prim` have
440440
// the same size.
441441
unsafe impl<$($tyvar)?> SizeEq<$atomic> for $prim {
442-
#[inline]
443-
fn cast_from_raw(a: PtrInner<'_, $atomic>) -> PtrInner<'_, $prim> {
444-
// SAFETY: The caller promised that `$atomic` and
445-
// `$prim` have the same size. Thus, this cast preserves
446-
// address, referent size, and provenance.
447-
unsafe { cast!(a) }
448-
}
442+
type CastFrom = $crate::pointer::cast::CastSized;
449443
}
450444
// SAFETY: See previous safety comment.
451445
unsafe impl<$($tyvar)?> SizeEq<$prim> for $atomic {
452-
#[inline]
453-
fn cast_from_raw(p: PtrInner<'_, $prim>) -> PtrInner<'_, $atomic> {
454-
// SAFETY: See previous safety comment.
455-
unsafe { cast!(p) }
456-
}
446+
type CastFrom = $crate::pointer::cast::CastSized;
457447
}
458448
// SAFETY: The caller promised that `$atomic` and `$prim` have
459449
// the same size. `UnsafeCell<T>` has the same size as `T` [1].
@@ -464,19 +454,11 @@ mod atomics {
464454
// its inner type `T`. A consequence of this guarantee is that
465455
// it is possible to convert between `T` and `UnsafeCell<T>`.
466456
unsafe impl<$($tyvar)?> SizeEq<$atomic> for UnsafeCell<$prim> {
467-
#[inline]
468-
fn cast_from_raw(a: PtrInner<'_, $atomic>) -> PtrInner<'_, UnsafeCell<$prim>> {
469-
// SAFETY: See previous safety comment.
470-
unsafe { cast!(a) }
471-
}
457+
type CastFrom = $crate::pointer::cast::CastSized;
472458
}
473459
// SAFETY: See previous safety comment.
474460
unsafe impl<$($tyvar)?> SizeEq<UnsafeCell<$prim>> for $atomic {
475-
#[inline]
476-
fn cast_from_raw(p: PtrInner<'_, UnsafeCell<$prim>>) -> PtrInner<'_, $atomic> {
477-
// SAFETY: See previous safety comment.
478-
unsafe { cast!(p) }
479-
}
461+
type CastFrom = $crate::pointer::cast::CastSized;
480462
}
481463

482464
// SAFETY: The caller promised that `$atomic` and `$prim` have
@@ -818,7 +800,8 @@ const _: () = {
818800
// private field, and because it is the name it is referred to in the public
819801
// documentation of `ManuallyDrop::new`, `ManuallyDrop::into_inner`,
820802
// `ManuallyDrop::take` and `ManuallyDrop::drop`.
821-
unsafe impl<T> HasField<value, { crate::STRUCT_VARIANT_ID }, { crate::ident_id!(value) }>
803+
unsafe impl<T: ?Sized>
804+
HasField<value, { crate::STRUCT_VARIANT_ID }, { crate::ident_id!(value) }>
822805
for ManuallyDrop<T>
823806
{
824807
type Type = T;
@@ -831,15 +814,16 @@ const _: () = {
831814
}
832815

833816
#[inline(always)]
834-
fn project(slf: PtrInner<'_, Self>) -> PtrInner<'_, T> {
817+
unsafe fn project(slf: *mut Self) -> *mut T {
835818
// SAFETY: `ManuallyDrop<T>` has the same layout and bit validity as
836819
// `T` [1].
837820
//
838821
// [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
839822
//
840823
// `ManuallyDrop<T>` is guaranteed to have the same layout and bit
841824
// validity as `T`
842-
unsafe { slf.cast() }
825+
#[allow(clippy::as_conversions)]
826+
return slf as *mut T;
843827
}
844828
}
845829
};

0 commit comments

Comments
 (0)