@@ -7,7 +7,7 @@ use syn::{
77 parse:: { discouraged:: Speculative , Parse , ParseStream } ,
88 punctuated:: Punctuated ,
99 spanned:: Spanned ,
10- Attribute , Data , Ident , Meta , NestedMeta , Path , PredicateType , Result , Token , TraitBound ,
10+ Attribute , Data , Ident , Meta , Path , PredicateType , Result , Token , TraitBound ,
1111 TraitBoundModifier , Type , TypeParamBound , TypePath , WhereClause , WherePredicate ,
1212} ;
1313
@@ -33,61 +33,57 @@ impl ItemAttr {
3333 let mut incomparables = Vec :: new ( ) ;
3434
3535 for attr in attrs {
36- if attr. path . is_ident ( DERIVE_WHERE ) {
37- if let Ok ( meta) = attr. parse_meta ( ) {
38- if let Meta :: List ( list) = meta {
39- match list. nested . len ( ) {
36+ if attr. path ( ) . is_ident ( DERIVE_WHERE ) {
37+ if let Meta :: List ( list) = & attr. meta {
38+ if let Ok ( nested) =
39+ list. parse_args_with ( Punctuated :: < Meta , Token ! [ , ] > :: parse_terminated)
40+ {
41+ match nested. len ( ) {
4042 // Don't allow an empty list.
4143 0 => return Err ( Error :: empty ( list. span ( ) ) ) ,
4244 // Check for `skip_inner` if list only has one item.
43- 1 => match list
44- . nested
45- . into_iter ( )
46- . next ( )
47- . expect ( "unexpected empty list" )
48- {
49- NestedMeta :: Meta ( meta) => {
50- if meta. path ( ) . is_ident ( Skip :: SKIP_INNER ) {
51- // Don't allow `skip_inner` on the item level for enums.
52- if let Data :: Enum ( _) = data {
53- return Err ( Error :: option_enum_skip_inner ( meta. span ( ) ) ) ;
54- }
55-
56- // Don't parse `Skip` yet, because it needs access to all
57- // `DeriveWhere`s.
58- skip_inners. push ( meta) ;
59- } else if meta. path ( ) . is_ident ( Incomparable :: INCOMPARABLE ) {
60- // Needs to be parsed after all traits are known.
61- incomparables. push ( meta)
62- } else if meta. path ( ) . is_ident ( "crate" ) {
63- // Do nothing, we checked this before
64- // already.
65- }
66- // The list can have one item but still not be the `skip_inner`
67- // attribute, continue with parsing `DeriveWhere`.
68- else {
69- self_
70- . derive_wheres
71- . push ( DeriveWhere :: from_attr ( span, data, attr) ?) ;
45+ 1 => {
46+ let meta =
47+ nested. into_iter ( ) . next ( ) . expect ( "unexpected empty list" ) ;
48+
49+ if meta. path ( ) . is_ident ( Skip :: SKIP_INNER ) {
50+ // Don't allow `skip_inner` on the item level for enums.
51+ if let Data :: Enum ( _) = data {
52+ return Err ( Error :: option_enum_skip_inner ( meta. span ( ) ) ) ;
7253 }
54+
55+ // Don't parse `Skip` yet, because it needs access to all
56+ // `DeriveWhere`s.
57+ skip_inners. push ( meta) ;
58+ } else if meta. path ( ) . is_ident ( Incomparable :: INCOMPARABLE ) {
59+ // Needs to be parsed after all traits are known.
60+ incomparables. push ( meta)
61+ } else if meta. path ( ) . is_ident ( "crate" ) {
62+ // Do nothing, we checked this before
63+ // already.
7364 }
74- nested_meta => {
75- return Err ( Error :: option_syntax ( nested_meta. span ( ) ) )
65+ // The list can have one item but still not be the `skip_inner`
66+ // attribute, continue with parsing `DeriveWhere`.
67+ else {
68+ self_
69+ . derive_wheres
70+ . push ( DeriveWhere :: from_attr ( span, data, attr) ?) ;
7671 }
77- } ,
72+ }
7873 _ => self_
7974 . derive_wheres
8075 . push ( DeriveWhere :: from_attr ( span, data, attr) ?) ,
8176 }
82- } else {
83- return Err ( Error :: option_syntax ( meta. span ( ) ) ) ;
8477 }
85- }
86- // Anything that can't be parsed by `Meta`, is because `A, B; C` isn't valid syntax.
87- else {
88- self_
89- . derive_wheres
90- . push ( DeriveWhere :: from_attr ( span, data, attr) ?)
78+ // Anything list that isn't using `,` as seperator, is because we expect
79+ // `A, B; C`.
80+ else {
81+ self_
82+ . derive_wheres
83+ . push ( DeriveWhere :: from_attr ( span, data, attr) ?)
84+ }
85+ } else {
86+ return Err ( Error :: option_syntax ( attr. meta . span ( ) ) ) ;
9187 }
9288 }
9389 }
@@ -479,15 +475,18 @@ impl DeriveTrait {
479475 }
480476 }
481477
482- match meta {
478+ match & meta {
483479 Meta :: Path ( path) => Ok ( ( path. span ( ) , trait_. default_derive_trait ( ) ) ) ,
484480 Meta :: List ( list) => {
485- if list. nested . is_empty ( ) {
481+ let nested =
482+ list. parse_args_with ( Punctuated :: < Meta , Token ! [ , ] > :: parse_terminated) ?;
483+
484+ if nested. is_empty ( ) {
486485 return Err ( Error :: option_empty ( list. span ( ) ) ) ;
487486 }
488487
489488 // This will return an error if no options are supported.
490- Ok ( ( list. span ( ) , trait_. parse_derive_trait ( list ) ?) )
489+ Ok ( ( list. span ( ) , trait_. parse_derive_trait ( meta . span ( ) , nested ) ?) )
491490 }
492491 Meta :: NameValue ( name_value) => Err ( Error :: option_syntax ( name_value. span ( ) ) ) ,
493492 }
0 commit comments