about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libsyntax/ext/deriving/generic/mod.rs11
1 files changed, 11 insertions, 0 deletions
diff --git a/src/libsyntax/ext/deriving/generic/mod.rs b/src/libsyntax/ext/deriving/generic/mod.rs
index e7d242ab703..8f9e0279b29 100644
--- a/src/libsyntax/ext/deriving/generic/mod.rs
+++ b/src/libsyntax/ext/deriving/generic/mod.rs
@@ -188,6 +188,7 @@ pub use self::SubstructureFields::*;
 use self::StructType::*;
 
 use std::cell::RefCell;
+use std::collections::HashSet;
 use std::vec;
 
 use abi::Abi;
@@ -549,10 +550,20 @@ impl<'a> TraitDef<'a> {
                 .map(|ty_param| ty_param.ident.name)
                 .collect();
 
+            let mut processed_field_types = HashSet::new();
             for field_ty in field_tys {
                 let tys = find_type_parameters(&*field_ty, &ty_param_names);
 
                 for ty in tys {
+                    // if we have already handled this type, skip it
+                    if let ast::TyPath(_, ref p) = ty.node {
+                        if p.segments.len() == 1
+                            && ty_param_names.contains(&p.segments[0].identifier.name)
+                            || processed_field_types.contains(&p.segments) {
+                            continue;
+                        };
+                        processed_field_types.insert(p.segments.clone());
+                    }
                     let mut bounds: Vec<_> = self.additional_bounds.iter().map(|p| {
                         cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
                     }).collect();