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