@@ -440,49 +440,142 @@ safety_comment! {
440
440
unsafe_impl_for_power_set!( A , B , C , D , E , F , G , H , I , J , K , L -> M => Immutable for opt_extern_c_fn!( ...) ) ;
441
441
}
442
442
443
- macro_rules! impl_traits_for_atomics {
444
- ( $( $atomics: ident) ,* $( , ) ?) => {
445
- $(
446
- impl_for_transparent_wrapper!( => TryFromBytes for $atomics) ;
447
- impl_for_transparent_wrapper!( => FromZeros for $atomics) ;
448
- impl_for_transparent_wrapper!( => FromBytes for $atomics) ;
449
- impl_for_transparent_wrapper!( => IntoBytes for $atomics) ;
450
- ) *
451
- } ;
452
- }
443
+ #[ cfg( zerocopy_target_has_atomics) ]
444
+ mod atomics {
445
+ use super :: * ;
453
446
454
- #[ rustfmt:: skip]
455
- impl_traits_for_atomics ! (
456
- AtomicI16 , AtomicI32 , AtomicI8 , AtomicIsize ,
457
- AtomicU16 , AtomicU32 , AtomicU8 , AtomicUsize ,
458
- ) ;
447
+ macro_rules! impl_traits_for_atomics {
448
+ ( $( $atomics: ident) ,* $( , ) ?) => {
449
+ $(
450
+ impl_known_layout!( $atomics) ;
451
+ impl_for_transparent_wrapper!( => TryFromBytes for $atomics) ;
452
+ impl_for_transparent_wrapper!( => FromZeros for $atomics) ;
453
+ impl_for_transparent_wrapper!( => FromBytes for $atomics) ;
454
+ impl_for_transparent_wrapper!( => IntoBytes for $atomics) ;
455
+ ) *
456
+ } ;
457
+ }
459
458
460
- impl_for_transparent_wrapper ! ( => TryFromBytes for AtomicBool ) ;
461
- impl_for_transparent_wrapper ! ( => FromZeros for AtomicBool ) ;
462
- impl_for_transparent_wrapper ! ( => IntoBytes for AtomicBool ) ;
459
+ #[ cfg( target_has_atomic = "8" ) ]
460
+ #[ cfg_attr( doc_cfg, doc( cfg( target_has_atomic = "8" ) ) ) ]
461
+ mod atomic_8 {
462
+ use core:: sync:: atomic:: { AtomicBool , AtomicI8 , AtomicU8 } ;
463
+
464
+ use super :: * ;
465
+
466
+ impl_traits_for_atomics ! ( AtomicU8 , AtomicI8 ) ;
467
+
468
+ impl_known_layout ! ( AtomicBool ) ;
469
+
470
+ impl_for_transparent_wrapper ! ( => TryFromBytes for AtomicBool ) ;
471
+ impl_for_transparent_wrapper ! ( => FromZeros for AtomicBool ) ;
472
+ impl_for_transparent_wrapper ! ( => IntoBytes for AtomicBool ) ;
473
+
474
+ safety_comment ! {
475
+ /// SAFETY:
476
+ /// Per [1], `AtomicBool`, `AtomicU8`, and `AtomicI8` have the same
477
+ /// size as `bool`, `u8`, and `i8` respectively. Since a type's
478
+ /// alignment cannot be smaller than 1 [2], and since its alignment
479
+ /// cannot be greater than its size [3], the only possible value for
480
+ /// the alignment is 1. Thus, it is sound to implement `Unaligned`.
481
+ ///
482
+ /// [1] TODO(#896), TODO(https://github.com/rust-lang/rust/pull/121943):
483
+ /// Cite docs once they've landed.
484
+ ///
485
+ /// [2] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
486
+ ///
487
+ /// Alignment is measured in bytes, and must be at least 1.
488
+ ///
489
+ /// [3] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
490
+ ///
491
+ /// The size of a value is always a multiple of its alignment.
492
+ unsafe_impl!( AtomicBool : Unaligned ) ;
493
+ unsafe_impl!( AtomicU8 : Unaligned ) ;
494
+ unsafe_impl!( AtomicI8 : Unaligned ) ;
495
+ assert_unaligned!( AtomicBool , AtomicU8 , AtomicI8 ) ;
496
+
497
+ /// SAFETY:
498
+ /// All of these pass an atomic type and that type's native equivalent, as
499
+ /// required by the macro safety preconditions.
500
+ unsafe_impl_transparent_wrapper_for_atomic!( AtomicU8 [ u8 ] , AtomicI8 [ i8 ] , AtomicBool [ bool ] ) ;
501
+ }
502
+ }
463
503
464
- safety_comment ! {
465
- /// SAFETY:
466
- /// Per [1], `AtomicBool`, `AtomicU8`, and `AtomicI8` have the same size as
467
- /// `bool`, `u8`, and `i8` respectively. Since a type's alignment cannot be
468
- /// smaller than 1 [2], and since its alignment cannot be greater than its
469
- /// size [3], the only possible value for the alignment is 1. Thus, it is
470
- /// sound to implement `Unaligned`.
471
- ///
472
- /// [1] TODO(#896), TODO(https://github.com/rust-lang/rust/pull/121943):
473
- /// Cite docs once they've landed.
474
- ///
475
- /// [2] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
476
- ///
477
- /// Alignment is measured in bytes, and must be at least 1.
478
- ///
479
- /// [3] Per https://doc.rust-lang.org/reference/type-layout.html#size-and-alignment:
480
- ///
481
- /// The size of a value is always a multiple of its alignment.
482
- unsafe_impl!( AtomicBool : Unaligned ) ;
483
- unsafe_impl!( AtomicU8 : Unaligned ) ;
484
- unsafe_impl!( AtomicI8 : Unaligned ) ;
485
- assert_unaligned!( AtomicBool , AtomicU8 , AtomicI8 ) ;
504
+ #[ cfg( target_has_atomic = "16" ) ]
505
+ #[ cfg_attr( doc_cfg, doc( cfg( target_has_atomic = "16" ) ) ) ]
506
+ mod atomic_16 {
507
+ use core:: sync:: atomic:: { AtomicI16 , AtomicU16 } ;
508
+
509
+ use super :: * ;
510
+
511
+ impl_traits_for_atomics ! ( AtomicU16 , AtomicI16 ) ;
512
+
513
+ safety_comment ! {
514
+ /// SAFETY:
515
+ /// All of these pass an atomic type and that type's native equivalent, as
516
+ /// required by the macro safety preconditions.
517
+ unsafe_impl_transparent_wrapper_for_atomic!( AtomicU16 [ u16 ] , AtomicI16 [ i16 ] ) ;
518
+ }
519
+ }
520
+
521
+ #[ cfg( target_has_atomic = "32" ) ]
522
+ #[ cfg_attr( doc_cfg, doc( cfg( target_has_atomic = "32" ) ) ) ]
523
+ mod atomic_32 {
524
+ use core:: sync:: atomic:: { AtomicI32 , AtomicU32 } ;
525
+
526
+ use super :: * ;
527
+
528
+ impl_traits_for_atomics ! ( AtomicU32 , AtomicI32 ) ;
529
+
530
+ safety_comment ! {
531
+ /// SAFETY:
532
+ /// All of these pass an atomic type and that type's native equivalent, as
533
+ /// required by the macro safety preconditions.
534
+ unsafe_impl_transparent_wrapper_for_atomic!( AtomicU32 [ u32 ] , AtomicI32 [ i32 ] ) ;
535
+ }
536
+ }
537
+
538
+ #[ cfg( target_has_atomic = "64" ) ]
539
+ #[ cfg_attr( doc_cfg, doc( cfg( target_has_atomic = "64" ) ) ) ]
540
+ mod atomic_64 {
541
+ use core:: sync:: atomic:: { AtomicI64 , AtomicU64 } ;
542
+
543
+ use super :: * ;
544
+
545
+ impl_traits_for_atomics ! ( AtomicU64 , AtomicI64 ) ;
546
+
547
+ safety_comment ! {
548
+ /// SAFETY:
549
+ /// All of these pass an atomic type and that type's native equivalent, as
550
+ /// required by the macro safety preconditions.
551
+ unsafe_impl_transparent_wrapper_for_atomic!( AtomicU64 [ u64 ] , AtomicI64 [ i64 ] ) ;
552
+ }
553
+ }
554
+
555
+ #[ cfg( target_has_atomic = "ptr" ) ]
556
+ #[ cfg_attr( doc_cfg, doc( cfg( target_has_atomic = "ptr" ) ) ) ]
557
+ mod atomic_ptr {
558
+ use core:: sync:: atomic:: { AtomicIsize , AtomicPtr , AtomicUsize } ;
559
+
560
+ use super :: * ;
561
+
562
+ impl_traits_for_atomics ! ( AtomicUsize , AtomicIsize ) ;
563
+
564
+ impl_known_layout ! ( T => AtomicPtr <T >) ;
565
+
566
+ // TODO(#170): Implement `FromBytes` and `IntoBytes` once we implement
567
+ // those traits for `*mut T`.
568
+ impl_for_transparent_wrapper ! ( T => TryFromBytes for AtomicPtr <T >) ;
569
+ impl_for_transparent_wrapper ! ( T => FromZeros for AtomicPtr <T >) ;
570
+
571
+ safety_comment ! {
572
+ /// SAFETY:
573
+ /// This passes an atomic type and that type's native equivalent, as
574
+ /// required by the macro safety preconditions.
575
+ unsafe_impl_transparent_wrapper_for_atomic!( AtomicUsize [ usize ] , AtomicIsize [ isize ] ) ;
576
+ unsafe_impl_transparent_wrapper_for_atomic!( T => AtomicPtr <T > [ * mut T ] ) ;
577
+ }
578
+ }
486
579
}
487
580
488
581
safety_comment ! {
0 commit comments