support deriving Zeroable for fieldless enums (#233)

* support deriving Zeroable for fieldless enums

* add test for deriving Zeroable on enum
This commit is contained in:
Tom Dohrmann 2024-05-28 19:53:32 +02:00 committed by GitHub
parent 9a27279008
commit a630404e18
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
2 changed files with 41 additions and 1 deletions

View File

@ -124,11 +124,43 @@ impl Derivable for Zeroable {
Ok(syn::parse_quote!(#crate_name::Zeroable))
}
fn check_attributes(ty: &Data, attributes: &[Attribute]) -> Result<()> {
let repr = get_repr(attributes)?;
match ty {
Data::Struct(_) => Ok(()),
Data::Enum(DataEnum { variants,.. }) => {
if !repr.repr.is_integer() {
bail!("Zeroable requires the enum to be an explicit #[repr(Int)]")
}
if variants.iter().any(|variant| !variant.fields.is_empty()) {
bail!("Only fieldless enums are supported for Zeroable")
}
let iter = VariantDiscriminantIterator::new(variants.iter());
let mut has_zero_variant = false;
for res in iter {
let discriminant = res?;
if discriminant == 0 {
has_zero_variant = true;
break;
}
}
if !has_zero_variant {
bail!("No variant's discriminant is 0")
}
Ok(())
},
Data::Union(_) => Ok(())
}
}
fn asserts(input: &DeriveInput, crate_name: &TokenStream) -> Result<TokenStream> {
match &input.data {
Data::Union(_) => Ok(quote!()), // unions are always `Zeroable`
Data::Struct(_) => generate_fields_are_trait(input, Self::ident(input, crate_name)?),
Data::Enum(_) => bail!("Deriving Zeroable is not supported for enums"),
Data::Enum(_) => Ok(quote!()),
}
}

View File

@ -50,6 +50,14 @@ struct ZeroGeneric<T: bytemuck::Zeroable> {
a: T,
}
#[derive(Zeroable)]
#[repr(u8)]
enum ZeroEnum {
A = 0,
B = 1,
C = 2,
}
#[derive(TransparentWrapper)]
#[repr(transparent)]
struct TransparentSingle {