@@ -104,10 +104,13 @@ assert_unaligned!(bool);
104104// The value false has the bit pattern 0x00 and the value true has the bit
105105// pattern 0x01.
106106const _: ( ) = unsafe {
107- unsafe_impl ! ( => TryFromBytes for bool ; |byte| {
108- let byte = byte. transmute:: <u8 , invariant:: Valid , _>( ) ;
109- * byte. unaligned_as_ref( ) < 2
110- } )
107+ unsafe_impl ! ( => TryFromBytes for bool ;
108+ type Uninit = crate :: init:: Uninit ;
109+ |byte| {
110+ let byte = byte. transmute:: <u8 , invariant:: Valid , _>( ) ;
111+ * byte. unaligned_as_ref( ) < 2
112+ }
113+ )
111114} ;
112115impl_size_eq ! ( bool , u8 ) ;
113116
@@ -133,11 +136,14 @@ const _: () = unsafe { unsafe_impl!(char: Immutable, FromZeros, IntoBytes) };
133136// `from_u32()` will return `None` if the input is not a valid value for a
134137// `char`.
135138const _: ( ) = unsafe {
136- unsafe_impl ! ( => TryFromBytes for char ; |c| {
137- let c = c. transmute:: <Unalign <u32 >, invariant:: Valid , _>( ) ;
138- let c = c. read_unaligned( ) . into_inner( ) ;
139- char :: from_u32( c) . is_some( )
140- } ) ;
139+ unsafe_impl ! ( => TryFromBytes for char ;
140+ type Uninit = crate :: init:: Uninit ;
141+ |c| {
142+ let c = c. transmute:: <Unalign <u32 >, invariant:: Valid , _>( ) ;
143+ let c = c. read_unaligned( ) . into_inner( ) ;
144+ char :: from_u32( c) . is_some( )
145+ }
146+ ) ;
141147} ;
142148
143149impl_size_eq ! ( char , Unalign <u32 >) ;
@@ -166,24 +172,31 @@ const _: () = unsafe { unsafe_impl!(str: Immutable, FromZeros, IntoBytes, Unalig
166172//
167173// Returns `Err` if the slice is not UTF-8.
168174const _: ( ) = unsafe {
169- unsafe_impl ! ( => TryFromBytes for str ; |c| {
170- let c = c. transmute:: <[ u8 ] , invariant:: Valid , _>( ) ;
171- let c = c. unaligned_as_ref( ) ;
172- core:: str :: from_utf8( c) . is_ok( )
173- } )
175+ unsafe_impl ! ( => TryFromBytes for str ;
176+ // TODO: Is this the best we can do?
177+ type Uninit = crate :: init:: Uninit ;
178+ |c| {
179+ let c = c. transmute:: <[ u8 ] , invariant:: Valid , _>( ) ;
180+ let c = c. unaligned_as_ref( ) ;
181+ core:: str :: from_utf8( c) . is_ok( )
182+ }
183+ )
174184} ;
175185
176186impl_size_eq ! ( str , [ u8 ] ) ;
177187
178188macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
179189 ( $( $nonzero: ident[ $prim: ty] ) ,* ) => {
180190 $(
181- unsafe_impl!( => TryFromBytes for $nonzero; |n| {
182- impl_size_eq!( $nonzero, Unalign <$prim>) ;
191+ unsafe_impl!( => TryFromBytes for $nonzero;
192+ type Uninit = crate :: init:: Uninit ;
193+ |n| {
194+ impl_size_eq!( $nonzero, Unalign <$prim>) ;
183195
184- let n = n. transmute:: <Unalign <$prim>, invariant:: Valid , _>( ) ;
185- $nonzero:: new( n. read_unaligned( ) . into_inner( ) ) . is_some( )
186- } ) ;
196+ let n = n. transmute:: <Unalign <$prim>, invariant:: Valid , _>( ) ;
197+ $nonzero:: new( n. read_unaligned( ) . into_inner( ) ) . is_some( )
198+ }
199+ ) ;
187200 ) *
188201 }
189202}
@@ -322,23 +335,31 @@ const _: () = unsafe {
322335 #[ cfg( feature = "alloc" ) ]
323336 unsafe_impl ! (
324337 #[ cfg_attr( doc_cfg, doc( cfg( feature = "alloc" ) ) ) ]
325- T => TryFromBytes for Option <Box <T >>; |c| pointer:: is_zeroed( c)
338+ T => TryFromBytes for Option <Box <T >>;
339+ type Uninit = crate :: init:: Uninit ;
340+ |c| pointer:: is_zeroed( c)
326341 ) ;
327342 #[ cfg( feature = "alloc" ) ]
328343 unsafe_impl ! (
329344 #[ cfg_attr( doc_cfg, doc( cfg( feature = "alloc" ) ) ) ]
330345 T => FromZeros for Option <Box <T >>
331346 ) ;
332347 unsafe_impl ! (
333- T => TryFromBytes for Option <& ' _ T >; |c| pointer:: is_zeroed( c)
348+ T => TryFromBytes for Option <& ' _ T >;
349+ type Uninit = crate :: init:: Uninit ;
350+ |c| pointer:: is_zeroed( c)
334351 ) ;
335352 unsafe_impl ! ( T => FromZeros for Option <& ' _ T >) ;
336353 unsafe_impl ! (
337- T => TryFromBytes for Option <& ' _ mut T >; |c| pointer:: is_zeroed( c)
354+ T => TryFromBytes for Option <& ' _ mut T >;
355+ type Uninit = crate :: init:: Uninit ;
356+ |c| pointer:: is_zeroed( c)
338357 ) ;
339358 unsafe_impl ! ( T => FromZeros for Option <& ' _ mut T >) ;
340359 unsafe_impl ! (
341- T => TryFromBytes for Option <NonNull <T >>; |c| pointer:: is_zeroed( c)
360+ T => TryFromBytes for Option <NonNull <T >>;
361+ type Uninit = crate :: init:: Uninit ;
362+ |c| pointer:: is_zeroed( c)
342363 ) ;
343364 unsafe_impl ! ( T => FromZeros for Option <NonNull <T >>) ;
344365 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_fn!( ...) ) ;
@@ -796,6 +817,8 @@ assert_unaligned!(UnsafeCell<()>, UnsafeCell<u8>);
796817
797818// SAFETY: See safety comment in `is_bit_valid` impl.
798819unsafe impl < T : TryFromBytes + ?Sized > TryFromBytes for UnsafeCell < T > {
820+ type Uninit = T :: Uninit ;
821+
799822 #[ allow( clippy:: missing_inline_in_public_items) ]
800823 fn only_derive_is_allowed_to_implement_this_trait ( )
801824 where
@@ -853,42 +876,48 @@ unsafe impl<T: TryFromBytes + ?Sized> TryFromBytes for UnsafeCell<T> {
853876// [1] https://doc.rust-lang.org/1.81.0/reference/type-layout.html#array-layout
854877const _: ( ) = unsafe {
855878 unsafe_impl ! ( const N : usize , T : Immutable => Immutable for [ T ; N ] ) ;
856- unsafe_impl ! ( const N : usize , T : TryFromBytes => TryFromBytes for [ T ; N ] ; |c| {
857- // Note that this call may panic, but it would still be sound even if it
858- // did. `is_bit_valid` does not promise that it will not panic (in fact,
859- // it explicitly warns that it's a possibility), and we have not
860- // violated any safety invariants that we must fix before returning.
861- <[ T ] as TryFromBytes >:: is_bit_valid( c. as_slice( ) )
862- } ) ;
879+ unsafe_impl ! ( const N : usize , T : TryFromBytes => TryFromBytes for [ T ; N ] ;
880+ type Uninit = T :: Uninit ;
881+ |c| {
882+ // Note that this call may panic, but it would still be sound even if it
883+ // did. `is_bit_valid` does not promise that it will not panic (in fact,
884+ // it explicitly warns that it's a possibility), and we have not
885+ // violated any safety invariants that we must fix before returning.
886+ <[ T ] as TryFromBytes >:: is_bit_valid( c. as_slice( ) )
887+ }
888+ ) ;
863889 unsafe_impl ! ( const N : usize , T : FromZeros => FromZeros for [ T ; N ] ) ;
864890 unsafe_impl ! ( const N : usize , T : FromBytes => FromBytes for [ T ; N ] ) ;
865891 unsafe_impl ! ( const N : usize , T : IntoBytes => IntoBytes for [ T ; N ] ) ;
866892 unsafe_impl ! ( const N : usize , T : Unaligned => Unaligned for [ T ; N ] ) ;
867893 assert_unaligned ! ( [ ( ) ; 0 ] , [ ( ) ; 1 ] , [ u8 ; 0 ] , [ u8 ; 1 ] ) ;
868894 unsafe_impl ! ( T : Immutable => Immutable for [ T ] ) ;
869- unsafe_impl ! ( T : TryFromBytes => TryFromBytes for [ T ] ; |c| {
870- // SAFETY: Per the reference [1]:
871- //
872- // An array of `[T; N]` has a size of `size_of::<T>() * N` and the
873- // same alignment of `T`. Arrays are laid out so that the zero-based
874- // `nth` element of the array is offset from the start of the array by
875- // `n * size_of::<T>()` bytes.
876- //
877- // ...
878- //
879- // Slices have the same layout as the section of the array they slice.
880- //
881- // In other words, the layout of a `[T] is a sequence of `T`s laid out
882- // back-to-back with no bytes in between. If all elements in `candidate`
883- // are `is_bit_valid`, so too is `candidate`.
884- //
885- // Note that any of the below calls may panic, but it would still be
886- // sound even if it did. `is_bit_valid` does not promise that it will
887- // not panic (in fact, it explicitly warns that it's a possibility), and
888- // we have not violated any safety invariants that we must fix before
889- // returning.
890- c. iter( ) . all( <T as TryFromBytes >:: is_bit_valid)
891- } ) ;
895+ unsafe_impl ! ( T : TryFromBytes => TryFromBytes for [ T ] ;
896+ type Uninit = T :: Uninit ;
897+ |c| {
898+ // SAFETY: Per the reference [1]:
899+ //
900+ // An array of `[T; N]` has a size of `size_of::<T>() * N` and the
901+ // same alignment of `T`. Arrays are laid out so that the zero-based
902+ // `nth` element of the array is offset from the start of the array by
903+ // `n * size_of::<T>()` bytes.
904+ //
905+ // ...
906+ //
907+ // Slices have the same layout as the section of the array they slice.
908+ //
909+ // In other words, the layout of a `[T] is a sequence of `T`s laid out
910+ // back-to-back with no bytes in between. If all elements in `candidate`
911+ // are `is_bit_valid`, so too is `candidate`.
912+ //
913+ // Note that any of the below calls may panic, but it would still be
914+ // sound even if it did. `is_bit_valid` does not promise that it will
915+ // not panic (in fact, it explicitly warns that it's a possibility), and
916+ // we have not violated any safety invariants that we must fix before
917+ // returning.
918+ c. iter( ) . all( <T as TryFromBytes >:: is_bit_valid)
919+ }
920+ ) ;
892921 unsafe_impl ! ( T : FromZeros => FromZeros for [ T ] ) ;
893922 unsafe_impl ! ( T : FromBytes => FromBytes for [ T ] ) ;
894923 unsafe_impl ! ( T : IntoBytes => IntoBytes for [ T ] ) ;
@@ -914,9 +943,15 @@ const _: () = unsafe {
914943const _: ( ) = unsafe {
915944 unsafe_impl ! ( T : ?Sized => Immutable for * const T ) ;
916945 unsafe_impl ! ( T : ?Sized => Immutable for * mut T ) ;
917- unsafe_impl ! ( T => TryFromBytes for * const T ; |c| pointer:: is_zeroed( c) ) ;
946+ unsafe_impl ! ( T => TryFromBytes for * const T ;
947+ type Uninit = crate :: init:: Uninit ;
948+ |c| pointer:: is_zeroed( c)
949+ ) ;
918950 unsafe_impl ! ( T => FromZeros for * const T ) ;
919- unsafe_impl ! ( T => TryFromBytes for * mut T ; |c| pointer:: is_zeroed( c) ) ;
951+ unsafe_impl ! ( T => TryFromBytes for * mut T ;
952+ type Uninit = crate :: init:: Uninit ;
953+ |c| pointer:: is_zeroed( c)
954+ ) ;
920955 unsafe_impl ! ( T => FromZeros for * mut T ) ;
921956} ;
922957
0 commit comments