@@ -417,13 +417,15 @@ 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!(=> TryFromBytes for $atomics);
426+ impl_for_transparent_wrapper!( => FromZeros for $atomics [ UnsafeCell <$primitives>] ) ;
427+ impl_for_transparent_wrapper!( => FromBytes for $atomics [ UnsafeCell <$primitives>] ) ;
428+ impl_for_transparent_wrapper!( => IntoBytes for $atomics [ UnsafeCell <$primitives>] ) ;
427429 ) *
428430 } ;
429431 }
@@ -435,13 +437,15 @@ mod atomics {
435437
436438 use super :: * ;
437439
438- impl_traits_for_atomics ! ( AtomicU8 , AtomicI8 ) ;
440+ impl_traits_for_atomics ! ( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] ) ;
439441
442+ impl_size_eq ! ( AtomicBool , bool ) ;
440443 impl_known_layout ! ( AtomicBool ) ;
441444
442- impl_for_transparent_wrapper ! ( => TryFromBytes for AtomicBool ) ;
443- impl_for_transparent_wrapper ! ( => FromZeros for AtomicBool ) ;
444- impl_for_transparent_wrapper ! ( => IntoBytes for AtomicBool ) ;
445+ // impl_for_transparent_wrapper!(=> TryFromBytes for AtomicBool);
446+ impl_for_transmute_from ! ( => TryFromBytes for AtomicBool [ UnsafeCell <bool >] ) ;
447+ impl_for_transparent_wrapper ! ( => FromZeros for AtomicBool [ UnsafeCell <bool >] ) ;
448+ impl_for_transparent_wrapper ! ( => IntoBytes for AtomicBool [ UnsafeCell <bool >] ) ;
445449
446450 safety_comment ! {
447451 /// SAFETY:
@@ -471,7 +475,8 @@ mod atomics {
471475 /// SAFETY:
472476 /// All of these pass an atomic type and that type's native equivalent, as
473477 /// required by the macro safety preconditions.
474- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] , AtomicBool [ bool ] ) ;
478+ // unsafe_impl_transparent_wrapper_for_atomic!(AtomicU8 [u8], AtomicI8 [i8], AtomicBool [bool]);
479+ unsafe_impl_transmute_from_for_atomic!( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] , AtomicBool [ bool ] ) ;
475480 }
476481 }
477482
@@ -482,13 +487,14 @@ mod atomics {
482487
483488 use super :: * ;
484489
485- impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
490+ impl_traits_for_atomics ! ( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
486491
487492 safety_comment ! {
488493 /// SAFETY:
489494 /// All of these pass an atomic type and that type's native equivalent, as
490495 /// required by the macro safety preconditions.
491- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
496+ // unsafe_impl_transparent_wrapper_for_atomic!(AtomicU16 [u16], AtomicI16 [i16]);
497+ unsafe_impl_transmute_from_for_atomic!( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
492498 }
493499 }
494500
@@ -499,13 +505,14 @@ mod atomics {
499505
500506 use super :: * ;
501507
502- impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
508+ impl_traits_for_atomics ! ( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503509
504510 safety_comment ! {
505511 /// SAFETY:
506512 /// All of these pass an atomic type and that type's native equivalent, as
507513 /// required by the macro safety preconditions.
508- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
514+ // unsafe_impl_transparent_wrapper_for_atomic!(AtomicU32 [u32], AtomicI32 [i32]);
515+ unsafe_impl_transmute_from_for_atomic!( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
509516 }
510517 }
511518
@@ -516,13 +523,14 @@ mod atomics {
516523
517524 use super :: * ;
518525
519- impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
526+ impl_traits_for_atomics ! ( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
520527
521528 safety_comment ! {
522529 /// SAFETY:
523530 /// All of these pass an atomic type and that type's native equivalent, as
524531 /// required by the macro safety preconditions.
525- unsafe_impl_transparent_wrapper_for_atomic!( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
532+ // unsafe_impl_transparent_wrapper_for_atomic!(AtomicU64 [u64], AtomicI64 [i64]);
533+ unsafe_impl_transmute_from_for_atomic!( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
526534 }
527535 }
528536
@@ -533,21 +541,34 @@ mod atomics {
533541
534542 use super :: * ;
535543
536- impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
544+ impl_traits_for_atomics ! ( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
537545
538546 impl_known_layout ! ( T => AtomicPtr <T >) ;
539547
548+ // SAFETY: `AtomicPtr<T>` and `*mut T` have the same size [1].
549+ //
550+ // [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicPtr.html:
551+ //
552+ // This type has the same size and bit validity as a `*mut T`.
553+ unsafe impl < T > crate :: pointer:: SizeEq < * mut T > for AtomicPtr < T > { }
554+ // SAFETY: See previous safety comment.
555+ unsafe impl < T > crate :: pointer:: SizeEq < AtomicPtr < T > > for * mut T { }
556+
540557 // TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541558 // 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 >) ;
559+ // impl_for_transparent_wrapper!(T => TryFromBytes for AtomicPtr<T>);
560+ impl_for_transmute_from ! ( T => TryFromBytes for AtomicPtr <T > [ UnsafeCell <* mut T >] ) ;
561+ // impl_for_transparent_wrapper!(T => FromZeros for AtomicPtr<T> [UnsafeCell<*mut T>]);
544562
545563 safety_comment ! {
546564 /// SAFETY:
547565 /// This passes an atomic type and that type's native equivalent, as
548566 /// 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 ] ) ;
567+ // unsafe_impl_transparent_wrapper_for_atomic!(AtomicUsize [usize], AtomicIsize [isize]);
568+ // unsafe_impl_transparent_wrapper_for_atomic!(T => AtomicPtr<T> [*mut T]);
569+
570+ unsafe_impl_transmute_from_for_atomic!( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
571+ unsafe_impl_transmute_from_for_atomic!( T => AtomicPtr <T > [ * mut T ] ) ;
551572 }
552573 }
553574}
@@ -577,12 +598,12 @@ safety_comment! {
577598 assert_unaligned!( PhantomData <( ) >, PhantomData <u8 >, PhantomData <u64 >) ;
578599}
579600
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 >) ;
601+ unsafe_impl ! ( T : Immutable => Immutable for Wrapping <T >) ;
602+ impl_for_transmute_from ! ( T : TryFromBytes => TryFromBytes for Wrapping <T >[ T ] ) ;
603+ impl_for_transparent_wrapper ! ( T : FromZeros => FromZeros for Wrapping <T >[ T ] ) ;
604+ impl_for_transparent_wrapper ! ( T : FromBytes => FromBytes for Wrapping <T >[ T ] ) ;
605+ impl_for_transparent_wrapper ! ( T : IntoBytes => IntoBytes for Wrapping <T >[ T ] ) ;
606+ unsafe_impl ! ( T : Unaligned => Unaligned for Wrapping <T >) ;
586607assert_unaligned ! ( Wrapping <( ) >, Wrapping <u8 >) ;
587608
588609safety_comment ! {
@@ -594,22 +615,52 @@ safety_comment! {
594615 unsafe_impl!( T => FromBytes for CoreMaybeUninit <T >) ;
595616}
596617
597- impl_for_transparent_wrapper ! ( T : Immutable => Immutable for CoreMaybeUninit <T >) ;
598- impl_for_transparent_wrapper ! ( T : Unaligned => Unaligned for CoreMaybeUninit <T >) ;
618+ unsafe_impl ! ( T : Immutable => Immutable for CoreMaybeUninit <T >) ;
619+ unsafe_impl ! ( T : Unaligned => Unaligned for CoreMaybeUninit <T >) ;
599620assert_unaligned ! ( CoreMaybeUninit <( ) >, CoreMaybeUninit <u8 >) ;
600621
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 >) ;
622+ unsafe_impl ! ( T : ?Sized + Immutable => Immutable for ManuallyDrop <T >) ;
623+
624+ // SAFETY: See inline safety comment justifying that the implementation of
625+ // `is_bit_valid`is sound.
626+ unsafe impl < T : ?Sized + TryFromBytes > TryFromBytes for ManuallyDrop < T > {
627+ #[ allow( clippy:: missing_inline_in_public_items) ]
628+ fn only_derive_is_allowed_to_implement_this_trait ( ) { }
629+
630+ #[ inline( always) ]
631+ fn is_bit_valid < A : crate :: pointer:: invariant:: Reference > (
632+ candidate : Maybe < ' _ , Self , A > ,
633+ ) -> bool {
634+ // SAFETY: `ManuallyDrop<T>` and `T` have the same size [1], so this
635+ // cast preserves size. It also preserves provenance.
636+ //
637+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
638+ //
639+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
640+ // validity as `T`
641+ let c: Maybe < ' _ , T , A > = unsafe { candidate. cast_unsized ( |p| cast ! ( p => NonNull <_>) ) } ;
642+
643+ // SAFETY: `ManuallyDrop<T>` and `T` have the same bit validity [1], so
644+ // this is a sound implementation of `ManuallyDrop::is_bit_valid`.
645+ //
646+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
647+ //
648+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
649+ // validity as `T`
650+ <T as TryFromBytes >:: is_bit_valid ( c)
651+ }
652+ }
653+
654+ impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for ManuallyDrop <T >[ T ] ) ;
655+ impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for ManuallyDrop <T >[ T ] ) ;
656+ impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for ManuallyDrop <T >[ T ] ) ;
657+ unsafe_impl ! ( T : ?Sized + Unaligned => Unaligned for ManuallyDrop <T >) ;
607658assert_unaligned ! ( ManuallyDrop <( ) >, ManuallyDrop <u8 >) ;
608659
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 >) ;
660+ impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for UnsafeCell <T >[ T ] ) ;
661+ impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for UnsafeCell <T >[ T ] ) ;
662+ impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for UnsafeCell <T >[ T ] ) ;
663+ unsafe_impl ! ( T : ?Sized + Unaligned => Unaligned for UnsafeCell <T >) ;
613664assert_unaligned ! ( UnsafeCell <( ) >, UnsafeCell <u8 >) ;
614665
615666// SAFETY: See safety comment in `is_bit_valid` impl.
0 commit comments