@@ -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
+ 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,8 +284,8 @@ 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 ,
287
+ Generic :: NoBound ( GenericNoBound ( lifetimes , path) ) => PredicateType {
288
+ lifetimes : lifetimes . clone ( ) ,
286
289
bounded_ty : path. clone ( ) ,
287
290
colon_token : <Token ! [ : ] >:: default ( ) ,
288
291
bounds : trait_. where_bounds ( item) ,
@@ -293,21 +296,31 @@ impl DeriveWhere {
293
296
}
294
297
}
295
298
296
- /// Holds a single generic [type](Type) or [type with bound](PredicateType).
299
+ /// Holds the first part of a [`PredicateType`] prior to the `:`. Optionally contains lifetime `for`
300
+ /// bindings.
301
+ #[ derive( Eq , PartialEq ) ]
302
+ pub struct GenericNoBound ( Option < BoundLifetimes > , Type ) ;
303
+ impl Parse for GenericNoBound {
304
+ fn parse ( input : ParseStream ) -> Result < Self > {
305
+ Ok ( Self ( input. parse ( ) ?, input. parse ( ) ?) )
306
+ }
307
+ }
308
+
309
+ /// Holds a single generic [type](GenericNoBound) with optional lifetime bounds or [type with bound](PredicateType).
297
310
#[ derive( Eq , PartialEq ) ]
298
311
pub enum Generic {
299
312
/// Generic type with custom [specified bounds](PredicateType).
300
313
CustomBound ( PredicateType ) ,
301
- /// Generic [type](Type ) which will be bound to the [`DeriveTrait`].
302
- NoBound ( Type ) ,
314
+ /// Generic [type](GenericNoBound ) which will be bound to the [`DeriveTrait`].
315
+ NoBound ( GenericNoBound ) ,
303
316
}
304
317
305
318
impl Parse for Generic {
306
319
fn parse ( input : ParseStream ) -> Result < Self > {
307
320
let fork = input. fork ( ) ;
308
321
309
322
// 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
323
+ // start with an optional lifetime for bound and then Type, so starting with the `WherePredicate` is the easiest way
311
324
// of differentiating them.
312
325
if let Ok ( where_predicate) = WherePredicate :: parse ( & fork) {
313
326
input. advance_to ( & fork) ;
@@ -319,8 +332,8 @@ impl Parse for Generic {
319
332
Err ( Error :: generic ( where_predicate. span ( ) ) )
320
333
}
321
334
} else {
322
- match Type :: parse ( input) {
323
- Ok ( type_ ) => Ok ( Generic :: NoBound ( type_ ) ) ,
335
+ match GenericNoBound :: parse ( input) {
336
+ Ok ( no_bound ) => Ok ( Generic :: NoBound ( no_bound ) ) ,
324
337
Err ( error) => Err ( Error :: generic_syntax ( error. span ( ) , error) ) ,
325
338
}
326
339
}
0 commit comments