@@ -7,7 +7,7 @@ use syn::{
7
7
parse:: { discouraged:: Speculative , Parse , ParseStream } ,
8
8
punctuated:: Punctuated ,
9
9
spanned:: Spanned ,
10
- Attribute , Data , Ident , Meta , Path , PredicateType , Result , Token , TraitBound ,
10
+ Attribute , BoundLifetimes , Data , Ident , Meta , Path , PredicateType , Result , Token , TraitBound ,
11
11
TraitBoundModifier , Type , TypeParamBound , TypePath , WhereClause , WherePredicate ,
12
12
} ;
13
13
@@ -241,7 +241,10 @@ impl DeriveWhere {
241
241
/// Returns `true` if the given generic type parameter if present.
242
242
pub fn has_type_param ( & self , type_param : & Ident ) -> bool {
243
243
self . generics . iter ( ) . any ( |generic| match generic {
244
- Generic :: NoBound ( Type :: Path ( TypePath { qself : None , path } ) ) => {
244
+ Generic :: NoBound ( GenericNoBound {
245
+ lifetimes : _,
246
+ ty : Type :: Path ( TypePath { qself : None , path } ) ,
247
+ } ) => {
245
248
if let Some ( ident) = path. get_ident ( ) {
246
249
ident == type_param
247
250
} else {
@@ -281,9 +284,12 @@ impl DeriveWhere {
281
284
. predicates
282
285
. push ( WherePredicate :: Type ( match generic {
283
286
Generic :: CustomBound ( type_bound) => type_bound. clone ( ) ,
284
- Generic :: NoBound ( path) => PredicateType {
285
- lifetimes : None ,
286
- bounded_ty : path. clone ( ) ,
287
+ Generic :: NoBound ( GenericNoBound {
288
+ lifetimes : bound_lifetimes,
289
+ ty,
290
+ } ) => PredicateType {
291
+ lifetimes : bound_lifetimes. clone ( ) ,
292
+ bounded_ty : ty. clone ( ) ,
287
293
colon_token : <Token ! [ : ] >:: default ( ) ,
288
294
bounds : trait_. where_bounds ( item) ,
289
295
} ,
@@ -293,22 +299,43 @@ impl DeriveWhere {
293
299
}
294
300
}
295
301
296
- /// Holds a single generic [type](Type) or [type with bound](PredicateType).
302
+ /// Holds the first part of a [`PredicateType`] prior to the `:`. Optionally
303
+ /// contains lifetime `for` bindings.
304
+ #[ derive( Eq , PartialEq ) ]
305
+ pub struct GenericNoBound {
306
+ /// Any `for<'a, 'b, 'etc>` bindings for the type.
307
+ lifetimes : Option < BoundLifetimes > ,
308
+ /// The type bound to the [`DeriveTrait`].
309
+ ty : Type ,
310
+ }
311
+
312
+ impl Parse for GenericNoBound {
313
+ fn parse ( input : ParseStream ) -> Result < Self > {
314
+ Ok ( Self {
315
+ lifetimes : input. parse ( ) ?,
316
+ ty : input. parse ( ) ?,
317
+ } )
318
+ }
319
+ }
320
+
321
+ /// Holds a single generic [type](GenericNoBound) with optional lifetime bounds
322
+ /// or [type with bound](PredicateType).
297
323
#[ derive( Eq , PartialEq ) ]
298
324
pub enum Generic {
299
325
/// Generic type with custom [specified bounds](PredicateType).
300
326
CustomBound ( PredicateType ) ,
301
- /// Generic [type](Type) which will be bound to the [`DeriveTrait`].
302
- NoBound ( Type ) ,
327
+ /// Generic [type](GenericNoBound) which will be bound to the
328
+ /// [`DeriveTrait`].
329
+ NoBound ( GenericNoBound ) ,
303
330
}
304
331
305
332
impl Parse for Generic {
306
333
fn parse ( input : ParseStream ) -> Result < Self > {
307
334
let fork = input. fork ( ) ;
308
335
309
336
// Try to parse input as a `WherePredicate`. The problem is, both expressions
310
- // start with a Type, so starting with the `WherePredicate` is the easiest way
311
- // of differentiating them.
337
+ // start with an optional lifetime for bound and then Type, so starting with the
338
+ // `WherePredicate` is the easiest way of differentiating them.
312
339
if let Ok ( where_predicate) = WherePredicate :: parse ( & fork) {
313
340
input. advance_to ( & fork) ;
314
341
@@ -319,8 +346,8 @@ impl Parse for Generic {
319
346
Err ( Error :: generic ( where_predicate. span ( ) ) )
320
347
}
321
348
} else {
322
- match Type :: parse ( input) {
323
- Ok ( type_ ) => Ok ( Generic :: NoBound ( type_ ) ) ,
349
+ match GenericNoBound :: parse ( input) {
350
+ Ok ( no_bound ) => Ok ( Generic :: NoBound ( no_bound ) ) ,
324
351
Err ( error) => Err ( Error :: generic_syntax ( error. span ( ) , error) ) ,
325
352
}
326
353
}
0 commit comments