@@ -417,13 +417,14 @@ mod atomics {
417
417
use super :: * ;
418
418
419
419
macro_rules! impl_traits_for_atomics {
420
- ( $( $atomics: ident) ,* $( , ) ?) => {
420
+ ( $( $atomics: ident [ $primitives : ident ] ) ,* $( , ) ?) => {
421
421
$(
422
+ impl_size_eq!( $atomics, $primitives) ;
422
423
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> ] ) ;
427
428
) *
428
429
} ;
429
430
}
@@ -435,13 +436,14 @@ mod atomics {
435
436
436
437
use super :: * ;
437
438
438
- impl_traits_for_atomics ! ( AtomicU8 , AtomicI8 ) ;
439
+ impl_traits_for_atomics ! ( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] ) ;
439
440
441
+ impl_size_eq ! ( AtomicBool , bool ) ;
440
442
impl_known_layout ! ( AtomicBool ) ;
441
443
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 > ] ) ;
445
447
446
448
safety_comment ! {
447
449
/// SAFETY:
@@ -468,10 +470,8 @@ mod atomics {
468
470
unsafe_impl!( AtomicI8 : Unaligned ) ;
469
471
assert_unaligned!( AtomicBool , AtomicU8 , AtomicI8 ) ;
470
472
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 ] ) ;
475
475
}
476
476
}
477
477
@@ -482,13 +482,11 @@ mod atomics {
482
482
483
483
use super :: * ;
484
484
485
- impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
485
+ impl_traits_for_atomics ! ( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
486
486
487
487
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 ] ) ;
492
490
}
493
491
}
494
492
@@ -499,13 +497,11 @@ mod atomics {
499
497
500
498
use super :: * ;
501
499
502
- impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
500
+ impl_traits_for_atomics ! ( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503
501
504
502
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 ] ) ;
509
505
}
510
506
}
511
507
@@ -516,13 +512,11 @@ mod atomics {
516
512
517
513
use super :: * ;
518
514
519
- impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
515
+ impl_traits_for_atomics ! ( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
520
516
521
517
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 ] ) ;
526
520
}
527
521
}
528
522
@@ -533,21 +527,27 @@ mod atomics {
533
527
534
528
use super :: * ;
535
529
536
- impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
530
+ impl_traits_for_atomics ! ( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
537
531
538
532
impl_known_layout ! ( T => AtomicPtr <T >) ;
539
533
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
+
540
543
// TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541
544
// 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 >] ) ;
544
546
545
547
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 ] ) ;
551
551
}
552
552
}
553
553
}
@@ -577,12 +577,12 @@ safety_comment! {
577
577
assert_unaligned!( PhantomData <( ) >, PhantomData <u8 >, PhantomData <u64 >) ;
578
578
}
579
579
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 >) ;
586
586
assert_unaligned ! ( Wrapping <( ) >, Wrapping <u8 >) ;
587
587
588
588
safety_comment ! {
@@ -594,22 +594,52 @@ safety_comment! {
594
594
unsafe_impl!( T => FromBytes for CoreMaybeUninit <T >) ;
595
595
}
596
596
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 >) ;
599
599
assert_unaligned ! ( CoreMaybeUninit <( ) >, CoreMaybeUninit <u8 >) ;
600
600
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 >) ;
607
637
assert_unaligned ! ( ManuallyDrop <( ) >, ManuallyDrop <u8 >) ;
608
638
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 >) ;
613
643
assert_unaligned ! ( UnsafeCell <( ) >, UnsafeCell <u8 >) ;
614
644
615
645
// SAFETY: See safety comment in `is_bit_valid` impl.
0 commit comments