Skip to content

Commit

Permalink
[derive] Simplify code, remove obsolete features (#375)
Browse files Browse the repository at this point in the history
Clean up the implementation, especially in `fn impl_block`. Make the
following notable changes:
- Previously, `syn` didn't support parsing macro invocations in const
  generics without the `full` feature enabled. To avoid the compile-time
  overhead of that feature, we worked around it by constructing AST
  nodes manually. `syn` has since added support for this without
  requiring the `full` feature, so we make use of it.
- We used to need to split types into those that transatively depended
  upon type generics (like `[T; 2]`) and those that didn't (like
  `[u8; 2]`). We made a change in #119 that made this distinction
  irrelevant, but we never removed the code to perform the split. In
  this commit, we remove that code. That code was the only reason we
  needed to enable `syn`'s `visit` feature, so we are also able to
  remove that feature dependency.
  • Loading branch information
joshlf committed Sep 12, 2023
1 parent 9803616 commit 04c5363
Show file tree
Hide file tree
Showing 3 changed files with 101 additions and 200 deletions.
2 changes: 1 addition & 1 deletion zerocopy-derive/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ proc-macro = true
[dependencies]
proc-macro2 = "1.0.1"
quote = "1.0.10"
syn = { version = "2", features = ["visit"] }
syn = "2.0.31"

[dev-dependencies]
rustversion = "1.0"
Expand Down
51 changes: 19 additions & 32 deletions zerocopy-derive/src/ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,39 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

use syn::{Data, DataEnum, DataStruct, DataUnion, Field, Fields, Type};
use syn::{Data, DataEnum, DataStruct, DataUnion, Type};

pub trait DataExt {
fn nested_types(&self) -> Vec<&Type>;
/// Extract the types of all fields. For enums, extract the types of fields
/// from each variant.
fn field_types(&self) -> Vec<&Type>;
}

impl DataExt for Data {
fn nested_types(&self) -> Vec<&Type> {
fn field_types(&self) -> Vec<&Type> {
match self {
Data::Struct(strc) => strc.nested_types(),
Data::Enum(enm) => enm.nested_types(),
Data::Union(un) => un.nested_types(),
Data::Struct(strc) => strc.field_types(),
Data::Enum(enm) => enm.field_types(),
Data::Union(un) => un.field_types(),
}
}
}

impl DataExt for DataStruct {
fn nested_types(&self) -> Vec<&Type> {
fields_to_types(&self.fields)
fn field_types(&self) -> Vec<&Type> {
self.fields.iter().map(|f| &f.ty).collect()
}
}

impl DataExt for DataEnum {
fn nested_types(&self) -> Vec<&Type> {
self.variants.iter().map(|var| fields_to_types(&var.fields)).fold(Vec::new(), |mut a, b| {
a.extend(b);
a
})
fn field_types(&self) -> Vec<&Type> {
self.variants.iter().flat_map(|var| &var.fields).map(|f| &f.ty).collect()
}
}

impl DataExt for DataUnion {
fn field_types(&self) -> Vec<&Type> {
self.fields.named.iter().map(|f| &f.ty).collect()
}
}

Expand All @@ -39,24 +44,6 @@ pub trait EnumExt {

impl EnumExt for DataEnum {
fn is_c_like(&self) -> bool {
self.nested_types().is_empty()
self.field_types().is_empty()
}
}

impl DataExt for DataUnion {
fn nested_types(&self) -> Vec<&Type> {
field_iter_to_types(&self.fields.named)
}
}

fn fields_to_types(fields: &Fields) -> Vec<&Type> {
match fields {
Fields::Named(named) => field_iter_to_types(&named.named),
Fields::Unnamed(unnamed) => field_iter_to_types(&unnamed.unnamed),
Fields::Unit => Vec::new(),
}
}

fn field_iter_to_types<'a, I: IntoIterator<Item = &'a Field>>(fields: I) -> Vec<&'a Type> {
fields.into_iter().map(|f| &f.ty).collect()
}

0 comments on commit 04c5363

Please sign in to comment.