• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2024 The Fuchsia Authors
2 //
3 // Licensed under a BSD-style license <LICENSE-BSD>, Apache License, Version 2.0
4 // <LICENSE-APACHE or https://www.apache.org/licenses/LICENSE-2.0>, or the MIT
5 // license <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your option.
6 // This file may not be copied, modified, or distributed except according to
7 // those terms.
8 
9 use crate::IntoTokenStream;
10 use dissimilar::Chunk;
11 use proc_macro2::TokenStream;
12 
13 macro_rules! use_as_trait_name {
14     ($($alias:ident => $derive:ident),* $(,)?) => {
15         $(use super::$derive as $alias;)*
16     };
17 }
18 
19 // This permits invocations of `test!` to be more ergonomic, passing the name of
20 // the trait under test rather than the name of the inner derive function.
21 use_as_trait_name!(
22     KnownLayout => derive_known_layout_inner,
23     Immutable => derive_no_cell_inner,
24     TryFromBytes => derive_try_from_bytes_inner,
25     FromZeros => derive_from_zeros_inner,
26     FromBytes => derive_from_bytes_inner,
27     IntoBytes => derive_into_bytes_inner,
28     Unaligned => derive_unaligned_inner,
29     ByteHash => derive_hash_inner,
30     ByteEq => derive_eq_inner,
31 );
32 
33 /// Test that the given derive input expands to the expected output.
34 ///
35 /// Equality is tested by formatting both token streams using `prettyplease` and
36 /// performing string equality on the results. This has the effect of making the
37 /// tests less brittle and robust against meaningless formatting changes.
38 // Adapted from https://github.com/joshlf/synstructure/blob/400499aaf54840056ff56718beb7810540e6be59/src/macros.rs#L212-L317
39 macro_rules! test {
40     ($name:ident { $($i:tt)* } expands to { $($o:tt)* }) => {
41         {
42             #[allow(dead_code)]
43             fn ensure_compiles() {
44                 $($i)*
45                 $($o)*
46             }
47 
48             test!($name { $($i)* } expands to { $($o)* } no_build);
49         }
50     };
51 
52     ($name:ident { $($i:tt)* } expands to { $($o:tt)* } no_build) => {
53         {
54             let ts: proc_macro2::TokenStream = quote::quote!( $($i)* );
55             let ast = syn::parse2::<syn::DeriveInput>(ts).unwrap();
56             let res = $name(&ast, crate::Trait::$name);
57             let expected_toks = quote::quote!( $($o)* );
58             assert_eq_streams(expected_toks.into(), res.into_ts().into());
59         }
60     };
61 }
62 
63 #[track_caller]
assert_eq_streams(expect: TokenStream, res: TokenStream)64 fn assert_eq_streams(expect: TokenStream, res: TokenStream) {
65     let pretty =
66         |ts: TokenStream| prettyplease::unparse(&syn::parse_file(&ts.to_string()).unwrap());
67 
68     let expect = pretty(expect.clone());
69     let res = pretty(res.clone());
70     if expect != res {
71         let diff = dissimilar::diff(&expect, &res)
72             .into_iter()
73             .flat_map(|chunk| {
74                 let (prefix, chunk) = match chunk {
75                     Chunk::Equal(chunk) => (" ", chunk),
76                     Chunk::Delete(chunk) => ("-", chunk),
77                     Chunk::Insert(chunk) => ("+", chunk),
78                 };
79                 [prefix, chunk, "\n"]
80             })
81             .collect::<String>();
82 
83         panic!(
84             "\
85 test failed:
86 got:
87 ```
88 {}
89 ```
90 
91 diff (expected vs got):
92 ```
93 {}
94 ```\n",
95             res, diff
96         );
97     }
98 }
99 
100 #[test]
test_known_layout()101 fn test_known_layout() {
102     test! {
103         KnownLayout {
104             struct Foo;
105         } expands to {
106             #[allow(deprecated)]
107             #[automatically_derived]
108             unsafe impl ::zerocopy::KnownLayout for Foo
109             where
110                 Self: ::zerocopy::util::macro_util::core_reexport::marker::Sized,
111             {
112                 fn only_derive_is_allowed_to_implement_this_trait() {}
113 
114                 type PointerMetadata = ();
115 
116                 type MaybeUninit = ::zerocopy::util::macro_util::core_reexport::mem::MaybeUninit<Self>;
117 
118                 const LAYOUT: ::zerocopy::DstLayout = ::zerocopy::DstLayout::for_type::<Self>();
119 
120                 #[inline(always)]
121                 fn raw_from_ptr_len(
122                     bytes: ::zerocopy::util::macro_util::core_reexport::ptr::NonNull<u8>,
123                     _meta: (),
124                 ) -> ::zerocopy::util::macro_util::core_reexport::ptr::NonNull<Self> {
125                     bytes.cast::<Self>()
126                 }
127 
128                 #[inline(always)]
129                 fn pointer_to_metadata(_ptr: *mut Self) -> () {}
130             }
131         } no_build
132     }
133 
134     test! {
135         KnownLayout {
136             #[repr(C, align(2))]
137             struct Foo<T, U>(T, U);
138         }
139         expands to {
140             const _: () = {
141                 #[allow(deprecated)]
142                 #[automatically_derived]
143                 unsafe impl<T, U> ::zerocopy::KnownLayout for Foo<T, U>
144                 where
145                     U: ::zerocopy::KnownLayout,
146                 {
147                     fn only_derive_is_allowed_to_implement_this_trait() {}
148                     type PointerMetadata = <U as ::zerocopy::KnownLayout>::PointerMetadata;
149                     type MaybeUninit = __ZerocopyKnownLayoutMaybeUninit<T, U>;
150                     const LAYOUT: ::zerocopy::DstLayout = {
151                         use ::zerocopy::util::macro_util::core_reexport::num::NonZeroUsize;
152                         use ::zerocopy::{DstLayout, KnownLayout};
153                         let repr_align = ::zerocopy::util::macro_util::core_reexport::num::NonZeroUsize::new(
154                             2u32 as usize,
155                         );
156                         let repr_packed = ::zerocopy::util::macro_util::core_reexport::option::Option::None;
157                         DstLayout::new_zst(repr_align)
158                             .extend(DstLayout::for_type::<T>(), repr_packed)
159                             .extend(<U as KnownLayout>::LAYOUT, repr_packed)
160                             .pad_to_align()
161                     };
162                     #[inline(always)]
163                     fn raw_from_ptr_len(
164                         bytes: ::zerocopy::util::macro_util::core_reexport::ptr::NonNull<u8>,
165                         meta: Self::PointerMetadata,
166                     ) -> ::zerocopy::util::macro_util::core_reexport::ptr::NonNull<Self> {
167                         use ::zerocopy::KnownLayout;
168                         let trailing = <U as KnownLayout>::raw_from_ptr_len(bytes, meta);
169                         let slf = trailing.as_ptr() as *mut Self;
170                         unsafe {
171                             ::zerocopy::util::macro_util::core_reexport::ptr::NonNull::new_unchecked(
172                                 slf,
173                             )
174                         }
175                     }
176                     #[inline(always)]
177                     fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata {
178                         <U>::pointer_to_metadata(ptr as *mut _)
179                     }
180                 }
181                 #[allow(non_camel_case_types)]
182                 struct __Zerocopy_Field_0;
183                 #[allow(non_camel_case_types)]
184                 struct __Zerocopy_Field_1;
185                 unsafe impl<T, U> ::zerocopy::util::macro_util::Field<__Zerocopy_Field_0>
186                 for Foo<T, U> {
187                     type Type = T;
188                 }
189                 unsafe impl<T, U> ::zerocopy::util::macro_util::Field<__Zerocopy_Field_1>
190                 for Foo<T, U> {
191                     type Type = U;
192                 }
193                 #[repr(C)]
194                 #[repr(align(2))]
195                 #[doc(hidden)]
196                 #[allow(private_bounds)]
197                 struct __ZerocopyKnownLayoutMaybeUninit<T, U>(
198                     ::zerocopy::util::macro_util::core_reexport::mem::MaybeUninit<
199                         <Foo<T, U> as ::zerocopy::util::macro_util::Field<__Zerocopy_Field_0>>::Type,
200                     >,
201                     ::zerocopy::util::macro_util::core_reexport::mem::ManuallyDrop<
202                         <<Foo<
203                             T,
204                             U,
205                         > as ::zerocopy::util::macro_util::Field<
206                             __Zerocopy_Field_1,
207                         >>::Type as ::zerocopy::KnownLayout>::MaybeUninit
208                     >,
209                 )
210                 where
211                     <Foo<
212                         T,
213                         U,
214                     > as ::zerocopy::util::macro_util::Field<
215                         __Zerocopy_Field_1,
216                     >>::Type: ::zerocopy::KnownLayout;
217                 unsafe impl<T, U> ::zerocopy::KnownLayout for __ZerocopyKnownLayoutMaybeUninit<T, U>
218                 where
219                     <Foo<
220                         T,
221                         U,
222                     > as ::zerocopy::util::macro_util::Field<
223                         __Zerocopy_Field_1,
224                     >>::Type: ::zerocopy::KnownLayout,
225                 {
226                     #[allow(clippy::missing_inline_in_public_items)]
227                     fn only_derive_is_allowed_to_implement_this_trait() {}
228                     type PointerMetadata = <Foo<T, U> as ::zerocopy::KnownLayout>::PointerMetadata;
229                     type MaybeUninit = Self;
230                     const LAYOUT: ::zerocopy::DstLayout = <Foo<
231                         T,
232                         U,
233                     > as ::zerocopy::KnownLayout>::LAYOUT;
234                     #[inline(always)]
235                     fn raw_from_ptr_len(
236                         bytes: ::zerocopy::util::macro_util::core_reexport::ptr::NonNull<u8>,
237                         meta: Self::PointerMetadata,
238                     ) -> ::zerocopy::util::macro_util::core_reexport::ptr::NonNull<Self> {
239                         use ::zerocopy::KnownLayout;
240                         let trailing = <<<Foo<
241                             T,
242                             U,
243                         > as ::zerocopy::util::macro_util::Field<
244                             __Zerocopy_Field_1,
245                         >>::Type as ::zerocopy::KnownLayout>::MaybeUninit as KnownLayout>::raw_from_ptr_len(
246                             bytes,
247                             meta,
248                         );
249                         let slf = trailing.as_ptr() as *mut Self;
250                         unsafe {
251                             ::zerocopy::util::macro_util::core_reexport::ptr::NonNull::new_unchecked(
252                                 slf,
253                             )
254                         }
255                     }
256                     #[inline(always)]
257                     fn pointer_to_metadata(ptr: *mut Self) -> Self::PointerMetadata {
258                         <<<Foo<
259                             T,
260                             U,
261                         > as ::zerocopy::util::macro_util::Field<
262                             __Zerocopy_Field_1,
263                         >>::Type as ::zerocopy::KnownLayout>::MaybeUninit>::pointer_to_metadata(
264                             ptr as *mut _,
265                         )
266                     }
267                 }
268             };
269         } no_build
270     }
271 }
272 
273 #[test]
test_immutable()274 fn test_immutable() {
275     test! {
276         Immutable {
277             struct Foo;
278         } expands to {
279             #[allow(deprecated)]
280             #[automatically_derived]
281             unsafe impl ::zerocopy::Immutable for Foo {
282                 fn only_derive_is_allowed_to_implement_this_trait() {}
283             }
284         } no_build
285     }
286 }
287 
288 #[test]
test_try_from_bytes()289 fn test_try_from_bytes() {
290     test! {
291         TryFromBytes {
292             struct Foo;
293         } expands to {
294             #[allow(deprecated)]
295             #[automatically_derived]
296             unsafe impl ::zerocopy::TryFromBytes for Foo {
297                 fn only_derive_is_allowed_to_implement_this_trait() {}
298 
299                 fn is_bit_valid<___ZerocopyAliasing>(
300                     mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
301                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
302                 where
303                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
304                 {
305                     true
306                 }
307             }
308         } no_build
309     }
310 }
311 
312 #[test]
test_from_zeros()313 fn test_from_zeros() {
314     test! {
315         FromZeros {
316             struct Foo;
317         } expands to {
318             #[allow(deprecated)]
319             #[automatically_derived]
320             unsafe impl ::zerocopy::TryFromBytes for Foo {
321                 fn only_derive_is_allowed_to_implement_this_trait() {}
322 
323                 fn is_bit_valid<___ZerocopyAliasing>(
324                     mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
325                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
326                 where
327                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
328                 {
329                     true
330                 }
331             }
332 
333             #[allow(deprecated)]
334             #[automatically_derived]
335             unsafe impl ::zerocopy::FromZeros for Foo {
336                 fn only_derive_is_allowed_to_implement_this_trait() {}
337             }
338         } no_build
339     }
340 }
341 
342 #[test]
test_from_bytes_struct()343 fn test_from_bytes_struct() {
344     test! {
345         FromBytes {
346             struct Foo;
347         } expands to {
348             #[allow(deprecated)]
349             #[automatically_derived]
350             unsafe impl ::zerocopy::TryFromBytes for Foo {
351                 fn only_derive_is_allowed_to_implement_this_trait() {}
352 
353                 fn is_bit_valid<___ZerocopyAliasing>(
354                     _candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
355                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
356                 where
357                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
358                 {
359                     if false {
360                         fn assert_is_from_bytes<T>()
361                         where
362                             T: ::zerocopy::FromBytes,
363                             T: ?::zerocopy::util::macro_util::core_reexport::marker::Sized,
364                         {}
365                         assert_is_from_bytes::<Self>();
366                     }
367 
368                     true
369                 }
370             }
371 
372             #[allow(deprecated)]
373             #[automatically_derived]
374             unsafe impl ::zerocopy::FromZeros for Foo {
375                 fn only_derive_is_allowed_to_implement_this_trait() {}
376             }
377 
378             #[allow(deprecated)]
379             #[automatically_derived]
380             unsafe impl ::zerocopy::FromBytes for Foo {
381                 fn only_derive_is_allowed_to_implement_this_trait() {}
382             }
383         } no_build
384     }
385 }
386 
387 #[test]
test_from_bytes_union()388 fn test_from_bytes_union() {
389     test! {
390         FromBytes {
391             union Foo {
392                 a: u8,
393             }
394         } expands to {
395             #[allow(deprecated)]
396             #[automatically_derived]
397             unsafe impl ::zerocopy::TryFromBytes for Foo
398             where
399                 u8: ::zerocopy::TryFromBytes + ::zerocopy::Immutable,
400             {
401                 fn only_derive_is_allowed_to_implement_this_trait() {}
402 
403                 fn is_bit_valid<___ZerocopyAliasing>(
404                     _candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
405                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
406                 where
407                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
408                 {
409                     if false {
410                         fn assert_is_from_bytes<T>()
411                         where
412                             T: ::zerocopy::FromBytes,
413                             T: ?::zerocopy::util::macro_util::core_reexport::marker::Sized,
414                         {}
415                         assert_is_from_bytes::<Self>();
416                     }
417 
418                     true
419                 }
420             }
421 
422             #[allow(deprecated)]
423             #[automatically_derived]
424             unsafe impl ::zerocopy::FromZeros for Foo
425             where
426                 u8: ::zerocopy::FromZeros + ::zerocopy::Immutable,
427             {
428                 fn only_derive_is_allowed_to_implement_this_trait() {}
429             }
430 
431             #[allow(deprecated)]
432             #[automatically_derived]
433             unsafe impl ::zerocopy::FromBytes for Foo
434             where
435                 u8: ::zerocopy::FromBytes + ::zerocopy::Immutable,
436             {
437                 fn only_derive_is_allowed_to_implement_this_trait() {}
438             }
439         } no_build
440     }
441 }
442 
443 #[test]
test_into_bytes()444 fn test_into_bytes() {
445     test! {
446         IntoBytes {
447             #[repr(C)]
448             struct Foo;
449         } expands to {
450             #[allow(deprecated)]
451             #[automatically_derived]
452             unsafe impl ::zerocopy::IntoBytes for Foo {
453                 fn only_derive_is_allowed_to_implement_this_trait() {}
454             }
455         } no_build
456     }
457 
458     test! {
459         IntoBytes {
460             #[repr(C)]
461             struct Foo {
462                 a: u8,
463                 b: u8,
464             }
465         } expands to {
466             #[allow(deprecated)]
467             #[automatically_derived]
468             unsafe impl ::zerocopy::IntoBytes for Foo
469             where
470                 u8: ::zerocopy::IntoBytes,
471                 u8: ::zerocopy::IntoBytes,
472                 (): ::zerocopy::util::macro_util::PaddingFree<
473                     Self,
474                     { ::zerocopy::struct_has_padding!(Self, [u8, u8]) },
475                 >,
476             {
477                 fn only_derive_is_allowed_to_implement_this_trait() {}
478             }
479         } no_build
480     }
481 }
482 
483 #[test]
test_unaligned()484 fn test_unaligned() {
485     test! {
486         Unaligned {
487             #[repr(C)]
488             struct Foo;
489         } expands to {
490             #[allow(deprecated)]
491             #[automatically_derived]
492             unsafe impl ::zerocopy::Unaligned for Foo {
493                 fn only_derive_is_allowed_to_implement_this_trait() {}
494             }
495         } no_build
496     }
497 }
498 
499 #[test]
test_try_from_bytes_enum()500 fn test_try_from_bytes_enum() {
501     test! {
502         TryFromBytes {
503             #[repr(u8)]
504             enum ComplexWithGenerics<'a: 'static, const N: usize, X, Y: Deref>
505             where
506                 X: Deref<Target = &'a [(X, Y); N]>,
507             {
508                 UnitLike,
509                 StructLike { a: u8, b: X, c: X::Target, d: Y::Target, e: [(X, Y); N] },
510                 TupleLike(bool, Y, PhantomData<&'a [(X, Y); N]>),
511             }
512         } expands to {
513             #[allow(deprecated)]
514             #[automatically_derived]
515             unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
516                 for ComplexWithGenerics<'a, { N }, X, Y>
517             where
518                 X: Deref<Target = &'a [(X, Y); N]>,
519                 u8: ::zerocopy::TryFromBytes,
520                 X: ::zerocopy::TryFromBytes,
521                 X::Target: ::zerocopy::TryFromBytes,
522                 Y::Target: ::zerocopy::TryFromBytes,
523                 [(X, Y); N]: ::zerocopy::TryFromBytes,
524                 bool: ::zerocopy::TryFromBytes,
525                 Y: ::zerocopy::TryFromBytes,
526                 PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes,
527             {
528                 fn only_derive_is_allowed_to_implement_this_trait() {}
529                 fn is_bit_valid<___ZerocopyAliasing>(
530                     mut candidate: ::zerocopy::Maybe<'_, Self, ___ZerocopyAliasing>,
531                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
532                 where
533                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
534                 {
535                     use ::zerocopy::util::macro_util::core_reexport;
536                     #[repr(u8)]
537                     #[allow(dead_code, non_camel_case_types)]
538                     enum ___ZerocopyTag {
539                         UnitLike,
540                         StructLike,
541                         TupleLike,
542                     }
543                     type ___ZerocopyTagPrimitive = ::zerocopy::util::macro_util::SizeToTag<
544                         { core_reexport::mem::size_of::<___ZerocopyTag>() },
545                     >;
546                     #[allow(non_upper_case_globals)]
547                     const ___ZEROCOPY_TAG_UnitLike: ___ZerocopyTagPrimitive =
548                         ___ZerocopyTag::UnitLike as ___ZerocopyTagPrimitive;
549                     #[allow(non_upper_case_globals)]
550                     const ___ZEROCOPY_TAG_StructLike: ___ZerocopyTagPrimitive =
551                         ___ZerocopyTag::StructLike as ___ZerocopyTagPrimitive;
552                     #[allow(non_upper_case_globals)]
553                     const ___ZEROCOPY_TAG_TupleLike: ___ZerocopyTagPrimitive =
554                         ___ZerocopyTag::TupleLike as ___ZerocopyTagPrimitive;
555                     type ___ZerocopyOuterTag = ();
556                     type ___ZerocopyInnerTag = ___ZerocopyTag;
557                     #[repr(C)]
558                     #[allow(non_snake_case)]
559                     struct ___ZerocopyVariantStruct_StructLike<'a: 'static, const N: usize, X, Y: Deref>(
560                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>,
561                         u8,
562                         X,
563                         X::Target,
564                         Y::Target,
565                         [(X, Y); N],
566                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>,
567                     )
568                     where
569                         X: Deref<Target = &'a [(X, Y); N]>;
570                     #[allow(deprecated)]
571                     #[automatically_derived]
572                     unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
573                         for ___ZerocopyVariantStruct_StructLike<'a, { N }, X, Y>
574                     where
575                         X: Deref<Target = &'a [(X, Y); N]>,
576                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes,
577                         u8: ::zerocopy::TryFromBytes,
578                         X: ::zerocopy::TryFromBytes,
579                         X::Target: ::zerocopy::TryFromBytes,
580                         Y::Target: ::zerocopy::TryFromBytes,
581                         [(X, Y); N]: ::zerocopy::TryFromBytes,
582                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>:
583                             ::zerocopy::TryFromBytes,
584                     {
585                         fn only_derive_is_allowed_to_implement_this_trait() {}
586                         fn is_bit_valid<___ZerocopyAliasing>(
587                             mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
588                         ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
589                         where
590                             ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
591                         {
592                             true && {
593                                 let field_candidate = unsafe {
594                                     let project = |slf: *mut Self| {
595                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0)
596                                     };
597                                     candidate.reborrow().cast_unsized_unchecked(project)
598                                 };
599                                 <core_reexport::mem::MaybeUninit<
600                                         ___ZerocopyInnerTag,
601                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
602                             } && {
603                                 let field_candidate = unsafe {
604                                     let project = |slf: *mut Self| {
605                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1)
606                                     };
607                                     candidate.reborrow().cast_unsized_unchecked(project)
608                                 };
609                                 <u8 as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
610                             } && {
611                                 let field_candidate = unsafe {
612                                     let project = |slf: *mut Self| {
613                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2)
614                                     };
615                                     candidate.reborrow().cast_unsized_unchecked(project)
616                                 };
617                                 <X as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
618                             } && {
619                                 let field_candidate = unsafe {
620                                     let project = |slf: *mut Self| {
621                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3)
622                                     };
623                                     candidate.reborrow().cast_unsized_unchecked(project)
624                                 };
625                                 <X::Target as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
626                             } && {
627                                 let field_candidate = unsafe {
628                                     let project = |slf: *mut Self| {
629                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4)
630                                     };
631                                     candidate.reborrow().cast_unsized_unchecked(project)
632                                 };
633                                 <Y::Target as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
634                             } && {
635                                 let field_candidate = unsafe {
636                                     let project = |slf: *mut Self| {
637                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).5)
638                                     };
639                                     candidate.reborrow().cast_unsized_unchecked(project)
640                                 };
641                                 <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
642                             } && {
643                                 let field_candidate = unsafe {
644                                     let project = |slf: *mut Self| {
645                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).6)
646                                     };
647                                     candidate.reborrow().cast_unsized_unchecked(project)
648                                 };
649                                 <core_reexport::marker::PhantomData<
650                                         ComplexWithGenerics<'a, N, X, Y>,
651                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
652                             }
653                         }
654                     }
655                     #[repr(C)]
656                     #[allow(non_snake_case)]
657                     struct ___ZerocopyVariantStruct_TupleLike<'a: 'static, const N: usize, X, Y: Deref>(
658                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>,
659                         bool,
660                         Y,
661                         PhantomData<&'a [(X, Y); N]>,
662                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>,
663                     )
664                     where
665                         X: Deref<Target = &'a [(X, Y); N]>;
666                     #[allow(deprecated)]
667                     #[automatically_derived]
668                     unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
669                         for ___ZerocopyVariantStruct_TupleLike<'a, { N }, X, Y>
670                     where
671                         X: Deref<Target = &'a [(X, Y); N]>,
672                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes,
673                         bool: ::zerocopy::TryFromBytes,
674                         Y: ::zerocopy::TryFromBytes,
675                         PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes,
676                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>:
677                             ::zerocopy::TryFromBytes,
678                     {
679                         fn only_derive_is_allowed_to_implement_this_trait() {}
680                         fn is_bit_valid<___ZerocopyAliasing>(
681                             mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
682                         ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
683                         where
684                             ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
685                         {
686                             true && {
687                                 let field_candidate = unsafe {
688                                     let project = |slf: *mut Self| {
689                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0)
690                                     };
691                                     candidate.reborrow().cast_unsized_unchecked(project)
692                                 };
693                                 <core_reexport::mem::MaybeUninit<
694                                         ___ZerocopyInnerTag,
695                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
696                             } && {
697                                 let field_candidate = unsafe {
698                                     let project = |slf: *mut Self| {
699                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1)
700                                     };
701                                     candidate.reborrow().cast_unsized_unchecked(project)
702                                 };
703                                 <bool as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
704                             } && {
705                                 let field_candidate = unsafe {
706                                     let project = |slf: *mut Self| {
707                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2)
708                                     };
709                                     candidate.reborrow().cast_unsized_unchecked(project)
710                                 };
711                                 <Y as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
712                             } && {
713                                 let field_candidate = unsafe {
714                                     let project = |slf: *mut Self| {
715                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3)
716                                     };
717                                     candidate.reborrow().cast_unsized_unchecked(project)
718                                 };
719                                 <PhantomData<&'a [(X, Y); N]> as ::zerocopy::TryFromBytes>::is_bit_valid(
720                                     field_candidate,
721                                 )
722                             } && {
723                                 let field_candidate = unsafe {
724                                     let project = |slf: *mut Self| {
725                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4)
726                                     };
727                                     candidate.reborrow().cast_unsized_unchecked(project)
728                                 };
729                                 <core_reexport::marker::PhantomData<
730                                         ComplexWithGenerics<'a, N, X, Y>,
731                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
732                             }
733                         }
734                     }
735                     #[repr(C)]
736                     #[allow(non_snake_case)]
737                     union ___ZerocopyVariants<'a: 'static, const N: usize, X, Y: Deref> {
738                         __field_StructLike:
739                             core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>,
740                         __field_TupleLike:
741                             core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>,
742                         __nonempty: (),
743                     }
744                     #[repr(C)]
745                     struct ___ZerocopyRawEnum<'a: 'static, const N: usize, X, Y: Deref> {
746                         tag: ___ZerocopyOuterTag,
747                         variants: ___ZerocopyVariants<'a, N, X, Y>,
748                     }
749                     let tag = {
750                         let tag_ptr = unsafe {
751                             candidate.reborrow().cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive })
752                         };
753                         let tag_ptr = unsafe { tag_ptr.assume_initialized() };
754                         tag_ptr.bikeshed_recall_valid().read_unaligned::<::zerocopy::BecauseImmutable>()
755                     };
756                     let raw_enum = unsafe {
757                         candidate.cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> })
758                     };
759                     let raw_enum = unsafe { raw_enum.assume_initialized() };
760                     let variants = unsafe {
761                         raw_enum.cast_unsized_unchecked(|p: *mut ___ZerocopyRawEnum<'a, N, X, Y>| {
762                             core_reexport::ptr::addr_of_mut!((*p).variants)
763                         })
764                     };
765                     #[allow(non_upper_case_globals)]
766                     match tag {
767                         ___ZEROCOPY_TAG_UnitLike => true,
768                         ___ZEROCOPY_TAG_StructLike => {
769                             let variant = unsafe {
770                                 variants.cast_unsized_unchecked(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| {
771                                     p as *mut ___ZerocopyVariantStruct_StructLike<'a, N, X, Y>
772                                 })
773                             };
774                             let variant = unsafe { variant.assume_initialized() };
775                         <___ZerocopyVariantStruct_StructLike<'a, N, X, Y> as ::zerocopy ::TryFromBytes>::is_bit_valid (
776                                             variant)
777                         }
778                         ___ZEROCOPY_TAG_TupleLike => {
779                             let variant = unsafe {
780                                 variants.cast_unsized_unchecked(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| {
781                                     p as *mut ___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>
782                                 })
783                             };
784                             let variant = unsafe { variant.assume_initialized() };
785                         <___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> as ::zerocopy ::TryFromBytes>::is_bit_valid (
786                                             variant)
787                         }
788                         _ => false,
789                     }
790                 }
791             }
792         } no_build
793     }
794 
795     test! {
796         TryFromBytes {
797             #[repr(u32)]
798             enum ComplexWithGenerics<'a: 'static, const N: usize, X, Y: Deref>
799             where
800                 X: Deref<Target = &'a [(X, Y); N]>,
801             {
802                 UnitLike,
803                 StructLike { a: u8, b: X, c: X::Target, d: Y::Target, e: [(X, Y); N] },
804                 TupleLike(bool, Y, PhantomData<&'a [(X, Y); N]>),
805             }
806         } expands to {
807             #[allow(deprecated)]
808             #[automatically_derived]
809             unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
810                 for ComplexWithGenerics<'a, { N }, X, Y>
811             where
812                 X: Deref<Target = &'a [(X, Y); N]>,
813                 u8: ::zerocopy::TryFromBytes,
814                 X: ::zerocopy::TryFromBytes,
815                 X::Target: ::zerocopy::TryFromBytes,
816                 Y::Target: ::zerocopy::TryFromBytes,
817                 [(X, Y); N]: ::zerocopy::TryFromBytes,
818                 bool: ::zerocopy::TryFromBytes,
819                 Y: ::zerocopy::TryFromBytes,
820                 PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes,
821             {
822                 fn only_derive_is_allowed_to_implement_this_trait() {}
823                 fn is_bit_valid<___ZerocopyAliasing>(
824                     mut candidate: ::zerocopy::Maybe<'_, Self, ___ZerocopyAliasing>,
825                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
826                 where
827                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
828                 {
829                     use ::zerocopy::util::macro_util::core_reexport;
830                     #[repr(u32)]
831                     #[allow(dead_code, non_camel_case_types)]
832                     enum ___ZerocopyTag {
833                         UnitLike,
834                         StructLike,
835                         TupleLike,
836                     }
837                     type ___ZerocopyTagPrimitive = ::zerocopy::util::macro_util::SizeToTag<
838                         { core_reexport::mem::size_of::<___ZerocopyTag>() },
839                     >;
840                     #[allow(non_upper_case_globals)]
841                     const ___ZEROCOPY_TAG_UnitLike: ___ZerocopyTagPrimitive =
842                         ___ZerocopyTag::UnitLike as ___ZerocopyTagPrimitive;
843                     #[allow(non_upper_case_globals)]
844                     const ___ZEROCOPY_TAG_StructLike: ___ZerocopyTagPrimitive =
845                         ___ZerocopyTag::StructLike as ___ZerocopyTagPrimitive;
846                     #[allow(non_upper_case_globals)]
847                     const ___ZEROCOPY_TAG_TupleLike: ___ZerocopyTagPrimitive =
848                         ___ZerocopyTag::TupleLike as ___ZerocopyTagPrimitive;
849                     type ___ZerocopyOuterTag = ();
850                     type ___ZerocopyInnerTag = ___ZerocopyTag;
851                     #[repr(C)]
852                     #[allow(non_snake_case)]
853                     struct ___ZerocopyVariantStruct_StructLike<'a: 'static, const N: usize, X, Y: Deref>(
854                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>,
855                         u8,
856                         X,
857                         X::Target,
858                         Y::Target,
859                         [(X, Y); N],
860                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>,
861                     )
862                     where
863                         X: Deref<Target = &'a [(X, Y); N]>;
864                     #[allow(deprecated)]
865                     #[automatically_derived]
866                     unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
867                         for ___ZerocopyVariantStruct_StructLike<'a, { N }, X, Y>
868                     where
869                         X: Deref<Target = &'a [(X, Y); N]>,
870                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes,
871                         u8: ::zerocopy::TryFromBytes,
872                         X: ::zerocopy::TryFromBytes,
873                         X::Target: ::zerocopy::TryFromBytes,
874                         Y::Target: ::zerocopy::TryFromBytes,
875                         [(X, Y); N]: ::zerocopy::TryFromBytes,
876                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>:
877                             ::zerocopy::TryFromBytes,
878                     {
879                         fn only_derive_is_allowed_to_implement_this_trait() {}
880                         fn is_bit_valid<___ZerocopyAliasing>(
881                             mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
882                         ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
883                         where
884                             ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
885                         {
886                             true && {
887                                 let field_candidate = unsafe {
888                                     let project = |slf: *mut Self| {
889                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0)
890                                     };
891                                     candidate.reborrow().cast_unsized_unchecked(project)
892                                 };
893                                 <core_reexport::mem::MaybeUninit<
894                                         ___ZerocopyInnerTag,
895                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
896                             } && {
897                                 let field_candidate = unsafe {
898                                     let project = |slf: *mut Self| {
899                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1)
900                                     };
901                                     candidate.reborrow().cast_unsized_unchecked(project)
902                                 };
903                                 <u8 as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
904                             } && {
905                                 let field_candidate = unsafe {
906                                     let project = |slf: *mut Self| {
907                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2)
908                                     };
909                                     candidate.reborrow().cast_unsized_unchecked(project)
910                                 };
911                                 <X as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
912                             } && {
913                                 let field_candidate = unsafe {
914                                     let project = |slf: *mut Self| {
915                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3)
916                                     };
917                                     candidate.reborrow().cast_unsized_unchecked(project)
918                                 };
919                                 <X::Target as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
920                             } && {
921                                 let field_candidate = unsafe {
922                                     let project = |slf: *mut Self| {
923                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4)
924                                     };
925                                     candidate.reborrow().cast_unsized_unchecked(project)
926                                 };
927                                 <Y::Target as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
928                             } && {
929                                 let field_candidate = unsafe {
930                                     let project = |slf: *mut Self| {
931                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).5)
932                                     };
933                                     candidate.reborrow().cast_unsized_unchecked(project)
934                                 };
935                                 <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
936                             } && {
937                                 let field_candidate = unsafe {
938                                     let project = |slf: *mut Self| {
939                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).6)
940                                     };
941                                     candidate.reborrow().cast_unsized_unchecked(project)
942                                 };
943                                 <core_reexport::marker::PhantomData<
944                                         ComplexWithGenerics<'a, N, X, Y>,
945                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
946                             }
947                         }
948                     }
949                     #[repr(C)]
950                     #[allow(non_snake_case)]
951                     struct ___ZerocopyVariantStruct_TupleLike<'a: 'static, const N: usize, X, Y: Deref>(
952                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>,
953                         bool,
954                         Y,
955                         PhantomData<&'a [(X, Y); N]>,
956                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>,
957                     )
958                     where
959                         X: Deref<Target = &'a [(X, Y); N]>;
960                     #[allow(deprecated)]
961                     #[automatically_derived]
962                     unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
963                         for ___ZerocopyVariantStruct_TupleLike<'a, { N }, X, Y>
964                     where
965                         X: Deref<Target = &'a [(X, Y); N]>,
966                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes,
967                         bool: ::zerocopy::TryFromBytes,
968                         Y: ::zerocopy::TryFromBytes,
969                         PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes,
970                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>:
971                             ::zerocopy::TryFromBytes,
972                     {
973                         fn only_derive_is_allowed_to_implement_this_trait() {}
974                         fn is_bit_valid<___ZerocopyAliasing>(
975                             mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
976                         ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
977                         where
978                             ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
979                         {
980                             true && {
981                                 let field_candidate = unsafe {
982                                     let project = |slf: *mut Self| {
983                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0)
984                                     };
985                                     candidate.reborrow().cast_unsized_unchecked(project)
986                                 };
987                                 <core_reexport::mem::MaybeUninit<
988                                         ___ZerocopyInnerTag,
989                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
990                             } && {
991                                 let field_candidate = unsafe {
992                                     let project = |slf: *mut Self| {
993                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1)
994                                     };
995                                     candidate.reborrow().cast_unsized_unchecked(project)
996                                 };
997                                 <bool as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
998                             } && {
999                                 let field_candidate = unsafe {
1000                                     let project = |slf: *mut Self| {
1001                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2)
1002                                     };
1003                                     candidate.reborrow().cast_unsized_unchecked(project)
1004                                 };
1005                                 <Y as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1006                             } && {
1007                                 let field_candidate = unsafe {
1008                                     let project = |slf: *mut Self| {
1009                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3)
1010                                     };
1011                                     candidate.reborrow().cast_unsized_unchecked(project)
1012                                 };
1013                                 <PhantomData<&'a [(X, Y); N]> as ::zerocopy::TryFromBytes>::is_bit_valid(
1014                                     field_candidate,
1015                                 )
1016                             } && {
1017                                 let field_candidate = unsafe {
1018                                     let project = |slf: *mut Self| {
1019                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4)
1020                                     };
1021                                     candidate.reborrow().cast_unsized_unchecked(project)
1022                                 };
1023                                 <core_reexport::marker::PhantomData<
1024                                         ComplexWithGenerics<'a, N, X, Y>,
1025                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1026                             }
1027                         }
1028                     }
1029                     #[repr(C)]
1030                     #[allow(non_snake_case)]
1031                     union ___ZerocopyVariants<'a: 'static, const N: usize, X, Y: Deref> {
1032                         __field_StructLike:
1033                             core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>,
1034                         __field_TupleLike:
1035                             core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>,
1036                         __nonempty: (),
1037                     }
1038                     #[repr(C)]
1039                     struct ___ZerocopyRawEnum<'a: 'static, const N: usize, X, Y: Deref> {
1040                         tag: ___ZerocopyOuterTag,
1041                         variants: ___ZerocopyVariants<'a, N, X, Y>,
1042                     }
1043                     let tag = {
1044                         let tag_ptr = unsafe {
1045                             candidate.reborrow().cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive })
1046                         };
1047                         let tag_ptr = unsafe { tag_ptr.assume_initialized() };
1048                         tag_ptr.bikeshed_recall_valid().read_unaligned::<::zerocopy::BecauseImmutable>()
1049                     };
1050                     let raw_enum = unsafe {
1051                         candidate.cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> })
1052                     };
1053                     let raw_enum = unsafe { raw_enum.assume_initialized() };
1054                     let variants = unsafe {
1055                         raw_enum.cast_unsized_unchecked(|p: *mut ___ZerocopyRawEnum<'a, N, X, Y>| {
1056                             core_reexport::ptr::addr_of_mut!((*p).variants)
1057                         })
1058                     };
1059                     #[allow(non_upper_case_globals)]
1060                     match tag {
1061                         ___ZEROCOPY_TAG_UnitLike => true,
1062                         ___ZEROCOPY_TAG_StructLike => {
1063                             let variant = unsafe {
1064                                 variants.cast_unsized_unchecked(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| {
1065                                     p as *mut ___ZerocopyVariantStruct_StructLike<'a, N, X, Y>
1066                                 })
1067                             };
1068                             let variant = unsafe { variant.assume_initialized() };
1069                         <___ZerocopyVariantStruct_StructLike<'a, N, X, Y> as ::zerocopy ::TryFromBytes>::is_bit_valid (
1070                                             variant)
1071                         }
1072                         ___ZEROCOPY_TAG_TupleLike => {
1073                             let variant = unsafe {
1074                                 variants.cast_unsized_unchecked(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| {
1075                                     p as *mut ___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>
1076                                 })
1077                             };
1078                             let variant = unsafe { variant.assume_initialized() };
1079                         <___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> as ::zerocopy ::TryFromBytes>::is_bit_valid (
1080                                             variant)
1081                         }
1082                         _ => false,
1083                     }
1084                 }
1085             }
1086         } no_build
1087     }
1088 
1089     test! {
1090         TryFromBytes {
1091             #[repr(C)]
1092             enum ComplexWithGenerics<'a: 'static, const N: usize, X, Y: Deref>
1093             where
1094                 X: Deref<Target = &'a [(X, Y); N]>,
1095             {
1096                 UnitLike,
1097                 StructLike { a: u8, b: X, c: X::Target, d: Y::Target, e: [(X, Y); N] },
1098                 TupleLike(bool, Y, PhantomData<&'a [(X, Y); N]>),
1099             }
1100         } expands to {
1101             #[allow(deprecated)]
1102             #[automatically_derived]
1103             unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
1104                 for ComplexWithGenerics<'a, { N }, X, Y>
1105             where
1106                 X: Deref<Target = &'a [(X, Y); N]>,
1107                 u8: ::zerocopy::TryFromBytes,
1108                 X: ::zerocopy::TryFromBytes,
1109                 X::Target: ::zerocopy::TryFromBytes,
1110                 Y::Target: ::zerocopy::TryFromBytes,
1111                 [(X, Y); N]: ::zerocopy::TryFromBytes,
1112                 bool: ::zerocopy::TryFromBytes,
1113                 Y: ::zerocopy::TryFromBytes,
1114                 PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes,
1115             {
1116                 fn only_derive_is_allowed_to_implement_this_trait() {}
1117                 fn is_bit_valid<___ZerocopyAliasing>(
1118                     mut candidate: ::zerocopy::Maybe<'_, Self, ___ZerocopyAliasing>,
1119                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
1120                 where
1121                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
1122                 {
1123                     use ::zerocopy::util::macro_util::core_reexport;
1124                     #[repr(C)]
1125                     #[allow(dead_code, non_camel_case_types)]
1126                     enum ___ZerocopyTag {
1127                         UnitLike,
1128                         StructLike,
1129                         TupleLike,
1130                     }
1131                     type ___ZerocopyTagPrimitive = ::zerocopy::util::macro_util::SizeToTag<
1132                         { core_reexport::mem::size_of::<___ZerocopyTag>() },
1133                     >;
1134                     #[allow(non_upper_case_globals)]
1135                     const ___ZEROCOPY_TAG_UnitLike: ___ZerocopyTagPrimitive =
1136                         ___ZerocopyTag::UnitLike as ___ZerocopyTagPrimitive;
1137                     #[allow(non_upper_case_globals)]
1138                     const ___ZEROCOPY_TAG_StructLike: ___ZerocopyTagPrimitive =
1139                         ___ZerocopyTag::StructLike as ___ZerocopyTagPrimitive;
1140                     #[allow(non_upper_case_globals)]
1141                     const ___ZEROCOPY_TAG_TupleLike: ___ZerocopyTagPrimitive =
1142                         ___ZerocopyTag::TupleLike as ___ZerocopyTagPrimitive;
1143                     type ___ZerocopyOuterTag = ___ZerocopyTag;
1144                     type ___ZerocopyInnerTag = ();
1145                     #[repr(C)]
1146                     #[allow(non_snake_case)]
1147                     struct ___ZerocopyVariantStruct_StructLike<'a: 'static, const N: usize, X, Y: Deref>(
1148                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>,
1149                         u8,
1150                         X,
1151                         X::Target,
1152                         Y::Target,
1153                         [(X, Y); N],
1154                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>,
1155                     )
1156                     where
1157                         X: Deref<Target = &'a [(X, Y); N]>;
1158                     #[allow(deprecated)]
1159                     #[automatically_derived]
1160                     unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
1161                         for ___ZerocopyVariantStruct_StructLike<'a, { N }, X, Y>
1162                     where
1163                         X: Deref<Target = &'a [(X, Y); N]>,
1164                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes,
1165                         u8: ::zerocopy::TryFromBytes,
1166                         X: ::zerocopy::TryFromBytes,
1167                         X::Target: ::zerocopy::TryFromBytes,
1168                         Y::Target: ::zerocopy::TryFromBytes,
1169                         [(X, Y); N]: ::zerocopy::TryFromBytes,
1170                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>:
1171                             ::zerocopy::TryFromBytes,
1172                     {
1173                         fn only_derive_is_allowed_to_implement_this_trait() {}
1174                         fn is_bit_valid<___ZerocopyAliasing>(
1175                             mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
1176                         ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
1177                         where
1178                             ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
1179                         {
1180                             true && {
1181                                 let field_candidate = unsafe {
1182                                     let project = |slf: *mut Self| {
1183                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0)
1184                                     };
1185                                     candidate.reborrow().cast_unsized_unchecked(project)
1186                                 };
1187                                 <core_reexport::mem::MaybeUninit<
1188                                         ___ZerocopyInnerTag,
1189                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1190                             } && {
1191                                 let field_candidate = unsafe {
1192                                     let project = |slf: *mut Self| {
1193                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1)
1194                                     };
1195                                     candidate.reborrow().cast_unsized_unchecked(project)
1196                                 };
1197                                 <u8 as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1198                             } && {
1199                                 let field_candidate = unsafe {
1200                                     let project = |slf: *mut Self| {
1201                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2)
1202                                     };
1203                                     candidate.reborrow().cast_unsized_unchecked(project)
1204                                 };
1205                                 <X as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1206                             } && {
1207                                 let field_candidate = unsafe {
1208                                     let project = |slf: *mut Self| {
1209                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3)
1210                                     };
1211                                     candidate.reborrow().cast_unsized_unchecked(project)
1212                                 };
1213                                 <X::Target as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1214                             } && {
1215                                 let field_candidate = unsafe {
1216                                     let project = |slf: *mut Self| {
1217                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4)
1218                                     };
1219                                     candidate.reborrow().cast_unsized_unchecked(project)
1220                                 };
1221                                 <Y::Target as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1222                             } && {
1223                                 let field_candidate = unsafe {
1224                                     let project = |slf: *mut Self| {
1225                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).5)
1226                                     };
1227                                     candidate.reborrow().cast_unsized_unchecked(project)
1228                                 };
1229                                 <[(X, Y); N] as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1230                             } && {
1231                                 let field_candidate = unsafe {
1232                                     let project = |slf: *mut Self| {
1233                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).6)
1234                                     };
1235                                     candidate.reborrow().cast_unsized_unchecked(project)
1236                                 };
1237                                 <core_reexport::marker::PhantomData<
1238                                         ComplexWithGenerics<'a, N, X, Y>,
1239                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1240                             }
1241                         }
1242                     }
1243                     #[repr(C)]
1244                     #[allow(non_snake_case)]
1245                     struct ___ZerocopyVariantStruct_TupleLike<'a: 'static, const N: usize, X, Y: Deref>(
1246                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>,
1247                         bool,
1248                         Y,
1249                         PhantomData<&'a [(X, Y); N]>,
1250                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>,
1251                     )
1252                     where
1253                         X: Deref<Target = &'a [(X, Y); N]>;
1254                     #[allow(deprecated)]
1255                     #[automatically_derived]
1256                     unsafe impl<'a: 'static, const N: usize, X, Y: Deref> ::zerocopy::TryFromBytes
1257                         for ___ZerocopyVariantStruct_TupleLike<'a, { N }, X, Y>
1258                     where
1259                         X: Deref<Target = &'a [(X, Y); N]>,
1260                         core_reexport::mem::MaybeUninit<___ZerocopyInnerTag>: ::zerocopy::TryFromBytes,
1261                         bool: ::zerocopy::TryFromBytes,
1262                         Y: ::zerocopy::TryFromBytes,
1263                         PhantomData<&'a [(X, Y); N]>: ::zerocopy::TryFromBytes,
1264                         core_reexport::marker::PhantomData<ComplexWithGenerics<'a, N, X, Y>>:
1265                             ::zerocopy::TryFromBytes,
1266                     {
1267                         fn only_derive_is_allowed_to_implement_this_trait() {}
1268                         fn is_bit_valid<___ZerocopyAliasing>(
1269                             mut candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
1270                         ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
1271                         where
1272                             ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
1273                         {
1274                             true && {
1275                                 let field_candidate = unsafe {
1276                                     let project = |slf: *mut Self| {
1277                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).0)
1278                                     };
1279                                     candidate.reborrow().cast_unsized_unchecked(project)
1280                                 };
1281                                 <core_reexport::mem::MaybeUninit<
1282                                         ___ZerocopyInnerTag,
1283                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1284                             } && {
1285                                 let field_candidate = unsafe {
1286                                     let project = |slf: *mut Self| {
1287                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).1)
1288                                     };
1289                                     candidate.reborrow().cast_unsized_unchecked(project)
1290                                 };
1291                                 <bool as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1292                             } && {
1293                                 let field_candidate = unsafe {
1294                                     let project = |slf: *mut Self| {
1295                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).2)
1296                                     };
1297                                     candidate.reborrow().cast_unsized_unchecked(project)
1298                                 };
1299                                 <Y as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1300                             } && {
1301                                 let field_candidate = unsafe {
1302                                     let project = |slf: *mut Self| {
1303                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).3)
1304                                     };
1305                                     candidate.reborrow().cast_unsized_unchecked(project)
1306                                 };
1307                                 <PhantomData<&'a [(X, Y); N]> as ::zerocopy::TryFromBytes>::is_bit_valid(
1308                                     field_candidate,
1309                                 )
1310                             } && {
1311                                 let field_candidate = unsafe {
1312                                     let project = |slf: *mut Self| {
1313                                         ::zerocopy::util::macro_util::core_reexport::ptr::addr_of_mut!((*slf).4)
1314                                     };
1315                                     candidate.reborrow().cast_unsized_unchecked(project)
1316                                 };
1317                                 <core_reexport::marker::PhantomData<
1318                                         ComplexWithGenerics<'a, N, X, Y>,
1319                                     > as ::zerocopy::TryFromBytes>::is_bit_valid(field_candidate)
1320                             }
1321                         }
1322                     }
1323                     #[repr(C)]
1324                     #[allow(non_snake_case)]
1325                     union ___ZerocopyVariants<'a: 'static, const N: usize, X, Y: Deref> {
1326                         __field_StructLike:
1327                             core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_StructLike<'a, N, X, Y>>,
1328                         __field_TupleLike:
1329                             core_reexport::mem::ManuallyDrop<___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>>,
1330                         __nonempty: (),
1331                     }
1332                     #[repr(C)]
1333                     struct ___ZerocopyRawEnum<'a: 'static, const N: usize, X, Y: Deref> {
1334                         tag: ___ZerocopyOuterTag,
1335                         variants: ___ZerocopyVariants<'a, N, X, Y>,
1336                     }
1337                     let tag = {
1338                         let tag_ptr = unsafe {
1339                             candidate.reborrow().cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyTagPrimitive })
1340                         };
1341                         let tag_ptr = unsafe { tag_ptr.assume_initialized() };
1342                         tag_ptr.bikeshed_recall_valid().read_unaligned::<::zerocopy::BecauseImmutable>()
1343                     };
1344                     let raw_enum = unsafe {
1345                         candidate.cast_unsized_unchecked(|p: *mut Self| { p as *mut ___ZerocopyRawEnum<'a, N, X, Y> })
1346                     };
1347                     let raw_enum = unsafe { raw_enum.assume_initialized() };
1348                     let variants = unsafe {
1349                         raw_enum.cast_unsized_unchecked(|p: *mut ___ZerocopyRawEnum<'a, N, X, Y>| {
1350                             core_reexport::ptr::addr_of_mut!((*p).variants)
1351                         })
1352                     };
1353                     #[allow(non_upper_case_globals)]
1354                     match tag {
1355                         ___ZEROCOPY_TAG_UnitLike => true,
1356                         ___ZEROCOPY_TAG_StructLike => {
1357                             let variant = unsafe {
1358                                 variants.cast_unsized_unchecked(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| {
1359                                     p as *mut ___ZerocopyVariantStruct_StructLike<'a, N, X, Y>
1360                                 })
1361                             };
1362                             let variant = unsafe { variant.assume_initialized() };
1363                         <___ZerocopyVariantStruct_StructLike<'a, N, X, Y> as ::zerocopy ::TryFromBytes>::is_bit_valid (
1364                                             variant)
1365                         }
1366                         ___ZEROCOPY_TAG_TupleLike => {
1367                             let variant = unsafe {
1368                                 variants.cast_unsized_unchecked(|p: *mut ___ZerocopyVariants<'a, N, X, Y>| {
1369                                     p as *mut ___ZerocopyVariantStruct_TupleLike<'a, N, X, Y>
1370                                 })
1371                             };
1372                             let variant = unsafe { variant.assume_initialized() };
1373                         <___ZerocopyVariantStruct_TupleLike<'a, N, X, Y> as ::zerocopy ::TryFromBytes>::is_bit_valid (
1374                                             variant)
1375                         }
1376                         _ => false,
1377                     }
1378                 }
1379             }
1380         } no_build
1381     }
1382 }
1383 
1384 // This goes at the bottom because it's so verbose and it makes scrolling past
1385 // other code a pain.
1386 #[test]
test_from_bytes_enum()1387 fn test_from_bytes_enum() {
1388     test! {
1389         FromBytes {
1390             #[repr(u8)]
1391             enum Foo {
1392                 Variant0,
1393                 Variant1,
1394                 Variant2,
1395                 Variant3,
1396                 Variant4,
1397                 Variant5,
1398                 Variant6,
1399                 Variant7,
1400                 Variant8,
1401                 Variant9,
1402                 Variant10,
1403                 Variant11,
1404                 Variant12,
1405                 Variant13,
1406                 Variant14,
1407                 Variant15,
1408                 Variant16,
1409                 Variant17,
1410                 Variant18,
1411                 Variant19,
1412                 Variant20,
1413                 Variant21,
1414                 Variant22,
1415                 Variant23,
1416                 Variant24,
1417                 Variant25,
1418                 Variant26,
1419                 Variant27,
1420                 Variant28,
1421                 Variant29,
1422                 Variant30,
1423                 Variant31,
1424                 Variant32,
1425                 Variant33,
1426                 Variant34,
1427                 Variant35,
1428                 Variant36,
1429                 Variant37,
1430                 Variant38,
1431                 Variant39,
1432                 Variant40,
1433                 Variant41,
1434                 Variant42,
1435                 Variant43,
1436                 Variant44,
1437                 Variant45,
1438                 Variant46,
1439                 Variant47,
1440                 Variant48,
1441                 Variant49,
1442                 Variant50,
1443                 Variant51,
1444                 Variant52,
1445                 Variant53,
1446                 Variant54,
1447                 Variant55,
1448                 Variant56,
1449                 Variant57,
1450                 Variant58,
1451                 Variant59,
1452                 Variant60,
1453                 Variant61,
1454                 Variant62,
1455                 Variant63,
1456                 Variant64,
1457                 Variant65,
1458                 Variant66,
1459                 Variant67,
1460                 Variant68,
1461                 Variant69,
1462                 Variant70,
1463                 Variant71,
1464                 Variant72,
1465                 Variant73,
1466                 Variant74,
1467                 Variant75,
1468                 Variant76,
1469                 Variant77,
1470                 Variant78,
1471                 Variant79,
1472                 Variant80,
1473                 Variant81,
1474                 Variant82,
1475                 Variant83,
1476                 Variant84,
1477                 Variant85,
1478                 Variant86,
1479                 Variant87,
1480                 Variant88,
1481                 Variant89,
1482                 Variant90,
1483                 Variant91,
1484                 Variant92,
1485                 Variant93,
1486                 Variant94,
1487                 Variant95,
1488                 Variant96,
1489                 Variant97,
1490                 Variant98,
1491                 Variant99,
1492                 Variant100,
1493                 Variant101,
1494                 Variant102,
1495                 Variant103,
1496                 Variant104,
1497                 Variant105,
1498                 Variant106,
1499                 Variant107,
1500                 Variant108,
1501                 Variant109,
1502                 Variant110,
1503                 Variant111,
1504                 Variant112,
1505                 Variant113,
1506                 Variant114,
1507                 Variant115,
1508                 Variant116,
1509                 Variant117,
1510                 Variant118,
1511                 Variant119,
1512                 Variant120,
1513                 Variant121,
1514                 Variant122,
1515                 Variant123,
1516                 Variant124,
1517                 Variant125,
1518                 Variant126,
1519                 Variant127,
1520                 Variant128,
1521                 Variant129,
1522                 Variant130,
1523                 Variant131,
1524                 Variant132,
1525                 Variant133,
1526                 Variant134,
1527                 Variant135,
1528                 Variant136,
1529                 Variant137,
1530                 Variant138,
1531                 Variant139,
1532                 Variant140,
1533                 Variant141,
1534                 Variant142,
1535                 Variant143,
1536                 Variant144,
1537                 Variant145,
1538                 Variant146,
1539                 Variant147,
1540                 Variant148,
1541                 Variant149,
1542                 Variant150,
1543                 Variant151,
1544                 Variant152,
1545                 Variant153,
1546                 Variant154,
1547                 Variant155,
1548                 Variant156,
1549                 Variant157,
1550                 Variant158,
1551                 Variant159,
1552                 Variant160,
1553                 Variant161,
1554                 Variant162,
1555                 Variant163,
1556                 Variant164,
1557                 Variant165,
1558                 Variant166,
1559                 Variant167,
1560                 Variant168,
1561                 Variant169,
1562                 Variant170,
1563                 Variant171,
1564                 Variant172,
1565                 Variant173,
1566                 Variant174,
1567                 Variant175,
1568                 Variant176,
1569                 Variant177,
1570                 Variant178,
1571                 Variant179,
1572                 Variant180,
1573                 Variant181,
1574                 Variant182,
1575                 Variant183,
1576                 Variant184,
1577                 Variant185,
1578                 Variant186,
1579                 Variant187,
1580                 Variant188,
1581                 Variant189,
1582                 Variant190,
1583                 Variant191,
1584                 Variant192,
1585                 Variant193,
1586                 Variant194,
1587                 Variant195,
1588                 Variant196,
1589                 Variant197,
1590                 Variant198,
1591                 Variant199,
1592                 Variant200,
1593                 Variant201,
1594                 Variant202,
1595                 Variant203,
1596                 Variant204,
1597                 Variant205,
1598                 Variant206,
1599                 Variant207,
1600                 Variant208,
1601                 Variant209,
1602                 Variant210,
1603                 Variant211,
1604                 Variant212,
1605                 Variant213,
1606                 Variant214,
1607                 Variant215,
1608                 Variant216,
1609                 Variant217,
1610                 Variant218,
1611                 Variant219,
1612                 Variant220,
1613                 Variant221,
1614                 Variant222,
1615                 Variant223,
1616                 Variant224,
1617                 Variant225,
1618                 Variant226,
1619                 Variant227,
1620                 Variant228,
1621                 Variant229,
1622                 Variant230,
1623                 Variant231,
1624                 Variant232,
1625                 Variant233,
1626                 Variant234,
1627                 Variant235,
1628                 Variant236,
1629                 Variant237,
1630                 Variant238,
1631                 Variant239,
1632                 Variant240,
1633                 Variant241,
1634                 Variant242,
1635                 Variant243,
1636                 Variant244,
1637                 Variant245,
1638                 Variant246,
1639                 Variant247,
1640                 Variant248,
1641                 Variant249,
1642                 Variant250,
1643                 Variant251,
1644                 Variant252,
1645                 Variant253,
1646                 Variant254,
1647                 Variant255,
1648             }
1649         } expands to {
1650             #[allow(deprecated)]
1651             #[automatically_derived]
1652             unsafe impl ::zerocopy::TryFromBytes for Foo {
1653                 fn only_derive_is_allowed_to_implement_this_trait() {}
1654 
1655                 fn is_bit_valid<___ZerocopyAliasing>(
1656                     _candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
1657                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
1658                 where
1659                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
1660                 {
1661                     if false {
1662                         fn assert_is_from_bytes<T>()
1663                         where
1664                             T: ::zerocopy::FromBytes,
1665                             T: ?::zerocopy::util::macro_util::core_reexport::marker::Sized,
1666                         {}
1667                         assert_is_from_bytes::<Self>();
1668                     }
1669 
1670                     true
1671                 }
1672             }
1673 
1674             #[allow(deprecated)]
1675             #[automatically_derived]
1676             unsafe impl ::zerocopy::FromZeros for Foo {
1677                 fn only_derive_is_allowed_to_implement_this_trait() {}
1678             }
1679 
1680             #[allow(deprecated)]
1681             #[automatically_derived]
1682             unsafe impl ::zerocopy::FromBytes for Foo {
1683                 fn only_derive_is_allowed_to_implement_this_trait() {}
1684             }
1685         } no_build
1686     }
1687 }
1688 
1689 #[test]
test_try_from_bytes_trivial_is_bit_valid_enum()1690 fn test_try_from_bytes_trivial_is_bit_valid_enum() {
1691     // Even when we aren't deriving `FromBytes` as the top-level trait,
1692     // `TryFromBytes` on enums still detects whether we *could* derive
1693     // `FromBytes`, and if so, performs the same "trivial `is_bit_valid`"
1694     // optimization.
1695     test! {
1696         TryFromBytes {
1697             #[repr(u8)]
1698             enum Foo {
1699                 Variant0,
1700                 Variant1,
1701                 Variant2,
1702                 Variant3,
1703                 Variant4,
1704                 Variant5,
1705                 Variant6,
1706                 Variant7,
1707                 Variant8,
1708                 Variant9,
1709                 Variant10,
1710                 Variant11,
1711                 Variant12,
1712                 Variant13,
1713                 Variant14,
1714                 Variant15,
1715                 Variant16,
1716                 Variant17,
1717                 Variant18,
1718                 Variant19,
1719                 Variant20,
1720                 Variant21,
1721                 Variant22,
1722                 Variant23,
1723                 Variant24,
1724                 Variant25,
1725                 Variant26,
1726                 Variant27,
1727                 Variant28,
1728                 Variant29,
1729                 Variant30,
1730                 Variant31,
1731                 Variant32,
1732                 Variant33,
1733                 Variant34,
1734                 Variant35,
1735                 Variant36,
1736                 Variant37,
1737                 Variant38,
1738                 Variant39,
1739                 Variant40,
1740                 Variant41,
1741                 Variant42,
1742                 Variant43,
1743                 Variant44,
1744                 Variant45,
1745                 Variant46,
1746                 Variant47,
1747                 Variant48,
1748                 Variant49,
1749                 Variant50,
1750                 Variant51,
1751                 Variant52,
1752                 Variant53,
1753                 Variant54,
1754                 Variant55,
1755                 Variant56,
1756                 Variant57,
1757                 Variant58,
1758                 Variant59,
1759                 Variant60,
1760                 Variant61,
1761                 Variant62,
1762                 Variant63,
1763                 Variant64,
1764                 Variant65,
1765                 Variant66,
1766                 Variant67,
1767                 Variant68,
1768                 Variant69,
1769                 Variant70,
1770                 Variant71,
1771                 Variant72,
1772                 Variant73,
1773                 Variant74,
1774                 Variant75,
1775                 Variant76,
1776                 Variant77,
1777                 Variant78,
1778                 Variant79,
1779                 Variant80,
1780                 Variant81,
1781                 Variant82,
1782                 Variant83,
1783                 Variant84,
1784                 Variant85,
1785                 Variant86,
1786                 Variant87,
1787                 Variant88,
1788                 Variant89,
1789                 Variant90,
1790                 Variant91,
1791                 Variant92,
1792                 Variant93,
1793                 Variant94,
1794                 Variant95,
1795                 Variant96,
1796                 Variant97,
1797                 Variant98,
1798                 Variant99,
1799                 Variant100,
1800                 Variant101,
1801                 Variant102,
1802                 Variant103,
1803                 Variant104,
1804                 Variant105,
1805                 Variant106,
1806                 Variant107,
1807                 Variant108,
1808                 Variant109,
1809                 Variant110,
1810                 Variant111,
1811                 Variant112,
1812                 Variant113,
1813                 Variant114,
1814                 Variant115,
1815                 Variant116,
1816                 Variant117,
1817                 Variant118,
1818                 Variant119,
1819                 Variant120,
1820                 Variant121,
1821                 Variant122,
1822                 Variant123,
1823                 Variant124,
1824                 Variant125,
1825                 Variant126,
1826                 Variant127,
1827                 Variant128,
1828                 Variant129,
1829                 Variant130,
1830                 Variant131,
1831                 Variant132,
1832                 Variant133,
1833                 Variant134,
1834                 Variant135,
1835                 Variant136,
1836                 Variant137,
1837                 Variant138,
1838                 Variant139,
1839                 Variant140,
1840                 Variant141,
1841                 Variant142,
1842                 Variant143,
1843                 Variant144,
1844                 Variant145,
1845                 Variant146,
1846                 Variant147,
1847                 Variant148,
1848                 Variant149,
1849                 Variant150,
1850                 Variant151,
1851                 Variant152,
1852                 Variant153,
1853                 Variant154,
1854                 Variant155,
1855                 Variant156,
1856                 Variant157,
1857                 Variant158,
1858                 Variant159,
1859                 Variant160,
1860                 Variant161,
1861                 Variant162,
1862                 Variant163,
1863                 Variant164,
1864                 Variant165,
1865                 Variant166,
1866                 Variant167,
1867                 Variant168,
1868                 Variant169,
1869                 Variant170,
1870                 Variant171,
1871                 Variant172,
1872                 Variant173,
1873                 Variant174,
1874                 Variant175,
1875                 Variant176,
1876                 Variant177,
1877                 Variant178,
1878                 Variant179,
1879                 Variant180,
1880                 Variant181,
1881                 Variant182,
1882                 Variant183,
1883                 Variant184,
1884                 Variant185,
1885                 Variant186,
1886                 Variant187,
1887                 Variant188,
1888                 Variant189,
1889                 Variant190,
1890                 Variant191,
1891                 Variant192,
1892                 Variant193,
1893                 Variant194,
1894                 Variant195,
1895                 Variant196,
1896                 Variant197,
1897                 Variant198,
1898                 Variant199,
1899                 Variant200,
1900                 Variant201,
1901                 Variant202,
1902                 Variant203,
1903                 Variant204,
1904                 Variant205,
1905                 Variant206,
1906                 Variant207,
1907                 Variant208,
1908                 Variant209,
1909                 Variant210,
1910                 Variant211,
1911                 Variant212,
1912                 Variant213,
1913                 Variant214,
1914                 Variant215,
1915                 Variant216,
1916                 Variant217,
1917                 Variant218,
1918                 Variant219,
1919                 Variant220,
1920                 Variant221,
1921                 Variant222,
1922                 Variant223,
1923                 Variant224,
1924                 Variant225,
1925                 Variant226,
1926                 Variant227,
1927                 Variant228,
1928                 Variant229,
1929                 Variant230,
1930                 Variant231,
1931                 Variant232,
1932                 Variant233,
1933                 Variant234,
1934                 Variant235,
1935                 Variant236,
1936                 Variant237,
1937                 Variant238,
1938                 Variant239,
1939                 Variant240,
1940                 Variant241,
1941                 Variant242,
1942                 Variant243,
1943                 Variant244,
1944                 Variant245,
1945                 Variant246,
1946                 Variant247,
1947                 Variant248,
1948                 Variant249,
1949                 Variant250,
1950                 Variant251,
1951                 Variant252,
1952                 Variant253,
1953                 Variant254,
1954                 Variant255,
1955             }
1956         } expands to {
1957             #[allow(deprecated)]
1958             #[automatically_derived]
1959             unsafe impl ::zerocopy::TryFromBytes for Foo {
1960                 fn only_derive_is_allowed_to_implement_this_trait() {}
1961 
1962                 fn is_bit_valid<___ZerocopyAliasing>(
1963                     _candidate: ::zerocopy::Maybe<Self, ___ZerocopyAliasing>,
1964                 ) -> ::zerocopy::util::macro_util::core_reexport::primitive::bool
1965                 where
1966                     ___ZerocopyAliasing: ::zerocopy::pointer::invariant::Reference,
1967                 {
1968                     true
1969                 }
1970             }
1971         } no_build
1972     }
1973 }
1974 
1975 #[test]
test_hash()1976 fn test_hash() {
1977     test! {
1978         ByteHash {
1979             struct Foo<T: Clone>(T) where Self: Sized;
1980         } expands to {
1981             #[allow(deprecated)]
1982             #[automatically_derived]
1983             impl<T: Clone> ::zerocopy::util::macro_util::core_reexport::hash::Hash for Foo<T>
1984             where
1985                 Self: ::zerocopy::IntoBytes + ::zerocopy::Immutable,
1986                 Self: Sized,
1987             {
1988                 fn hash<H>(&self, state: &mut H)
1989                 where
1990                     H: ::zerocopy::util::macro_util::core_reexport::hash::Hasher,
1991                 {
1992                     ::zerocopy::util::macro_util::core_reexport::hash::Hasher::write(
1993                         state,
1994                         ::zerocopy::IntoBytes::as_bytes(self)
1995                     )
1996                 }
1997 
1998                 fn hash_slice<H>(data: &[Self], state: &mut H)
1999                 where
2000                     H: ::zerocopy::util::macro_util::core_reexport::hash::Hasher,
2001                 {
2002                     ::zerocopy::util::macro_util::core_reexport::hash::Hasher::write(
2003                         state,
2004                         ::zerocopy::IntoBytes::as_bytes(data)
2005                     )
2006                 }
2007             }
2008         } no_build
2009     }
2010 }
2011 
2012 #[test]
test_eq()2013 fn test_eq() {
2014     test! {
2015         ByteEq {
2016             struct Foo<T: Clone>(T) where Self: Sized;
2017         } expands to {
2018             #[allow(deprecated)]
2019             #[automatically_derived]
2020             impl<T: Clone> ::zerocopy::util::macro_util::core_reexport::cmp::PartialEq for Foo<T>
2021             where
2022                 Self: ::zerocopy::IntoBytes + ::zerocopy::Immutable,
2023                 Self: Sized,
2024             {
2025                 fn eq(&self, other: &Self) -> bool {
2026                     ::zerocopy::util::macro_util::core_reexport::cmp::PartialEq::eq(
2027                         ::zerocopy::IntoBytes::as_bytes(self),
2028                         ::zerocopy::IntoBytes::as_bytes(other),
2029                     )
2030                 }
2031             }
2032 
2033             #[allow(deprecated)]
2034             #[automatically_derived]
2035             impl<T: Clone> ::zerocopy::util::macro_util::core_reexport::cmp::Eq for Foo<T>
2036             where
2037                 Self: ::zerocopy::IntoBytes + ::zerocopy::Immutable,
2038                 Self: Sized,
2039             {
2040             }
2041         } no_build
2042     }
2043 }
2044