@@ -8,15 +8,15 @@ use field::SequenceField;
8
8
use proc_macro2:: TokenStream ;
9
9
use proc_macro_error:: abort;
10
10
use quote:: quote;
11
- use syn:: { DeriveInput , Ident , Lifetime } ;
11
+ use syn:: { DeriveInput , GenericParam , Generics , Ident , Lifetime , LifetimeParam } ;
12
12
13
13
/// Derive the `Sequence` trait for a struct
14
14
pub ( crate ) struct DeriveSequence {
15
15
/// Name of the sequence struct.
16
16
ident : Ident ,
17
17
18
- /// Lifetime of the struct.
19
- lifetime : Option < Lifetime > ,
18
+ /// Generics of the struct.
19
+ generics : Generics ,
20
20
21
21
/// Fields of the struct.
22
22
fields : Vec < SequenceField > ,
@@ -33,13 +33,6 @@ impl DeriveSequence {
33
33
) ,
34
34
} ;
35
35
36
- // TODO(tarcieri): properly handle multiple lifetimes
37
- let lifetime = input
38
- . generics
39
- . lifetimes ( )
40
- . next ( )
41
- . map ( |lt| lt. lifetime . clone ( ) ) ;
42
-
43
36
let type_attrs = TypeAttrs :: parse ( & input. attrs ) ;
44
37
45
38
let fields = data
@@ -50,27 +43,33 @@ impl DeriveSequence {
50
43
51
44
Self {
52
45
ident : input. ident ,
53
- lifetime,
46
+ // lifetime,
47
+ generics : input. generics . clone ( ) ,
54
48
fields,
55
49
}
56
50
}
57
51
58
52
/// Lower the derived output into a [`TokenStream`].
59
53
pub fn to_tokens ( & self ) -> TokenStream {
60
54
let ident = & self . ident ;
61
-
62
- let lifetime = match self . lifetime {
63
- Some ( ref lifetime) => quote ! ( #lifetime) ,
64
- None => default_lifetime ( ) ,
55
+ let mut generics = self . generics . clone ( ) ;
56
+
57
+ // Use the first lifetime parameter as lifetime for Decode/Encode lifetime
58
+ // if none found, add one.
59
+ let lifetime: Lifetime = if let Some ( lt) = generics. lifetimes ( ) . next ( ) {
60
+ lt. lifetime . clone ( )
61
+ } else {
62
+ let lifetime = default_lifetime ( ) ;
63
+ generics. params . insert (
64
+ 0 ,
65
+ GenericParam :: Lifetime ( LifetimeParam :: new ( lifetime. clone ( ) ) ) ,
66
+ ) ;
67
+ lifetime
65
68
} ;
66
69
67
- // Lifetime parameters
68
- // TODO(tarcieri): support multiple lifetimes
69
- let lt_params = self
70
- . lifetime
71
- . as_ref ( )
72
- . map ( |_| lifetime. clone ( ) )
73
- . unwrap_or_default ( ) ;
70
+ // We may or may not have inserted a lifetime.
71
+ let ( _impl_generics, ty_generics, where_clause) = self . generics . split_for_impl ( ) ;
72
+ let ( impl_generics, _ty_generics, _where_clause) = generics. split_for_impl ( ) ;
74
73
75
74
let mut decode_body = Vec :: new ( ) ;
76
75
let mut decode_result = Vec :: new ( ) ;
@@ -87,7 +86,7 @@ impl DeriveSequence {
87
86
}
88
87
89
88
quote ! {
90
- impl <#lifetime> :: der:: DecodeValue <#lifetime> for #ident<#lt_params> {
89
+ impl #impl_generics :: der:: DecodeValue <#lifetime> for #ident #ty_generics #where_clause {
91
90
fn decode_value<R : :: der:: Reader <#lifetime>>(
92
91
reader: & mut R ,
93
92
header: :: der:: Header ,
@@ -104,7 +103,7 @@ impl DeriveSequence {
104
103
}
105
104
}
106
105
107
- impl <#lifetime> :: der:: EncodeValue for #ident<#lt_params> {
106
+ impl #impl_generics :: der:: EncodeValue for #ident #ty_generics #where_clause {
108
107
fn value_len( & self ) -> :: der:: Result <:: der:: Length > {
109
108
use :: der:: Encode as _;
110
109
@@ -122,7 +121,7 @@ impl DeriveSequence {
122
121
}
123
122
}
124
123
125
- impl <#lifetime> :: der:: Sequence <#lifetime> for #ident<#lt_params> { }
124
+ impl #impl_generics :: der:: Sequence <#lifetime> for #ident #ty_generics #where_clause { }
126
125
}
127
126
}
128
127
}
0 commit comments