Skip to content

Commit 65934e7

Browse files
committed
der_derive: handle type generics in sequence
1 parent b1b6b73 commit 65934e7

File tree

3 files changed

+30
-30
lines changed

3 files changed

+30
-30
lines changed

der/derive/src/choice.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,10 @@ impl DeriveChoice {
6161

6262
let lifetime = match self.lifetime {
6363
Some(ref lifetime) => quote!(#lifetime),
64-
None => default_lifetime(),
64+
None => {
65+
let lifetime = default_lifetime();
66+
quote!(#lifetime)
67+
}
6568
};
6669

6770
// Lifetime parameters

der/derive/src/lib.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -141,13 +141,11 @@ use crate::{
141141
use proc_macro::TokenStream;
142142
use proc_macro2::Span;
143143
use proc_macro_error::proc_macro_error;
144-
use quote::quote;
145144
use syn::{parse_macro_input, DeriveInput, Lifetime};
146145

147146
/// Get the default lifetime.
148-
fn default_lifetime() -> proc_macro2::TokenStream {
149-
let lifetime = Lifetime::new("'__der_lifetime", Span::call_site());
150-
quote!(#lifetime)
147+
fn default_lifetime() -> Lifetime {
148+
Lifetime::new("'__der_lifetime", Span::call_site())
151149
}
152150

153151
/// Derive the [`Choice`][1] trait on an `enum`.

der/derive/src/sequence.rs

+24-25
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@ use field::SequenceField;
88
use proc_macro2::TokenStream;
99
use proc_macro_error::abort;
1010
use quote::quote;
11-
use syn::{DeriveInput, Ident, Lifetime};
11+
use syn::{DeriveInput, GenericParam, Generics, Ident, Lifetime, LifetimeParam};
1212

1313
/// Derive the `Sequence` trait for a struct
1414
pub(crate) struct DeriveSequence {
1515
/// Name of the sequence struct.
1616
ident: Ident,
1717

18-
/// Lifetime of the struct.
19-
lifetime: Option<Lifetime>,
18+
/// Generics of the struct.
19+
generics: Generics,
2020

2121
/// Fields of the struct.
2222
fields: Vec<SequenceField>,
@@ -33,13 +33,6 @@ impl DeriveSequence {
3333
),
3434
};
3535

36-
// TODO(tarcieri): properly handle multiple lifetimes
37-
let lifetime = input
38-
.generics
39-
.lifetimes()
40-
.next()
41-
.map(|lt| lt.lifetime.clone());
42-
4336
let type_attrs = TypeAttrs::parse(&input.attrs);
4437

4538
let fields = data
@@ -50,27 +43,33 @@ impl DeriveSequence {
5043

5144
Self {
5245
ident: input.ident,
53-
lifetime,
46+
// lifetime,
47+
generics: input.generics.clone(),
5448
fields,
5549
}
5650
}
5751

5852
/// Lower the derived output into a [`TokenStream`].
5953
pub fn to_tokens(&self) -> TokenStream {
6054
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
6568
};
6669

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();
7473

7574
let mut decode_body = Vec::new();
7675
let mut decode_result = Vec::new();
@@ -87,7 +86,7 @@ impl DeriveSequence {
8786
}
8887

8988
quote! {
90-
impl<#lifetime> ::der::DecodeValue<#lifetime> for #ident<#lt_params> {
89+
impl #impl_generics ::der::DecodeValue<#lifetime> for #ident #ty_generics #where_clause {
9190
fn decode_value<R: ::der::Reader<#lifetime>>(
9291
reader: &mut R,
9392
header: ::der::Header,
@@ -104,7 +103,7 @@ impl DeriveSequence {
104103
}
105104
}
106105

107-
impl<#lifetime> ::der::EncodeValue for #ident<#lt_params> {
106+
impl #impl_generics ::der::EncodeValue for #ident #ty_generics #where_clause {
108107
fn value_len(&self) -> ::der::Result<::der::Length> {
109108
use ::der::Encode as _;
110109

@@ -122,7 +121,7 @@ impl DeriveSequence {
122121
}
123122
}
124123

125-
impl<#lifetime> ::der::Sequence<#lifetime> for #ident<#lt_params> {}
124+
impl #impl_generics ::der::Sequence<#lifetime> for #ident #ty_generics #where_clause {}
126125
}
127126
}
128127
}

0 commit comments

Comments
 (0)