@@ -108,10 +108,14 @@ assert_unaligned!(bool);
108108// The value false has the bit pattern 0x00 and the value true has the bit
109109// pattern 0x01.
110110const _: ( ) = unsafe {
111- unsafe_impl ! ( => TryFromBytes for bool ; |byte| {
112- let byte = byte. transmute_with:: <u8 , invariant:: Valid , CastSizedExact , BecauseImmutable >( ) ;
113- * byte. unaligned_as_ref( ) < 2
114- } )
111+ unsafe_impl ! ( => TryFromBytes for bool ;
112+ // FIXME(#2749): Justify this `Uninit`.
113+ type Uninit = crate :: invariant:: Uninit ;
114+ |byte| {
115+ let byte = byte. transmute_with:: <u8 , invariant:: Valid , CastSizedExact , BecauseImmutable >( ) ;
116+ * byte. unaligned_as_ref( ) < 2
117+ }
118+ )
115119} ;
116120
117121// SAFETY:
@@ -137,11 +141,15 @@ const _: () = unsafe { unsafe_impl!(char: Immutable, FromZeros, IntoBytes) };
137141// `from_u32()` will return `None` if the input is not a valid value for a
138142// `char`.
139143const _: ( ) = unsafe {
140- unsafe_impl ! ( => TryFromBytes for char ; |c| {
141- let c = c. transmute_with:: <Unalign <u32 >, invariant:: Valid , CastSizedExact , BecauseImmutable >( ) ;
142- let c = c. read( ) . into_inner( ) ;
143- char :: from_u32( c) . is_some( )
144- } ) ;
144+ unsafe_impl ! ( => TryFromBytes for char ;
145+ // FIXME(#2749): Justify this `Uninit`.
146+ type Uninit = crate :: invariant:: Uninit ;
147+ |c| {
148+ let c = c. transmute_with:: <Unalign <u32 >, invariant:: Valid , CastSizedExact , BecauseImmutable >( ) ;
149+ let c = c. read( ) . into_inner( ) ;
150+ char :: from_u32( c) . is_some( )
151+ }
152+ ) ;
145153} ;
146154
147155// SAFETY: Per the Reference [1], `str` has the same layout as `[u8]`.
@@ -170,20 +178,28 @@ const _: () = unsafe { unsafe_impl!(str: Immutable, FromZeros, IntoBytes, Unalig
170178//
171179// Returns `Err` if the slice is not UTF-8.
172180const _: ( ) = unsafe {
173- unsafe_impl ! ( => TryFromBytes for str ; |c| {
174- let c = c. transmute_with:: <[ u8 ] , invariant:: Valid , CastUnsized , BecauseImmutable >( ) ;
175- let c = c. unaligned_as_ref( ) ;
176- core:: str :: from_utf8( c) . is_ok( )
177- } )
181+ unsafe_impl ! ( => TryFromBytes for str ;
182+ // FIXME(#2749): Justify this `Uninit`.
183+ type Uninit = crate :: invariant:: Uninit ;
184+ |c| {
185+ let c = c. transmute_with:: <[ u8 ] , invariant:: Valid , CastUnsized , BecauseImmutable >( ) ;
186+ let c = c. unaligned_as_ref( ) ;
187+ core:: str :: from_utf8( c) . is_ok( )
188+ }
189+ )
178190} ;
179191
180192macro_rules! unsafe_impl_try_from_bytes_for_nonzero {
181193 ( $( $nonzero: ident[ $prim: ty] ) ,* ) => {
182194 $(
183- unsafe_impl!( => TryFromBytes for $nonzero; |n| {
184- let n = n. transmute_with:: <Unalign <$prim>, invariant:: Valid , CastSizedExact , BecauseImmutable >( ) ;
185- $nonzero:: new( n. read( ) . into_inner( ) ) . is_some( )
186- } ) ;
195+ unsafe_impl!( => TryFromBytes for $nonzero;
196+ // FIXME(#2749): Justify this `Uninit`.
197+ type Uninit = crate :: invariant:: Uninit ;
198+ |n| {
199+ let n = n. transmute_with:: <Unalign <$prim>, invariant:: Valid , CastSizedExact , BecauseImmutable >( ) ;
200+ $nonzero:: new( n. read( ) . into_inner( ) ) . is_some( )
201+ }
202+ ) ;
187203 ) *
188204 }
189205}
@@ -331,43 +347,63 @@ const _: () = unsafe {
331347 #[ cfg( feature = "alloc" ) ]
332348 unsafe_impl ! (
333349 #[ cfg_attr( doc_cfg, doc( cfg( feature = "alloc" ) ) ) ]
334- T => TryFromBytes for Option <Box <T >>; |c| pointer:: is_zeroed( c)
350+ T => TryFromBytes for Option <Box <T >>;
351+ // FIXME(#2749): Justify this `Uninit`.
352+ type Uninit = crate :: invariant:: Uninit ;
353+ |c| pointer:: is_zeroed( c)
335354 ) ;
336355 #[ cfg( feature = "alloc" ) ]
337356 unsafe_impl ! (
338357 #[ cfg_attr( doc_cfg, doc( cfg( feature = "alloc" ) ) ) ]
339358 T => FromZeros for Option <Box <T >>
340359 ) ;
341360 unsafe_impl ! (
342- T => TryFromBytes for Option <& ' _ T >; |c| pointer:: is_zeroed( c)
361+ T => TryFromBytes for Option <& ' _ T >;
362+ // FIXME(#2749): Justify this `Uninit`.
363+ type Uninit = crate :: invariant:: Uninit ;
364+ |c| pointer:: is_zeroed( c)
343365 ) ;
344366 unsafe_impl ! ( T => FromZeros for Option <& ' _ T >) ;
345367 unsafe_impl ! (
346- T => TryFromBytes for Option <& ' _ mut T >; |c| pointer:: is_zeroed( c)
368+ T => TryFromBytes for Option <& ' _ mut T >;
369+ // FIXME(#2749): Justify this `Uninit`.
370+ type Uninit = crate :: invariant:: Uninit ;
371+ |c| pointer:: is_zeroed( c)
347372 ) ;
348373 unsafe_impl ! ( T => FromZeros for Option <& ' _ mut T >) ;
349374 unsafe_impl ! (
350- T => TryFromBytes for Option <NonNull <T >>; |c| pointer:: is_zeroed( c)
375+ T => TryFromBytes for Option <NonNull <T >>;
376+ // FIXME(#2749): Justify this `Uninit`.
377+ type Uninit = crate :: invariant:: Uninit ;
378+ |c| pointer:: is_zeroed( c)
351379 ) ;
352380 unsafe_impl ! ( T => FromZeros for Option <NonNull <T >>) ;
353381 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_fn!( ...) ) ;
354382 unsafe_impl_for_power_set ! (
355383 A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_fn!( ...) ;
384+ // FIXME(#2749): Justify this `Uninit`.
385+ type Uninit = crate :: invariant:: Uninit ;
356386 |c| pointer:: is_zeroed( c)
357387 ) ;
358388 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_unsafe_fn!( ...) ) ;
359389 unsafe_impl_for_power_set ! (
360390 A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_unsafe_fn!( ...) ;
391+ // FIXME(#2749): Justify this `Uninit`.
392+ type Uninit = crate :: invariant:: Uninit ;
361393 |c| pointer:: is_zeroed( c)
362394 ) ;
363395 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_extern_c_fn!( ...) ) ;
364396 unsafe_impl_for_power_set ! (
365397 A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_extern_c_fn!( ...) ;
398+ // FIXME(#2749): Justify this `Uninit`.
399+ type Uninit = crate :: invariant:: Uninit ;
366400 |c| pointer:: is_zeroed( c)
367401 ) ;
368402 unsafe_impl_for_power_set ! ( A , B , C , D , E , F , G , H , I , J , K , L -> M => FromZeros for opt_unsafe_extern_c_fn!( ...) ) ;
369403 unsafe_impl_for_power_set ! (
370404 A , B , C , D , E , F , G , H , I , J , K , L -> M => TryFromBytes for opt_unsafe_extern_c_fn!( ...) ;
405+ // FIXME(#2749): Justify this `Uninit`.
406+ type Uninit = crate :: invariant:: Uninit ;
371407 |c| pointer:: is_zeroed( c)
372408 ) ;
373409} ;
@@ -650,6 +686,7 @@ mod atomics {
650686#[ allow( clippy:: multiple_unsafe_ops_per_block) ]
651687const _: ( ) = unsafe {
652688 unsafe_impl ! ( T : ?Sized => Immutable for PhantomData <T >) ;
689+ // FIXME(#2749): Justify this `Uninit`.
653690 unsafe_impl ! ( T : ?Sized => TryFromBytes for PhantomData <T >) ;
654691 unsafe_impl ! ( T : ?Sized => FromZeros for PhantomData <T >) ;
655692 unsafe_impl ! ( T : ?Sized => FromBytes for PhantomData <T >) ;
@@ -684,6 +721,7 @@ const _: () = unsafe { unsafe_impl!(T: Unaligned => Unaligned for Wrapping<T>) }
684721// `MaybeUninit<T>` has no restrictions on its contents.
685722#[ allow( clippy:: multiple_unsafe_ops_per_block) ]
686723const _: ( ) = unsafe {
724+ // FIXME(#2749): Justify this `Uninit`.
687725 unsafe_impl ! ( T => TryFromBytes for CoreMaybeUninit <T >) ;
688726 unsafe_impl ! ( T => FromZeros for CoreMaybeUninit <T >) ;
689727 unsafe_impl ! ( T => FromBytes for CoreMaybeUninit <T >) ;
@@ -856,6 +894,9 @@ unsafe impl<T: TryFromBytes + ?Sized> TryFromBytes for UnsafeCell<T> {
856894 {
857895 }
858896
897+ // FIXME(#2749): Justify this `Uninit`.
898+ type Uninit = crate :: invariant:: Uninit ;
899+
859900 #[ inline( always) ]
860901 fn is_bit_valid < A > ( candidate : Maybe < ' _ , Self , A > ) -> bool
861902 where
@@ -889,48 +930,56 @@ unsafe impl<T: TryFromBytes + ?Sized> TryFromBytes for UnsafeCell<T> {
889930#[ allow( clippy:: multiple_unsafe_ops_per_block) ]
890931const _: ( ) = unsafe {
891932 unsafe_impl ! ( const N : usize , T : Immutable => Immutable for [ T ; N ] ) ;
892- unsafe_impl ! ( const N : usize , T : TryFromBytes => TryFromBytes for [ T ; N ] ; |c| {
893- let c: Ptr <' _, [ ReadOnly <T >; N ] , _> = c. cast:: <_, crate :: pointer:: cast:: CastSized , _>( ) ;
894- let c: Ptr <' _, [ ReadOnly <T >] , _> = c. as_slice( ) ;
895- let c: Ptr <' _, ReadOnly <[ T ] >, _> = c. cast:: <_, crate :: pointer:: cast:: CastUnsized , _>( ) ;
896-
897- // Note that this call may panic, but it would still be sound even if it
898- // did. `is_bit_valid` does not promise that it will not panic (in fact,
899- // it explicitly warns that it's a possibility), and we have not
900- // violated any safety invariants that we must fix before returning.
901- <[ T ] as TryFromBytes >:: is_bit_valid( c)
902- } ) ;
933+ unsafe_impl ! ( const N : usize , T : TryFromBytes => TryFromBytes for [ T ; N ] ;
934+ // FIXME(#2749): Justify this `Uninit`.
935+ type Uninit = crate :: invariant:: Uninit ;
936+ |c| {
937+ let c: Ptr <' _, [ ReadOnly <T >; N ] , _> = c. cast:: <_, crate :: pointer:: cast:: CastSized , _>( ) ;
938+ let c: Ptr <' _, [ ReadOnly <T >] , _> = c. as_slice( ) ;
939+ let c: Ptr <' _, ReadOnly <[ T ] >, _> = c. cast:: <_, crate :: pointer:: cast:: CastUnsized , _>( ) ;
940+
941+ // Note that this call may panic, but it would still be sound even if it
942+ // did. `is_bit_valid` does not promise that it will not panic (in fact,
943+ // it explicitly warns that it's a possibility), and we have not
944+ // violated any safety invariants that we must fix before returning.
945+ <[ T ] as TryFromBytes >:: is_bit_valid( c)
946+ }
947+ ) ;
903948 unsafe_impl ! ( const N : usize , T : FromZeros => FromZeros for [ T ; N ] ) ;
904949 unsafe_impl ! ( const N : usize , T : FromBytes => FromBytes for [ T ; N ] ) ;
905950 unsafe_impl ! ( const N : usize , T : IntoBytes => IntoBytes for [ T ; N ] ) ;
906951 unsafe_impl ! ( const N : usize , T : Unaligned => Unaligned for [ T ; N ] ) ;
907952 assert_unaligned ! ( [ ( ) ; 0 ] , [ ( ) ; 1 ] , [ u8 ; 0 ] , [ u8 ; 1 ] ) ;
908953 unsafe_impl ! ( T : Immutable => Immutable for [ T ] ) ;
909- unsafe_impl ! ( T : TryFromBytes => TryFromBytes for [ T ] ; |c| {
910- let c: Ptr <' _, [ ReadOnly <T >] , _> = c. cast:: <_, crate :: pointer:: cast:: CastUnsized , _>( ) ;
954+ unsafe_impl ! ( T : TryFromBytes => TryFromBytes for [ T ] ;
955+ // FIXME(#2749): Justify this `Uninit`.
956+ type Uninit = crate :: invariant:: Uninit ;
957+ |c| {
958+ let c: Ptr <' _, [ ReadOnly <T >] , _> = c. cast:: <_, crate :: pointer:: cast:: CastUnsized , _>( ) ;
911959
912- // SAFETY: Per the reference [1]:
913- //
914- // An array of `[T; N]` has a size of `size_of::<T>() * N` and the
915- // same alignment of `T`. Arrays are laid out so that the zero-based
916- // `nth` element of the array is offset from the start of the array by
917- // `n * size_of::<T>()` bytes.
918- //
919- // ...
920- //
921- // Slices have the same layout as the section of the array they slice.
922- //
923- // In other words, the layout of a `[T] is a sequence of `T`s laid out
924- // back-to-back with no bytes in between. If all elements in `candidate`
925- // are `is_bit_valid`, so too is `candidate`.
926- //
927- // Note that any of the below calls may panic, but it would still be
928- // sound even if it did. `is_bit_valid` does not promise that it will
929- // not panic (in fact, it explicitly warns that it's a possibility), and
930- // we have not violated any safety invariants that we must fix before
931- // returning.
932- c. iter( ) . all( <T as TryFromBytes >:: is_bit_valid)
933- } ) ;
960+ // SAFETY: Per the reference [1]:
961+ //
962+ // An array of `[T; N]` has a size of `size_of::<T>() * N` and the
963+ // same alignment of `T`. Arrays are laid out so that the zero-based
964+ // `nth` element of the array is offset from the start of the array by
965+ // `n * size_of::<T>()` bytes.
966+ //
967+ // ...
968+ //
969+ // Slices have the same layout as the section of the array they slice.
970+ //
971+ // In other words, the layout of a `[T] is a sequence of `T`s laid out
972+ // back-to-back with no bytes in between. If all elements in `candidate`
973+ // are `is_bit_valid`, so too is `candidate`.
974+ //
975+ // Note that any of the below calls may panic, but it would still be
976+ // sound even if it did. `is_bit_valid` does not promise that it will
977+ // not panic (in fact, it explicitly warns that it's a possibility), and
978+ // we have not violated any safety invariants that we must fix before
979+ // returning.
980+ c. iter( ) . all( <T as TryFromBytes >:: is_bit_valid)
981+ }
982+ ) ;
934983 unsafe_impl ! ( T : FromZeros => FromZeros for [ T ] ) ;
935984 unsafe_impl ! ( T : FromBytes => FromBytes for [ T ] ) ;
936985 unsafe_impl ! ( T : IntoBytes => IntoBytes for [ T ] ) ;
@@ -963,9 +1012,17 @@ const _: () = unsafe {
9631012const _: ( ) = unsafe {
9641013 unsafe_impl ! ( T : ?Sized => Immutable for * const T ) ;
9651014 unsafe_impl ! ( T : ?Sized => Immutable for * mut T ) ;
966- unsafe_impl ! ( T => TryFromBytes for * const T ; |c| pointer:: is_zeroed( c) ) ;
1015+ unsafe_impl ! ( T => TryFromBytes for * const T ;
1016+ // FIXME(#2749): Justify this `Uninit`.
1017+ type Uninit = crate :: invariant:: Uninit ;
1018+ |c| pointer:: is_zeroed( c)
1019+ ) ;
9671020 unsafe_impl ! ( T => FromZeros for * const T ) ;
968- unsafe_impl ! ( T => TryFromBytes for * mut T ; |c| pointer:: is_zeroed( c) ) ;
1021+ unsafe_impl ! ( T => TryFromBytes for * mut T ;
1022+ // FIXME(#2749): Justify this `Uninit`.
1023+ type Uninit = crate :: invariant:: Uninit ;
1024+ |c| pointer:: is_zeroed( c)
1025+ ) ;
9691026 unsafe_impl ! ( T => FromZeros for * mut T ) ;
9701027} ;
9711028
@@ -990,6 +1047,8 @@ const _: () = unsafe { unsafe_impl!(T: Immutable => Immutable for Option<T>) };
9901047mod tuples {
9911048 use super :: * ;
9921049
1050+ type Uninit < const N : usize > = crate :: invariant:: Uninit ;
1051+
9931052 /// Generates various trait implementations for tuples.
9941053 ///
9951054 /// # Safety
@@ -1011,11 +1070,14 @@ mod tuples {
10111070 unsafe_impl!( $( $head_T: Immutable , ) * $next_T: Immutable => Immutable for ( $( $head_T, ) * $next_T, ) ) ;
10121071
10131072 // SAFETY: If all fields in `c` are `is_bit_valid`, so too is `c`.
1014- unsafe_impl!( $( $head_T: TryFromBytes , ) * $next_T: TryFromBytes => TryFromBytes for ( $( $head_T, ) * $next_T, ) ; |c| {
1015- let mut c = c;
1016- $( TryFromBytes :: is_bit_valid( into_inner!( c. reborrow( ) . project:: <_, { crate :: STRUCT_VARIANT_ID } , { crate :: ident_id!( $head_I) } >( ) ) ) &&) *
1017- TryFromBytes :: is_bit_valid( into_inner!( c. reborrow( ) . project:: <_, { crate :: STRUCT_VARIANT_ID } , { crate :: ident_id!( $next_I) } >( ) ) )
1018- } ) ;
1073+ unsafe_impl!( $( $head_T: TryFromBytes , ) * $next_T: TryFromBytes => TryFromBytes for ( $( $head_T, ) * $next_T, ) ;
1074+ type Uninit = ( $( Uninit <$head_I>, ) * Uninit <$next_I>, ) ;
1075+ |c| {
1076+ let mut c = c;
1077+ $( TryFromBytes :: is_bit_valid( into_inner!( c. reborrow( ) . project:: <_, { crate :: STRUCT_VARIANT_ID } , { crate :: ident_id!( $head_I) } >( ) ) ) &&) *
1078+ TryFromBytes :: is_bit_valid( into_inner!( c. reborrow( ) . project:: <_, { crate :: STRUCT_VARIANT_ID } , { crate :: ident_id!( $next_I) } >( ) ) )
1079+ }
1080+ ) ;
10191081
10201082 // SAFETY: If all fields in `Self` are `FromZeros`, so too is `Self`.
10211083 unsafe_impl!( $( $head_T: FromZeros , ) * $next_T: FromZeros => FromZeros for ( $( $head_T, ) * $next_T, ) ) ;
0 commit comments