Skip to content

Commit 06c65ba

Browse files
committed
[pointer][transmute] Support generic TransmuteFrom
This commit replaces the `TransparentWrapper` trait with a more generic, bidirectional `TransmuteFrom<T>` trait. `U: TransmuteFrom<T>` indicates that `T` and `U` have the same sizes and that `T` can be transmuted into `U` given certain alignment and validity invariant mappings. Makes progress on #1122 gherrit-pr-id: I25973ea67f59671329a920dd39183c1348942a1a
1 parent 2b2f66a commit 06c65ba

File tree

7 files changed

+961
-418
lines changed

7 files changed

+961
-418
lines changed

src/impls.rs

+39-39
Original file line numberDiff line numberDiff line change
@@ -447,13 +447,13 @@ mod atomics {
447447
use super::*;
448448

449449
macro_rules! impl_traits_for_atomics {
450-
($($atomics:ident),* $(,)?) => {
450+
($($atomics:ident[$repr:ty]),* $(,)?) => {
451451
$(
452452
impl_known_layout!($atomics);
453-
impl_for_transparent_wrapper!(=> TryFromBytes for $atomics);
454-
impl_for_transparent_wrapper!(=> FromZeros for $atomics);
455-
impl_for_transparent_wrapper!(=> FromBytes for $atomics);
456-
impl_for_transparent_wrapper!(=> IntoBytes for $atomics);
453+
impl_for_transmute_from!(=> TryFromBytes for $atomics[UnsafeCell<$repr>]);
454+
impl_for_transmute_from!(=> FromZeros for $atomics[UnsafeCell<$repr>]);
455+
impl_for_transmute_from!(=> FromBytes for $atomics[UnsafeCell<$repr>]);
456+
impl_for_transmute_from!(=> IntoBytes for $atomics[UnsafeCell<$repr>]);
457457
)*
458458
};
459459
}
@@ -465,13 +465,13 @@ mod atomics {
465465

466466
use super::*;
467467

468-
impl_traits_for_atomics!(AtomicU8, AtomicI8);
468+
impl_traits_for_atomics!(AtomicU8[u8], AtomicI8[i8]);
469469

470470
impl_known_layout!(AtomicBool);
471471

472-
impl_for_transparent_wrapper!(=> TryFromBytes for AtomicBool);
473-
impl_for_transparent_wrapper!(=> FromZeros for AtomicBool);
474-
impl_for_transparent_wrapper!(=> IntoBytes for AtomicBool);
472+
impl_for_transmute_from!(=> TryFromBytes for AtomicBool[UnsafeCell<bool>]);
473+
impl_for_transmute_from!(=> FromZeros for AtomicBool[UnsafeCell<bool>]);
474+
impl_for_transmute_from!(=> IntoBytes for AtomicBool[UnsafeCell<bool>]);
475475

476476
safety_comment! {
477477
/// SAFETY:
@@ -501,7 +501,7 @@ mod atomics {
501501
/// SAFETY:
502502
/// All of these pass an atomic type and that type's native equivalent, as
503503
/// required by the macro safety preconditions.
504-
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU8 [u8], AtomicI8 [i8], AtomicBool [bool]);
504+
unsafe_impl_transmute_from_for_atomic!(AtomicU8 [u8], AtomicI8 [i8], AtomicBool [bool]);
505505
}
506506
}
507507

@@ -512,13 +512,13 @@ mod atomics {
512512

513513
use super::*;
514514

515-
impl_traits_for_atomics!(AtomicU16, AtomicI16);
515+
impl_traits_for_atomics!(AtomicU16[u16], AtomicI16[i16]);
516516

517517
safety_comment! {
518518
/// SAFETY:
519519
/// All of these pass an atomic type and that type's native equivalent, as
520520
/// required by the macro safety preconditions.
521-
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU16 [u16], AtomicI16 [i16]);
521+
unsafe_impl_transmute_from_for_atomic!(AtomicU16 [u16], AtomicI16 [i16]);
522522
}
523523
}
524524

@@ -529,13 +529,13 @@ mod atomics {
529529

530530
use super::*;
531531

532-
impl_traits_for_atomics!(AtomicU32, AtomicI32);
532+
impl_traits_for_atomics!(AtomicU32[u32], AtomicI32[i32]);
533533

534534
safety_comment! {
535535
/// SAFETY:
536536
/// All of these pass an atomic type and that type's native equivalent, as
537537
/// required by the macro safety preconditions.
538-
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU32 [u32], AtomicI32 [i32]);
538+
unsafe_impl_transmute_from_for_atomic!(AtomicU32 [u32], AtomicI32 [i32]);
539539
}
540540
}
541541

