Skip to content

Commit

Permalink
[derive] Rename is_c_like -> is_fieldless
Browse files Browse the repository at this point in the history
The implementation of this method checks for the presence of fields.
While this is /similar/ to the concept of a C-like enum, it's not the
same. Fieldless enums are exactly as described: none of their variants
has fields. C-like enums, on the other hand, are more recently referred
to as "unit-only" because their variants are not permitted to contain
parentheses or curly braces. E.g., the following is a fieldless enum,
but is not a C-like/unit-only enum:

  #[repr(u8)]
  enum Foo {
      A,   // This is fine
      B(), // This is not fine
      C{}  // This is not fine
  }

This distinction is important specifically when it comes to
discriminants. The syntax `Foo::A as u8` computes the discriminant value
of the `A` variant. However, `Foo::B` is a type constructor, and thus is
a function. As a result, `Foo::B as u8` computes the address of the
function `Foo::B`.
  • Loading branch information
joshlf committed Jan 21, 2024
1 parent 7fd67a6 commit 8c787b3
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 15 deletions.
4 changes: 2 additions & 2 deletions zerocopy-derive/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ fn map_fields<'a>(
}

pub trait EnumExt {
fn is_c_like(&self) -> bool;
fn is_fieldless(&self) -> bool;
}

impl EnumExt for DataEnum {
fn is_c_like(&self) -> bool {
fn is_fieldless(&self) -> bool {
self.fields().is_empty()
}
}
26 changes: 13 additions & 13 deletions zerocopy-derive/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,8 +413,8 @@ fn derive_from_zeros_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_macro
// - one of the variants has a discriminant of `0`

fn derive_from_zeros_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement FromZeros")
if !enm.is_fieldless() {
return Error::new_spanned(ast, "only field-less enums can implement FromZeros")
.to_compile_error();
}

Expand Down Expand Up @@ -475,8 +475,8 @@ fn derive_from_bytes_struct(ast: &DeriveInput, strct: &DataStruct) -> proc_macro
// this would require ~4 billion enum variants, which obviously isn't a thing.

fn derive_from_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement FromBytes")
if !enm.is_fieldless() {
return Error::new_spanned(ast, "only field-less enums can implement FromBytes")
.to_compile_error();
}

Expand Down Expand Up @@ -577,11 +577,11 @@ const STRUCT_UNION_AS_BYTES_CFG: Config<StructRepr> = Config {
disallowed_but_legal_combinations: &[],
};

// An enum is `IntoBytes` if it is C-like and has a defined repr.
// An enum is `IntoBytes` if it is field-less and has a defined repr.

fn derive_as_bytes_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement IntoBytes")
if !enm.is_fieldless() {
return Error::new_spanned(ast, "only field-less enums can implement IntoBytes")
.to_compile_error();
}

Expand Down Expand Up @@ -668,8 +668,8 @@ const STRUCT_UNION_UNALIGNED_CFG: Config<StructRepr> = Config {
// - `repr(u8)` or `repr(i8)`

fn derive_unaligned_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::TokenStream {
if !enm.is_c_like() {
return Error::new_spanned(ast, "only C-like enums can implement Unaligned")
if !enm.is_fieldless() {
return Error::new_spanned(ast, "only field-less enums can implement Unaligned")
.to_compile_error();
}

Expand All @@ -678,10 +678,10 @@ fn derive_unaligned_enum(ast: &DeriveInput, enm: &DataEnum) -> proc_macro2::Toke
// requirement.
let _: Vec<repr::EnumRepr> = try_or_print!(ENUM_UNALIGNED_CFG.validate_reprs(ast));

// C-like enums cannot currently have type parameters, so this value of true
// for `require_trait_bound_on_field_types` doesn't really do anything. But
// it's marginally more future-proof in case that restriction is lifted in
// the future.
// field-less enums cannot currently have type parameters, so this value of
// true for `require_trait_bound_on_field_types` doesn't really do anything.
// But it's marginally more future-proof in case that restriction is lifted
// in the future.
impl_block(ast, enm, Trait::Unaligned, RequireBoundedFields::Yes, false, None, None)
}

Expand Down

0 comments on commit 8c787b3

Please sign in to comment.