@@ -417,13 +417,15 @@ 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!(=> 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>] ) ;
427
429
) *
428
430
} ;
429
431
}
@@ -435,13 +437,15 @@ mod atomics {
435
437
436
438
use super :: * ;
437
439
438
- impl_traits_for_atomics ! ( AtomicU8 , AtomicI8 ) ;
440
+ impl_traits_for_atomics ! ( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] ) ;
439
441
442
+ impl_size_eq ! ( AtomicBool , bool ) ;
440
443
impl_known_layout ! ( AtomicBool ) ;
441
444
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 >] ) ;
445
449
446
450
safety_comment ! {
447
451
/// SAFETY:
@@ -471,7 +475,8 @@ mod atomics {
471
475
/// SAFETY:
472
476
/// All of these pass an atomic type and that type's native equivalent, as
473
477
/// 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 ] ) ;
475
480
}
476
481
}
477
482
@@ -482,13 +487,14 @@ mod atomics {
482
487
483
488
use super :: * ;
484
489
485
- impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
490
+ impl_traits_for_atomics ! ( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
486
491
487
492
safety_comment ! {
488
493
/// SAFETY:
489
494
/// All of these pass an atomic type and that type's native equivalent, as
490
495
/// 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 ] ) ;
492
498
}
493
499
}
494
500
@@ -499,13 +505,14 @@ mod atomics {
499
505
500
506
use super :: * ;
501
507
502
- impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
508
+ impl_traits_for_atomics ! ( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503
509
504
510
safety_comment ! {
505
511
/// SAFETY:
506
512
/// All of these pass an atomic type and that type's native equivalent, as
507
513
/// 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 ] ) ;
509
516
}
510
517
}
511
518
@@ -516,13 +523,14 @@ mod atomics {
516
523
517
524
use super :: * ;
518
525
519
- impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
526
+ impl_traits_for_atomics ! ( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
520
527
521
528
safety_comment ! {
522
529
/// SAFETY:
523
530
/// All of these pass an atomic type and that type's native equivalent, as
524
531
/// 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 ] ) ;
526
534
}
527
535
}
528
536
@@ -533,21 +541,34 @@ mod atomics {
533
541
534
542
use super :: * ;
535
543
536
- impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
544
+ impl_traits_for_atomics ! ( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
537
545
538
546
impl_known_layout ! ( T => AtomicPtr <T >) ;
539
547
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
+
540
557
// TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541
558
// 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>]);
544
562
545
563
safety_comment ! {
546
564
/// SAFETY:
547
565
/// This passes an atomic type and that type's native equivalent, as
548
566
/// 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 ] ) ;
551
572
}
552
573
}
553
574
}
@@ -577,12 +598,12 @@ safety_comment! {
577
598
assert_unaligned!( PhantomData <( ) >, PhantomData <u8 >, PhantomData <u64 >) ;
578
599
}
579
600
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 >) ;
586
607
assert_unaligned ! ( Wrapping <( ) >, Wrapping <u8 >) ;
587
608
588
609
safety_comment ! {
@@ -594,22 +615,52 @@ safety_comment! {
594
615
unsafe_impl!( T => FromBytes for CoreMaybeUninit <T >) ;
595
616
}
596
617
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 >) ;
599
620
assert_unaligned ! ( CoreMaybeUninit <( ) >, CoreMaybeUninit <u8 >) ;
600
621
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 >) ;
607
658
assert_unaligned ! ( ManuallyDrop <( ) >, ManuallyDrop <u8 >) ;
608
659
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 >) ;
613
664
assert_unaligned ! ( UnsafeCell <( ) >, UnsafeCell <u8 >) ;
614
665
615
666
// SAFETY: See safety comment in `is_bit_valid` impl.
0 commit comments