@@ -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:
@@ -469,9 +471,28 @@ mod atomics {
469471 assert_unaligned!( AtomicBool , AtomicU8 , AtomicI8 ) ;
470472
471473 /// 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 ] ) ;
474+ /// `AtomicU8`, `AtomicI8`, and `AtomicBool` have the same size and
475+ /// bit validity as `u8`, `i8`, and `bool` respectively [1][2][3].
476+ ///
477+ /// [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicU8.html:
478+ ///
479+ /// This type has the same size, alignment, and bit validity as
480+ /// the underlying integer type, `u8`.
481+ ///
482+ /// [2] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicI8.html:
483+ ///
484+ /// This type has the same size, alignment, and bit validity as
485+ /// the underlying integer type, `i8`.
486+ ///
487+ /// [3] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicBool.html:
488+ ///
489+ /// This type has the same size, alignment, and bit validity a
490+ /// `bool`.
491+ unsafe_impl_transmute_from_for_atomic!(
492+ => AtomicU8 [ u8 ] ,
493+ => AtomicI8 [ i8 ] ,
494+ => AtomicBool [ bool ]
495+ ) ;
475496 }
476497 }
477498
@@ -482,13 +503,23 @@ mod atomics {
482503
483504 use super :: * ;
484505
485- impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
506+ impl_traits_for_atomics ! ( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
486507
487508 safety_comment ! {
488509 /// 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 ] ) ;
510+ /// `AtomicU16` and `AtomicI16` have the same size and bit validity
511+ /// as `u16` and `i16` respectively [1][2].
512+ ///
513+ /// [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicU16.html:
514+ ///
515+ /// This type has the same size and bit validity as the underlying
516+ /// integer type, `u16`.
517+ ///
518+ /// [2] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicI16.html:
519+ ///
520+ /// This type has the same size and bit validity as the underlying
521+ /// integer type, `i16`.
522+ unsafe_impl_transmute_from_for_atomic!( => AtomicU16 [ u16 ] , => AtomicI16 [ i16 ] ) ;
492523 }
493524 }
494525
@@ -499,13 +530,23 @@ mod atomics {
499530
500531 use super :: * ;
501532
502- impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
533+ impl_traits_for_atomics ! ( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503534
504535 safety_comment ! {
505536 /// 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 ] ) ;
537+ /// `AtomicU32` and `AtomicI32` have the same size and bit validity
538+ /// as `u32` and `i32` respectively [1][2].
539+ ///
540+ /// [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicU32.html:
541+ ///
542+ /// This type has the same size and bit validity as the underlying
543+ /// integer type, `u32`.
544+ ///
545+ /// [2] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicI32.html:
546+ ///
547+ /// This type has the same size and bit validity as the underlying
548+ /// integer type, `i32`.
549+ unsafe_impl_transmute_from_for_atomic!( => AtomicU32 [ u32 ] , => AtomicI32 [ i32 ] ) ;
509550 }
510551 }
511552
@@ -516,13 +557,23 @@ mod atomics {
516557
517558 use super :: * ;
518559
519- impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
560+ impl_traits_for_atomics ! ( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
520561
521562 safety_comment ! {
522563 /// 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 ] ) ;
564+ /// `AtomicU64` and `AtomicI64` have the same size and bit validity
565+ /// as `u64` and `i64` respectively [1][2].
566+ ///
567+ /// [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicU64.html:
568+ ///
569+ /// This type has the same size and bit validity as the underlying
570+ /// integer type, `u64`.
571+ ///
572+ /// [2] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicI64.html:
573+ ///
574+ /// This type has the same size and bit validity as the underlying
575+ /// integer type, `i64`.
576+ unsafe_impl_transmute_from_for_atomic!( => AtomicU64 [ u64 ] , => AtomicI64 [ i64 ] ) ;
526577 }
527578 }
528579
@@ -533,21 +584,43 @@ mod atomics {
533584
534585 use super :: * ;
535586
536- impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
587+ impl_traits_for_atomics ! ( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
537588
538589 impl_known_layout ! ( T => AtomicPtr <T >) ;
539590
591+ // SAFETY: `AtomicPtr<T>` and `*mut T` have the same size [1].
592+ //
593+ // [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicPtr.html:
594+ //
595+ // This type has the same size and bit validity as a `*mut T`.
596+ unsafe impl < T > crate :: pointer:: SizeEq < * mut T > for AtomicPtr < T > { }
597+ // SAFETY: See previous safety comment.
598+ unsafe impl < T > crate :: pointer:: SizeEq < AtomicPtr < T > > for * mut T { }
599+
540600 // TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541601 // 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 >) ;
602+ impl_for_transmute_from ! ( T => TryFromBytes for AtomicPtr <T > [ UnsafeCell <* mut T >] ) ;
544603
545604 safety_comment ! {
546605 /// 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 ] ) ;
606+ /// `AtomicUsize` and `AtomicIsize` have the same size and bit
607+ /// validity as `usize` and `isize` respectively [1][2].
608+ ///
609+ /// [1] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicUsize.html:
610+ ///
611+ /// This type has the same size and bit validity as the underlying
612+ /// integer type, `usize`.
613+ ///
614+ /// [2] Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicIsize.html:
615+ ///
616+ /// This type has the same size and bit validity as the underlying
617+ /// integer type, `isize`.
618+ unsafe_impl_transmute_from_for_atomic!( => AtomicUsize [ usize ] , => AtomicIsize [ isize ] ) ;
619+ /// SAFETY:
620+ /// Per https://doc.rust-lang.org/1.85.0/std/sync/atomic/struct.AtomicPtr.html:
621+ ///
622+ /// This type has the same size and bit validity as a `*mut T`.
623+ unsafe_impl_transmute_from_for_atomic!( T => AtomicPtr <T > [ * mut T ] ) ;
551624 }
552625 }
553626}
@@ -577,39 +650,76 @@ safety_comment! {
577650 assert_unaligned!( PhantomData <( ) >, PhantomData <u8 >, PhantomData <u64 >) ;
578651}
579652
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 >) ;
653+ impl_for_transmute_from ! ( T : TryFromBytes => TryFromBytes for Wrapping <T >[ T ] ) ;
654+ impl_for_transparent_wrapper ! ( T : FromZeros => FromZeros for Wrapping <T >[ T ] ) ;
655+ impl_for_transparent_wrapper ! ( T : FromBytes => FromBytes for Wrapping <T >[ T ] ) ;
656+ impl_for_transparent_wrapper ! ( T : IntoBytes => IntoBytes for Wrapping <T >[ T ] ) ;
586657assert_unaligned ! ( Wrapping <( ) >, Wrapping <u8 >) ;
587658
659+ safety_comment ! {
660+ /// SAFETY: TODO
661+ unsafe_impl!( T : Immutable => Immutable for Wrapping <T >) ;
662+ unsafe_impl!( T : Unaligned => Unaligned for Wrapping <T >) ;
663+ }
664+
588665safety_comment ! {
589666 /// SAFETY:
590667 /// `TryFromBytes` (with no validator), `FromZeros`, `FromBytes`:
591668 /// `MaybeUninit<T>` has no restrictions on its contents.
592669 unsafe_impl!( T => TryFromBytes for CoreMaybeUninit <T >) ;
593670 unsafe_impl!( T => FromZeros for CoreMaybeUninit <T >) ;
594671 unsafe_impl!( T => FromBytes for CoreMaybeUninit <T >) ;
672+ /// SAFETY: TODO
673+ unsafe_impl!( T : Immutable => Immutable for CoreMaybeUninit <T >) ;
674+ unsafe_impl!( T : Unaligned => Unaligned for CoreMaybeUninit <T >) ;
595675}
596-
597- impl_for_transparent_wrapper ! ( T : Immutable => Immutable for CoreMaybeUninit <T >) ;
598- impl_for_transparent_wrapper ! ( T : Unaligned => Unaligned for CoreMaybeUninit <T >) ;
599676assert_unaligned ! ( CoreMaybeUninit <( ) >, CoreMaybeUninit <u8 >) ;
600677
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 >) ;
678+ safety_comment ! {
679+ /// SAFETY: TODO
680+ unsafe_impl!( T : ?Sized + Immutable => Immutable for ManuallyDrop <T >) ;
681+ }
682+
683+ // SAFETY: See inline safety comment justifying that the implementation of
684+ // `is_bit_valid`is sound.
685+ unsafe impl < T : ?Sized + TryFromBytes > TryFromBytes for ManuallyDrop < T > {
686+ #[ allow( clippy:: missing_inline_in_public_items) ]
687+ fn only_derive_is_allowed_to_implement_this_trait ( ) { }
688+
689+ #[ inline( always) ]
690+ fn is_bit_valid < A : crate :: pointer:: invariant:: Reference > (
691+ candidate : Maybe < ' _ , Self , A > ,
692+ ) -> bool {
693+ // SAFETY: `ManuallyDrop<T>` and `T` have the same size [1], so this
694+ // cast preserves size. It also preserves provenance.
695+ //
696+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
697+ //
698+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
699+ // validity as `T`
700+ let c: Maybe < ' _ , T , A > = unsafe { candidate. cast_unsized ( |p| cast ! ( p => NonNull <_>) ) } ;
701+
702+ // SAFETY: `ManuallyDrop<T>` and `T` have the same bit validity [1], so
703+ // this is a sound implementation of `ManuallyDrop::is_bit_valid`.
704+ //
705+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
706+ //
707+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
708+ // validity as `T`
709+ <T as TryFromBytes >:: is_bit_valid ( c)
710+ }
711+ }
712+
713+ impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for ManuallyDrop <T >[ T ] ) ;
714+ impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for ManuallyDrop <T >[ T ] ) ;
715+ impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for ManuallyDrop <T >[ T ] ) ;
716+ unsafe_impl ! ( T : ?Sized + Unaligned => Unaligned for ManuallyDrop <T >) ;
607717assert_unaligned ! ( ManuallyDrop <( ) >, ManuallyDrop <u8 >) ;
608718
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 >) ;
719+ impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for UnsafeCell <T >[ T ] ) ;
720+ impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for UnsafeCell <T >[ T ] ) ;
721+ impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for UnsafeCell <T >[ T ] ) ;
722+ unsafe_impl ! ( T : ?Sized + Unaligned => Unaligned for UnsafeCell <T >) ;
613723assert_unaligned ! ( UnsafeCell <( ) >, UnsafeCell <u8 >) ;
614724
615725// SAFETY: See safety comment in `is_bit_valid` impl.
0 commit comments