diff --git a/zerocopy-derive/src/output_tests.rs b/zerocopy-derive/src/output_tests.rs index 7285601417..98ebf2ec84 100644 --- a/zerocopy-derive/src/output_tests.rs +++ b/zerocopy-derive/src/output_tests.rs @@ -197,19 +197,28 @@ fn test_try_from_bytes_enum() { test_derive! { TryFromBytes { #[repr(u8)] - enum ComplexWithGenerics { + enum ComplexWithGenerics<'a, const N: usize, X, Y: Deref> + where + X: Deref, + { UnitLike, - StructLike { a: u8, b: X }, - TupleLike(bool, Y), + StructLike { a: u8, b: X, c: X::Target, d: Y::Target, e: [(X, Y); N] }, + TupleLike(bool, Y, PhantomData<&'a [(X, Y); N]>), } } expands to { #[allow(deprecated)] - unsafe impl ::zerocopy::TryFromBytes for ComplexWithGenerics + unsafe impl<'a, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes + for ComplexWithGenerics<'a, { N }, X, Y> where + X: Deref, u8: ::zerocopy::TryFromBytes, X: ::zerocopy::TryFromBytes, + X::Target: ::zerocopy::TryFromBytes, + Y::Target: ::zerocopy::TryFromBytes, + [(X, Y); N]: ::zerocopy::TryFromBytes, bool: ::zerocopy::TryFromBytes, Y: ::zerocopy::TryFromBytes, + PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid( @@ -244,34 +253,42 @@ fn test_try_from_bytes_enum() { #[repr(C)] #[allow(non_snake_case)] #[derive(:: zerocopy_derive :: TryFromBytes)] - struct ___ZerocopyVariantStruct_StructLike( + struct ___ZerocopyVariantStruct_StructLike<'a, const N: usize, X, Y: Deref>( core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, u8, X, - core_reexport::marker::PhantomData >, - ); + X::Target, + Y::Target, + [(X, Y); N], + core_reexport::marker::PhantomData >, + ) + where + X: Deref,; #[repr(C)] #[allow(non_snake_case)] #[derive(:: zerocopy_derive :: TryFromBytes)] - struct ___ZerocopyVariantStruct_TupleLike( + struct ___ZerocopyVariantStruct_TupleLike<'a, const N: usize, X, Y: Deref>( core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, bool, Y, - core_reexport::marker::PhantomData >, - ); + PhantomData<&'a [(X, Y); N]>, + core_reexport::marker::PhantomData >, + ) + where + X: Deref,; #[repr(C)] #[allow(non_snake_case)] - union ___ZerocopyVariants { + union ___ZerocopyVariants<'a, const N: usize, X, Y: Deref> { __field_StructLike: - core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike >, + core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike<'a, N, X, Y> >, __field_TupleLike: - core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike >, + core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> >, __nonempty: (), } #[repr(C)] - struct ___ZerocopyRawEnum { + struct ___ZerocopyRawEnum<'a, const N: usize, X, Y: Deref> { tag: ___ZerocopyOuterTag, - variants: ___ZerocopyVariants, + variants: ___ZerocopyVariants<'a, N, X, Y>, } let tag = { let tag_ptr = unsafe { @@ -280,11 +297,12 @@ fn test_try_from_bytes_enum() { let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.bikeshed_recall_valid().read_unaligned() }; - let raw_enum = - unsafe { candidate.cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyRawEnum }) }; + let raw_enum = unsafe { + candidate.cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> }) + }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { - raw_enum.project(|p: *mut ___ZerocopyRawEnum| { + raw_enum.project(|p: *mut ___ZerocopyRawEnum<'a, N, X, Y>| { core_reexport::ptr::addr_of_mut!((*p).variants) }) }; @@ -293,25 +311,23 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_UnitLike => true, ___ZEROCOPY_TAG_StructLike => { let variant = unsafe { - variants.cast_unsized(|p: *mut ___ZerocopyVariants| { - p as *mut ___ZerocopyVariantStruct_StructLike + variants.cast_unsized(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| { + p as *mut ___ZerocopyVariantStruct_StructLike<'a, N, X, Y> }) }; let variant = unsafe { variant.assume_initialized() }; - < ___ZerocopyVariantStruct_StructLike < X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( - variant - ) + < ___ZerocopyVariantStruct_StructLike < 'a , N , X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( + variant) }, ___ZEROCOPY_TAG_TupleLike => { let variant = unsafe { - variants.cast_unsized(|p: *mut ___ZerocopyVariants| { - p as *mut ___ZerocopyVariantStruct_TupleLike + variants.cast_unsized(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| { + p as *mut ___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> }) }; let variant = unsafe { variant.assume_initialized() }; - <___ZerocopyVariantStruct_TupleLike as ::zerocopy::TryFromBytes>::is_bit_valid( - variant - ) + < ___ZerocopyVariantStruct_TupleLike < 'a , N , X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( + variant) }, _ => false, } @@ -323,19 +339,28 @@ fn test_try_from_bytes_enum() { test_derive! { TryFromBytes { #[repr(u32)] - enum ComplexWithGenerics { + enum ComplexWithGenerics<'a, const N: usize, X, Y: Deref> + where + X: Deref, + { UnitLike, - StructLike { a: u8, b: X }, - TupleLike(bool, Y), + StructLike { a: u8, b: X, c: X::Target, d: Y::Target, e: [(X, Y); N] }, + TupleLike(bool, Y, PhantomData<&'a [(X, Y); N]>), } } expands to { #[allow(deprecated)] - unsafe impl ::zerocopy::TryFromBytes for ComplexWithGenerics + unsafe impl<'a, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes + for ComplexWithGenerics<'a, { N }, X, Y> where + X: Deref, u8: ::zerocopy::TryFromBytes, X: ::zerocopy::TryFromBytes, + X::Target: ::zerocopy::TryFromBytes, + Y::Target: ::zerocopy::TryFromBytes, + [(X, Y); N]: ::zerocopy::TryFromBytes, bool: ::zerocopy::TryFromBytes, Y: ::zerocopy::TryFromBytes, + PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid( @@ -370,34 +395,42 @@ fn test_try_from_bytes_enum() { #[repr(C)] #[allow(non_snake_case)] #[derive(:: zerocopy_derive :: TryFromBytes)] - struct ___ZerocopyVariantStruct_StructLike( + struct ___ZerocopyVariantStruct_StructLike<'a, const N: usize, X, Y: Deref>( core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, u8, X, - core_reexport::marker::PhantomData >, - ); + X::Target, + Y::Target, + [(X, Y); N], + core_reexport::marker::PhantomData >, + ) + where + X: Deref,; #[repr(C)] #[allow(non_snake_case)] #[derive(:: zerocopy_derive :: TryFromBytes)] - struct ___ZerocopyVariantStruct_TupleLike( + struct ___ZerocopyVariantStruct_TupleLike<'a, const N: usize, X, Y: Deref>( core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, bool, Y, - core_reexport::marker::PhantomData >, - ); + PhantomData<&'a [(X, Y); N]>, + core_reexport::marker::PhantomData >, + ) + where + X: Deref,; #[repr(C)] #[allow(non_snake_case)] - union ___ZerocopyVariants { + union ___ZerocopyVariants<'a, const N: usize, X, Y: Deref> { __field_StructLike: - core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike >, + core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike<'a, N, X, Y> >, __field_TupleLike: - core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike >, + core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> >, __nonempty: (), } #[repr(C)] - struct ___ZerocopyRawEnum { + struct ___ZerocopyRawEnum<'a, const N: usize, X, Y: Deref> { tag: ___ZerocopyOuterTag, - variants: ___ZerocopyVariants, + variants: ___ZerocopyVariants<'a, N, X, Y>, } let tag = { let tag_ptr = unsafe { @@ -406,11 +439,12 @@ fn test_try_from_bytes_enum() { let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.bikeshed_recall_valid().read_unaligned() }; - let raw_enum = - unsafe { candidate.cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyRawEnum }) }; + let raw_enum = unsafe { + candidate.cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> }) + }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { - raw_enum.project(|p: *mut ___ZerocopyRawEnum| { + raw_enum.project(|p: *mut ___ZerocopyRawEnum<'a, N, X, Y>| { core_reexport::ptr::addr_of_mut!((*p).variants) }) }; @@ -419,25 +453,23 @@ fn test_try_from_bytes_enum() { ___ZEROCOPY_TAG_UnitLike => true, ___ZEROCOPY_TAG_StructLike => { let variant = unsafe { - variants.cast_unsized(|p: *mut ___ZerocopyVariants| { - p as *mut ___ZerocopyVariantStruct_StructLike + variants.cast_unsized(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| { + p as *mut ___ZerocopyVariantStruct_StructLike<'a, N, X, Y> }) }; let variant = unsafe { variant.assume_initialized() }; - < ___ZerocopyVariantStruct_StructLike < X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( - variant - ) + < ___ZerocopyVariantStruct_StructLike < 'a , N , X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( + variant) }, ___ZEROCOPY_TAG_TupleLike => { let variant = unsafe { - variants.cast_unsized(|p: *mut ___ZerocopyVariants| { - p as *mut ___ZerocopyVariantStruct_TupleLike + variants.cast_unsized(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| { + p as *mut ___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> }) }; let variant = unsafe { variant.assume_initialized() }; - <___ZerocopyVariantStruct_TupleLike as ::zerocopy::TryFromBytes>::is_bit_valid( - variant - ) + < ___ZerocopyVariantStruct_TupleLike < 'a , N , X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( + variant) }, _ => false, } @@ -449,126 +481,142 @@ fn test_try_from_bytes_enum() { test_derive! { TryFromBytes { #[repr(C)] - enum ComplexWithGenerics { + enum ComplexWithGenerics<'a, const N: usize, X, Y: Deref> + where + X: Deref, + { UnitLike, - StructLike { a: u8, b: X }, - TupleLike(bool, Y), + StructLike { a: u8, b: X, c: X::Target, d: Y::Target, e: [(X, Y); N] }, + TupleLike(bool, Y, PhantomData<&'a [(X, Y); N]>), } } expands to { #[allow(deprecated)] - unsafe impl ::zerocopy::TryFromBytes for ComplexWithGenerics + unsafe impl<'a, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes + for ComplexWithGenerics<'a, { N }, X, Y> + where + X: Deref, + u8: ::zerocopy::TryFromBytes, + X: ::zerocopy::TryFromBytes, + X::Target: ::zerocopy::TryFromBytes, + Y::Target: ::zerocopy::TryFromBytes, + [(X, Y); N]: ::zerocopy::TryFromBytes, + bool: ::zerocopy::TryFromBytes, + Y: ::zerocopy::TryFromBytes, + PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes, + { + fn only_derive_is_allowed_to_implement_this_trait() {} + fn is_bit_valid( + mut candidate: ::zerocopy::Maybe<'_, Self, A>, + ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where - u8: ::zerocopy::TryFromBytes, - X: ::zerocopy::TryFromBytes, - bool: ::zerocopy::TryFromBytes, - Y: ::zerocopy::TryFromBytes, + A: ::zerocopy::pointer::invariant::Aliasing + + ::zerocopy::pointer::invariant::AtLeast<::zerocopy::pointer::invariant::Shared>, { - fn only_derive_is_allowed_to_implement_this_trait() {} - fn is_bit_valid( - mut candidate: ::zerocopy::Maybe<'_, Self, A>, - ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool + use ::zerocopy::util::macro_util::core_reexport; + #[repr(C)] + #[allow(dead_code)] + enum ___ZerocopyTag { + UnitLike, + StructLike, + TupleLike, + } + type ___ZerocopyTagPrimitive = ::zerocopy::util::macro_util::SizeToTag< + { core_reexport::mem::size_of::<___ZerocopyTag>() }, + >; + #[allow(non_upper_case_globals)] + const ___ZEROCOPY_TAG_UnitLike: ___ZerocopyTagPrimitive = + ___ZerocopyTag::UnitLike as ___ZerocopyTagPrimitive; + #[allow(non_upper_case_globals)] + const ___ZEROCOPY_TAG_StructLike: ___ZerocopyTagPrimitive = + ___ZerocopyTag::StructLike as ___ZerocopyTagPrimitive; + #[allow(non_upper_case_globals)] + const ___ZEROCOPY_TAG_TupleLike: ___ZerocopyTagPrimitive = + ___ZerocopyTag::TupleLike as ___ZerocopyTagPrimitive; + type ___ZerocopyOuterTag = ___ZerocopyTag; + type ___ZerocopyInnerTag = (); + #[repr(C)] + #[allow(non_snake_case)] + #[derive(:: zerocopy_derive :: TryFromBytes)] + struct ___ZerocopyVariantStruct_StructLike<'a, const N: usize, X, Y: Deref>( + core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, + u8, + X, + X::Target, + Y::Target, + [(X, Y); N], + core_reexport::marker::PhantomData >, + ) where - A: ::zerocopy::pointer::invariant::Aliasing - + ::zerocopy::pointer::invariant::AtLeast<::zerocopy::pointer::invariant::Shared>, - { - use ::zerocopy::util::macro_util::core_reexport; - #[repr(C)] - #[allow(dead_code)] - enum ___ZerocopyTag { - UnitLike, - StructLike, - TupleLike, - } - type ___ZerocopyTagPrimitive = ::zerocopy::util::macro_util::SizeToTag< - { core_reexport::mem::size_of::<___ZerocopyTag>() }, - >; - #[allow(non_upper_case_globals)] - const ___ZEROCOPY_TAG_UnitLike: ___ZerocopyTagPrimitive = - ___ZerocopyTag::UnitLike as ___ZerocopyTagPrimitive; - #[allow(non_upper_case_globals)] - const ___ZEROCOPY_TAG_StructLike: ___ZerocopyTagPrimitive = - ___ZerocopyTag::StructLike as ___ZerocopyTagPrimitive; - #[allow(non_upper_case_globals)] - const ___ZEROCOPY_TAG_TupleLike: ___ZerocopyTagPrimitive = - ___ZerocopyTag::TupleLike as ___ZerocopyTagPrimitive; - type ___ZerocopyOuterTag = ___ZerocopyTag; - type ___ZerocopyInnerTag = (); - #[repr(C)] - #[allow(non_snake_case)] - #[derive(:: zerocopy_derive :: TryFromBytes)] - struct ___ZerocopyVariantStruct_StructLike( - core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, - u8, - X, - core_reexport::marker::PhantomData >, - ); - #[repr(C)] - #[allow(non_snake_case)] - #[derive(:: zerocopy_derive :: TryFromBytes)] - struct ___ZerocopyVariantStruct_TupleLike( - core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, - bool, - Y, - core_reexport::marker::PhantomData >, - ); - #[repr(C)] - #[allow(non_snake_case)] - union ___ZerocopyVariants { - __field_StructLike: - core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike >, - __field_TupleLike: - core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike >, - __nonempty: (), - } - #[repr(C)] - struct ___ZerocopyRawEnum { - tag: ___ZerocopyOuterTag, - variants: ___ZerocopyVariants, - } - let tag = { - let tag_ptr = unsafe { - candidate.reborrow().cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive }) - }; - let tag_ptr = unsafe { tag_ptr.assume_initialized() }; - tag_ptr.bikeshed_recall_valid().read_unaligned() - }; - let raw_enum = - unsafe { candidate.cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyRawEnum }) }; - let raw_enum = unsafe { raw_enum.assume_initialized() }; - let variants = unsafe { - raw_enum.project(|p: *mut ___ZerocopyRawEnum| { - core_reexport::ptr::addr_of_mut!((*p).variants) - }) + X: Deref,; + #[repr(C)] + #[allow(non_snake_case)] + #[derive(:: zerocopy_derive :: TryFromBytes)] + struct ___ZerocopyVariantStruct_TupleLike<'a, const N: usize, X, Y: Deref>( + core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>, + bool, + Y, + PhantomData<&'a [(X, Y); N]>, + core_reexport::marker::PhantomData >, + ) + where + X: Deref,; + #[repr(C)] + #[allow(non_snake_case)] + union ___ZerocopyVariants<'a, const N: usize, X, Y: Deref> { + __field_StructLike: + core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike<'a, N, X, Y> >, + __field_TupleLike: + core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> >, + __nonempty: (), + } + #[repr(C)] + struct ___ZerocopyRawEnum<'a, const N: usize, X, Y: Deref> { + tag: ___ZerocopyOuterTag, + variants: ___ZerocopyVariants<'a, N, X, Y>, + } + let tag = { + let tag_ptr = unsafe { + candidate.reborrow().cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive }) }; - #[allow(non_upper_case_globals)] - match tag { - ___ZEROCOPY_TAG_UnitLike => true, - ___ZEROCOPY_TAG_StructLike => { - let variant = unsafe { - variants.cast_unsized(|p: *mut ___ZerocopyVariants| { - p as *mut ___ZerocopyVariantStruct_StructLike - }) - }; - let variant = unsafe { variant.assume_initialized() }; - < ___ZerocopyVariantStruct_StructLike < X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( - variant - ) - }, - ___ZEROCOPY_TAG_TupleLike => { - let variant = unsafe { - variants.cast_unsized(|p: *mut ___ZerocopyVariants| { - p as *mut ___ZerocopyVariantStruct_TupleLike - }) - }; - let variant = unsafe { variant.assume_initialized() }; - <___ZerocopyVariantStruct_TupleLike as ::zerocopy::TryFromBytes>::is_bit_valid( - variant - ) - }, - _ => false, - } + let tag_ptr = unsafe { tag_ptr.assume_initialized() }; + tag_ptr.bikeshed_recall_valid().read_unaligned() + }; + let raw_enum = unsafe { + candidate.cast_unsized(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> }) + }; + let raw_enum = unsafe { raw_enum.assume_initialized() }; + let variants = unsafe { + raw_enum.project(|p: *mut ___ZerocopyRawEnum<'a, N, X, Y>| { + core_reexport::ptr::addr_of_mut!((*p).variants) + }) + }; + #[allow(non_upper_case_globals)] + match tag { + ___ZEROCOPY_TAG_UnitLike => true, + ___ZEROCOPY_TAG_StructLike => { + let variant = unsafe { + variants.cast_unsized(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| { + p as *mut ___ZerocopyVariantStruct_StructLike<'a, N, X, Y> + }) + }; + let variant = unsafe { variant.assume_initialized() }; + < ___ZerocopyVariantStruct_StructLike < 'a , N , X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( + variant) + }, + ___ZEROCOPY_TAG_TupleLike => { + let variant = unsafe { + variants.cast_unsized(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| { + p as *mut ___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> + }) + }; + let variant = unsafe { variant.assume_initialized() }; + < ___ZerocopyVariantStruct_TupleLike < 'a , N , X , Y > as :: zerocopy :: TryFromBytes > :: is_bit_valid ( + variant) + }, + _ => false, } } + } } no_build } }