@@ -546,13 +546,13 @@ mod atomics {
546546

547547
use super::*;
548548

549-
impl_traits_for_atomics!(AtomicU64, AtomicI64);
549+
impl_traits_for_atomics!(AtomicU64[u64], AtomicI64[i64]);
550550

551551
safety_comment! {
552552
/// SAFETY:
553553
/// All of these pass an atomic type and that type's native equivalent, as
554554
/// required by the macro safety preconditions.
555-
unsafe_impl_transparent_wrapper_for_atomic!(AtomicU64 [u64], AtomicI64 [i64]);
555+
unsafe_impl_transmute_from_for_atomic!(AtomicU64 [u64], AtomicI64 [i64]);
556556
}
557557
}
558558

@@ -563,21 +563,21 @@ mod atomics {
563563

564564
use super::*;
565565

566-
impl_traits_for_atomics!(AtomicUsize, AtomicIsize);
566+
impl_traits_for_atomics!(AtomicUsize[usize], AtomicIsize[isize]);
567567

568568
impl_known_layout!(T => AtomicPtr<T>);
569569

570570
// TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
571571
// those traits for `*mut T`.
572-
impl_for_transparent_wrapper!(T => TryFromBytes for AtomicPtr<T>);
573-
impl_for_transparent_wrapper!(T => FromZeros for AtomicPtr<T>);
572+
impl_for_transmute_from!(T => TryFromBytes for AtomicPtr<T>[UnsafeCell<*mut T>]);
573+
impl_for_transmute_from!(T => FromZeros for AtomicPtr<T>[UnsafeCell<*mut T>]);
574574

575575
safety_comment! {
576576
/// SAFETY:
577577
/// This passes an atomic type and that type's native equivalent, as
578578
/// required by the macro safety preconditions.
579-
unsafe_impl_transparent_wrapper_for_atomic!(AtomicUsize [usize], AtomicIsize [isize]);
580-
unsafe_impl_transparent_wrapper_for_atomic!(T => AtomicPtr<T> [*mut T]);
579+
unsafe_impl_transmute_from_for_atomic!(AtomicUsize [usize], AtomicIsize [isize]);
580+
unsafe_impl_transmute_from_for_atomic!(T => AtomicPtr<T> [*mut T]);
581581
}
582582
}
583583
}
@@ -607,12 +607,12 @@ safety_comment! {
607607
assert_unaligned!(PhantomData<()>, PhantomData<u8>, PhantomData<u64>);
608608
}
609609

610-
impl_for_transparent_wrapper!(T: Immutable => Immutable for Wrapping<T>);
611-
impl_for_transparent_wrapper!(T: TryFromBytes => TryFromBytes for Wrapping<T>);
612-
impl_for_transparent_wrapper!(T: FromZeros => FromZeros for Wrapping<T>);
613-
impl_for_transparent_wrapper!(T: FromBytes => FromBytes for Wrapping<T>);
614-
impl_for_transparent_wrapper!(T: IntoBytes => IntoBytes for Wrapping<T>);
615-
impl_for_transparent_wrapper!(T: Unaligned => Unaligned for Wrapping<T>);
610+
impl_for_transmute_from!(T: Immutable => Immutable for Wrapping<T>[T]);
611+
impl_for_transmute_from!(T: TryFromBytes => TryFromBytes for Wrapping<T>[T]);
612+
impl_for_transmute_from!(T: FromZeros => FromZeros for Wrapping<T>[T]);
613+
impl_for_transmute_from!(T: FromBytes => FromBytes for Wrapping<T>[T]);
614+
impl_for_transmute_from!(T: IntoBytes => IntoBytes for Wrapping<T>[T]);
615+
impl_for_transmute_from!(T: Unaligned => Unaligned for Wrapping<T>[T]);
616616
assert_unaligned!(Wrapping<()>, Wrapping<u8>);
617617

