Skip to content

Commit 939e375

Browse files
committed
Address review
1 parent 96e247f commit 939e375

File tree

11 files changed

+52
-56
lines changed

11 files changed

+52
-56
lines changed

src/attr/field.rs

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Attribute parsing for fields.
22
3-
use syn::{punctuated::Punctuated, spanned::Spanned, Attribute, Meta, Result, Token};
3+
use syn::{spanned::Spanned, Attribute, Meta, Result};
44

5-
use crate::{DeriveWhere, Error, Skip, DERIVE_WHERE};
5+
use crate::{util::MetaListExt, DeriveWhere, Error, Skip, DERIVE_WHERE};
66
#[cfg(feature = "zeroize")]
77
use crate::{Trait, TraitImpl, ZeroizeFqs};
88

@@ -45,11 +45,7 @@ impl FieldAttr {
4545
debug_assert!(meta.path().is_ident(DERIVE_WHERE));
4646

4747
if let Meta::List(list) = meta {
48-
let nested = list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?;
49-
50-
if nested.is_empty() {
51-
return Err(Error::empty(list.span()));
52-
}
48+
let nested = list.parse_non_empty_nested_metas()?;
5349

5450
for meta in &nested {
5551
if meta.path().is_ident(Skip::SKIP) {

src/attr/item.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,10 @@ use syn::{
1111
TraitBoundModifier, Type, TypeParamBound, TypePath, WhereClause, WherePredicate,
1212
};
1313

14-
use crate::{util, Error, Incomparable, Item, Skip, SkipGroup, Trait, TraitImpl, DERIVE_WHERE};
14+
use crate::{
15+
util::{self, MetaListExt},
16+
Error, Incomparable, Item, Skip, SkipGroup, Trait, TraitImpl, DERIVE_WHERE,
17+
};
1518

1619
/// Attributes on item.
1720
#[derive(Default)]
@@ -163,6 +166,8 @@ impl DeriveWhere {
163166
let mut generics = Vec::new();
164167

165168
// Check for an empty list is already done in `ItemAttr::from_attrs`.
169+
assert!(!input.is_empty());
170+
166171
while !input.is_empty() {
167172
// Start with parsing a trait.
168173
// Not checking for duplicates here, we do that after merging `derive_where`s
@@ -478,12 +483,7 @@ impl DeriveTrait {
478483
match &meta {
479484
Meta::Path(path) => Ok((path.span(), trait_.default_derive_trait())),
480485
Meta::List(list) => {
481-
let nested =
482-
list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?;
483-
484-
if nested.is_empty() {
485-
return Err(Error::option_empty(list.span()));
486-
}
486+
let nested = list.parse_non_empty_nested_metas()?;
487487

488488
// This will return an error if no options are supported.
489489
Ok((list.span(), trait_.parse_derive_trait(meta.span(), nested)?))

src/attr/skip.rs

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@
22
33
use std::default::Default;
44

5-
use syn::{punctuated::Punctuated, spanned::Spanned, Meta, Path, Result, Token};
5+
use syn::{spanned::Spanned, Meta, Path, Result};
66

7-
use crate::{DeriveWhere, Error, Trait};
7+
use crate::{util::MetaListExt, DeriveWhere, Error, Trait};
88

99
/// Stores what [`Trait`]s to skip this field or variant for.
1010
#[cfg_attr(test, derive(Debug))]
@@ -78,13 +78,7 @@ impl Skip {
7878
}
7979
}
8080
Meta::List(list) => {
81-
let nested =
82-
list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?;
83-
84-
// Don't allow an empty list.
85-
if nested.is_empty() {
86-
return Err(Error::option_empty(list.span()));
87-
}
81+
let nested = list.parse_non_empty_nested_metas()?;
8882

8983
// Get traits already set to be skipped.
9084
let traits = match self {

src/attr/variant.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,8 @@
11
//! Attribute parsing for variants.
22
3-
use syn::{
4-
punctuated::Punctuated, spanned::Spanned, Attribute, Fields, Meta, Result, Token, Variant,
5-
};
3+
use syn::{spanned::Spanned, Attribute, Fields, Meta, Result, Variant};
64

7-
use crate::{Default, DeriveWhere, Error, Incomparable, Skip, DERIVE_WHERE};
5+
use crate::{util::MetaListExt, Default, DeriveWhere, Error, Incomparable, Skip, DERIVE_WHERE};
86

97
/// Attributes on variant.
108
#[derive(Default)]
@@ -46,7 +44,7 @@ impl VariantAttr {
4644
debug_assert!(meta.path().is_ident(DERIVE_WHERE));
4745

4846
if let Meta::List(list) = meta {
49-
let nested = list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?;
47+
let nested = list.parse_non_empty_nested_metas()?;
5048

5149
if nested.is_empty() {
5250
return Err(Error::empty(list.span()));

src/attr/zeroize_fqs.rs

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Attribute parsing for the `Zeroize(fqs)` option.
22
3-
use syn::{punctuated::Punctuated, spanned::Spanned, Meta, Result, Token};
3+
use syn::{spanned::Spanned, Meta, Result};
44

5-
use crate::{DeriveWhere, Error, Trait, TraitImpl};
5+
use crate::{util::MetaListExt, DeriveWhere, Error, Trait, TraitImpl};
66

77
/// Stores if this field should use FQS to call [`Zeroize::zeroize`](https://docs.rs/zeroize/latest/zeroize/trait.Zeroize.html#tymethod.zeroize).
88
#[derive(Default)]
@@ -26,12 +26,7 @@ impl ZeroizeFqs {
2626

2727
match meta {
2828
Meta::List(list) => {
29-
let nested =
30-
list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?;
31-
32-
if nested.is_empty() {
33-
return Err(Error::option_empty(list.span()));
34-
}
29+
let nested = list.parse_non_empty_nested_metas()?;
3530

3631
for meta in &nested {
3732
if let Meta::Path(path) = meta {

src/lib.rs

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -393,10 +393,10 @@ use std::{borrow::Cow, iter};
393393
use proc_macro2::TokenStream;
394394
use quote::{quote, quote_spanned, ToTokens};
395395
use syn::{
396-
punctuated::Punctuated, spanned::Spanned, Attribute, DataEnum, DataStruct, DataUnion,
397-
DeriveInput, Expr, ExprLit, ExprPath, Fields, FieldsNamed, FieldsUnnamed, Generics, Lit, Meta,
398-
Path, Token, Variant,
396+
spanned::Spanned, Attribute, DataEnum, DataStruct, DataUnion, DeriveInput, Expr, ExprLit,
397+
ExprPath, Fields, FieldsNamed, FieldsUnnamed, Generics, Lit, Meta, Path, Result, Variant,
399398
};
399+
use util::MetaListExt;
400400

401401
#[cfg(feature = "zeroize")]
402402
use self::attr::ZeroizeFqs;
@@ -476,16 +476,14 @@ pub fn derive_where(
476476
}
477477

478478
/// Convenient way to deal with [`Result`] for [`derive_where()`].
479-
fn derive_where_internal(mut item: DeriveInput) -> Result<TokenStream, syn::Error> {
479+
fn derive_where_internal(mut item: DeriveInput) -> Result<TokenStream> {
480480
let mut crate_ = None;
481481

482482
// Search for `crate` option.
483483
for attr in &item.attrs {
484484
if attr.path().is_ident(DERIVE_WHERE) {
485485
if let Meta::List(list) = &attr.meta {
486-
if let Ok(nested) =
487-
list.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)
488-
{
486+
if let Ok(nested) = list.parse_non_empty_nested_metas() {
489487
if nested.len() == 1 {
490488
let meta = nested.into_iter().next().expect("unexpected empty list");
491489

src/util.rs

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,12 @@
11
//! Utility functions.
22
33
use proc_macro2::Span;
4-
use syn::{punctuated::Punctuated, Ident, Path, PathArguments, PathSegment, Token};
4+
use syn::{
5+
punctuated::Punctuated, spanned::Spanned, Ident, Meta, MetaList, Path, PathArguments,
6+
PathSegment, Result, Token,
7+
};
8+
9+
use crate::error::Error;
510

611
/// Convenience type to return two possible values.
712
pub enum Either<L, R> {
@@ -49,3 +54,21 @@ pub fn path_from_root_and_strs(root: Path, segments: &[&str]) -> Path {
4954
.collect(),
5055
}
5156
}
57+
58+
/// Extension for [`MetaList`].
59+
pub trait MetaListExt {
60+
/// Shorthand for parsing a [`MetaList`] into a list of [`Meta`]s.
61+
fn parse_non_empty_nested_metas(&self) -> Result<Punctuated<Meta, Token![,]>>;
62+
}
63+
64+
impl MetaListExt for MetaList {
65+
fn parse_non_empty_nested_metas(&self) -> Result<Punctuated<Meta, Token![,]>> {
66+
let list = self.parse_args_with(Punctuated::<Meta, Token![,]>::parse_terminated)?;
67+
68+
if list.is_empty() {
69+
return Err(Error::option_empty(self.span()));
70+
}
71+
72+
Ok(list)
73+
}
74+
}

tests/ui/not-zeroize/item_option_syntax.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ use derive_where::derive_where;
44

55
#[derive_where = "invalid"]
66
struct WrongAttributeSyntax<T>(PhantomData<T>);
7+
8+
fn main() {}

tests/ui/not-zeroize/item_option_syntax.stderr

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,3 @@ error: unsupported trait syntax, expected one of Clone, Copy, Debug, Default, Eq
99
|
1010
5 | #[derive_where = "invalid"]
1111
| ^^^^^^^^^
12-
13-
error[E0601]: `main` function not found in crate `$CRATE`
14-
--> tests/ui/not-zeroize/item_option_syntax.rs:6:48
15-
|
16-
6 | struct WrongAttributeSyntax<T>(PhantomData<T>);
17-
| ^ consider adding a `main` function to `$DIR/tests/ui/not-zeroize/item_option_syntax.rs`

tests/ui/zeroize/item_option_syntax.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,5 @@ use derive_where::derive_where;
44

55
#[derive_where = "invalid"]
66
struct WrongAttributeSyntax<T>(PhantomData<T>);
7+
8+
fn main() {}

0 commit comments

Comments
 (0)