// SPDX-License-Identifier: (BSD-2-Clause OR Apache-2.0) OR MIT
//
use proc_macro2::TokenStream;
use quote::quote;
use syn::{
    parse_quote, spanned::Spanned as _, Data, DataEnum, DataStruct, DataUnion, DeriveInput, Error,
    Expr, Fields, Ident, Index, Type,
};

use crate::{
    repr::{EnumRepr, StructUnionRepr},
    util::{
        const_block, enum_size_from_repr, generate_tag_enum, Ctx, DataExt, FieldBounds,
        ImplBlockBuilder, Trait, TraitBound,
    },
};
fn tag_ident(variant_ident: &Ident) -> Ident {
    ident!(("___ZEROCOPY_TAG_{}", variant_ident), variant_ident.span())
}

/// Generates a constant for the tag associated with each variant of the enum.
/// When we match on the enum's tag, each arm matches one of these constants. We
/// have to use constants here because:
///
/// - The type that we're matching on is not the type of the tag, it's an
///   integer of the same size as the tag type and with the same bit patterns.
/// - We can't read the enum tag as an enum because the bytes may not represent
///   a valid variant.
/// - Patterns do not currently support const expressions, so we have to assign
///   these constants to names rather than use them inline in the `match`
///   statement.
fn generate_tag_consts(data: &DataEnum) -> TokenStream {
    let tags = data.variants.iter().map(|v| {
        let variant_ident = &v.ident;
        let tag_ident = tag_ident(variant_ident);

        quote! {
            // This casts the enum variant to its discriminant, and then
            // converts the discriminant to the target integral type via a
            // numeric cast [1].
            //
            // Because these are the same size, this is defined to be a no-op
            // and therefore is a lossless conversion [2].
            //
            // [1] Per https://doc.rust-lang.org/1.81.0/reference/expressions/operator-expr.html#enum-cast:
            //
            //   Casts an enum to its discriminant.
            //
            // [2] Per https://doc.rust-lang.org/1.81.0/reference/expressions/operator-expr.html#numeric-cast:
            //
            //   Casting between two integers of the same size (e.g. i32 -> u32)
            //   is a no-op.
            const #tag_ident: ___ZerocopyTagPrimitive =
                ___ZerocopyTag::#variant_ident as ___ZerocopyTagPrimitive;
        }
    });

    quote! {
        #(#tags)*
    }
}

fn variant_struct_ident(variant_ident: &Ident) -> Ident {
    ident!(("___ZerocopyVariantStruct_{}", variant_ident), variant_ident.span())
}

/// Generates variant structs for the given enum variant.
///
/// These are structs associated with each variant of an enum. They are
/// `repr(C)` tuple structs with the same fields as the variant after a
/// `MaybeUninit<___ZerocopyInnerTag>`.
///
/// In order to unify the generated types for `repr(C)` and `repr(int)` enums,
/// we use a "fused" representation with fields for both an inner tag and an
/// outer tag. Depending on the repr, we will set one of these tags to the tag
/// type and the other to `()`. This lets us generate the same code but put the
/// tags in different locations.
fn generate_variant_structs(ctx: &Ctx, data: &DataEnum) -> TokenStream {
    let (impl_generics, ty_generics, where_clause) = ctx.ast.generics.split_for_impl();

    let enum_name = &ctx.ast.ident;

    // All variant structs have a `PhantomData<MyEnum<...>>` field because we
    // don't know which generic parameters each variant will use, and unused
    // generic parameters are a compile error.
    let core = ctx.core_path();
    let phantom_ty = quote! {
        #core::marker::PhantomData<#enum_name #ty_generics>
    };

    let variant_structs = data.variants.iter().filter_map(|variant| {
        // We don't generate variant structs for unit variants because we only
        // need to check the tag. This helps cut down our generated code a bit.
        if matches!(variant.fields, Fields::Unit) {
            return None;
        }

        let variant_struct_ident = variant_struct_ident(&variant.ident);
        let field_types = variant.fields.iter().map(|f| &f.ty);

        let variant_struct = parse_quote! {
            #[repr(C)]
            struct #variant_struct_ident #impl_generics (
                #core::mem::MaybeUninit<___ZerocopyInnerTag>,
                #(#field_types,)*
                #phantom_ty,
            ) #where_clause;
        };

        // We do this rather than emitting `#[derive(::zerocopy::TryFromBytes)]`
        // because that is not hygienic, and this is also more performant.
        let try_from_bytes_impl =
            derive_try_from_bytes(&ctx.with_input(&variant_struct), Trait::TryFromBytes)
                .expect("derive_try_from_bytes should not fail on synthesized type");

        Some(quote! {
            #variant_struct
            #try_from_bytes_impl
        })
    });

    quote! {
        #(#variant_structs)*
    }
}

