@@ -1880,6 +1880,37 @@ safety_comment! {
1880
1880
unsafe_impl!( Option <NonZeroIsize >: FromZeroes , FromBytes , AsBytes ) ;
1881
1881
}
1882
1882
1883
+ safety_comment ! {
1884
+ /// SAFETY:
1885
+ /// The following types can be transmuted from `[0u8; size_of::<T>()]`. [1]
1886
+ /// None of them contain `UnsafeCell`s, and so they all soundly implement
1887
+ /// `FromZeroes`.
1888
+ ///
1889
+ /// [1] Per
1890
+ /// https://doc.rust-lang.org/nightly/core/option/index.html#representation:
1891
+ ///
1892
+ /// Rust guarantees to optimize the following types `T` such that
1893
+ /// [`Option<T>`] has the same size and alignment as `T`. In some of these
1894
+ /// cases, Rust further guarantees that `transmute::<_, Option<T>>([0u8;
1895
+ /// size_of::<T>()])` is sound and produces `Option::<T>::None`. These
1896
+ /// cases are identified by the second column:
1897
+ ///
1898
+ /// | `T` | `transmute::<_, Option<T>>([0u8; size_of::<T>()])` sound? |
1899
+ /// |---------------------|-----------------------------------------------------------|
1900
+ /// | [`Box<U>`] | when `U: Sized` |
1901
+ /// | `&U` | when `U: Sized` |
1902
+ /// | `&mut U` | when `U: Sized` |
1903
+ /// | [`ptr::NonNull<U>`] | when `U: Sized` |
1904
+ ///
1905
+ /// TODO(#429), TODO(https://github.com/rust-lang/rust/pull/115333): Cite
1906
+ /// the Stable docs once they're available.
1907
+ #[ cfg( feature = "alloc" ) ]
1908
+ unsafe_impl!( T => FromZeroes for Option <Box <T >>) ;
1909
+ unsafe_impl!( T => FromZeroes for Option <& ' _ T >) ;
1910
+ unsafe_impl!( T => FromZeroes for Option <& ' _ mut T >) ;
1911
+ unsafe_impl!( T => FromZeroes for Option <NonNull <T >>) ;
1912
+ }
1913
+
1883
1914
safety_comment ! {
1884
1915
/// SAFETY:
1885
1916
/// For all `T`, `PhantomData<T>` has size 0 and alignment 1. [1]
@@ -3820,7 +3851,7 @@ pub use alloc_support::*;
3820
3851
mod tests {
3821
3852
#![ allow( clippy:: unreadable_literal) ]
3822
3853
3823
- use core:: { convert:: TryInto as _, ops:: Deref } ;
3854
+ use core:: { cell :: UnsafeCell , convert:: TryInto as _, ops:: Deref } ;
3824
3855
3825
3856
use static_assertions:: assert_impl_all;
3826
3857
@@ -5515,6 +5546,16 @@ mod tests {
5515
5546
// Implements none of the ZC traits.
5516
5547
struct NotZerocopy ;
5517
5548
5549
+ #[ cfg( feature = "alloc" ) ]
5550
+ assert_impls ! ( Option <Box <UnsafeCell <NotZerocopy >>>: KnownLayout , FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5551
+ assert_impls ! ( Option <Box <[ UnsafeCell <NotZerocopy >] >>: KnownLayout , !FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5552
+ assert_impls ! ( Option <& ' static UnsafeCell <NotZerocopy >>: KnownLayout , FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5553
+ assert_impls ! ( Option <& ' static [ UnsafeCell <NotZerocopy >] >: KnownLayout , !FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5554
+ assert_impls ! ( Option <& ' static mut UnsafeCell <NotZerocopy >>: KnownLayout , FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5555
+ assert_impls ! ( Option <& ' static mut [ UnsafeCell <NotZerocopy >] >: KnownLayout , !FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5556
+ assert_impls ! ( Option <NonNull <UnsafeCell <NotZerocopy >>>: KnownLayout , FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5557
+ assert_impls ! ( Option <NonNull <[ UnsafeCell <NotZerocopy >] >>: KnownLayout , !FromZeroes , !FromBytes , !AsBytes , !Unaligned ) ;
5558
+
5518
5559
assert_impls ! ( PhantomData <NotZerocopy >: KnownLayout , FromZeroes , FromBytes , AsBytes , Unaligned ) ;
5519
5560
assert_impls ! ( PhantomData <[ u8 ] >: KnownLayout , FromZeroes , FromBytes , AsBytes , Unaligned ) ;
5520
5561
0 commit comments