@@ -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:
@@ -469,9 +471,28 @@ mod atomics {
469
471
assert_unaligned!( AtomicBool , AtomicU8 , AtomicI8 ) ;
470
472
471
473
/// 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
+ ) ;
475
496
}
476
497
}
477
498
@@ -482,13 +503,23 @@ mod atomics {
482
503
483
504
use super :: * ;
484
505
485
- impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
506
+ impl_traits_for_atomics ! ( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
486
507
487
508
safety_comment ! {
488
509
/// 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 ] ) ;
492
523
}
493
524
}
494
525
@@ -499,13 +530,23 @@ mod atomics {
499
530
500
531
use super :: * ;
501
532
502
- impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
533
+ impl_traits_for_atomics ! ( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503
534
504
535
safety_comment ! {
505
536
/// 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 ] ) ;
509
550
}
510
551
}
511
552
@@ -516,13 +557,23 @@ mod atomics {
516
557
517
558
use super :: * ;
518
559
519
- impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
560
+ impl_traits_for_atomics ! ( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
520
561
521
562
safety_comment ! {
522
563
/// 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 ] ) ;
526
577
}
527
578
}
528
579
@@ -533,21 +584,43 @@ mod atomics {
533
584
534
585
use super :: * ;
535
586
536
- impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
587
+ impl_traits_for_atomics ! ( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
537
588
538
589
impl_known_layout ! ( T => AtomicPtr <T >) ;
539
590
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
+
540
600
// TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541
601
// 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 >] ) ;
544
603
545
604
safety_comment ! {
546
605
/// 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 ] ) ;
551
624
}
552
625
}
553
626
}
@@ -577,39 +650,76 @@ safety_comment! {
577
650
assert_unaligned!( PhantomData <( ) >, PhantomData <u8 >, PhantomData <u64 >) ;
578
651
}
579
652
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 ] ) ;
586
657
assert_unaligned ! ( Wrapping <( ) >, Wrapping <u8 >) ;
587
658
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
+
588
665
safety_comment ! {
589
666
/// SAFETY:
590
667
/// `TryFromBytes` (with no validator), `FromZeros`, `FromBytes`:
591
668
/// `MaybeUninit<T>` has no restrictions on its contents.
592
669
unsafe_impl!( T => TryFromBytes for CoreMaybeUninit <T >) ;
593
670
unsafe_impl!( T => FromZeros for CoreMaybeUninit <T >) ;
594
671
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 >) ;
595
675
}
596
-
597
- impl_for_transparent_wrapper ! ( T : Immutable => Immutable for CoreMaybeUninit <T >) ;
598
- impl_for_transparent_wrapper ! ( T : Unaligned => Unaligned for CoreMaybeUninit <T >) ;
599
676
assert_unaligned ! ( CoreMaybeUninit <( ) >, CoreMaybeUninit <u8 >) ;
600
677
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 >) ;
607
717
assert_unaligned ! ( ManuallyDrop <( ) >, ManuallyDrop <u8 >) ;
608
718
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 >) ;
613
723
assert_unaligned ! ( UnsafeCell <( ) >, UnsafeCell <u8 >) ;
614
724
615
725
// SAFETY: See safety comment in `is_bit_valid` impl.
0 commit comments