fn variants_union_field_ident(ident: &Ident) -> Ident {
    // Field names are prefixed with `__field_` to prevent name collision
    // with the `__nonempty` field.
    ident!(("__field_{}", ident), ident.span())
}

fn generate_variants_union(ctx: &Ctx, data: &DataEnum) -> TokenStream {
    let generics = &ctx.ast.generics;
    let (_, ty_generics, _) = generics.split_for_impl();

    let fields = data.variants.iter().filter_map(|variant| {
        // We don't generate variant structs for unit variants because we only
        // need to check the tag. This helps cut down our generated code a bit.
        if matches!(variant.fields, Fields::Unit) {
            return None;
        }

        let field_name = variants_union_field_ident(&variant.ident);
        let variant_struct_ident = variant_struct_ident(&variant.ident);

        let core = ctx.core_path();
        Some(quote! {
            #field_name: #core::mem::ManuallyDrop<#variant_struct_ident #ty_generics>,
        })
    });

    let variants_union = parse_quote! {
        #[repr(C)]
        union ___ZerocopyVariants #generics {
            #(#fields)*
            // Enums can have variants with no fields, but unions must
            // have at least one field. So we just add a trailing unit
            // to ensure that this union always has at least one field.
            // Because this union is `repr(C)`, this unit type does not
            // affect the layout.
            __nonempty: (),
        }
    };

    let has_field =
        derive_has_field_struct_union(&ctx.with_input(&variants_union), &variants_union.data);

    quote! {
        #variants_union
        #has_field
    }
}

