@@ -417,13 +417,14 @@ mod atomics {
417417 use super :: * ;
418418
419419 macro_rules! impl_traits_for_atomics {
420- ( $( $atomics: ident) ,* $( , ) ?) => {
420+ ( $( $atomics: ident [ $primitives : ident ] ) ,* $( , ) ?) => {
421421 $(
422+ impl_size_eq!( $atomics, $primitives) ;
422423 impl_known_layout!( $atomics) ;
423- impl_for_transparent_wrapper !( => TryFromBytes for $atomics) ;
424- impl_for_transparent_wrapper!( => FromZeros for $atomics) ;
425- impl_for_transparent_wrapper!( => FromBytes for $atomics) ;
426- impl_for_transparent_wrapper!( => IntoBytes for $atomics) ;
424+ impl_for_transmute_from !( => TryFromBytes for $atomics [ UnsafeCell <$primitives> ] ) ;
425+ impl_for_transparent_wrapper!( => FromZeros for $atomics [ UnsafeCell <$primitives> ] ) ;
426+ impl_for_transparent_wrapper!( => FromBytes for $atomics [ UnsafeCell <$primitives> ] ) ;
427+ impl_for_transparent_wrapper!( => IntoBytes for $atomics [ UnsafeCell <$primitives> ] ) ;
427428 ) *
428429 } ;
429430 }
@@ -435,13 +436,14 @@ mod atomics {
435436
436437 use super :: * ;
437438
438- impl_traits_for_atomics ! ( AtomicU8 , AtomicI8 ) ;
439+ impl_traits_for_atomics ! ( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] ) ;
439440
441+ impl_size_eq ! ( AtomicBool , bool ) ;
440442 impl_known_layout ! ( AtomicBool ) ;
441443
442- impl_for_transparent_wrapper ! ( => TryFromBytes for AtomicBool ) ;
443- impl_for_transparent_wrapper ! ( => FromZeros for AtomicBool ) ;
444- impl_for_transparent_wrapper ! ( => IntoBytes for AtomicBool ) ;
444+ impl_for_transmute_from ! ( => TryFromBytes for AtomicBool [ UnsafeCell < bool > ] ) ;
445+ impl_for_transparent_wrapper ! ( => FromZeros for AtomicBool [ UnsafeCell < bool > ] ) ;
446+ impl_for_transparent_wrapper ! ( => IntoBytes for AtomicBool [ UnsafeCell < bool > ] ) ;
445447
446448 safety_comment ! {
447449 /// SAFETY:
@@ -468,10 +470,8 @@ mod atomics {
468470 unsafe_impl!( AtomicI8 : Unaligned ) ;
469471 assert_unaligned!( AtomicBool , AtomicU8 , AtomicI8 ) ;
470472
471- /// SAFETY:
472- /// All of these pass an atomic type and that type's native equivalent, as
473- /// required by the macro safety preconditions.
474- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] , AtomicBool [ bool ] ) ;
473+ /// SAFETY: TODO
474+ unsafe_impl_transmute_from_for_atomic!( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] , AtomicBool [ bool ] ) ;
475475 }
476476 }
477477
@@ -482,13 +482,11 @@ mod atomics {
482482
483483 use super :: * ;
484484
485- impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
485+ impl_traits_for_atomics ! ( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
486486
487487 safety_comment ! {
488- /// SAFETY:
489- /// All of these pass an atomic type and that type's native equivalent, as
490- /// required by the macro safety preconditions.
491- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
488+ /// SAFETY: TODO
489+ unsafe_impl_transmute_from_for_atomic!( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
492490 }
493491 }
494492
@@ -499,13 +497,11 @@ mod atomics {
499497
500498 use super :: * ;
501499
502- impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
500+ impl_traits_for_atomics ! ( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503501
504502 safety_comment ! {
505- /// SAFETY:
506- /// All of these pass an atomic type and that type's native equivalent, as
507- /// required by the macro safety preconditions.
508- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503+ /// SAFETY: TODO
504+ unsafe_impl_transmute_from_for_atomic!( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
509505 }
510506 }
511507
@@ -516,13 +512,11 @@ mod atomics {
516512
517513 use super :: * ;
518514
519- impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
515+ impl_traits_for_atomics ! ( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
520516
521517 safety_comment ! {
522- /// SAFETY:
523- /// All of these pass an atomic type and that type's native equivalent, as
524- /// required by the macro safety preconditions.
525- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
518+ /// SAFETY: TODO
519+ unsafe_impl_transmute_from_for_atomic!( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
526520 }
527521 }
528522
@@ -533,21 +527,27 @@ mod atomics {
533527
534528 use super :: * ;
535529
536- impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
530+ impl_traits_for_atomics ! ( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
537531
538532 impl_known_layout ! ( T => AtomicPtr <T >) ;
539533
534+ // SAFETY: `AtomicPtr<T>` and `*mut T` have the same size [1].
535+ //
536+ // [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicPtr.html:
537+ //
538+ // This type has the same size and bit validity as a `*mut T`.
539+ unsafe impl < T > crate :: pointer:: SizeEq < * mut T > for AtomicPtr < T > { }
540+ // SAFETY: See previous safety comment.
541+ unsafe impl < T > crate :: pointer:: SizeEq < AtomicPtr < T > > for * mut T { }
542+
540543 // TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541544 // those traits for `*mut T`.
542- impl_for_transparent_wrapper ! ( T => TryFromBytes for AtomicPtr <T >) ;
543- impl_for_transparent_wrapper ! ( T => FromZeros for AtomicPtr <T >) ;
545+ impl_for_transmute_from ! ( T => TryFromBytes for AtomicPtr <T > [ UnsafeCell <* mut T >] ) ;
544546
545547 safety_comment ! {
546- /// SAFETY:
547- /// This passes an atomic type and that type's native equivalent, as
548- /// required by the macro safety preconditions.
549- unsafe_impl_transparent_wrapper_for_atomic!( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
550- unsafe_impl_transparent_wrapper_for_atomic!( T => AtomicPtr <T > [ * mut T ] ) ;
548+ /// SAFETY: TODO
549+ unsafe_impl_transmute_from_for_atomic!( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
550+ unsafe_impl_transmute_from_for_atomic!( T => AtomicPtr <T > [ * mut T ] ) ;
551551 }
552552 }
553553}
@@ -577,12 +577,12 @@ safety_comment! {
577577 assert_unaligned!( PhantomData <( ) >, PhantomData <u8 >, PhantomData <u64 >) ;
578578}
579579
580- impl_for_transparent_wrapper ! ( T : Immutable => Immutable for Wrapping <T >) ;
581- impl_for_transparent_wrapper ! ( T : TryFromBytes => TryFromBytes for Wrapping <T >) ;
582- impl_for_transparent_wrapper ! ( T : FromZeros => FromZeros for Wrapping <T >) ;
583- impl_for_transparent_wrapper ! ( T : FromBytes => FromBytes for Wrapping <T >) ;
584- impl_for_transparent_wrapper ! ( T : IntoBytes => IntoBytes for Wrapping <T >) ;
585- impl_for_transparent_wrapper ! ( T : Unaligned => Unaligned for Wrapping <T >) ;
580+ unsafe_impl ! ( T : Immutable => Immutable for Wrapping <T >) ;
581+ impl_for_transmute_from ! ( T : TryFromBytes => TryFromBytes for Wrapping <T >[ T ] ) ;
582+ impl_for_transparent_wrapper ! ( T : FromZeros => FromZeros for Wrapping <T >[ T ] ) ;
583+ impl_for_transparent_wrapper ! ( T : FromBytes => FromBytes for Wrapping <T >[ T ] ) ;
584+ impl_for_transparent_wrapper ! ( T : IntoBytes => IntoBytes for Wrapping <T >[ T ] ) ;
585+ unsafe_impl ! ( T : Unaligned => Unaligned for Wrapping <T >) ;
586586assert_unaligned ! ( Wrapping <( ) >, Wrapping <u8 >) ;
587587
588588safety_comment ! {
@@ -594,22 +594,52 @@ safety_comment! {
594594 unsafe_impl!( T => FromBytes for CoreMaybeUninit <T >) ;
595595}
596596
597- impl_for_transparent_wrapper ! ( T : Immutable => Immutable for CoreMaybeUninit <T >) ;
598- impl_for_transparent_wrapper ! ( T : Unaligned => Unaligned for CoreMaybeUninit <T >) ;
597+ unsafe_impl ! ( T : Immutable => Immutable for CoreMaybeUninit <T >) ;
598+ unsafe_impl ! ( T : Unaligned => Unaligned for CoreMaybeUninit <T >) ;
599599assert_unaligned ! ( CoreMaybeUninit <( ) >, CoreMaybeUninit <u8 >) ;
600600
601- impl_for_transparent_wrapper ! ( T : ?Sized + Immutable => Immutable for ManuallyDrop <T >) ;
602- impl_for_transparent_wrapper ! ( T : ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop <T >) ;
603- impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for ManuallyDrop <T >) ;
604- impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for ManuallyDrop <T >) ;
605- impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for ManuallyDrop <T >) ;
606- impl_for_transparent_wrapper ! ( T : ?Sized + Unaligned => Unaligned for ManuallyDrop <T >) ;
601+ unsafe_impl ! ( T : ?Sized + Immutable => Immutable for ManuallyDrop <T >) ;
602+
603+ // SAFETY: See inline safety comment justifying that the implementation of
604+ // `is_bit_valid`is sound.
605+ unsafe impl < T : ?Sized + TryFromBytes > TryFromBytes for ManuallyDrop < T > {
606+ #[ allow( clippy:: missing_inline_in_public_items) ]
607+ fn only_derive_is_allowed_to_implement_this_trait ( ) { }
608+
609+ #[ inline( always) ]
610+ fn is_bit_valid < A : crate :: pointer:: invariant:: Reference > (
611+ candidate : Maybe < ' _ , Self , A > ,
612+ ) -> bool {
613+ // SAFETY: `ManuallyDrop<T>` and `T` have the same size [1], so this
614+ // cast preserves size. It also preserves provenance.
615+ //
616+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
617+ //
618+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
619+ // validity as `T`
620+ let c: Maybe < ' _ , T , A > = unsafe { candidate. cast_unsized ( |p| cast ! ( p => NonNull <_>) ) } ;
621+
622+ // SAFETY: `ManuallyDrop<T>` and `T` have the same bit validity [1], so
623+ // this is a sound implementation of `ManuallyDrop::is_bit_valid`.
624+ //
625+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
626+ //
627+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
628+ // validity as `T`
629+ <T as TryFromBytes >:: is_bit_valid ( c)
630+ }
631+ }
632+
633+ impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for ManuallyDrop <T >[ T ] ) ;
634+ impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for ManuallyDrop <T >[ T ] ) ;
635+ impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for ManuallyDrop <T >[ T ] ) ;
636+ unsafe_impl ! ( T : ?Sized + Unaligned => Unaligned for ManuallyDrop <T >) ;
607637assert_unaligned ! ( ManuallyDrop <( ) >, ManuallyDrop <u8 >) ;
608638
609- impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for UnsafeCell <T >) ;
610- impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for UnsafeCell <T >) ;
611- impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for UnsafeCell <T >) ;
612- impl_for_transparent_wrapper ! ( T : ?Sized + Unaligned => Unaligned for UnsafeCell <T >) ;
639+ impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for UnsafeCell <T >[ T ] ) ;
640+ impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for UnsafeCell <T >[ T ] ) ;
641+ impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for UnsafeCell <T >[ T ] ) ;
642+ unsafe_impl ! ( T : ?Sized + Unaligned => Unaligned for UnsafeCell <T >) ;
613643assert_unaligned ! ( UnsafeCell <( ) >, UnsafeCell <u8 >) ;
614644
615645// SAFETY: See safety comment in `is_bit_valid` impl.
0 commit comments