diff --git a/serde_derive/src/bound.rs b/serde_derive/src/bound.rs index 1506a9ba..ceb4c8b6 100644 --- a/serde_derive/src/bound.rs +++ b/serde_derive/src/bound.rs @@ -9,7 +9,7 @@ use std::collections::HashSet; use syn::{self, visit}; -use syn::punctuated::Punctuated; +use syn::punctuated::{Punctuated, Pair}; use internals::ast::{Data, Container}; use internals::attr; @@ -61,33 +61,35 @@ where F: Fn(&attr::Field) -> Option<&[syn::WherePredicate]>, W: Fn(&attr::Field) -> bool, { - let predicates = cont.data - .all_fields() - .flat_map(|field| { - let field_ty = field.ty; - let matching_generic = |t: &syn::PathSegment, g: &syn::GenericParam| match *g { - syn::GenericParam::Type(ref generic_ty) - if generic_ty.ident == t.ident => true, - _ => false - }; + let type_params = generics.type_params() + .map(|param| param.ident) + .collect::>(); - let mut field_bound: Option = 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().any(|g| matching_generic(t, g)) { - Some(parse_quote!(#field_ty: #trait_bound)) - } else {None}, - (_, _) => None - }; + let predicates_from_associated_types = cont.data + .all_fields() + .filter(|field| gen_bound_where(&field.attrs)) + .filter_map(|field| { + if let syn::Type::Path(ref ty) = *field.ty { + if let Some(Pair::Punctuated(ref t, _)) = ty.path.segments.first() { + if type_params.contains(&t.ident) { + return Some(parse_quote!(#ty: #trait_bound)); + } + } } - field_bound.into_iter().chain(from_field(&field.attrs).into_iter().flat_map(|predicates| predicates.to_vec())) + None:: }); + let predicates_from_field_attrs = cont.data + .all_fields() + .flat_map(|field| from_field(&field.attrs)) + .flat_map(|predicates| predicates.to_vec()); + let mut generics = generics.clone(); - generics.make_where_clause() - .predicates - .extend(predicates); + { + let predicates = &mut generics.make_where_clause().predicates; + predicates.extend(predicates_from_associated_types); + predicates.extend(predicates_from_field_attrs); + } generics }