/// Generates an implementation of `is_bit_valid` for an arbitrary enum.
///
/// The general process is:
///
/// 1. Generate a tag enum. This is an enum with the same repr, variants, and
///    corresponding discriminants as the original enum, but without any fields
///    on the variants. This gives us access to an enum where the variants have
///    the same discriminants as the one we're writing `is_bit_valid` for.
/// 2. Make constants from the variants of the tag enum. We need these because
///    we can't put const exprs in match arms.
/// 3. Generate variant structs. These are structs which have the same fields as
///    each variant of the enum, and are `#[repr(C)]` with an optional "inner
///    tag".
/// 4. Generate a variants union, with one field for each variant struct type.
/// 5. And finally, our raw enum is a `#[repr(C)]` struct of an "outer tag" and
///    the variants union.
///
/// See these reference links for fully-worked example decompositions.
///
/// - `repr(C)`: <https://doc.rust-lang.org/reference/type-layout.html#reprc-enums-with-fields>
/// - `repr(int)`: <https://doc.rust-lang.org/reference/type-layout.html#primitive-representation-of-enums-with-fields>
/// - `repr(C, int)`: <https://doc.rust-lang.org/reference/type-layout.html#combining-primitive-representations-of-enums-with-fields-and-reprc>
pub(crate) fn derive_is_bit_valid(
    ctx: &Ctx,
    data: &DataEnum,
    repr: &EnumRepr,
) -> Result<TokenStream, Error> {
    let trait_path = Trait::TryFromBytes.crate_path(ctx);
    let tag_enum = generate_tag_enum(ctx, repr, data);
    let tag_consts = generate_tag_consts(data);

    let (outer_tag_type, inner_tag_type) = if repr.is_c() {
        (quote! { ___ZerocopyTag }, quote! { () })
    } else if repr.is_primitive() {
        (quote! { () }, quote! { ___ZerocopyTag })
    } else {
        return Err(Error::new(
            ctx.ast.span(),
            "must have #[repr(C)] or #[repr(Int)] attribute in order to guarantee this type's memory layout",
        ));
    };

    let variant_structs = generate_variant_structs(ctx, data);
    let variants_union = generate_variants_union(ctx, data);

    let (impl_generics, ty_generics, where_clause) = ctx.ast.generics.split_for_impl();

    let zerocopy_crate = &ctx.zerocopy_crate;
    let has_tag = ImplBlockBuilder::new(ctx, data, Trait::HasTag, FieldBounds::None)
        .inner_extras(quote! {
            type Tag = ___ZerocopyTag;
            type ProjectToTag = #zerocopy_crate::pointer::cast::CastSized;
        })
        .build();
    let has_fields = data.variants().into_iter().flat_map(|(variant, fields)| {
        let variant_ident = &variant.unwrap().ident;
        let variants_union_field_ident = variants_union_field_ident(variant_ident);
        let field: Box<syn::Type> = parse_quote!(());
        fields.into_iter().enumerate().map(move |(idx, (vis, ident, ty))| {
            // Rust does not presently support explicit visibility modifiers on
            // enum fields, but we guard against the possibility to ensure this
            // derive remains sound.
            assert!(matches!(vis, syn::Visibility::Inherited));
            let variant_struct_field_index = Index::from(idx + 1);
            let (_, ty_generics, _) = ctx.ast.generics.split_for_impl();
            let has_field_trait = Trait::HasField {
                variant_id: parse_quote!({ #zerocopy_crate::ident_id!(#variant_ident) }),
                // Since Rust does not presently support explicit visibility
                // modifiers on enum fields, any public type is suitable here;
                // we use `()`.
                field: field.clone(),
                field_id: parse_quote!({ #zerocopy_crate::ident_id!(#ident) }),
            };
            let has_field_path = has_field_trait.crate_path(ctx);
            let has_field = ImplBlockBuilder::new(
                ctx,
                data,
                has_field_trait,
                FieldBounds::None,
            )
            .inner_extras(quote! {
                type Type = #ty;

                #[inline(always)]
                fn project(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut <Self as #has_field_path>::Type {
                    use #zerocopy_crate::pointer::cast::{CastSized, Projection};

                    slf.project::<___ZerocopyRawEnum #ty_generics, CastSized>()
                        .project::<_, Projection<_, { #zerocopy_crate::STRUCT_VARIANT_ID }, { #zerocopy_crate::ident_id!(variants) }>>()
                        .project::<_, Projection<_, { #zerocopy_crate::REPR_C_UNION_VARIANT_ID }, { #zerocopy_crate::ident_id!(#variants_union_field_ident) }>>()
                        .project::<_, Projection<_, { #zerocopy_crate::STRUCT_VARIANT_ID }, { #zerocopy_crate::ident_id!(value) }>>()
                        .project::<_, Projection<_, { #zerocopy_crate::STRUCT_VARIANT_ID }, { #zerocopy_crate::ident_id!(#variant_struct_field_index) }>>()
                        .as_ptr()
                }
            })
            .build();

            let project = ImplBlockBuilder::new(
                ctx,
                data,
                Trait::ProjectField {
                    variant_id: parse_quote!({ #zerocopy_crate::ident_id!(#variant_ident) }),
                    // Since Rust does not presently support explicit visibility
                    // modifiers on enum fields, any public type is suitable
                    // here; we use `()`.
                    field: field.clone(),
                    field_id: parse_quote!({ #zerocopy_crate::ident_id!(#ident) }),
                    invariants: parse_quote!((Aliasing, Alignment, #zerocopy_crate::invariant::Initialized)),
                },
                FieldBounds::None,
            )
            .param_extras(vec![
                parse_quote!(Aliasing: #zerocopy_crate::invariant::Aliasing),
                parse_quote!(Alignment: #zerocopy_crate::invariant::Alignment),
            ])
            .inner_extras(quote! {
                type Error = #zerocopy_crate::util::macro_util::core_reexport::convert::Infallible;
                type Invariants = (Aliasing, Alignment, #zerocopy_crate::invariant::Initialized);
            })
            .build();

            quote! {
                #has_field
                #project
            }
        })
    });

    let core = ctx.core_path();
    let match_arms = data.variants.iter().map(|variant| {
        let tag_ident = tag_ident(&variant.ident);
        let variant_struct_ident = variant_struct_ident(&variant.ident);
        let variants_union_field_ident = variants_union_field_ident(&variant.ident);

        if matches!(variant.fields, Fields::Unit) {
            // Unit variants don't need any further validation beyond checking
            // the tag.
            quote! {
                #tag_ident => true
            }
        } else {
            quote! {
                #tag_ident => {
                    // SAFETY: Since we know that the tag is `#tag_ident`, we
                    // know that no other `&`s exist which refer to this enum
                    // as any other variant.
                    let variant_md = variants.cast::<
                        _,
                        #zerocopy_crate::pointer::cast::Projection<
                            // #zerocopy_crate::ReadOnly<_>,
                            _,
                            { #zerocopy_crate::REPR_C_UNION_VARIANT_ID },
                            { #zerocopy_crate::ident_id!(#variants_union_field_ident) }
                        >,
                        _
                    >();
                    let variant = variant_md.cast::<
                        #zerocopy_crate::ReadOnly<#variant_struct_ident #ty_generics>,
                        #zerocopy_crate::pointer::cast::CastSized,
                        (#zerocopy_crate::pointer::BecauseRead, _)
                    >();
                    <
                        #variant_struct_ident #ty_generics as #trait_path
                    >::is_bit_valid(variant)
                }
            }
        }
    });

    let generics = &ctx.ast.generics;
    let raw_enum: DeriveInput = parse_quote! {
        #[repr(C)]
        struct ___ZerocopyRawEnum #generics {
            tag: ___ZerocopyOuterTag,
            variants: ___ZerocopyVariants #ty_generics,
        }
    };

    let self_ident = &ctx.ast.ident;
    let invariants_eq_impl = quote! {
        // SAFETY: `___ZerocopyRawEnum` is designed to have the same layout,
        // validity, and invariants as `Self`.
        unsafe impl #impl_generics #zerocopy_crate::pointer::InvariantsEq<___ZerocopyRawEnum #ty_generics> for #self_ident #ty_generics #where_clause {}
    };

    let raw_enum_projections =
        derive_has_field_struct_union(&ctx.with_input(&raw_enum), &raw_enum.data);

    let raw_enum = quote! {
        #raw_enum
        #invariants_eq_impl
        #raw_enum_projections
    };

    Ok(quote! {
        // SAFETY: We use `is_bit_valid` to validate that the bit pattern of the
        // enum's tag corresponds to one of the enum's discriminants. Then, we
        // check the bit validity of each field of the corresponding variant.
        // Thus, this is a sound implementation of `is_bit_valid`.
        #[inline]
        fn is_bit_valid<___ZcAlignment>(
            mut candidate: #zerocopy_crate::Maybe<'_, Self, ___ZcAlignment>,
        ) -> #core::primitive::bool
        where
            ___ZcAlignment: #zerocopy_crate::invariant::Alignment,
        {
            #tag_enum

            type ___ZerocopyTagPrimitive = #zerocopy_crate::util::macro_util::SizeToTag<
                { #core::mem::size_of::<___ZerocopyTag>() },
            >;

            #tag_consts

            type ___ZerocopyOuterTag = #outer_tag_type;
            type ___ZerocopyInnerTag = #inner_tag_type;

            #variant_structs

            #variants_union

            #raw_enum

            #has_tag

            #(#has_fields)*

            let tag = {
                // SAFETY:
                // - The provided cast addresses a subset of the bytes addressed
                //   by `candidate` because it addresses the starting tag of the
                //   enum.
                // - Because the pointer is cast from `candidate`, it has the
                //   same provenance as it.
                // - There are no `UnsafeCell`s in the tag because it is a
                //   primitive integer.
                // - `tag_ptr` is casted from `candidate`, whose referent is
                //   `Initialized`. Since we have not written uninitialized
                //   bytes into the referent, `tag_ptr` is also `Initialized`.
                //
                // FIXME(#2874): Revise this to a `cast` once `candidate`
                // references a `ReadOnly<Self>`.
                let tag_ptr = unsafe {
                    candidate.reborrow().project_transmute_unchecked::<
                        _,
                        #zerocopy_crate::invariant::Initialized,
                        #zerocopy_crate::pointer::cast::CastSized
                    >()
                };
                tag_ptr.recall_validity::<_, (_, (_, _))>().read::<#zerocopy_crate::BecauseImmutable>()
            };

            let mut raw_enum = candidate.cast::<
                #zerocopy_crate::ReadOnly<___ZerocopyRawEnum #ty_generics>,
                #zerocopy_crate::pointer::cast::CastSized,
                (#zerocopy_crate::pointer::BecauseRead, _)
            >();

            let variants = #zerocopy_crate::into_inner!(raw_enum.project::<
                _,
                { #zerocopy_crate::STRUCT_VARIANT_ID },
                { #zerocopy_crate::ident_id!(variants) }
            >());

            match tag {
                #(#match_arms,)*
                _ => false,
            }
        }
    })
}
pub(crate) fn derive_try_from_bytes(ctx: &Ctx, top_level: Trait) -> Result<TokenStream, Error> {
    match &ctx.ast.data {
        Data::Struct(strct) => derive_try_from_bytes_struct(ctx, strct, top_level),
        Data::Enum(enm) => derive_try_from_bytes_enum(ctx, enm, top_level),
        Data::Union(unn) => Ok(derive_try_from_bytes_union(ctx, unn, top_level)),
    }
}
fn derive_has_field_struct_union(ctx: &Ctx, data: &dyn DataExt) -> TokenStream {
    let fields = ctx.ast.data.fields();
    if fields.is_empty() {
        return quote! {};
    }

    let field_tokens = fields.iter().map(|(vis, ident, _)| {
        let ident = ident!(("__z{}", ident), ident.span());
        quote!(
            #vis enum #ident {}
        )
    });

    let zerocopy_crate = &ctx.zerocopy_crate;
    let variant_id: Box<Expr> = match &ctx.ast.data {
        Data::Struct(_) => parse_quote!({ #zerocopy_crate::STRUCT_VARIANT_ID }),
        Data::Union(_) => {
            let is_repr_c = StructUnionRepr::from_attrs(&ctx.ast.attrs)
                .map(|repr| repr.is_c())
                .unwrap_or(false);
            if is_repr_c {
                parse_quote!({ #zerocopy_crate::REPR_C_UNION_VARIANT_ID })
            } else {
                parse_quote!({ #zerocopy_crate::UNION_VARIANT_ID })
            }
        }
        _ => unreachable!(),
    };

    let core = ctx.core_path();
    let has_tag = ImplBlockBuilder::new(ctx, data, Trait::HasTag, FieldBounds::None)
        .inner_extras(quote! {
            type Tag = ();
            type ProjectToTag = #zerocopy_crate::pointer::cast::CastToUnit;
        })
        .build();
    let has_fields = fields.iter().map(move |(_, ident, ty)| {
        let field_token = ident!(("__z{}", ident), ident.span());
        let field: Box<Type> = parse_quote!(#field_token);
        let field_id: Box<Expr> = parse_quote!({ #zerocopy_crate::ident_id!(#ident) });
        let has_field_trait = Trait::HasField {
                variant_id: variant_id.clone(),
                field: field.clone(),
                field_id: field_id.clone(),
            };
            let has_field_path = has_field_trait.crate_path(ctx);
            ImplBlockBuilder::new(
                ctx,
                data,
                has_field_trait,
                FieldBounds::None,
            )
            .inner_extras(quote! {
                type Type = #ty;

                #[inline(always)]
                fn project(slf: #zerocopy_crate::pointer::PtrInner<'_, Self>) -> *mut <Self as #has_field_path>::Type {
                    let slf = slf.as_ptr();
                    // SAFETY: By invariant on `PtrInner`, `slf` is a non-null
                    // pointer whose referent is zero-sized or lives in a valid
                    // allocation. Since `#ident` is a struct or union field of
                    // `Self`, this projection preserves or shrinks the referent
                    // size, and so the resulting referent also fits in the same
                    // allocation.
                    unsafe { #core::ptr::addr_of_mut!((*slf).#ident) }
                }
            }).outer_extras(if matches!(&ctx.ast.data, Data::Struct(..)) {
            let fields_preserve_alignment = StructUnionRepr::from_attrs(&ctx.ast.attrs)
                .map(|repr| repr.get_packed().is_none())
                .unwrap();
            let alignment = if fields_preserve_alignment {
                quote! { Alignment }
            } else {
                quote! { #zerocopy_crate::invariant::Unaligned }
            };
            // SAFETY: See comments on items.
            ImplBlockBuilder::new(
                ctx,
                data,
                Trait::ProjectField {
                    variant_id: variant_id.clone(),
                    field,
                    field_id,
                    invariants: parse_quote!((Aliasing, Alignment, #zerocopy_crate::invariant::Initialized)),
                },
                FieldBounds::None,
            )
            .param_extras(vec![
                parse_quote!(Aliasing: #zerocopy_crate::invariant::Aliasing),
                parse_quote!(Alignment: #zerocopy_crate::invariant::Alignment),
            ])
            .inner_extras(quote! {
                // SAFETY: Projection into structs is always infallible.
                type Error = #zerocopy_crate::util::macro_util::core_reexport::convert::Infallible;
                // SAFETY: The alignment of the projected `Ptr` is `Unaligned`
                // if the structure is packed; otherwise inherited from the
                // outer `Ptr`. If the validity of the outer pointer is
                // `Initialized`, so too is the validity of its fields.
                type Invariants = (Aliasing, #alignment, #zerocopy_crate::invariant::Initialized);
            })
            .build()
        } else {
            quote! {}
        })
        .build()
    });

    const_block(field_tokens.into_iter().chain(Some(has_tag)).chain(has_fields).map(Some))
}
fn derive_try_from_bytes_struct(
    ctx: &Ctx,
    strct: &DataStruct,
    top_level: Trait,
) -> Result<TokenStream, Error> {
    let extras = try_gen_trivial_is_bit_valid(ctx, top_level).unwrap_or_else(|| {
        let zerocopy_crate = &ctx.zerocopy_crate;
        let fields = strct.fields();
        let field_names = fields.iter().map(|(_vis, name, _ty)| name);
        let field_tys = fields.iter().map(|(_vis, _name, ty)| ty);
        let core = ctx.core_path();
        quote!(
            // SAFETY: We use `is_bit_valid` to validate that each field is
            // bit-valid, and only return `true` if all of them are. The bit
            // validity of a struct is just the composition of the bit
            // validities of its fields, so this is a sound implementation
            // of `is_bit_valid`.
            #[inline]
            fn is_bit_valid<___ZcAlignment>(
                mut candidate: #zerocopy_crate::Maybe<'_, Self, ___ZcAlignment>,
            ) -> #core::primitive::bool
            where
                ___ZcAlignment: #zerocopy_crate::invariant::Alignment,
            {
                true #(&& {
                    let field_candidate =   #zerocopy_crate::into_inner!(candidate.reborrow().project::<
                        _,
                        { #zerocopy_crate::STRUCT_VARIANT_ID },
                        { #zerocopy_crate::ident_id!(#field_names) }
                    >());
                    <#field_tys as #zerocopy_crate::TryFromBytes>::is_bit_valid(field_candidate)
                })*
            }
        )
    });
    Ok(ImplBlockBuilder::new(ctx, strct, Trait::TryFromBytes, FieldBounds::ALL_SELF)
        .inner_extras(extras)
        .outer_extras(derive_has_field_struct_union(ctx, strct))
        .build())
}
fn derive_try_from_bytes_union(ctx: &Ctx, unn: &DataUnion, top_level: Trait) -> TokenStream {
    let field_type_trait_bounds = FieldBounds::All(&[TraitBound::Slf]);

    let zerocopy_crate = &ctx.zerocopy_crate;
    let variant_id: Box<Expr> = {
        let is_repr_c =
            StructUnionRepr::from_attrs(&ctx.ast.attrs).map(|repr| repr.is_c()).unwrap_or(false);
        if is_repr_c {
            parse_quote!({ #zerocopy_crate::REPR_C_UNION_VARIANT_ID })
        } else {
            parse_quote!({ #zerocopy_crate::UNION_VARIANT_ID })
        }
    };

    let extras = try_gen_trivial_is_bit_valid(ctx, top_level).unwrap_or_else(|| {
        let fields = unn.fields();
        let field_names = fields.iter().map(|(_vis, name, _ty)| name);
        let field_tys = fields.iter().map(|(_vis, _name, ty)| ty);
        let core = ctx.core_path();
        quote!(
            // SAFETY: We use `is_bit_valid` to validate that any field is
            // bit-valid; we only return `true` if at least one of them is.
            // The bit validity of a union is not yet well defined in Rust,
            // but it is guaranteed to be no more strict than this
            // definition. See #696 for a more in-depth discussion.
            #[inline]
            fn is_bit_valid<___ZcAlignment>(
                mut candidate: #zerocopy_crate::Maybe<'_, Self, ___ZcAlignment>,
            ) -> #core::primitive::bool
            where
                ___ZcAlignment: #zerocopy_crate::invariant::Alignment,
            {
                false #(|| {
                    // SAFETY:
                    // - Since `ReadOnly<Self>: Immutable` unconditionally,
                    //   neither `*slf` nor the returned pointer's referent
                    //   permit interior mutation.
                    // - Both source and destination validity are
                    //   `Initialized`, which is always a sound
                    //   transmutation.
                    let field_candidate = unsafe {
                        candidate.reborrow().project_transmute_unchecked::<
                            _,
                            _,
                            #zerocopy_crate::pointer::cast::Projection<
                                _,
                                #variant_id,
                                { #zerocopy_crate::ident_id!(#field_names) }
                            >
                        >()
                    };

                    <#field_tys as #zerocopy_crate::TryFromBytes>::is_bit_valid(field_candidate)
                })*
            }
        )
    });
    ImplBlockBuilder::new(ctx, unn, Trait::TryFromBytes, field_type_trait_bounds)
        .inner_extras(extras)
        .outer_extras(derive_has_field_struct_union(ctx, unn))
        .build()
}
fn derive_try_from_bytes_enum(
    ctx: &Ctx,
    enm: &DataEnum,
    top_level: Trait,
) -> Result<TokenStream, Error> {
    let repr = EnumRepr::from_attrs(&ctx.ast.attrs)?;

    // If an enum has no fields, it has a well-defined integer representation,
    // and every possible bit pattern corresponds to a valid discriminant tag,
    // then it *could* be `FromBytes` (even if the user hasn't derived
    // `FromBytes`). This holds if, for `repr(uN)` or `repr(iN)`, there are 2^N
    // variants.
    let could_be_from_bytes = enum_size_from_repr(&repr)
        .map(|size| enm.fields().is_empty() && enm.variants.len() == 1usize << size)
        .unwrap_or(false);

    let trivial_is_bit_valid = try_gen_trivial_is_bit_valid(ctx, top_level);
    let extra = match (trivial_is_bit_valid, could_be_from_bytes) {
        (Some(is_bit_valid), _) => is_bit_valid,
        // SAFETY: It would be sound for the enum to implement `FromBytes`, as
        // required by `gen_trivial_is_bit_valid_unchecked`.
        (None, true) => unsafe { gen_trivial_is_bit_valid_unchecked(ctx) },
        (None, false) => match derive_is_bit_valid(ctx, enm, &repr) {
            Ok(extra) => extra,
            Err(_) if ctx.skip_on_error => return Ok(TokenStream::new()),
            Err(e) => return Err(e),
        },
    };

    Ok(ImplBlockBuilder::new(ctx, enm, Trait::TryFromBytes, FieldBounds::ALL_SELF)
        .inner_extras(extra)
        .build())
}
fn try_gen_trivial_is_bit_valid(ctx: &Ctx, top_level: Trait) -> Option<proc_macro2::TokenStream> {
    // If the top-level trait is `FromBytes` and `Self` has no type parameters,
    // then the `FromBytes` derive will fail compilation if `Self` is not
    // actually soundly `FromBytes`, and so we can rely on that for our
    // `is_bit_valid` impl. It's plausible that we could make changes - or Rust
    // could make changes (such as the "trivial bounds" language feature) - that
    // make this no longer true. To hedge against these, we include an explicit
    // `Self: FromBytes` check in the generated `is_bit_valid`, which is
    // bulletproof.
    //
    // If `ctx.skip_on_error` is true, we can't rely on the `FromBytes` derive
    // to fail compilation if `Self` is not actually soundly `FromBytes`.
    if matches!(top_level, Trait::FromBytes)
        && ctx.ast.generics.params.is_empty()
        && !ctx.skip_on_error
    {
        let zerocopy_crate = &ctx.zerocopy_crate;
        let core = ctx.core_path();
        Some(quote!(
            // SAFETY: See inline.
            #[inline(always)]
            fn is_bit_valid<___ZcAlignment>(
                _candidate: #zerocopy_crate::Maybe<'_, Self, ___ZcAlignment>,
            ) -> #core::primitive::bool
            where
                ___ZcAlignment: #zerocopy_crate::invariant::Alignment,
            {
                if false {
                    fn assert_is_from_bytes<T>()
                    where
                        T: #zerocopy_crate::FromBytes,
                        T: ?#core::marker::Sized,
                    {
                    }

                    assert_is_from_bytes::<Self>();
                }

                // SAFETY: The preceding code only compiles if `Self:
                // FromBytes`. Thus, this code only compiles if all initialized
                // byte sequences represent valid instances of `Self`.
                true
            }
        ))
    } else {
        None
    }
}

/// # Safety
///
/// All initialized bit patterns must be valid for `Self`.
unsafe fn gen_trivial_is_bit_valid_unchecked(ctx: &Ctx) -> proc_macro2::TokenStream {
    let zerocopy_crate = &ctx.zerocopy_crate;
    let core = ctx.core_path();
    quote!(
        // SAFETY: The caller of `gen_trivial_is_bit_valid_unchecked` has
        // promised that all initialized bit patterns are valid for `Self`.
        #[inline(always)]
        fn is_bit_valid<___ZcAlignment>(
            _candidate: #zerocopy_crate::Maybe<'_, Self, ___ZcAlignment>,
        ) -> #core::primitive::bool
        where
            ___ZcAlignment: #zerocopy_crate::invariant::Alignment,
        {
            true
        }
    )
}
