Skip to content

Commit

Permalink
Fix associated types only working for first generic parameter
Browse files Browse the repository at this point in the history
Also, removes extraneous `where for`
  • Loading branch information
Osspial committed Apr 12, 2018
1 parent def8d6e commit 4415d10
Show file tree
Hide file tree
Showing 2 changed files with 23 additions and 12 deletions.
27 changes: 15 additions & 12 deletions serde_derive/src/bound.rs
Original file line number Diff line number Diff line change
Expand Up @@ -59,24 +59,27 @@ pub fn with_where_predicates_from_fields<F, W>(
) -> syn::Generics
where
F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>,
W: for<'a> Fn(&attr::Field) -> bool,
W: Fn(&attr::Field) -> bool,
{
let predicates = cont.data
.all_fields()
.flat_map(|field| {
let field_ty = field.ty;
let field_bound: Option<syn::WherePredicate> = match (field_ty, gen_bound_where(&field.attrs)) {
(&syn::Type::Path(ref ty_path), true) => match (ty_path.path.segments.first(), generics.params.first()) {
(Some(syn::punctuated::Pair::Punctuated(ref t, _)), Some(syn::punctuated::Pair::End(&syn::GenericParam::Type(ref generic_ty))))
if generic_ty.ident == t.ident =>
{
let predicate: syn::WherePredicate = parse_quote!(#field_ty: #trait_bound);
Some(predicate)
},
_ => None
},
(_, _) => None
let matching_generic = |t: &syn::PathSegment, g| match g {
&syn::GenericParam::Type(ref generic_ty)
if generic_ty.ident == t.ident => true,
_ => false
};

let mut field_bound: Option<syn::WherePredicate> = None;
if let &syn::Type::Path(ref ty_path) = field_ty {
field_bound = match (gen_bound_where(&field.attrs), ty_path.path.segments.first()) {
(true, Some(syn::punctuated::Pair::Punctuated(ref t, _)))
if generics.params.iter().fold(false, |b, g| b || matching_generic(t, g))
=> Some(parse_quote!(#field_ty: #trait_bound)),
(_, _) => None
};
}
field_bound.into_iter().chain(from_field(&field.attrs).into_iter().flat_map(|predicates| predicates.to_vec()))
});

Expand Down
8 changes: 8 additions & 0 deletions test_suite/tests/test_gen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -555,6 +555,14 @@ fn test_gen() {
}

assert::<AssocDerive<NoSerdeImpl>>();

#[derive(Serialize, Deserialize)]
struct AssocDeriveMulti<S, T: AssocSerde> {
s: S,
assoc: T::Assoc,
}

assert::<AssocDeriveMulti<i32, NoSerdeImpl>>();
}

//////////////////////////////////////////////////////////////////////////
Expand Down

0 comments on commit 4415d10

Please sign in to comment.