@@ -417,10 +417,11 @@ 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
422
impl_known_layout!( $atomics) ;
423
- impl_for_transparent_wrapper!( => TryFromBytes for $atomics) ;
423
+ impl_for_transmute_from!( => TryFromBytes for $atomics [ UnsafeCell <$primitives>] ) ;
424
+ // impl_for_transparent_wrapper!(=> TryFromBytes for $atomics);
424
425
impl_for_transparent_wrapper!( => FromZeros for $atomics) ;
425
426
impl_for_transparent_wrapper!( => FromBytes for $atomics) ;
426
427
impl_for_transparent_wrapper!( => IntoBytes for $atomics) ;
@@ -435,11 +436,12 @@ 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
440
441
impl_known_layout ! ( AtomicBool ) ;
441
442
442
- impl_for_transparent_wrapper ! ( => TryFromBytes for AtomicBool ) ;
443
+ // impl_for_transparent_wrapper!(=> TryFromBytes for AtomicBool);
444
+ impl_for_transmute_from ! ( => TryFromBytes for AtomicBool [ UnsafeCell <bool >] ) ;
443
445
impl_for_transparent_wrapper ! ( => FromZeros for AtomicBool ) ;
444
446
impl_for_transparent_wrapper ! ( => IntoBytes for AtomicBool ) ;
445
447
@@ -472,6 +474,7 @@ mod atomics {
472
474
/// All of these pass an atomic type and that type's native equivalent, as
473
475
/// required by the macro safety preconditions.
474
476
unsafe_impl_transparent_wrapper_for_atomic!( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] , AtomicBool [ bool ] ) ;
477
+ unsafe_impl_transmute_from_for_atomic!( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] , AtomicBool [ bool ] ) ;
475
478
}
476
479
}
477
480
@@ -482,13 +485,14 @@ mod atomics {
482
485
483
486
use super :: * ;
484
487
485
- impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
488
+ impl_traits_for_atomics ! ( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
486
489
487
490
safety_comment ! {
488
491
/// SAFETY:
489
492
/// All of these pass an atomic type and that type's native equivalent, as
490
493
/// required by the macro safety preconditions.
491
494
unsafe_impl_transparent_wrapper_for_atomic!( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
495
+ unsafe_impl_transmute_from_for_atomic!( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
492
496
}
493
497
}
494
498
@@ -499,13 +503,14 @@ mod atomics {
499
503
500
504
use super :: * ;
501
505
502
- impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
506
+ impl_traits_for_atomics ! ( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
503
507
504
508
safety_comment ! {
505
509
/// SAFETY:
506
510
/// All of these pass an atomic type and that type's native equivalent, as
507
511
/// required by the macro safety preconditions.
508
512
unsafe_impl_transparent_wrapper_for_atomic!( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
513
+ unsafe_impl_transmute_from_for_atomic!( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
509
514
}
510
515
}
511
516
@@ -516,13 +521,14 @@ mod atomics {
516
521
517
522
use super :: * ;
518
523
519
- impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
524
+ impl_traits_for_atomics ! ( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
520
525
521
526
safety_comment ! {
522
527
/// SAFETY:
523
528
/// All of these pass an atomic type and that type's native equivalent, as
524
529
/// required by the macro safety preconditions.
525
530
unsafe_impl_transparent_wrapper_for_atomic!( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
531
+ unsafe_impl_transmute_from_for_atomic!( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
526
532
}
527
533
}
528
534
@@ -533,13 +539,14 @@ mod atomics {
533
539
534
540
use super :: * ;
535
541
536
- impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
542
+ impl_traits_for_atomics ! ( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
537
543
538
544
impl_known_layout ! ( T => AtomicPtr <T >) ;
539
545
540
546
// TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
541
547
// those traits for `*mut T`.
542
- impl_for_transparent_wrapper ! ( T => TryFromBytes for AtomicPtr <T >) ;
548
+ // impl_for_transparent_wrapper!(T => TryFromBytes for AtomicPtr<T>);
549
+ impl_for_transmute_from ! ( T => TryFromBytes for AtomicPtr <T > [ UnsafeCell <* mut T >] ) ;
543
550
impl_for_transparent_wrapper ! ( T => FromZeros for AtomicPtr <T >) ;
544
551
545
552
safety_comment ! {
@@ -548,6 +555,9 @@ mod atomics {
548
555
/// required by the macro safety preconditions.
549
556
unsafe_impl_transparent_wrapper_for_atomic!( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
550
557
unsafe_impl_transparent_wrapper_for_atomic!( T => AtomicPtr <T > [ * mut T ] ) ;
558
+
559
+ unsafe_impl_transmute_from_for_atomic!( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
560
+ unsafe_impl_transmute_from_for_atomic!( T => AtomicPtr <T > [ * mut T ] ) ;
551
561
}
552
562
}
553
563
}
@@ -578,7 +588,7 @@ safety_comment! {
578
588
}
579
589
580
590
impl_for_transparent_wrapper ! ( T : Immutable => Immutable for Wrapping <T >) ;
581
- impl_for_transparent_wrapper ! ( T : TryFromBytes => TryFromBytes for Wrapping <T >) ;
591
+ impl_for_transmute_from ! ( T : TryFromBytes => TryFromBytes for Wrapping <T >[ T ] ) ;
582
592
impl_for_transparent_wrapper ! ( T : FromZeros => FromZeros for Wrapping <T >) ;
583
593
impl_for_transparent_wrapper ! ( T : FromBytes => FromBytes for Wrapping <T >) ;
584
594
impl_for_transparent_wrapper ! ( T : IntoBytes => IntoBytes for Wrapping <T >) ;
@@ -599,7 +609,35 @@ impl_for_transparent_wrapper!(T: Unaligned => Unaligned for CoreMaybeUninit<T>);
599
609
assert_unaligned ! ( CoreMaybeUninit <( ) >, CoreMaybeUninit <u8 >) ;
600
610
601
611
impl_for_transparent_wrapper ! ( T : ?Sized + Immutable => Immutable for ManuallyDrop <T >) ;
602
- impl_for_transparent_wrapper ! ( T : ?Sized + TryFromBytes => TryFromBytes for ManuallyDrop <T >) ;
612
+
613
+ unsafe impl < T : ?Sized + TryFromBytes > TryFromBytes for ManuallyDrop < T > {
614
+ #[ allow( clippy:: missing_inline_in_public_items) ]
615
+ fn only_derive_is_allowed_to_implement_this_trait ( ) { }
616
+
617
+ #[ inline( always) ]
618
+ fn is_bit_valid < A : crate :: pointer:: invariant:: Reference > (
619
+ candidate : Maybe < ' _ , Self , A > ,
620
+ ) -> bool {
621
+ // SAFETY: `ManuallyDrop<T>` and `T` have the same size [1], so this
622
+ // cast preserves size. It also preserves provenance.
623
+ //
624
+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
625
+ //
626
+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
627
+ // validity as `T`
628
+ let c: Maybe < ' _ , T , A > = unsafe { candidate. cast_unsized ( |p| cast ! ( p => NonNull <_>) ) } ;
629
+
630
+ // SAFETY: `ManuallyDrop<T>` and `T` have the same bit validity [1], so
631
+ // this is a sound implementation of `ManuallyDrop::is_bit_valid`.
632
+ //
633
+ // [1] Per https://doc.rust-lang.org/1.85.0/std/mem/struct.ManuallyDrop.html:
634
+ //
635
+ // `ManuallyDrop<T>` is guaranteed to have the same layout and bit
636
+ // validity as `T`
637
+ <T as TryFromBytes >:: is_bit_valid ( c)
638
+ }
639
+ }
640
+
603
641
impl_for_transparent_wrapper ! ( T : ?Sized + FromZeros => FromZeros for ManuallyDrop <T >) ;
604
642
impl_for_transparent_wrapper ! ( T : ?Sized + FromBytes => FromBytes for ManuallyDrop <T >) ;
605
643
impl_for_transparent_wrapper ! ( T : ?Sized + IntoBytes => IntoBytes for ManuallyDrop <T >) ;
0 commit comments