// Copyright 2024 The Fuchsia Authors // // Licensed under a BSD-style license , Apache License, Version 2.0 // , or the MIT // license , at your option. // This file may not be copied, modified, or distributed except according to // those terms. use crate::IntoTokenStream; use dissimilar::Chunk; use proc_macro2::TokenStream; macro_rules! use_as_trait_name { ($($alias:ident => $derive:ident),* $(,)?) => { $(use super::$derive as $alias;)* }; } // This permits invocations of `test!` to be more ergonomic, passing the name of // the trait under test rather than the name of the inner derive function. use_as_trait_name!( KnownLayout => derive_known_layout_inner, Immutable => derive_no_cell_inner, TryFromBytes => derive_try_from_bytes_inner, FromZeros => derive_from_zeros_inner, FromBytes => derive_from_bytes_inner, IntoBytes => derive_into_bytes_inner, Unaligned => derive_unaligned_inner, ByteHash => derive_hash_inner, ByteEq => derive_eq_inner, ); /// Test that the given derive input expands to the expected output. /// /// Equality is tested by formatting both token streams using `prettyplease` and /// performing string equality on the results. This has the effect of making the /// tests less brittle and robust against meaningless formatting changes. // Adapted from https://github.com/joshlf/synstructure/blob/400499aaf54840056ff56718beb7810540e6be59/src/macros.rs#L212-L317 macro_rules! test { ($name:ident { $($i:tt)* } expands to { $($o:tt)* }) => { { #[allow(dead_code)] fn ensure_compiles() { $($i)* $($o)* } test!($name { $($i)* } expands to { $($o)* } no_build); } }; ($name:ident { $($i:tt)* } expands to { $($o:tt)* } no_build) => { { let ts: proc_macro2::TokenStream = quote::quote!( $($i)* ); let ast = syn::parse2::(ts).unwrap(); let res = $name(&ast, crate::Trait::$name); let expected_toks = quote::quote!( $($o)* ); assert_eq_streams(expected_toks.into(), res.into_ts().into()); } }; } #[track_caller] fn assert_eq_streams(expect: TokenStream, res: TokenStream) { let pretty = |ts: TokenStream| prettyplease::unparse(&syn::parse_file(&ts.to_string()).unwrap()); let expect = pretty(expect.clone()); let res = pretty(res.clone()); if expect != res { let diff = dissimilar::diff(&expect, &res) .into_iter() .flat_map(|chunk| { let (prefix, chunk) = match chunk { Chunk::Equal(chunk) => (" ", chunk), Chunk::Delete(chunk) => ("-", chunk), Chunk::Insert(chunk) => ("+", chunk), }; [prefix, chunk, "\n"] }) .collect::(); panic!( "\ test failed: got: ``` {} ``` diff (expected vs got): ``` {} ```\n", res, diff ); } } #[test] fn test_known_layout() { test! { KnownLayout { struct Foo; } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::KnownLayout for Foo where Self: ::zerocopy::util::macro_util::core_reexport::marker::Sized, { fn only_derive_is_allowed_to_implement_this_trait() {} type PointerMetadata = (); type MaybeUninit = ::zerocopy::util::macro_util::core_reexport::mem::MaybeUninit; const LAYOUT: ::zerocopy::DstLayout = ::zerocopy::DstLayout::for_type::(); #[inline(always)] fn raw_from_ptr_len( bytes: ::zerocopy::util::macro_util::core_reexport::ptr::NonNull, _meta: (), ) -> ::zerocopy::util::macro_util::core_reexport::ptr::NonNull { bytes.cast::() } #[inline(always)] fn pointer_to_metadata(_ptr: *mut Self) -> () {} } } no_build } test! { KnownLayout { #[repr(C, align(2))] struct Foo(T, U); } expands to { const _: () = { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::KnownLayout for Foo where U: ::zerocopy::KnownLayout, { fn only_derive_is_allowed_to_implement_this_trait() {} type PointerMetadata = ::PointerMetadata; type MaybeUninit = __ZerocopyKnownLayoutMaybeUninit; const LAYOUT: ::zerocopy::DstLayout = { use ::zerocopy::util::macro_util::core_reexport::num::NonZeroUsize; use ::zerocopy::{DstLayout, KnownLayout}; let repr_align = ::zerocopy::util::macro_util::core_reexport::num::NonZeroUsize::new( 2u32 as usize, ); let repr_packed = ::zerocopy::util::macro_util::core_reexport::option::Option::None; DstLayout::new_zst(repr_align) .extend(DstLayout::for_type::(), repr_packed) .extend(::LAYOUT, repr_packed) .pad_to_align() }; #[inline(always)] fn raw_from_ptr_len( bytes: ::zerocopy::util::macro_util::core_reexport::ptr::NonNull, meta: Self::PointerMetadata, ) -> ::zerocopy::util::macro_util::core_reexport::ptr::NonNull { use ::zerocopy::KnownLayout; let trailing = ::raw_from_ptr_len(bytes, meta); let slf = trailing.as_ptr() as *mut Self; unsafe { ::zerocopy::util::macro_util::core_reexport::ptr::NonNull::new_unchecked( slf, ) } } #[inline(always)] fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata { ::pointer_to_metadata(ptr as *mut _) } } #[allow(non_camel_case_types)] struct __Zerocopy_Field_0; #[allow(non_camel_case_types)] struct __Zerocopy_Field_1; unsafe impl ::zerocopy::util::macro_util::Field<__Zerocopy_Field_0> for Foo { type Type = T; } unsafe impl ::zerocopy::util::macro_util::Field<__Zerocopy_Field_1> for Foo { type Type = U; } #[repr(C)] #[repr(align(2))] #[doc(hidden)] #[allow(private_bounds)] struct __ZerocopyKnownLayoutMaybeUninit( ::zerocopy::util::macro_util::core_reexport::mem::MaybeUninit< as ::zerocopy::util::macro_util::Field<__Zerocopy_Field_0>>::Type, >, ::zerocopy::util::macro_util::core_reexport::mem::ManuallyDrop< < as ::zerocopy::util::macro_util::Field< __Zerocopy_Field_1, >>::Type as ::zerocopy::KnownLayout>::MaybeUninit >, ) where as ::zerocopy::util::macro_util::Field< __Zerocopy_Field_1, >>::Type: ::zerocopy::KnownLayout; unsafe impl ::zerocopy::KnownLayout for __ZerocopyKnownLayoutMaybeUninit where as ::zerocopy::util::macro_util::Field< __Zerocopy_Field_1, >>::Type: ::zerocopy::KnownLayout, { #[allow(clippy::missing_inline_in_public_items)] fn only_derive_is_allowed_to_implement_this_trait() {} type PointerMetadata = as ::zerocopy::KnownLayout>::PointerMetadata; type MaybeUninit = Self; const LAYOUT: ::zerocopy::DstLayout = as ::zerocopy::KnownLayout>::LAYOUT; #[inline(always)] fn raw_from_ptr_len( bytes: ::zerocopy::util::macro_util::core_reexport::ptr::NonNull, meta: Self::PointerMetadata, ) -> ::zerocopy::util::macro_util::core_reexport::ptr::NonNull { use ::zerocopy::KnownLayout; let trailing = << as ::zerocopy::util::macro_util::Field< __Zerocopy_Field_1, >>::Type as ::zerocopy::KnownLayout>::MaybeUninit as KnownLayout>::raw_from_ptr_len( bytes, meta, ); let slf = trailing.as_ptr() as *mut Self; unsafe { ::zerocopy::util::macro_util::core_reexport::ptr::NonNull::new_unchecked( slf, ) } } #[inline(always)] fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata { << as ::zerocopy::util::macro_util::Field< __Zerocopy_Field_1, >>::Type as ::zerocopy::KnownLayout>::MaybeUninit>::pointer_to_metadata( ptr as *mut _, ) } } }; } no_build } } #[test] fn test_immutable() { test! { Immutable { struct Foo; } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::Immutable for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } } #[test] fn test_try_from_bytes() { test! { TryFromBytes { struct Foo; } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::TryFromBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true } } } no_build } } #[test] fn test_from_zeros() { test! { FromZeros { struct Foo; } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::TryFromBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true } } #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::FromZeros for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } } #[test] fn test_from_bytes_struct() { test! { FromBytes { struct Foo; } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::TryFromBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( _candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { if false { fn assert_is_from_bytes() where T: ::zerocopy::FromBytes, T: ?::zerocopy::util::macro_util::core_reexport::marker::Sized, {} assert_is_from_bytes::(); } true } } #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::FromZeros for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::FromBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } } #[test] fn test_from_bytes_union() { test! { FromBytes { union Foo { a: u8, } } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::TryFromBytes for Foo where u8: ::zerocopy::TryFromBytes + ::zerocopy::Immutable, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( _candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { if false { fn assert_is_from_bytes() where T: ::zerocopy::FromBytes, T: ?::zerocopy::util::macro_util::core_reexport::marker::Sized, {} assert_is_from_bytes::(); } true } } #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::FromZeros for Foo where u8: ::zerocopy::FromZeros + ::zerocopy::Immutable, { fn only_derive_is_allowed_to_implement_this_trait() {} } #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::FromBytes for Foo where u8: ::zerocopy::FromBytes + ::zerocopy::Immutable, { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } } #[test] fn test_into_bytes() { test! { IntoBytes { #[repr(C)] struct Foo; } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::IntoBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } test! { IntoBytes { #[repr(C)] struct Foo { a: u8, b: u8, } } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::IntoBytes for Foo where u8: ::zerocopy::IntoBytes, u8: ::zerocopy::IntoBytes, (): ::zerocopy::util::macro_util::PaddingFree< Self, { ::zerocopy::struct_has_padding!(Self, [u8, u8]) }, >, { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } } #[test] fn test_unaligned() { test! { Unaligned { #[repr(C)] struct Foo; } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::Unaligned for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } } #[test] fn test_try_from_bytes_enum() { test! { TryFromBytes { #[repr(u8)] enum ComplexWithGenerics<'a: 'static, const N: usize, X, Y: Deref> where X: Deref, { UnitLike, 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)] #[automatically_derived] unsafe impl<'a: 'static, 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<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe<'_, Self, ___ZerocopyAliasing>, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; #[repr(u8)] #[allow(dead_code, non_camel_case_types)] 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 = (); type ___ZerocopyInnerTag = ___ZerocopyTag; #[repr(C)] #[allow(non_snake_case)] struct ___ZerocopyVariantStruct_StructLike<'a: 'static, 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 X: Deref; #[allow(deprecated)] #[automatically_derived] unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes for ___ZerocopyVariantStruct_StructLike<'a, { N }, X, Y> where X: Deref, core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes, u8: ::zerocopy::TryFromBytes, X: ::zerocopy::TryFromBytes, X::Target: ::zerocopy::TryFromBytes, Y::Target: ::zerocopy::TryFromBytes, [(X, Y); N]: ::zerocopy::TryFromBytes, core_reexport::marker::PhantomData>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).5) }; candidate.reborrow().cast_unsized_unchecked(project) }; <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).6) }; candidate.reborrow().cast_unsized_unchecked(project) }; , > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } } } #[repr(C)] #[allow(non_snake_case)] struct ___ZerocopyVariantStruct_TupleLike<'a: 'static, 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; #[allow(deprecated)] #[automatically_derived] unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes for ___ZerocopyVariantStruct_TupleLike<'a, { N }, X, Y> where X: Deref, core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes, bool: ::zerocopy::TryFromBytes, Y: ::zerocopy::TryFromBytes, PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes, core_reexport::marker::PhantomData>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid( field_candidate, ) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4) }; candidate.reborrow().cast_unsized_unchecked(project) }; , > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } } } #[repr(C)] #[allow(non_snake_case)] union ___ZerocopyVariants<'a: 'static, 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: 'static, const N: usize, X, Y: Deref> { tag: ___ZerocopyOuterTag, variants: ___ZerocopyVariants<'a, N, X, Y>, } let tag = { let tag_ptr = unsafe { candidate.reborrow().cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive }) }; let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.bikeshed_recall_valid().read_unaligned::<::zerocopy::BecauseImmutable>() }; let raw_enum = unsafe { candidate.cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> }) }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { raw_enum.cast_unsized_unchecked(|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_unchecked(|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_unchecked(|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 } test! { TryFromBytes { #[repr(u32)] enum ComplexWithGenerics<'a: 'static, const N: usize, X, Y: Deref> where X: Deref, { UnitLike, 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)] #[automatically_derived] unsafe impl<'a: 'static, 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<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe<'_, Self, ___ZerocopyAliasing>, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; #[repr(u32)] #[allow(dead_code, non_camel_case_types)] 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 = (); type ___ZerocopyInnerTag = ___ZerocopyTag; #[repr(C)] #[allow(non_snake_case)] struct ___ZerocopyVariantStruct_StructLike<'a: 'static, 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 X: Deref; #[allow(deprecated)] #[automatically_derived] unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes for ___ZerocopyVariantStruct_StructLike<'a, { N }, X, Y> where X: Deref, core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes, u8: ::zerocopy::TryFromBytes, X: ::zerocopy::TryFromBytes, X::Target: ::zerocopy::TryFromBytes, Y::Target: ::zerocopy::TryFromBytes, [(X, Y); N]: ::zerocopy::TryFromBytes, core_reexport::marker::PhantomData>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).5) }; candidate.reborrow().cast_unsized_unchecked(project) }; <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).6) }; candidate.reborrow().cast_unsized_unchecked(project) }; , > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } } } #[repr(C)] #[allow(non_snake_case)] struct ___ZerocopyVariantStruct_TupleLike<'a: 'static, 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; #[allow(deprecated)] #[automatically_derived] unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes for ___ZerocopyVariantStruct_TupleLike<'a, { N }, X, Y> where X: Deref, core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes, bool: ::zerocopy::TryFromBytes, Y: ::zerocopy::TryFromBytes, PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes, core_reexport::marker::PhantomData>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid( field_candidate, ) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4) }; candidate.reborrow().cast_unsized_unchecked(project) }; , > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } } } #[repr(C)] #[allow(non_snake_case)] union ___ZerocopyVariants<'a: 'static, 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: 'static, const N: usize, X, Y: Deref> { tag: ___ZerocopyOuterTag, variants: ___ZerocopyVariants<'a, N, X, Y>, } let tag = { let tag_ptr = unsafe { candidate.reborrow().cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive }) }; let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.bikeshed_recall_valid().read_unaligned::<::zerocopy::BecauseImmutable>() }; let raw_enum = unsafe { candidate.cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> }) }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { raw_enum.cast_unsized_unchecked(|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_unchecked(|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_unchecked(|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 } test! { TryFromBytes { #[repr(C)] enum ComplexWithGenerics<'a: 'static, const N: usize, X, Y: Deref> where X: Deref, { UnitLike, 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)] #[automatically_derived] unsafe impl<'a: 'static, 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<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe<'_, Self, ___ZerocopyAliasing>, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { use ::zerocopy::util::macro_util::core_reexport; #[repr(C)] #[allow(dead_code, non_camel_case_types)] 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)] struct ___ZerocopyVariantStruct_StructLike<'a: 'static, 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 X: Deref; #[allow(deprecated)] #[automatically_derived] unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes for ___ZerocopyVariantStruct_StructLike<'a, { N }, X, Y> where X: Deref, core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes, u8: ::zerocopy::TryFromBytes, X: ::zerocopy::TryFromBytes, X::Target: ::zerocopy::TryFromBytes, Y::Target: ::zerocopy::TryFromBytes, [(X, Y); N]: ::zerocopy::TryFromBytes, core_reexport::marker::PhantomData>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).5) }; candidate.reborrow().cast_unsized_unchecked(project) }; <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).6) }; candidate.reborrow().cast_unsized_unchecked(project) }; , > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } } } #[repr(C)] #[allow(non_snake_case)] struct ___ZerocopyVariantStruct_TupleLike<'a: 'static, 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; #[allow(deprecated)] #[automatically_derived] unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes for ___ZerocopyVariantStruct_TupleLike<'a, { N }, X, Y> where X: Deref, core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes, bool: ::zerocopy::TryFromBytes, Y: ::zerocopy::TryFromBytes, PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes, core_reexport::marker::PhantomData>: ::zerocopy::TryFromBytes, { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( mut candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2) }; candidate.reborrow().cast_unsized_unchecked(project) }; ::is_bit_valid(field_candidate) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3) }; candidate.reborrow().cast_unsized_unchecked(project) }; as ::zerocopy::TryFromBytes>::is_bit_valid( field_candidate, ) } && { let field_candidate = unsafe { let project = |slf: *mut Self| { ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4) }; candidate.reborrow().cast_unsized_unchecked(project) }; , > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate) } } } #[repr(C)] #[allow(non_snake_case)] union ___ZerocopyVariants<'a: 'static, 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: 'static, const N: usize, X, Y: Deref> { tag: ___ZerocopyOuterTag, variants: ___ZerocopyVariants<'a, N, X, Y>, } let tag = { let tag_ptr = unsafe { candidate.reborrow().cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive }) }; let tag_ptr = unsafe { tag_ptr.assume_initialized() }; tag_ptr.bikeshed_recall_valid().read_unaligned::<::zerocopy::BecauseImmutable>() }; let raw_enum = unsafe { candidate.cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> }) }; let raw_enum = unsafe { raw_enum.assume_initialized() }; let variants = unsafe { raw_enum.cast_unsized_unchecked(|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_unchecked(|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_unchecked(|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 } } // This goes at the bottom because it's so verbose and it makes scrolling past // other code a pain. #[test] fn test_from_bytes_enum() { test! { FromBytes { #[repr(u8)] enum Foo { Variant0, Variant1, Variant2, Variant3, Variant4, Variant5, Variant6, Variant7, Variant8, Variant9, Variant10, Variant11, Variant12, Variant13, Variant14, Variant15, Variant16, Variant17, Variant18, Variant19, Variant20, Variant21, Variant22, Variant23, Variant24, Variant25, Variant26, Variant27, Variant28, Variant29, Variant30, Variant31, Variant32, Variant33, Variant34, Variant35, Variant36, Variant37, Variant38, Variant39, Variant40, Variant41, Variant42, Variant43, Variant44, Variant45, Variant46, Variant47, Variant48, Variant49, Variant50, Variant51, Variant52, Variant53, Variant54, Variant55, Variant56, Variant57, Variant58, Variant59, Variant60, Variant61, Variant62, Variant63, Variant64, Variant65, Variant66, Variant67, Variant68, Variant69, Variant70, Variant71, Variant72, Variant73, Variant74, Variant75, Variant76, Variant77, Variant78, Variant79, Variant80, Variant81, Variant82, Variant83, Variant84, Variant85, Variant86, Variant87, Variant88, Variant89, Variant90, Variant91, Variant92, Variant93, Variant94, Variant95, Variant96, Variant97, Variant98, Variant99, Variant100, Variant101, Variant102, Variant103, Variant104, Variant105, Variant106, Variant107, Variant108, Variant109, Variant110, Variant111, Variant112, Variant113, Variant114, Variant115, Variant116, Variant117, Variant118, Variant119, Variant120, Variant121, Variant122, Variant123, Variant124, Variant125, Variant126, Variant127, Variant128, Variant129, Variant130, Variant131, Variant132, Variant133, Variant134, Variant135, Variant136, Variant137, Variant138, Variant139, Variant140, Variant141, Variant142, Variant143, Variant144, Variant145, Variant146, Variant147, Variant148, Variant149, Variant150, Variant151, Variant152, Variant153, Variant154, Variant155, Variant156, Variant157, Variant158, Variant159, Variant160, Variant161, Variant162, Variant163, Variant164, Variant165, Variant166, Variant167, Variant168, Variant169, Variant170, Variant171, Variant172, Variant173, Variant174, Variant175, Variant176, Variant177, Variant178, Variant179, Variant180, Variant181, Variant182, Variant183, Variant184, Variant185, Variant186, Variant187, Variant188, Variant189, Variant190, Variant191, Variant192, Variant193, Variant194, Variant195, Variant196, Variant197, Variant198, Variant199, Variant200, Variant201, Variant202, Variant203, Variant204, Variant205, Variant206, Variant207, Variant208, Variant209, Variant210, Variant211, Variant212, Variant213, Variant214, Variant215, Variant216, Variant217, Variant218, Variant219, Variant220, Variant221, Variant222, Variant223, Variant224, Variant225, Variant226, Variant227, Variant228, Variant229, Variant230, Variant231, Variant232, Variant233, Variant234, Variant235, Variant236, Variant237, Variant238, Variant239, Variant240, Variant241, Variant242, Variant243, Variant244, Variant245, Variant246, Variant247, Variant248, Variant249, Variant250, Variant251, Variant252, Variant253, Variant254, Variant255, } } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::TryFromBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( _candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { if false { fn assert_is_from_bytes() where T: ::zerocopy::FromBytes, T: ?::zerocopy::util::macro_util::core_reexport::marker::Sized, {} assert_is_from_bytes::(); } true } } #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::FromZeros for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::FromBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} } } no_build } } #[test] fn test_try_from_bytes_trivial_is_bit_valid_enum() { // Even when we aren't deriving `FromBytes` as the top-level trait, // `TryFromBytes` on enums still detects whether we *could* derive // `FromBytes`, and if so, performs the same "trivial `is_bit_valid`" // optimization. test! { TryFromBytes { #[repr(u8)] enum Foo { Variant0, Variant1, Variant2, Variant3, Variant4, Variant5, Variant6, Variant7, Variant8, Variant9, Variant10, Variant11, Variant12, Variant13, Variant14, Variant15, Variant16, Variant17, Variant18, Variant19, Variant20, Variant21, Variant22, Variant23, Variant24, Variant25, Variant26, Variant27, Variant28, Variant29, Variant30, Variant31, Variant32, Variant33, Variant34, Variant35, Variant36, Variant37, Variant38, Variant39, Variant40, Variant41, Variant42, Variant43, Variant44, Variant45, Variant46, Variant47, Variant48, Variant49, Variant50, Variant51, Variant52, Variant53, Variant54, Variant55, Variant56, Variant57, Variant58, Variant59, Variant60, Variant61, Variant62, Variant63, Variant64, Variant65, Variant66, Variant67, Variant68, Variant69, Variant70, Variant71, Variant72, Variant73, Variant74, Variant75, Variant76, Variant77, Variant78, Variant79, Variant80, Variant81, Variant82, Variant83, Variant84, Variant85, Variant86, Variant87, Variant88, Variant89, Variant90, Variant91, Variant92, Variant93, Variant94, Variant95, Variant96, Variant97, Variant98, Variant99, Variant100, Variant101, Variant102, Variant103, Variant104, Variant105, Variant106, Variant107, Variant108, Variant109, Variant110, Variant111, Variant112, Variant113, Variant114, Variant115, Variant116, Variant117, Variant118, Variant119, Variant120, Variant121, Variant122, Variant123, Variant124, Variant125, Variant126, Variant127, Variant128, Variant129, Variant130, Variant131, Variant132, Variant133, Variant134, Variant135, Variant136, Variant137, Variant138, Variant139, Variant140, Variant141, Variant142, Variant143, Variant144, Variant145, Variant146, Variant147, Variant148, Variant149, Variant150, Variant151, Variant152, Variant153, Variant154, Variant155, Variant156, Variant157, Variant158, Variant159, Variant160, Variant161, Variant162, Variant163, Variant164, Variant165, Variant166, Variant167, Variant168, Variant169, Variant170, Variant171, Variant172, Variant173, Variant174, Variant175, Variant176, Variant177, Variant178, Variant179, Variant180, Variant181, Variant182, Variant183, Variant184, Variant185, Variant186, Variant187, Variant188, Variant189, Variant190, Variant191, Variant192, Variant193, Variant194, Variant195, Variant196, Variant197, Variant198, Variant199, Variant200, Variant201, Variant202, Variant203, Variant204, Variant205, Variant206, Variant207, Variant208, Variant209, Variant210, Variant211, Variant212, Variant213, Variant214, Variant215, Variant216, Variant217, Variant218, Variant219, Variant220, Variant221, Variant222, Variant223, Variant224, Variant225, Variant226, Variant227, Variant228, Variant229, Variant230, Variant231, Variant232, Variant233, Variant234, Variant235, Variant236, Variant237, Variant238, Variant239, Variant240, Variant241, Variant242, Variant243, Variant244, Variant245, Variant246, Variant247, Variant248, Variant249, Variant250, Variant251, Variant252, Variant253, Variant254, Variant255, } } expands to { #[allow(deprecated)] #[automatically_derived] unsafe impl ::zerocopy::TryFromBytes for Foo { fn only_derive_is_allowed_to_implement_this_trait() {} fn is_bit_valid<___ZerocopyAliasing>( _candidate: ::zerocopy::Maybe, ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool where ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference, { true } } } no_build } } #[test] fn test_hash() { test! { ByteHash { struct Foo(T) where Self: Sized; } expands to { #[allow(deprecated)] #[automatically_derived] impl ::zerocopy::util::macro_util::core_reexport::hash::Hash for Foo where Self: ::zerocopy::IntoBytes + ::zerocopy::Immutable, Self: Sized, { fn hash(&self, state: &mut H) where H: ::zerocopy::util::macro_util::core_reexport::hash::Hasher, { ::zerocopy::util::macro_util::core_reexport::hash::Hasher::write( state, ::zerocopy::IntoBytes::as_bytes(self) ) } fn hash_slice(data: &[Self], state: &mut H) where H: ::zerocopy::util::macro_util::core_reexport::hash::Hasher, { ::zerocopy::util::macro_util::core_reexport::hash::Hasher::write( state, ::zerocopy::IntoBytes::as_bytes(data) ) } } } no_build } } #[test] fn test_eq() { test! { ByteEq { struct Foo(T) where Self: Sized; } expands to { #[allow(deprecated)] #[automatically_derived] impl ::zerocopy::util::macro_util::core_reexport::cmp::PartialEq for Foo where Self: ::zerocopy::IntoBytes + ::zerocopy::Immutable, Self: Sized, { fn eq(&self, other: &Self) -> bool { ::zerocopy::util::macro_util::core_reexport::cmp::PartialEq::eq( ::zerocopy::IntoBytes::as_bytes(self), ::zerocopy::IntoBytes::as_bytes(other), ) } } #[allow(deprecated)] #[automatically_derived] impl ::zerocopy::util::macro_util::core_reexport::cmp::Eq for Foo where Self: ::zerocopy::IntoBytes + ::zerocopy::Immutable, Self: Sized, { } } no_build } }