about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-05-27 16:56:01 +0100
committervarkor <github@varkor.com>2018-06-20 12:21:52 +0100
commitf457b3d10aa2db4104402e2d04f72fab64a3c62e (patch)
treefa7bbf7fe41dd3c6055c308ef34e5821c00505c8
parent80b381e041d12259f24b1282e10e0a224bc6ec0e (diff)
Refactor generic parameters in rustdoc/clean
-rw-r--r--src/librustc/hir/intravisit.rs4
-rw-r--r--src/librustc/hir/lowering.rs101
-rw-r--r--src/librustc/hir/map/def_collector.rs7
-rw-r--r--src/librustc/hir/map/mod.rs8
-rw-r--r--src/librustc/hir/print.rs12
-rw-r--r--src/librustc/infer/error_reporting/mod.rs14
-rw-r--r--src/librustc/middle/resolve_lifetime.rs117
-rw-r--r--src/librustc/util/ppaux.rs2
-rw-r--r--src/librustc_lint/types.rs3
-rw-r--r--src/librustc_metadata/encoder.rs19
-rw-r--r--src/librustc_mir/monomorphize/collector.rs7
-rw-r--r--src/librustc_passes/ast_validation.rs43
-rw-r--r--src/librustc_privacy/lib.rs14
-rw-r--r--src/librustc_resolve/lib.rs15
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs42
-rw-r--r--src/librustc_typeck/check/mod.rs10
-rw-r--r--src/librustdoc/clean/auto_trait.rs23
-rw-r--r--src/librustdoc/clean/mod.rs189
-rw-r--r--src/librustdoc/clean/simplify.rs9
-rw-r--r--src/librustdoc/html/format.rs16
-rw-r--r--src/librustdoc/html/render.rs8
21 files changed, 296 insertions, 367 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 4c24c7afd73..51ce134544d 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -654,8 +654,8 @@ pub fn walk_path_segment<'v, V: Visitor<'v>>(visitor: &mut V,
 }
 
 pub fn walk_generic_args<'v, V: Visitor<'v>>(visitor: &mut V,
-                                                _path_span: Span,
-                                                generic_args: &'v GenericArgs) {
+                                             _path_span: Span,
+                                             generic_args: &'v GenericArgs) {
     walk_list!(visitor, visit_generic_arg, &generic_args.args);
     walk_list!(visitor, visit_assoc_type_binding, &generic_args.bindings);
 }
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index 1c62e5813ff..c0f94a138af 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -382,17 +382,9 @@ impl<'a> LoweringContext<'a> {
                     let item_lifetimes = match self.lctx.items.get(&item.id).unwrap().node {
                         hir::Item_::ItemImpl(_, _, _, ref generics, ..)
                         | hir::Item_::ItemTrait(_, _, ref generics, ..) => {
-                            generics.params
-                                    .iter()
-                                    .filter_map(|param| match param.kind {
-                                        hir::GenericParamKind::Lifetime { .. } => {
-                                            Some(param.clone())
-                                        }
-                                        _ => None,
-                                    })
-                            .collect::<Vec<_>>()
+                            generics.params.clone()
                         }
-                        _ => Vec::new(),
+                        _ => HirVec::new(),
                     };
 
                     self.lctx.with_parent_impl_lifetime_defs(&item_lifetimes, |this| {
@@ -766,16 +758,15 @@ impl<'a> LoweringContext<'a> {
     // This is used to track which lifetimes have already been defined, and
     // which are new in-band lifetimes that need to have a definition created
     // for them.
-    fn with_in_scope_lifetime_defs<'l, T, F>(
-        &mut self,
-        params: impl Iterator<Item = &'l GenericParamAST>,
-        f: F,
-    ) -> T
+    fn with_in_scope_lifetime_defs<T, F>(&mut self, params: &Vec<GenericParamAST>, f: F) -> T
     where
         F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
-        let lt_def_names = params.map(|param| param.ident.name);
+        let lt_def_names = params.iter().filter_map(|param| match param.kind {
+            GenericParamKindAST::Lifetime { .. } => Some(param.ident.name),
+            _ => None,
+        });
         self.in_scope_lifetimes.extend(lt_def_names);
 
         let res = f(self);
@@ -789,12 +780,17 @@ impl<'a> LoweringContext<'a> {
     // This should only be used with generics that have already had their
     // in-band lifetimes added. In practice, this means that this function is
     // only used when lowering a child item of a trait or impl.
-    fn with_parent_impl_lifetime_defs<T, F>(&mut self, params: &[hir::GenericParam], f: F) -> T
-    where
+    fn with_parent_impl_lifetime_defs<T, F>(&mut self,
+        params: &HirVec<hir::GenericParam>,
+        f: F
+    ) -> T where
         F: FnOnce(&mut LoweringContext) -> T,
     {
         let old_len = self.in_scope_lifetimes.len();
-        let lt_def_names = params.iter().map(|param| param.name());
+        let lt_def_names = params.iter().filter_map(|param| match param.kind {
+            hir::GenericParamKind::Lifetime { .. } => Some(param.name()),
+            _ => None,
+        });
         self.in_scope_lifetimes.extend(lt_def_names);
 
         let res = f(self);
@@ -820,10 +816,7 @@ impl<'a> LoweringContext<'a> {
         F: FnOnce(&mut LoweringContext) -> T,
     {
         let (in_band_defs, (mut lowered_generics, res)) = self.with_in_scope_lifetime_defs(
-            generics.params.iter().filter_map(|param| match param.kind {
-                GenericParamKindAST::Lifetime { .. } => Some(param),
-                _ => None,
-            }),
+            &generics.params,
             |this| {
                 let itctx = ImplTraitContext::Universal(parent_id);
                 this.collect_in_band_defs(parent_id, anonymous_lifetime_mode, |this| {
@@ -1051,16 +1044,12 @@ impl<'a> LoweringContext<'a> {
     }
 
     fn lower_generic_arg(&mut self,
-                        p: &ast::GenericArgAST,
+                        arg: &ast::GenericArgAST,
                         itctx: ImplTraitContext)
                         -> hir::GenericArg {
-        match p {
-            ast::GenericArgAST::Lifetime(lt) => {
-                GenericArg::Lifetime(self.lower_lifetime(&lt))
-            }
-            ast::GenericArgAST::Type(ty) => {
-                GenericArg::Type(self.lower_ty(&ty, itctx))
-            }
+        match arg {
+            ast::GenericArgAST::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(&lt)),
+            ast::GenericArgAST::Type(ty) => GenericArg::Type(self.lower_ty(&ty, itctx)),
         }
     }
 
@@ -1079,10 +1068,7 @@ impl<'a> LoweringContext<'a> {
                 hir::TyRptr(lifetime, self.lower_mt(mt, itctx))
             }
             TyKind::BareFn(ref f) => self.with_in_scope_lifetime_defs(
-                f.generic_params.iter().filter_map(|param| match param.kind {
-                    GenericParamKindAST::Lifetime { .. } => Some(param),
-                    _ => None,
-                }),
+                &f.generic_params,
                 |this| {
                     this.with_anonymous_lifetime_mode(
                         AnonymousLifetimeMode::PassThrough,
@@ -1946,6 +1932,15 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
+    fn lower_generic_params(
+        &mut self,
+        params: &Vec<GenericParamAST>,
+        add_bounds: &NodeMap<Vec<TyParamBound>>,
+        itctx: ImplTraitContext,
+    ) -> hir::HirVec<hir::GenericParam> {
+        params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
+    }
+
     fn lower_generic_param(&mut self,
                            param: &GenericParamAST,
                            add_bounds: &NodeMap<Vec<TyParamBound>>,
@@ -1986,10 +1981,9 @@ impl<'a> LoweringContext<'a> {
                 let mut bounds = self.lower_bounds(bounds, itctx);
                 let add_bounds = add_bounds.get(&param.id).map_or(&[][..], |x| &x);
                 if !add_bounds.is_empty() {
-                    bounds = bounds
-                        .into_iter()
-                        .chain(self.lower_bounds(add_bounds, itctx).into_iter())
-                        .collect();
+                    bounds = bounds.into_iter()
+                                   .chain(self.lower_bounds(add_bounds, itctx).into_iter())
+                                   .collect();
                 }
 
                 hir::GenericParam {
@@ -2005,7 +1999,7 @@ impl<'a> LoweringContext<'a> {
                         synthetic: param.attrs.iter()
                                               .filter(|attr| attr.check_name("rustc_synthetic"))
                                               .map(|_| hir::SyntheticTyParamKind::ImplTrait)
-                                              .nth(0),
+                                              .next(),
                         attrs: self.lower_attrs(&param.attrs),
                     }
                 }
@@ -2013,15 +2007,6 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_generic_params(
-        &mut self,
-        params: &Vec<GenericParamAST>,
-        add_bounds: &NodeMap<Vec<TyParamBound>>,
-        itctx: ImplTraitContext,
-    ) -> hir::HirVec<hir::GenericParam> {
-        params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
-    }
-
     fn lower_generics(
         &mut self,
         generics: &Generics,
@@ -2107,10 +2092,7 @@ impl<'a> LoweringContext<'a> {
                 span,
             }) => {
                 self.with_in_scope_lifetime_defs(
-                    bound_generic_params.iter().filter_map(|param| match param.kind {
-                        GenericParamKindAST::Lifetime { .. } => Some(param),
-                        _ => None,
-                    }),
+                    &bound_generic_params,
                     |this| {
                         hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
                             bound_generic_params: this.lower_generic_params(
@@ -2203,13 +2185,7 @@ impl<'a> LoweringContext<'a> {
         let bound_generic_params =
             self.lower_generic_params(&p.bound_generic_params, &NodeMap(), itctx);
         let trait_ref = self.with_parent_impl_lifetime_defs(
-            &bound_generic_params
-                .iter()
-                .filter_map(|param| match param.kind {
-                    hir::GenericParamKind::Lifetime { .. } => Some(param.clone()),
-                    _ => None,
-                })
-                .collect::<Vec<_>>(),
+            &bound_generic_params,
             |this| this.lower_trait_ref(&p.trait_ref, itctx),
         );
 
@@ -2426,10 +2402,7 @@ impl<'a> LoweringContext<'a> {
                 );
 
                 let new_impl_items = self.with_in_scope_lifetime_defs(
-                    ast_generics.params.iter().filter_map(|param| match param.kind {
-                        GenericParamKindAST::Lifetime { .. } => Some(param),
-                        _ => None,
-                    }),
+                    &ast_generics.params,
                     |this| {
                         impl_items
                             .iter()
diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs
index 6555be110d1..ab4a0826584 100644
--- a/src/librustc/hir/map/def_collector.rs
+++ b/src/librustc/hir/map/def_collector.rs
@@ -176,12 +176,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
             GenericParamKindAST::Lifetime { .. } => DefPathData::LifetimeParam(name),
             GenericParamKindAST::Type { .. } => DefPathData::TypeParam(name),
         };
-        self.create_def(
-            param.id,
-            def_path_data,
-            REGULAR_SPACE,
-            param.ident.span
-        );
+        self.create_def(param.id, def_path_data, REGULAR_SPACE, param.ident.span);
 
         visit::walk_generic_param(self, param);
     }
diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs
index c46f5813754..1f958d3fe95 100644
--- a/src/librustc/hir/map/mod.rs
+++ b/src/librustc/hir/map/mod.rs
@@ -974,11 +974,9 @@ impl<'hir> Map<'hir> {
             Some(NodeField(ref f)) => Some(&f.attrs[..]),
             Some(NodeExpr(ref e)) => Some(&*e.attrs),
             Some(NodeStmt(ref s)) => Some(s.node.attrs()),
-            Some(NodeGenericParam(param)) => {
-                match param.kind {
-                    GenericParamKind::Type { ref attrs, .. } => Some(&attrs[..]),
-                    _ => bug!("unexpected non-type NodeGenericParam")
-                }
+            Some(NodeGenericParam(param)) => match param.kind {
+                GenericParamKind::Type { ref attrs, .. } => Some(&attrs[..]),
+                _ => bug!("unexpected non-type NodeGenericParam")
             }
             // unit/tuple structs take the attributes straight from
             // the struct definition.
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index dc5d9749227..eabf554bc53 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -1270,13 +1270,10 @@ impl<'a> State<'a> {
         self.print_name(segment.name)?;
 
         segment.with_generic_args(|generic_args| {
-            if !generic_args.args.is_empty() ||
-                !generic_args.bindings.is_empty()
-            {
-                self.print_generic_args(&generic_args, segment.infer_types, true)
-            } else {
-                Ok(())
+            if !generic_args.args.is_empty() || !generic_args.bindings.is_empty() {
+                return self.print_generic_args(&generic_args, segment.infer_types, true);
             }
+            Ok(())
         })?;
         self.print_call_post(base_args)
     }
@@ -1642,8 +1639,7 @@ impl<'a> State<'a> {
                segment.name != keywords::DollarCrate.name() {
                self.print_name(segment.name)?;
                segment.with_generic_args(|generic_args| {
-                   self.print_generic_args(generic_args,
-                                           segment.infer_types,
+                   self.print_generic_args(generic_args, segment.infer_types,
                                            colons_before_params)
                })?;
             }
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index af38e8ba2d4..b30e5bab968 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -1036,21 +1036,19 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             // Get the `hir::TyParam` to verify whether it already has any bounds.
                             // We do this to avoid suggesting code that ends up as `T: 'a'b`,
                             // instead we suggest `T: 'a + 'b` in that case.
-                            let has_lifetimes =
-                                if let hir_map::NodeGenericParam(ref param) = hir.get(id) {
+                            let mut has_bounds = false;
+                            if let hir_map::NodeGenericParam(ref param) = hir.get(id) {
                                 match param.kind {
                                     GenericParamKind::Type { ref bounds, .. } => {
-                                        !bounds.is_empty()
+                                        has_bounds = !bounds.is_empty();
                                     }
                                     _ => bug!("unexpected non-type NodeGenericParam"),
                                 }
-                            } else {
-                                false
-                            };
+                            }
                             let sp = hir.span(id);
                             // `sp` only covers `T`, change it so that it covers
                             // `T:` when appropriate
-                            let sp = if has_lifetimes {
+                            let sp = if has_bounds {
                                 sp.to(self.tcx
                                     .sess
                                     .codemap()
@@ -1058,7 +1056,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             } else {
                                 sp
                             };
-                            (sp, has_lifetimes)
+                            (sp, has_bounds)
                         })
                     } else {
                         None
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 358df3a1733..67a5448babf 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -81,6 +81,18 @@ pub enum Region {
     Free(DefId, /* lifetime decl */ DefId),
 }
 
+fn new_region(hir_map: &Map, param: &hir::GenericParam)
+    -> (hir::LifetimeName, DefId, LifetimeDefOrigin) {
+    let def_id = hir_map.local_def_id(param.id);
+    let (name, origin) = match param.kind {
+        GenericParamKind::Lifetime { name, in_band, .. } => {
+            (name, LifetimeDefOrigin::from_is_in_band(in_band))
+        }
+        _ => bug!("expected a lifetime param"),
+    };
+    (name, def_id, origin)
+}
+
 impl Region {
     fn early(
         hir_map: &Map,
@@ -89,26 +101,14 @@ impl Region {
     ) -> (hir::LifetimeName, Region) {
         let i = *index;
         *index += 1;
-        let def_id = hir_map.local_def_id(param.id);
-        let (name, origin) = match param.kind {
-            GenericParamKind::Lifetime { name, in_band, .. } => {
-                (name, LifetimeDefOrigin::from_is_in_band(in_band))
-            }
-            _ => bug!("expected a lifetime param"),
-        };
+        let (name, def_id, origin) = new_region(hir_map, param);
         debug!("Region::early: index={} def_id={:?}", i, def_id);
         (name, Region::EarlyBound(i, def_id, origin))
     }
 
     fn late(hir_map: &Map, param: &hir::GenericParam) -> (hir::LifetimeName, Region) {
         let depth = ty::INNERMOST;
-        let def_id = hir_map.local_def_id(param.id);
-        let (name, origin) = match param.kind {
-            GenericParamKind::Lifetime { name, in_band, .. } => {
-                (name, LifetimeDefOrigin::from_is_in_band(in_band))
-            }
-            _ => bug!("expected a lifetime param"),
-        };
+        let (name, def_id, origin) = new_region(hir_map, param);
         debug!(
             "Region::late: def={:?} depth={:?} def_id={:?} origin={:?}",
             def,
@@ -580,15 +580,12 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 let was_in_fn_syntax = self.is_in_fn_syntax;
                 self.is_in_fn_syntax = true;
                 let scope = Scope::Binder {
-                    lifetimes: c.generic_params
-                                .iter()
-                                .filter_map(|param| match param.kind {
-                                    GenericParamKind::Lifetime { .. } => {
-                                        Some(Region::late(&self.tcx.hir, param))
-                                    }
-                                    _ => None,
-                                })
-                                .collect(),
+                    lifetimes: c.generic_params.iter().filter_map(|param| match param.kind {
+                        GenericParamKind::Lifetime { .. } => {
+                            Some(Region::late(&self.tcx.hir, param))
+                        }
+                        _ => None,
+                    }).collect(),
                     s: self.scope,
                     next_early_index,
                     track_lifetime_uses: true,
@@ -770,19 +767,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 let mut index = self.next_early_index();
                 debug!("visit_ty: index = {}", index);
                 let mut type_count = 0;
-                let lifetimes = generics.params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir, &mut index, param))
-                        }
-                        GenericParamKind::Type { .. } => {
-                            type_count += 1;
-                            None
-                        }
-                    })
-                    .collect();
-
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir, &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } => {
+                        type_count += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
                     next_early_index: index + type_count,
@@ -825,19 +818,15 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                 let mut index = self.next_early_index();
                 let mut next_early_index = index;
                 debug!("visit_ty: index = {}", index);
-                let lifetimes = generics.params
-                    .iter()
-                    .filter_map(|param| match param.kind {
-                        GenericParamKind::Lifetime { .. } => {
-                            Some(Region::early(&self.tcx.hir, &mut index, param))
-                        }
-                        GenericParamKind::Type { .. } => {
-                            next_early_index += 1;
-                            None
-                        }
-                    })
-                    .collect();
-
+                let lifetimes = generics.params.iter().filter_map(|param| match param.kind {
+                    GenericParamKind::Lifetime { .. } => {
+                        Some(Region::early(&self.tcx.hir, &mut index, param))
+                    }
+                    GenericParamKind::Type { .. } => {
+                        next_early_index += 1;
+                        None
+                    }
+                }).collect();
                 let scope = Scope::Binder {
                     lifetimes,
                     next_early_index,
@@ -888,13 +877,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
     }
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
-        check_mixed_explicit_and_in_band_defs(
-            self.tcx,
-            &generics.params.iter().filter_map(|param| match param.kind {
-                GenericParamKind::Lifetime { .. } => Some(param.clone()),
-                _ => None,
-            }).collect::<Vec<_>>()
-        );
+        check_mixed_explicit_and_in_band_defs(self.tcx, &generics.params);
         for param in &generics.params {
             match param.kind {
                 GenericParamKind::Lifetime { .. } => {}
@@ -920,8 +903,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
                                 Some(Region::late(&self.tcx.hir, param))
                             }
                             _ => None,
-                        })
-                        .collect();
+                        }).collect();
                     if !lifetimes.is_empty() {
                         self.trait_ref_hack = true;
                         let next_early_index = self.next_early_index();
@@ -992,16 +974,13 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
             }
             let next_early_index = self.next_early_index();
             let scope = Scope::Binder {
-                lifetimes: trait_ref
-                    .bound_generic_params
-                    .iter()
+                lifetimes: trait_ref.bound_generic_params.iter()
                     .filter_map(|param| match param.kind {
                         GenericParamKind::Lifetime { .. } => {
                             Some(Region::late(&self.tcx.hir, param))
                         }
                         _ => None,
-                    })
-                    .collect(),
+                    }).collect(),
                 s: self.scope,
                 next_early_index,
                 track_lifetime_uses: true,
@@ -1068,11 +1047,11 @@ impl ShadowKind {
 
 fn check_mixed_explicit_and_in_band_defs(
     tcx: TyCtxt<'_, '_, '_>,
-    params: &[hir::GenericParam],
+    params: &P<[hir::GenericParam]>,
 ) {
-    let in_bands: Vec<_> = params.iter().map(|param| match param.kind {
-        GenericParamKind::Lifetime { in_band, .. } => (in_band, param.span),
-        _ => bug!("expected lifetime param"),
+    let in_bands: Vec<_> = params.iter().filter_map(|param| match param.kind {
+        GenericParamKind::Lifetime { in_band, .. } => Some((in_band, param.span)),
+        _ => None,
     }).collect();
     let out_of_band = in_bands.iter().find(|(in_band, _)| !in_band);
     let in_band = in_bands.iter().find(|(in_band, _)| *in_band);
@@ -1707,9 +1686,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
         if elide_lifetimes {
             self.resolve_elided_lifetimes(lifetimes, true);
         } else {
-            for lt in lifetimes {
-                self.visit_lifetime(lt);
-            }
+            lifetimes.iter().for_each(|lt| self.visit_lifetime(lt));
         }
 
         // Figure out if this is a type/trait segment,
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index bd19a575c79..3252a2cd6ab 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -337,10 +337,10 @@ impl PrintContext {
             if !verbose {
                 let mut type_params =
                     generics.params.iter().rev().filter_map(|param| match param.kind {
+                        GenericParamDefKind::Lifetime => None,
                         GenericParamDefKind::Type { has_default, .. } => {
                             Some((param.def_id, has_default))
                         }
-                        GenericParamDefKind::Lifetime => None,
                     }).peekable();
                 let has_default = {
                     let has_default = type_params.peek().map(|(_, has_default)| has_default);
diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs
index 2149e654281..2d96c01a6df 100644
--- a/src/librustc_lint/types.rs
+++ b/src/librustc_lint/types.rs
@@ -836,8 +836,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences {
                     .zip(variants)
                     .map(|(variant, variant_layout)| {
                         // Subtract the size of the enum discriminant.
-                        let bytes = variant_layout.size.bytes()
-                            .saturating_sub(discr_size);
+                        let bytes = variant_layout.size.bytes().saturating_sub(discr_size);
 
                         debug!("- variant `{}` is {} bytes large", variant.node.name, bytes);
                         bytes
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index e105c9cd3c2..ed3dab09df9 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -1648,18 +1648,15 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> {
     }
 
     fn encode_info_for_generics(&mut self, generics: &hir::Generics) {
-        for param in &generics.params {
-            match param.kind {
-                hir::GenericParamKind::Lifetime { .. } => {}
-                hir::GenericParamKind::Type { ref default, .. } => {
-                    let def_id = self.tcx.hir.local_def_id(param.id);
-                    let has_default = Untracked(default.is_some());
-                    self.record(def_id,
-                                IsolatedEncoder::encode_info_for_ty_param,
-                                (def_id, has_default));
-                }
+        generics.params.iter().for_each(|param| match param.kind {
+            hir::GenericParamKind::Lifetime { .. } => {}
+            hir::GenericParamKind::Type { ref default, .. } => {
+                let def_id = self.tcx.hir.local_def_id(param.id);
+                let has_default = Untracked(default.is_some());
+                let encode_info = IsolatedEncoder::encode_info_for_ty_param;
+                self.record(def_id, encode_info, (def_id, has_default));
             }
-        }
+        });
     }
 
     fn encode_info_for_ty(&mut self, ty: &hir::Ty) {
diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs
index 9f5b9d405a1..ef69cb574e0 100644
--- a/src/librustc_mir/monomorphize/collector.rs
+++ b/src/librustc_mir/monomorphize/collector.rs
@@ -1099,12 +1099,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                  item: &'tcx hir::Item,
                                                  output: &mut Vec<MonoItem<'tcx>>) {
     match item.node {
-        hir::ItemImpl(_,
-                      _,
-                      _,
-                      ref generics,
-                      ..,
-                      ref impl_item_refs) => {
+        hir::ItemImpl(_, _, _, ref generics, .., ref impl_item_refs) => {
             for param in &generics.params {
                 match param.kind {
                     hir::GenericParamKind::Lifetime { .. } => {}
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index a6ef83671a5..d9a69f09d34 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -141,20 +141,19 @@ impl<'a> AstValidator<'a> {
     fn check_late_bound_lifetime_defs(&self, params: &Vec<GenericParamAST>) {
         // Check only lifetime parameters are present and that the lifetime
         // parameters that are present have no bounds.
-        let non_lifetime_param_spans: Vec<_> = params.iter()
-            .filter_map(|param| match param.kind {
+        let non_lt_param_spans: Vec<_> = params.iter().filter_map(|param| match param.kind {
                 GenericParamKindAST::Lifetime { ref bounds, .. } => {
                     if !bounds.is_empty() {
                         let spans: Vec<_> = bounds.iter().map(|b| b.ident.span).collect();
-                        self.err_handler().span_err(spans,
-                            "lifetime bounds cannot be used in this context");
+                        self.err_handler()
+                            .span_err(spans, "lifetime bounds cannot be used in this context");
                     }
                     None
                 }
                 _ => Some(param.ident.span),
             }).collect();
-        if !non_lifetime_param_spans.is_empty() {
-            self.err_handler().span_err(non_lifetime_param_spans,
+        if !non_lt_param_spans.is_empty() {
+            self.err_handler().span_err(non_lt_param_spans,
                 "only lifetime parameters can be used in this context");
         }
     }
@@ -333,16 +332,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         GenericParamKindAST::Lifetime { .. } => {}
                         GenericParamKindAST::Type { ref bounds, ref default, .. } => {
                             if !bounds.is_empty() {
-                                self.err_handler().span_err(param.ident.span,
-                                                            "type parameters on the left side \
-                                                             of a trait alias cannot be \
-                                                             bounded");
+                                self.err_handler()
+                                    .span_err(param.ident.span, "type parameters on the left \
+                                        side of a trait alias cannot be bounded");
                             }
                             if !default.is_none() {
-                                self.err_handler().span_err(param.ident.span,
-                                                            "type parameters on the left side \
-                                                             of a trait alias cannot have \
-                                                             defaults");
+                                self.err_handler()
+                                    .span_err(param.ident.span, "type parameters on the left \
+                                        side of a trait alias cannot have defaults");
                             }
                         }
                     }
@@ -402,10 +399,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
         visit::walk_vis(self, vis)
     }
 
-    fn visit_generics(&mut self, g: &'a Generics) {
+    fn visit_generics(&mut self, generics: &'a Generics) {
         let mut seen_non_lifetime_param = false;
         let mut seen_default = None;
-        for param in &g.params {
+        for param in &generics.params {
             match (&param.kind, seen_non_lifetime_param) {
                 (GenericParamKindAST::Lifetime { .. }, true) => {
                     self.err_handler()
@@ -424,13 +421,13 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 }
             }
         }
-        for predicate in &g.where_clause.predicates {
+        for predicate in &generics.where_clause.predicates {
             if let WherePredicate::EqPredicate(ref predicate) = *predicate {
                 self.err_handler().span_err(predicate.span, "equality constraints are not yet \
                                                              supported in where clauses (#20041)");
             }
         }
-        visit::walk_generics(self, g)
+        visit::walk_generics(self, generics)
     }
 
     fn visit_generic_param(&mut self, param: &'a GenericParam) {
@@ -516,12 +513,10 @@ impl<'a> Visitor<'a> for NestedImplTraitVisitor<'a> {
     fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) {
         match *generic_args {
             GenericArgs::AngleBracketed(ref data) => {
-                for arg in &data.args {
-                    match arg {
-                        GenericArgAST::Type(ty) => self.visit_ty(ty),
-                        _ => {}
-                    }
-                }
+                data.args.iter().for_each(|arg| match arg {
+                    GenericArgAST::Type(ty) => self.visit_ty(ty),
+                    _ => {}
+                });
                 for type_binding in &data.bindings {
                     // Type bindings such as `Item=impl Debug` in `Iterator<Item=Debug>`
                     // are allowed to contain nested `impl Trait`.
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 19ed04a7968..388ac5cdb50 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -1268,16 +1268,14 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     }
 
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
-        for param in &generics.params {
-            match param.kind {
-                GenericParamKind::Lifetime { .. } => {}
-                GenericParamKind::Type { ref bounds, .. } => {
-                    for bound in bounds {
-                        self.check_ty_param_bound(bound);
-                    }
+        generics.params.iter().for_each(|param| match param.kind {
+            GenericParamKind::Lifetime { .. } => {}
+            GenericParamKind::Type { ref bounds, .. } => {
+                for bound in bounds {
+                    self.check_ty_param_bound(bound);
                 }
             }
-        }
+        });
         for predicate in &generics.where_clause.predicates {
             match predicate {
                 &hir::WherePredicate::BoundPredicate(ref bound_pred) => {
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 37264eb3382..314eae8f338 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -802,10 +802,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
             .filter_map(|param| match param.kind {
                 GenericParamKindAST::Lifetime { .. } => None,
                 GenericParamKindAST::Type { ref default, .. } => {
-                    if default.is_some() {
+                    if found_default || default.is_some() {
                         found_default = true;
-                    }
-                    if found_default {
                         return Some((Ident::with_empty_ctxt(param.ident.name), Def::Err));
                     }
                     None
@@ -2209,8 +2207,7 @@ impl<'a> Resolver<'a> {
             HasTypeParameters(generics, rib_kind) => {
                 let mut function_type_rib = Rib::new(rib_kind);
                 let mut seen_bindings = FxHashMap();
-                for param in &generics.params {
-                    match param.kind {
+                generics.params.iter().for_each(|param| match param.kind {
                         GenericParamKindAST::Type { .. } => {
                             let ident = param.ident.modern();
                             debug!("with_type_parameter_rib: {}", param.id);
@@ -2225,15 +2222,13 @@ impl<'a> Resolver<'a> {
                             }
                             seen_bindings.entry(ident).or_insert(param.ident.span);
 
-                            // plain insert (no renaming)
-                            let def_id = self.definitions.local_def_id(param.id);
-                            let def = Def::TyParam(def_id);
+                        // Plain insert (no renaming).
+                        let def = Def::TyParam(self.definitions.local_def_id(param.id));
                             function_type_rib.bindings.insert(ident, def);
                             self.record_def(param.id, PathResolution::new(def));
                         }
                         _ => {}
-                    }
-                }
+                });
                 self.ribs[TypeNS].push(function_type_rib);
             }
 
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 5faa3559c76..ea5f452199a 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -826,12 +826,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
             if let Some(ref generic_args) = seg.args {
                 match **generic_args {
                     ast::GenericArgs::AngleBracketed(ref data) => {
-                        for arg in &data.args {
-                            match arg {
-                                ast::GenericArgAST::Type(ty) => self.visit_ty(ty),
-                                _ => {}
-                            }
-                        }
+                        data.args.iter().for_each(|arg| match arg {
+                            ast::GenericArgAST::Type(ty) => self.visit_ty(ty),
+                            _ => {}
+                        });
                     }
                     ast::GenericArgs::Parenthesized(ref data) => {
                         for t in &data.inputs {
@@ -915,12 +913,10 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
         // Explicit types in the turbo-fish.
         if let Some(ref generic_args) = seg.args {
             if let ast::GenericArgs::AngleBracketed(ref data) = **generic_args {
-                for arg in &data.args {
-                    match arg {
-                        ast::GenericArgAST::Type(ty) => self.visit_ty(ty),
-                        _ => {}
-                    }
-                }
+                data.args.iter().for_each(|arg| match arg {
+                    ast::GenericArgAST::Type(ty) => self.visit_ty(ty),
+                    _ => {}
+                });
             }
         }
 
@@ -1489,21 +1485,19 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
     }
 
     fn visit_generics(&mut self, generics: &'l ast::Generics) {
-        for param in &generics.params {
-            match param.kind {
-                ast::GenericParamKindAST::Lifetime { .. } => {}
-                ast::GenericParamKindAST::Type { ref bounds, ref default, .. } => {
-                    for bound in bounds {
-                        if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
-                            self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
-                        }
-                    }
-                    if let Some(ref ty) = default {
-                        self.visit_ty(&ty);
+        generics.params.iter().for_each(|param| match param.kind {
+            ast::GenericParamKindAST::Lifetime { .. } => {}
+            ast::GenericParamKindAST::Type { ref bounds, ref default, .. } => {
+                for bound in bounds {
+                    if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
+                        self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
                     }
                 }
+                if let Some(ref ty) = default {
+                    self.visit_ty(&ty);
+                }
             }
-        }
+        });
     }
 
     fn visit_ty(&mut self, t: &'l ast::Ty) {
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 4b731d5b883..6ac9a0fdfc0 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -4979,12 +4979,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                     |data| {
                         let mut lifetimes = vec![];
                         let mut types = vec![];
-                        for arg in &data.args {
-                            match arg {
-                                GenericArg::Lifetime(lt) => lifetimes.push(lt),
-                                GenericArg::Type(ty) => types.push(ty),
-                            }
-                        }
+                        data.args.iter().for_each(|arg| match arg {
+                            GenericArg::Lifetime(lt) => lifetimes.push(lt),
+                            GenericArg::Type(ty) => types.push(ty),
+                        });
                         (lifetimes, types, s.infer_types, &data.bindings[..])
                     }
                 )
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 4418c107223..2a63b124866 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -521,7 +521,10 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                         // We only care about late bound regions, as we need to add them
                         // to the 'for<>' section
                         &ty::ReLateBound(_, ty::BoundRegion::BrNamed(_, name)) => {
-                            Some(GenericParamDef::Lifetime(Lifetime(name.to_string())))
+                            Some(GenericParamDef {
+                                name: name.to_string(),
+                                kind: GenericParamDefKind::Lifetime,
+                            })
                         }
                         &ty::ReVar(_) | &ty::ReEarlyBound(_) => None,
                         _ => panic!("Unexpected region type {:?}", r),
@@ -867,19 +870,17 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
 
         existing_predicates.extend(final_bounds);
 
-        for p in generic_params.iter_mut() {
-            match p {
-                &mut GenericParamDef::Type(ref mut ty) => {
-                    // We never want something like 'impl<T=Foo>'
-                    ty.default.take();
-
-                    let generic_ty = Type::Generic(ty.name.clone());
-
+        for param in generic_params.iter_mut() {
+            match param.kind {
+                GenericParamDefKind::Type { ref mut default, ref mut bounds, .. } => {
+                    // We never want something like `impl<T=Foo>`.
+                    default.take();
+                    let generic_ty = Type::Generic(param.name.clone());
                     if !has_sized.contains(&generic_ty) {
-                        ty.bounds.insert(0, TyParamBound::maybe_sized(self.cx));
+                        bounds.insert(0, TyParamBound::maybe_sized(self.cx));
                     }
                 }
-                GenericParamDef::Lifetime(_) => {}
+                GenericParamDefKind::Lifetime => {}
             }
         }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index a2ae7afbc83..3a4e582622f 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1458,53 +1458,6 @@ impl Clean<Attributes> for [ast::Attribute] {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub struct TyParam {
-    pub name: String,
-    pub did: DefId,
-    pub bounds: Vec<TyParamBound>,
-    pub default: Option<Type>,
-    pub synthetic: Option<hir::SyntheticTyParamKind>,
-}
-
-impl Clean<TyParam> for hir::GenericParam {
-    fn clean(&self, cx: &DocContext) -> TyParam {
-        match self.kind {
-            hir::GenericParamKind::Type { ref bounds, ref default, synthetic, .. } => {
-                TyParam {
-                    name: self.name().clean(cx),
-                    did: cx.tcx.hir.local_def_id(self.id),
-                    bounds: bounds.clean(cx),
-                    default: default.clean(cx),
-                    synthetic: synthetic,
-                }
-            }
-            _ => panic!(),
-        }
-    }
-}
-
-impl<'tcx> Clean<TyParam> for ty::GenericParamDef {
-    fn clean(&self, cx: &DocContext) -> TyParam {
-        cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
-        let has_default = match self.kind {
-            ty::GenericParamDefKind::Type { has_default, .. } => has_default,
-            _ => panic!("tried to convert a non-type GenericParamDef as a type")
-        };
-        TyParam {
-            name: self.name.clean(cx),
-            did: self.def_id,
-            bounds: vec![], // these are filled in from the where-clauses
-            default: if has_default {
-                Some(cx.tcx.type_of(self.def_id).clean(cx))
-            } else {
-                None
-            },
-            synthetic: None,
-        }
-    }
-}
-
-#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
 pub enum TyParamBound {
     RegionBound(Lifetime),
     TraitBound(PolyTrait, hir::TraitBoundModifier)
@@ -1634,8 +1587,11 @@ impl<'a, 'tcx> Clean<TyParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
                     if let ty::TyRef(ref reg, _, _) = ty_s.sty {
                         if let &ty::RegionKind::ReLateBound(..) = *reg {
                             debug!("  hit an ReLateBound {:?}", reg);
-                            if let Some(lt) = reg.clean(cx) {
-                                late_bounds.push(GenericParamDef::Lifetime(lt));
+                            if let Some(Lifetime(name)) = reg.clean(cx) {
+                                late_bounds.push(GenericParamDef {
+                                    name,
+                                    kind: GenericParamDefKind::Lifetime,
+                                });
                             }
                         }
                     }
@@ -1872,27 +1828,90 @@ impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub enum GenericParamDef {
-    Lifetime(Lifetime),
-    Type(TyParam),
+pub enum GenericParamDefKind {
+    Lifetime,
+    Type {
+        did: DefId,
+        bounds: Vec<TyParamBound>,
+        default: Option<Type>,
+        synthetic: Option<hir::SyntheticTyParamKind>,
+    },
+}
+
+#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
+pub struct GenericParamDef {
+    pub name: String,
+
+    pub kind: GenericParamDefKind,
 }
 
 impl GenericParamDef {
     pub fn is_synthetic_type_param(&self) -> bool {
-        match self {
-            GenericParamDef::Type(ty) => ty.synthetic.is_some(),
-            GenericParamDef::Lifetime(_) => false,
+        match self.kind {
+            GenericParamDefKind::Lifetime => false,
+            GenericParamDefKind::Type { ref synthetic, .. } => synthetic.is_some(),
+        }
+    }
+}
+
+impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
+    fn clean(&self, cx: &DocContext) -> GenericParamDef {
+        let (name, kind) = match self.kind {
+            ty::GenericParamDefKind::Lifetime => {
+                (self.name.to_string(), GenericParamDefKind::Lifetime)
+            }
+            ty::GenericParamDefKind::Type { has_default, .. } => {
+                cx.renderinfo.borrow_mut().external_typarams
+                             .insert(self.def_id, self.name.clean(cx));
+                let default = if has_default {
+                    Some(cx.tcx.type_of(self.def_id).clean(cx))
+                } else {
+                    None
+                };
+                (self.name.clean(cx), GenericParamDefKind::Type {
+                    did: self.def_id,
+                    bounds: vec![], // These are filled in from the where-clauses.
+                    default,
+                    synthetic: None,
+                })
+            }
+        };
+
+        GenericParamDef {
+            name,
+            kind,
         }
     }
 }
 
 impl Clean<GenericParamDef> for hir::GenericParam {
     fn clean(&self, cx: &DocContext) -> GenericParamDef {
-        match self.kind {
-            hir::GenericParamKind::Lifetime { .. } => {
-                GenericParamDef::Lifetime(self.clean(cx))
+        let (name, kind) = match self.kind {
+            hir::GenericParamKind::Lifetime { ref bounds, .. } => {
+                let name = if bounds.len() > 0 {
+                    let mut s = format!("{}: {}", self.name(), bounds[0].name.name());
+                    for bound in bounds.iter().skip(1) {
+                        s.push_str(&format!(" + {}", bound.name.name()));
+                    }
+                    s
+                } else {
+                    self.name().to_string()
+                };
+                (name, GenericParamDefKind::Lifetime)
+            }
+            hir::GenericParamKind::Type { ref bounds, ref default, synthetic, .. } => {
+                (self.name().clean(cx), GenericParamDefKind::Type {
+                    did: cx.tcx.hir.local_def_id(self.id),
+                    bounds: bounds.clean(cx),
+                    default: default.clean(cx),
+                    synthetic: synthetic,
+                })
             }
-            hir::GenericParamKind::Type { .. } => GenericParamDef::Type(self.clean(cx)),
+        };
+
+        GenericParamDef {
+            name,
+            kind,
         }
     }
 }
@@ -1919,17 +1938,16 @@ impl Clean<Generics> for hir::Generics {
         }
         let impl_trait_params = self.params
             .iter()
-            .filter(|p| is_impl_trait(p))
-            .map(|p| {
-                let p = p.clean(cx);
-                if let GenericParamDef::Type(ref tp) = p {
-                    cx.impl_trait_bounds
-                        .borrow_mut()
-                        .insert(tp.did, tp.bounds.clone());
-                } else {
-                    unreachable!()
+            .filter(|param| is_impl_trait(param))
+            .map(|param| {
+                let param: GenericParamDef = param.clean(cx);
+                match param.kind {
+                    GenericParamDefKind::Lifetime => unreachable!(),
+                    GenericParamDefKind::Type { did, ref bounds, .. } => {
+                        cx.impl_trait_bounds.borrow_mut().insert(did, bounds.clone());
+                    }
                 }
-                p
+                param
             })
             .collect::<Vec<_>>();
 
@@ -1940,23 +1958,26 @@ impl Clean<Generics> for hir::Generics {
         }
         params.extend(impl_trait_params);
 
-        let mut g = Generics {
+        let mut generics = Generics {
             params,
-            where_predicates: self.where_clause.predicates.clean(cx)
+            where_predicates: self.where_clause.predicates.clean(cx),
         };
 
         // Some duplicates are generated for ?Sized bounds between type params and where
         // predicates. The point in here is to move the bounds definitions from type params
         // to where predicates when such cases occur.
-        for where_pred in &mut g.where_predicates {
+        for where_pred in &mut generics.where_predicates {
             match *where_pred {
                 WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => {
                     if bounds.is_empty() {
-                        for param in &mut g.params {
-                            if let GenericParamDef::Type(ref mut type_param) = *param {
-                                if &type_param.name == name {
-                                    mem::swap(bounds, &mut type_param.bounds);
-                                    break
+                        for param in &mut generics.params {
+                            match param.kind {
+                                GenericParamDefKind::Lifetime => {}
+                                GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => {
+                                    if &param.name == name {
+                                        mem::swap(bounds, ty_bounds);
+                                        break
+                                    }
                                 }
                             }
                         }
@@ -1965,7 +1986,7 @@ impl Clean<Generics> for hir::Generics {
                 _ => continue,
             }
         }
-        g
+        generics
     }
 }
 
@@ -1988,7 +2009,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
                 }
                 Some(param.clean(cx))
             }
-        }).collect::<Vec<TyParam>>();
+        }).collect::<Vec<GenericParamDef>>();
 
         let mut where_predicates = preds.predicates.to_vec().clean(cx);
 
@@ -2033,15 +2054,9 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
             params: gens.params
                         .iter()
                         .flat_map(|param| match param.kind {
-                            ty::GenericParamDefKind::Lifetime => {
-                                Some(GenericParamDef::Lifetime(param.clean(cx)))
-                            }
+                            ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)),
                             ty::GenericParamDefKind::Type { .. } => None,
-                        }).chain(
-                            simplify::ty_params(stripped_typarams)
-                                .into_iter()
-                                .map(|tp| GenericParamDef::Type(tp))
-                        )
+                        }).chain(simplify::ty_params(stripped_typarams).into_iter())
                         .collect(),
             where_predicates: simplify::where_clauses(cx, where_predicates),
         }
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index ac1952a4bab..95ceee85690 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -135,9 +135,14 @@ pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
     clauses
 }
 
-pub fn ty_params(mut params: Vec<clean::TyParam>) -> Vec<clean::TyParam> {
+pub fn ty_params(mut params: Vec<clean::GenericParamDef>) -> Vec<clean::GenericParamDef> {
     for param in &mut params {
-        param.bounds = ty_bounds(mem::replace(&mut param.bounds, Vec::new()));
+        match param.kind {
+            clean::GenericParamDefKind::Type { ref mut bounds, .. } => {
+                *bounds = ty_bounds(mem::replace(bounds, Vec::new()));
+            }
+            _ => panic!("expected only type parameters"),
+        }
     }
     params
 }
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index d2d068e5209..86c312275ff 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -119,20 +119,20 @@ impl<'a> fmt::Display for TyParamBounds<'a> {
 
 impl fmt::Display for clean::GenericParamDef {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        match *self {
-            clean::GenericParamDef::Lifetime(ref lp) => write!(f, "{}", lp),
-            clean::GenericParamDef::Type(ref tp) => {
-                f.write_str(&tp.name)?;
+        match self.kind {
+            clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name),
+            clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => {
+                f.write_str(&self.name)?;
 
-                if !tp.bounds.is_empty() {
+                if !bounds.is_empty() {
                     if f.alternate() {
-                        write!(f, ": {:#}", TyParamBounds(&tp.bounds))?;
+                        write!(f, ": {:#}", TyParamBounds(bounds))?;
                     } else {
-                        write!(f, ":&nbsp;{}", TyParamBounds(&tp.bounds))?;
+                        write!(f, ":&nbsp;{}", TyParamBounds(bounds))?;
                     }
                 }
 
-                if let Some(ref ty) = tp.default {
+                if let Some(ref ty) = default {
                     if f.alternate() {
                         write!(f, " = {:#}", ty)?;
                     } else {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 5c2ec2058ee..675d1097bda 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -1453,11 +1453,11 @@ impl DocFolder for Cache {
 impl<'a> Cache {
     fn generics(&mut self, generics: &clean::Generics) {
         for param in &generics.params {
-            match *param {
-                clean::GenericParamDef::Type(ref typ) => {
-                    self.typarams.insert(typ.did, typ.name.clone());
+            match param.kind {
+                clean::GenericParamDefKind::Lifetime => {}
+                clean::GenericParamDefKind::Type { did, .. } => {
+                    self.typarams.insert(did, param.name.clone());
                 }
-                clean::GenericParamDef::Lifetime(_) => {}
             }
         }
     }