@@ -128,7 +128,18 @@ macro_rules! unsafe_impl {
128128 unsafe_impl!( @method $trait $( ; |$candidate| $is_bit_valid) ?) ;
129129 }
130130 } } ;
131+ ( @method InitializeIntoBytes ; |$slf: ident| $initialize_padding: expr) => {
132+ #[ allow( clippy:: missing_inline_in_public_items, dead_code) ]
133+ #[ cfg_attr( all( coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS) , coverage( off) ) ]
134+ fn only_derive_is_allowed_to_implement_this_trait( ) { }
131135
136+ #[ allow( unused_mut) ]
137+ #[ inline( always) ]
138+ fn initialize_padding( $slf: Ptr <' _, Self , ( invariant:: Exclusive , invariant:: Unaligned , invariant:: AsInitialized ) >)
139+ {
140+ $initialize_padding
141+ }
142+ } ;
132143 ( @method TryFromBytes ; |$candidate: ident| $is_bit_valid: expr) => {
133144 #[ allow( clippy:: missing_inline_in_public_items, dead_code) ]
134145 #[ cfg_attr( all( coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS) , coverage( off) ) ]
@@ -174,6 +185,7 @@ macro_rules! impl_for_transmute_from {
174185 $( #[ $attr: meta] ) *
175186 $( $tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?) ?
176187 => $trait: ident for $ty: ty [ $repr: ty]
188+ $( |$slf: ident| $b: block) *
177189 ) => {
178190 const _: ( ) = {
179191 $( #[ $attr] ) *
@@ -214,12 +226,20 @@ macro_rules! impl_for_transmute_from {
214226 $( <$tyvar $( : $( ? $optbound +) * $( $bound +) * ) ?>) ?
215227 $trait for $ty [ $repr]
216228 ) ;
229+
230+ impl_for_transmute_from!(
231+ @initialize_into_bytes
232+ $( <$tyvar $( : $( ? $optbound +) * $( $bound +) * ) ?>) ?
233+ $trait for $ty [ $repr]
234+ $( |$slf| $b) *
235+ ) ;
217236 }
218237 } ;
219238 } ;
220239 ( @assert_is_supported_trait TryFromBytes ) => { } ;
221240 ( @assert_is_supported_trait FromZeros ) => { } ;
222241 ( @assert_is_supported_trait FromBytes ) => { } ;
242+ ( @assert_is_supported_trait InitializeIntoBytes ) => { } ;
223243 ( @assert_is_supported_trait IntoBytes ) => { } ;
224244 (
225245 @is_bit_valid
@@ -242,7 +262,29 @@ macro_rules! impl_for_transmute_from {
242262 $( <$tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?>) ?
243263 $trait: ident for $ty: ty [ $repr: ty]
244264 ) => {
245- // Trait other than `TryFromBytes`; no `is_bit_valid` impl.
265+ // Other trait; no additional items.
266+ } ;
267+ (
268+ @initialize_into_bytes
269+ $( <$tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?>) ?
270+ InitializeIntoBytes for $ty: ty [ $repr: ty]
271+ ) => {
272+ #[ inline( always) ]
273+ fn initialize_padding( ptr: Ptr <' _, Self , ( invariant:: Exclusive , invariant:: Unaligned , invariant:: AsInitialized ) >)
274+ {
275+ let ptr = ptr. transmute:: <$repr, _, ( _, ( _, _) ) >( ) ;
276+ // SAFETY: This macro ensures that `$repr` and `Self` have the same
277+ // size and bit validity. Thus, a bit-valid instance of `$repr` is
278+ // also a bit-valid instance of `Self`.
279+ <$repr as InitializeIntoBytes >:: initialize_padding( ptr)
280+ }
281+ } ;
282+ (
283+ @initialize_into_bytes
284+ $( <$tyvar: ident $( : $( ? $optbound: ident $( +) ?) * $( $bound: ident $( +) ?) * ) ?>) ?
285+ $trait: ident for $ty: ty [ $repr: ty] $( |$slf: ident| $b: block) *
286+ ) => {
287+ // Other trait; no additional items.
246288 } ;
247289}
248290
@@ -525,6 +567,36 @@ macro_rules! unsafe_impl_known_layout {
525567 } } ;
526568}
527569
570+ macro_rules! impl_initialize_into_bytes {
571+ ( $( const $constvar: ident : $constty: ty, $tyvar: ident $( : ?$optbound: ident) ? => $ty: ty) ,* $( , ) ?) => {
572+ $( impl_initialize_into_bytes!( @inner const $constvar: $constty, $tyvar $( : ?$optbound) ? => $ty) ; ) *
573+ } ;
574+ ( $( $tyvar: ident $( : ?$optbound: ident) ? => $ty: ty) ,* $( , ) ?) => {
575+ $( impl_initialize_into_bytes!( @inner , $tyvar $( : ?$optbound) ? => $ty) ; ) *
576+ } ;
577+ ( $( $( #[ $attrs: meta] ) * $ty: ty) ,* ) => { $( impl_initialize_into_bytes!( @inner , => $( #[ $attrs] ) * $ty) ; ) * } ;
578+ ( @inner $( const $constvar: ident : $constty: ty) ? , $( $tyvar: ident $( : ?$optbound: ident) ?) ? => $( #[ $attrs: meta] ) * $ty: ty) => {
579+ const _: ( ) = {
580+ #[ allow( non_local_definitions) ]
581+ $( #[ $attrs] ) *
582+ // SAFETY: TODO
583+ unsafe impl <$( $tyvar $( : ?$optbound) ?) ? $( , const $constvar : $constty) ?> InitializeIntoBytes for $ty
584+ where
585+ Self : IntoBytes
586+ {
587+ #[ allow( clippy:: missing_inline_in_public_items) ]
588+ #[ cfg_attr( all( coverage_nightly, __ZEROCOPY_INTERNAL_USE_ONLY_NIGHTLY_FEATURES_IN_TESTS) , coverage( off) ) ]
589+ fn only_derive_is_allowed_to_implement_this_trait( ) where Self : Sized { }
590+
591+ #[ inline( always) ]
592+ fn initialize_padding( _: Ptr <' _, Self , ( invariant:: Exclusive , invariant:: Unaligned , invariant:: AsInitialized ) >) {
593+ // By invariant on `Self: IntoBytes`, values of type `Self` never contain padding.
594+ }
595+ }
596+ } ;
597+ } ;
598+ }
599+
528600/// Uses `align_of` to confirm that a type or set of types have alignment 1.
529601///
530602/// Note that `align_of<T>` requires `T: Sized`, so this macro doesn't work for
@@ -740,14 +812,19 @@ macro_rules! unsafe_impl_for_transparent_wrapper {
740812 ( $vis: vis T $( : ?$optbound: ident) ? => $wrapper: ident<T >) => { {
741813 crate :: util:: macros:: __unsafe( ) ;
742814
743- use crate :: pointer:: { TransmuteFrom , cast:: { CastExact , TransitiveProject } , SizeEq , invariant:: Valid } ;
815+ use crate :: pointer:: { TransmuteFrom , cast:: { CastExact , TransitiveProject } , SizeEq , invariant:: { AsInitialized , Valid } } ;
744816 use crate :: wrappers:: ReadOnly ;
745817
746818 // SAFETY: The caller promises that `T` and `$wrapper<T>` have the same
747819 // bit validity.
748820 unsafe impl <T $( : ?$optbound) ?> TransmuteFrom <T , Valid , Valid > for $wrapper<T > { }
749821 // SAFETY: See previous safety comment.
750822 unsafe impl <T $( : ?$optbound) ?> TransmuteFrom <$wrapper<T >, Valid , Valid > for T { }
823+ // SAFETY: See previous safety comment.
824+ unsafe impl <T $( : ?$optbound) ?> TransmuteFrom <T , AsInitialized , AsInitialized > for $wrapper<T > { }
825+ // SAFETY: See previous safety comment.
826+ unsafe impl <T $( : ?$optbound) ?> TransmuteFrom <$wrapper<T >, AsInitialized , AsInitialized > for T { }
827+
751828 // SAFETY: The caller promises that a `T` to `$wrapper<T>` cast is
752829 // size-preserving.
753830 define_cast!( unsafe { $vis CastToWrapper <T $( : ?$optbound) ? > = T => $wrapper<T > } ) ;
0 commit comments