618618
safety_comment! {
@@ -624,22 +624,22 @@ safety_comment! {
624624
unsafe_impl!(T => FromBytes for MaybeUninit<T>);
625625
}
626626

627-
impl_for_transparent_wrapper!(T: Immutable => Immutable for MaybeUninit<T>);
628-
impl_for_transparent_wrapper!(T: Unaligned => Unaligned for MaybeUninit<T>);
627+
impl_for_transmute_from!(T: Immutable => Immutable for MaybeUninit<T>[T]);
628+
impl_for_transmute_from!(T: Unaligned => Unaligned for MaybeUninit<T>[T]);
629629
assert_unaligned!(MaybeUninit<()>, MaybeUninit<u8>);
630630

631-
impl_for_transparent_wrapper!(T: ?Sized + Immutable => Immutable for ManuallyDrop<T>);
632-
impl_for_transparent_wrapper!(T: ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop<T>);
633-
impl_for_transparent_wrapper!(T: ?Sized + FromZeros => FromZeros for ManuallyDrop<T>);
634-
impl_for_transparent_wrapper!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>);
635-
impl_for_transparent_wrapper!(T: ?Sized + IntoBytes => IntoBytes for ManuallyDrop<T>);
636-
impl_for_transparent_wrapper!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>);
631+
impl_for_transmute_from!(T: ?Sized + Immutable => Immutable for ManuallyDrop<T>[T]);
632+
impl_for_transmute_from!(T: ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop<T>[T]);
633+
impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for ManuallyDrop<T>[T]);
634+
impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for ManuallyDrop<T>[T]);
635+
impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for ManuallyDrop<T>[T]);
636+
impl_for_transmute_from!(T: ?Sized + Unaligned => Unaligned for ManuallyDrop<T>[T]);
637637
assert_unaligned!(ManuallyDrop<()>, ManuallyDrop<u8>);
638638

639-
impl_for_transparent_wrapper!(T: ?Sized + FromZeros => FromZeros for UnsafeCell<T>);
640-
impl_for_transparent_wrapper!(T: ?Sized + FromBytes => FromBytes for UnsafeCell<T>);
641-
impl_for_transparent_wrapper!(T: ?Sized + IntoBytes => IntoBytes for UnsafeCell<T>);
642-
impl_for_transparent_wrapper!(T: ?Sized + Unaligned => Unaligned for UnsafeCell<T>);
639+
impl_for_transmute_from!(T: ?Sized + FromZeros => FromZeros for UnsafeCell<T>[T]);
640+
impl_for_transmute_from!(T: ?Sized + FromBytes => FromBytes for UnsafeCell<T>[T]);
641+
impl_for_transmute_from!(T: ?Sized + IntoBytes => IntoBytes for UnsafeCell<T>[T]);
642+
impl_for_transmute_from!(T: ?Sized + Unaligned => Unaligned for UnsafeCell<T>[T]);
643643
assert_unaligned!(UnsafeCell<()>, UnsafeCell<u8>);
644644

645645
// SAFETY: See safety comment in `is_bit_valid` impl.

src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -2748,7 +2748,8 @@ unsafe fn try_read_from<S, T: TryFromBytes>(
27482748
// We use `from_mut` despite not mutating via `c_ptr` so that we don't need
27492749
// to add a `T: Immutable` bound.
27502750
let c_ptr = Ptr::from_mut(&mut candidate);
2751-
let c_ptr = c_ptr.transparent_wrapper_into_inner();
2751+
let c_ptr = c_ptr
2752+
.transmute::<_, _, crate::invariant::Unknown, pointer::transmute::BecauseBidirectional>();
27522753
// SAFETY: `c_ptr` has no uninitialized sub-ranges because it derived from
27532754
// `candidate`, which the caller promises is entirely initialized.
27542755
let c_ptr = unsafe { c_ptr.assume_validity::<invariant::Initialized>() };

0 commit comments

Comments
 (0)