about summary refs log tree commit diff
diff options
context:
space:
mode:
authorvarkor <github@varkor.com>2018-05-28 13:33:28 +0100
committervarkor <github@varkor.com>2018-06-20 12:22:46 +0100
commitaed530a457dd937fa633dfe52cf07811196d3173 (patch)
treed7848036bf766e1153e965028d8c4c5c8ecb5940
parenta5328bc17b8d18083478554b3381d55183647f15 (diff)
downloadrust-aed530a457dd937fa633dfe52cf07811196d3173.tar.gz
rust-aed530a457dd937fa633dfe52cf07811196d3173.zip
Lift bounds into GenericParam
-rw-r--r--src/librustc/hir/intravisit.rs8
-rw-r--r--src/librustc/hir/lowering.rs58
-rw-r--r--src/librustc/hir/mod.rs43
-rw-r--r--src/librustc/hir/print.rs27
-rw-r--r--src/librustc/ich/impls_hir.rs12
-rw-r--r--src/librustc/infer/error_reporting/mod.rs9
-rw-r--r--src/librustc/middle/resolve_lifetime.rs89
-rw-r--r--src/librustc_lint/builtin.rs9
-rw-r--r--src/librustc_passes/ast_validation.rs14
-rw-r--r--src/librustc_passes/hir_stats.rs8
-rw-r--r--src/librustc_privacy/lib.rs6
-rw-r--r--src/librustc_resolve/lib.rs4
-rw-r--r--src/librustc_save_analysis/dump_visitor.rs8
-rw-r--r--src/librustc_save_analysis/sig.rs26
-rw-r--r--src/librustc_typeck/check/compare_method.rs4
-rw-r--r--src/librustc_typeck/collect.rs45
-rw-r--r--src/librustdoc/clean/auto_trait.rs18
-rw-r--r--src/librustdoc/clean/inline.rs4
-rw-r--r--src/librustdoc/clean/mod.rs95
-rw-r--r--src/librustdoc/clean/simplify.rs2
-rw-r--r--src/librustdoc/core.rs2
-rw-r--r--src/librustdoc/doctree.rs2
-rw-r--r--src/librustdoc/html/format.rs20
-rw-r--r--src/librustdoc/html/render.rs6
-rw-r--r--src/libsyntax/ast.rs45
-rw-r--r--src/libsyntax/ext/build.rs16
-rw-r--r--src/libsyntax/fold.rs23
-rw-r--r--src/libsyntax/parse/parser.rs22
-rw-r--r--src/libsyntax/print/pprust.rs23
-rw-r--r--src/libsyntax/util/node_count.rs2
-rw-r--r--src/libsyntax/visit.rs11
-rw-r--r--src/libsyntax_ext/deriving/generic/mod.rs15
-rw-r--r--src/libsyntax_ext/deriving/generic/ty.rs7
33 files changed, 339 insertions, 344 deletions
diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs
index 0bbd2580807..d5c9d964eb2 100644
--- a/src/librustc/hir/intravisit.rs
+++ b/src/librustc/hir/intravisit.rs
@@ -314,7 +314,7 @@ pub trait Visitor<'v> : Sized {
     fn visit_trait_ref(&mut self, t: &'v TraitRef) {
         walk_trait_ref(self, t)
     }
-    fn visit_ty_param_bound(&mut self, bounds: &'v TyParamBound) {
+    fn visit_ty_param_bound(&mut self, bounds: &'v ParamBound) {
         walk_ty_param_bound(self, bounds)
     }
     fn visit_poly_trait_ref(&mut self, t: &'v PolyTraitRef, m: TraitBoundModifier) {
@@ -731,12 +731,12 @@ pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v
     walk_list!(visitor, visit_attribute, &foreign_item.attrs);
 }
 
-pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v TyParamBound) {
+pub fn walk_ty_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v ParamBound) {
     match *bound {
         TraitTyParamBound(ref typ, modifier) => {
             visitor.visit_poly_trait_ref(typ, modifier);
         }
-        RegionTyParamBound(ref lifetime) => {
+        Outlives(ref lifetime) => {
             visitor.visit_lifetime(lifetime);
         }
     }
@@ -759,11 +759,11 @@ pub fn walk_generic_param<'v, V: Visitor<'v>>(visitor: &mut V, param: &'v Generi
         }
         GenericParamKind::Type { name, ref bounds, ref default, ref attrs, .. } => {
             visitor.visit_name(param.span, name);
-            walk_list!(visitor, visit_ty_param_bound, bounds);
             walk_list!(visitor, visit_ty, default);
             walk_list!(visitor, visit_attribute, attrs.iter());
         }
     }
+    walk_list!(visitor, visit_ty_param_bound, &param.bounds);
 }
 
 pub fn walk_generics<'v, V: Visitor<'v>>(visitor: &mut V, generics: &'v Generics) {
diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs
index d8e03bea89d..494e6e1ba33 100644
--- a/src/librustc/hir/lowering.rs
+++ b/src/librustc/hir/lowering.rs
@@ -701,9 +701,9 @@ impl<'a> LoweringContext<'a> {
                     id: def_node_id,
                     span,
                     pure_wrt_drop: false,
+                    bounds: vec![].into(),
                     kind: hir::GenericParamKind::Lifetime {
                         name: hir_name,
-                        bounds: vec![].into(),
                         in_band: true,
                         lifetime: hir::Lifetime {
                             id: def_node_id,
@@ -1127,7 +1127,7 @@ impl<'a> LoweringContext<'a> {
                             Some(self.lower_poly_trait_ref(ty, itctx))
                         }
                         TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
-                        RegionTyParamBound(ref lifetime) => {
+                        Outlives(ref lifetime) => {
                             if lifetime_bound.is_none() {
                                 lifetime_bound = Some(self.lower_lifetime(lifetime));
                             }
@@ -1246,16 +1246,16 @@ impl<'a> LoweringContext<'a> {
                             span,
                         );
 
-                        let hir_bounds = self.lower_bounds(bounds, itctx);
+                        let hir_bounds = self.lower_param_bounds(bounds, itctx);
                         // Set the name to `impl Bound1 + Bound2`
                         let name = Symbol::intern(&pprust::ty_to_string(t));
                         self.in_band_ty_params.push(hir::GenericParam {
                             id: def_node_id,
                             span,
                             pure_wrt_drop: false,
+                            bounds: hir_bounds,
                             kind: hir::GenericParamKind::Type {
                                 name,
-                                bounds: hir_bounds,
                                 default: None,
                                 synthetic: Some(hir::SyntheticTyParamKind::ImplTrait),
                                 attrs: P::new(),
@@ -1299,7 +1299,7 @@ impl<'a> LoweringContext<'a> {
         &mut self,
         exist_ty_id: NodeId,
         parent_index: DefIndex,
-        bounds: &hir::TyParamBounds,
+        bounds: &hir::ParamBounds,
     ) -> (HirVec<hir::Lifetime>, HirVec<hir::GenericParam>) {
         // This visitor walks over impl trait bounds and creates defs for all lifetimes which
         // appear in the bounds, excluding lifetimes that are created within the bounds.
@@ -1420,9 +1420,9 @@ impl<'a> LoweringContext<'a> {
                         id: def_node_id,
                         span: lifetime.span,
                         pure_wrt_drop: false,
+                        bounds: vec![].into(),
                         kind: hir::GenericParamKind::Lifetime {
                             name,
-                            bounds: vec![].into(),
                             in_band: false,
                             lifetime: hir::Lifetime {
                                 id: def_node_id,
@@ -1882,18 +1882,18 @@ impl<'a> LoweringContext<'a> {
         })
     }
 
-    fn lower_ty_param_bound(
+    fn lower_param_bound(
         &mut self,
-        tpb: &TyParamBound,
+        tpb: &ParamBound,
         itctx: ImplTraitContext,
-    ) -> hir::TyParamBound {
+    ) -> hir::ParamBound {
         match *tpb {
             TraitTyParamBound(ref ty, modifier) => hir::TraitTyParamBound(
                 self.lower_poly_trait_ref(ty, itctx),
                 self.lower_trait_bound_modifier(modifier),
             ),
-            RegionTyParamBound(ref lifetime) => {
-                hir::RegionTyParamBound(self.lower_lifetime(lifetime))
+            Outlives(ref lifetime) => {
+                hir::Outlives(self.lower_lifetime(lifetime))
             }
         }
     }
@@ -1935,7 +1935,7 @@ impl<'a> LoweringContext<'a> {
     fn lower_generic_params(
         &mut self,
         params: &Vec<GenericParam>,
-        add_bounds: &NodeMap<Vec<TyParamBound>>,
+        add_bounds: &NodeMap<Vec<ParamBound>>,
         itctx: ImplTraitContext,
     ) -> hir::HirVec<hir::GenericParam> {
         params.iter().map(|param| self.lower_generic_param(param, add_bounds, itctx)).collect()
@@ -1943,11 +1943,12 @@ impl<'a> LoweringContext<'a> {
 
     fn lower_generic_param(&mut self,
                            param: &GenericParam,
-                           add_bounds: &NodeMap<Vec<TyParamBound>>,
+                           add_bounds: &NodeMap<Vec<ParamBound>>,
                            itctx: ImplTraitContext)
                            -> hir::GenericParam {
+        let mut bounds = self.lower_param_bounds(&param.bounds, itctx);
         match param.kind {
-            GenericParamKind::Lifetime { ref bounds, ref lifetime } => {
+            GenericParamKind::Lifetime { ref lifetime } => {
                 let was_collecting_in_band = self.is_collecting_in_band_lifetimes;
                 self.is_collecting_in_band_lifetimes = false;
 
@@ -1956,9 +1957,9 @@ impl<'a> LoweringContext<'a> {
                     id: lifetime.id,
                     span: lifetime.span,
                     pure_wrt_drop: attr::contains_name(&param.attrs, "may_dangle"),
+                    bounds,
                     kind: hir::GenericParamKind::Lifetime {
                         name: lifetime.name,
-                        bounds: bounds.iter().map(|lt| self.lower_lifetime(lt)).collect(),
                         in_band: false,
                         lifetime,
                     }
@@ -1968,7 +1969,7 @@ impl<'a> LoweringContext<'a> {
 
                 param
             }
-            GenericParamKind::Type { ref bounds, ref default } => {
+            GenericParamKind::Type { ref default, .. } => {
                 let mut name = self.lower_ident(param.ident);
 
                 // Don't expose `Self` (recovered "keyword used as ident" parse error).
@@ -1978,11 +1979,10 @@ impl<'a> LoweringContext<'a> {
                     name = Symbol::gensym("Self");
                 }
 
-                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())
+                                   .chain(self.lower_param_bounds(add_bounds, itctx).into_iter())
                                    .collect();
                 }
 
@@ -1990,9 +1990,9 @@ impl<'a> LoweringContext<'a> {
                     id: self.lower_node_id(param.id).node_id,
                     span: param.ident.span,
                     pure_wrt_drop: attr::contains_name(&param.attrs, "may_dangle"),
+                    bounds,
                     kind: hir::GenericParamKind::Type {
                         name,
-                        bounds,
                         default: default.as_ref().map(|x| {
                             self.lower_ty(x, ImplTraitContext::Disallowed)
                         }),
@@ -2107,7 +2107,7 @@ impl<'a> LoweringContext<'a> {
                                     // Ignore `?Trait` bounds.
                                     // Tthey were copied into type parameters already.
                                     TraitTyParamBound(_, TraitBoundModifier::Maybe) => None,
-                                    _ => Some(this.lower_ty_param_bound(
+                                    _ => Some(this.lower_param_bound(
                                         bound,
                                         ImplTraitContext::Disallowed,
                                     )),
@@ -2228,15 +2228,9 @@ impl<'a> LoweringContext<'a> {
         }
     }
 
-    fn lower_bounds(
-        &mut self,
-        bounds: &[TyParamBound],
-        itctx: ImplTraitContext,
-    ) -> hir::TyParamBounds {
-        bounds
-            .iter()
-            .map(|bound| self.lower_ty_param_bound(bound, itctx))
-            .collect()
+    fn lower_param_bounds(&mut self, bounds: &[ParamBound], itctx: ImplTraitContext)
+        -> hir::ParamBounds {
+        bounds.iter().map(|bound| self.lower_param_bound(bound, itctx)).collect()
     }
 
     fn lower_block(&mut self, b: &Block, targeted_by_break: bool) -> P<hir::Block> {
@@ -2422,7 +2416,7 @@ impl<'a> LoweringContext<'a> {
                 )
             }
             ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => {
-                let bounds = self.lower_bounds(bounds, ImplTraitContext::Disallowed);
+                let bounds = self.lower_param_bounds(bounds, ImplTraitContext::Disallowed);
                 let items = items
                     .iter()
                     .map(|item| self.lower_trait_item_ref(item))
@@ -2437,7 +2431,7 @@ impl<'a> LoweringContext<'a> {
             }
             ItemKind::TraitAlias(ref generics, ref bounds) => hir::ItemTraitAlias(
                 self.lower_generics(generics, ImplTraitContext::Disallowed),
-                self.lower_bounds(bounds, ImplTraitContext::Disallowed),
+                self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
             ),
             ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"),
         }
@@ -2664,7 +2658,7 @@ impl<'a> LoweringContext<'a> {
             TraitItemKind::Type(ref bounds, ref default) => (
                 self.lower_generics(&i.generics, ImplTraitContext::Disallowed),
                 hir::TraitItemKind::Type(
-                    self.lower_bounds(bounds, ImplTraitContext::Disallowed),
+                    self.lower_param_bounds(bounds, ImplTraitContext::Disallowed),
                     default
                         .as_ref()
                         .map(|x| self.lower_ty(x, ImplTraitContext::Disallowed)),
diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs
index 135403c9c27..8253a34f310 100644
--- a/src/librustc/hir/mod.rs
+++ b/src/librustc/hir/mod.rs
@@ -22,7 +22,7 @@ pub use self::Mutability::*;
 pub use self::PrimTy::*;
 pub use self::Stmt_::*;
 pub use self::Ty_::*;
-pub use self::TyParamBound::*;
+pub use self::ParamBound::*;
 pub use self::UnOp::*;
 pub use self::UnsafeSource::*;
 pub use self::Visibility::{Public, Inherited};
@@ -416,41 +416,42 @@ impl GenericArgs {
     }
 }
 
+/// A modifier on a bound, currently this is only used for `?Sized`, where the
+/// modifier is `Maybe`. Negative bounds should also be handled here.
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum TraitBoundModifier {
+    None,
+    Maybe,
+}
+
+pub type Outlives = Lifetime;
+
 /// The AST represents all type param bounds as types.
 /// typeck::collect::compute_bounds matches these against
 /// the "special" built-in traits (see middle::lang_items) and
 /// detects Copy, Send and Sync.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TyParamBound {
+pub enum ParamBound {
     TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
-    RegionTyParamBound(Lifetime),
+    Outlives(Lifetime),
 }
 
-impl TyParamBound {
+impl ParamBound {
     pub fn span(&self) -> Span {
         match self {
             &TraitTyParamBound(ref t, ..) => t.span,
-            &RegionTyParamBound(ref l) => l.span,
+            &Outlives(ref l) => l.span,
         }
     }
 }
 
-/// A modifier on a bound, currently this is only used for `?Sized`, where the
-/// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitBoundModifier {
-    None,
-    Maybe,
-}
-
-pub type TyParamBounds = HirVec<TyParamBound>;
+pub type ParamBounds = HirVec<ParamBound>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum GenericParamKind {
     /// A lifetime definition, eg `'a: 'b + 'c + 'd`.
     Lifetime {
         name: LifetimeName,
-        bounds: HirVec<Lifetime>,
         // Indicates that the lifetime definition was synthetically added
         // as a result of an in-band lifetime usage like:
         // `fn foo(x: &'a u8) -> &'a u8 { x }`
@@ -460,7 +461,6 @@ pub enum GenericParamKind {
     },
     Type {
         name: Name,
-        bounds: TyParamBounds,
         default: Option<P<Ty>>,
         synthetic: Option<SyntheticTyParamKind>,
         attrs: HirVec<Attribute>,
@@ -470,6 +470,7 @@ pub enum GenericParamKind {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct GenericParam {
     pub id: NodeId,
+    pub bounds: ParamBounds,
     pub span: Span,
     pub pure_wrt_drop: bool,
 
@@ -587,7 +588,7 @@ pub struct WhereBoundPredicate {
     /// The type being bounded
     pub bounded_ty: P<Ty>,
     /// Trait and lifetime bounds (`Clone+Send+'static`)
-    pub bounds: TyParamBounds,
+    pub bounds: ParamBounds,
 }
 
 /// A lifetime predicate, e.g. `'a: 'b+'c`
@@ -1554,7 +1555,7 @@ pub enum TraitItemKind {
     Method(MethodSig, TraitMethod),
     /// An associated type with (possibly empty) bounds and optional concrete
     /// type
-    Type(TyParamBounds, Option<P<Ty>>),
+    Type(ParamBounds, Option<P<Ty>>),
 }
 
 // The bodies for items are stored "out of line", in a separate
@@ -1639,7 +1640,7 @@ pub struct BareFnTy {
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub struct ExistTy {
     pub generics: Generics,
-    pub bounds: TyParamBounds,
+    pub bounds: ParamBounds,
     pub impl_trait_fn: Option<DefId>,
 }
 
@@ -2048,9 +2049,9 @@ pub enum Item_ {
     /// A union definition, e.g. `union Foo<A, B> {x: A, y: B}`
     ItemUnion(VariantData, Generics),
     /// Represents a Trait Declaration
-    ItemTrait(IsAuto, Unsafety, Generics, TyParamBounds, HirVec<TraitItemRef>),
+    ItemTrait(IsAuto, Unsafety, Generics, ParamBounds, HirVec<TraitItemRef>),
     /// Represents a Trait Alias Declaration
-    ItemTraitAlias(Generics, TyParamBounds),
+    ItemTraitAlias(Generics, ParamBounds),
 
     /// An implementation, eg `impl<A> Trait for Foo { .. }`
     ItemImpl(Unsafety,
diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs
index eabf554bc53..4058db17f2f 100644
--- a/src/librustc/hir/print.rs
+++ b/src/librustc/hir/print.rs
@@ -24,7 +24,7 @@ use syntax::util::parser::{self, AssocOp, Fixity};
 use syntax_pos::{self, BytePos, FileName};
 
 use hir;
-use hir::{PatKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier, RangeEnd};
+use hir::{PatKind, Outlives, TraitTyParamBound, TraitBoundModifier, RangeEnd};
 use hir::{GenericParam, GenericParamKind, GenericArg};
 
 use std::cell::Cell;
@@ -514,7 +514,7 @@ impl<'a> State<'a> {
 
     fn print_associated_type(&mut self,
                              name: ast::Name,
-                             bounds: Option<&hir::TyParamBounds>,
+                             bounds: Option<&hir::ParamBounds>,
                              ty: Option<&hir::Ty>)
                              -> io::Result<()> {
         self.word_space("type")?;
@@ -2071,7 +2071,7 @@ impl<'a> State<'a> {
         }
     }
 
-    pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::TyParamBound]) -> io::Result<()> {
+    pub fn print_bounds(&mut self, prefix: &str, bounds: &[hir::ParamBound]) -> io::Result<()> {
         if !bounds.is_empty() {
             self.s.word(prefix)?;
             let mut first = true;
@@ -2092,7 +2092,7 @@ impl<'a> State<'a> {
                         }
                         self.print_poly_trait_ref(tref)?;
                     }
-                    RegionTyParamBound(lt) => {
+                    Outlives(lt) => {
                         self.print_lifetime(lt)?;
                     }
                 }
@@ -2117,17 +2117,22 @@ impl<'a> State<'a> {
     pub fn print_generic_param(&mut self, param: &GenericParam) -> io::Result<()> {
         self.print_name(param.name())?;
         match param.kind {
-            GenericParamKind::Lifetime { ref bounds, .. } => {
+            GenericParamKind::Lifetime { .. } => {
                 let mut sep = ":";
-                for bound in bounds {
-                    self.s.word(sep)?;
-                    self.print_lifetime(bound)?;
-                    sep = "+";
+                for bound in &param.bounds {
+                    match bound {
+                        hir::ParamBound::Outlives(lt) => {
+                            self.s.word(sep)?;
+                            self.print_lifetime(lt)?;
+                            sep = "+";
+                        }
+                        _ => bug!(),
+                    }
                 }
                 Ok(())
             }
-            GenericParamKind::Type { ref bounds, ref default, .. } => {
-                self.print_bounds(":", bounds)?;
+            GenericParamKind::Type { ref default, .. } => {
+                self.print_bounds(":", &param.bounds)?;
                 match default {
                     Some(default) => {
                         self.s.space()?;
diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs
index fc0eee230cd..f8da828d2c3 100644
--- a/src/librustc/ich/impls_hir.rs
+++ b/src/librustc/ich/impls_hir.rs
@@ -184,9 +184,9 @@ impl_stable_hash_for!(struct hir::GenericArgs {
     parenthesized
 });
 
-impl_stable_hash_for!(enum hir::TyParamBound {
+impl_stable_hash_for!(enum hir::ParamBound {
     TraitTyParamBound(poly_trait_ref, trait_bound_modifier),
-    RegionTyParamBound(lifetime)
+    Outlives(lifetime)
 });
 
 impl_stable_hash_for!(enum hir::TraitBoundModifier {
@@ -198,6 +198,7 @@ impl_stable_hash_for!(struct hir::GenericParam {
     id,
     span,
     pure_wrt_drop,
+    bounds,
     kind
 });
 
@@ -207,16 +208,13 @@ impl<'a> HashStable<StableHashingContext<'a>> for hir::GenericParamKind {
                                           hasher: &mut StableHasher<W>) {
         mem::discriminant(self).hash_stable(hcx, hasher);
         match self {
-            hir::GenericParamKind::Lifetime { name, ref bounds, in_band,
-                                              ref lifetime } => {
+            hir::GenericParamKind::Lifetime { name, in_band, ref lifetime } => {
                 name.hash_stable(hcx, hasher);
-                bounds.hash_stable(hcx, hasher);
                 in_band.hash_stable(hcx, hasher);
                 lifetime.hash_stable(hcx, hasher);
             }
-            hir::GenericParamKind::Type { name, ref bounds, ref default, synthetic, attrs } => {
+            hir::GenericParamKind::Type { name, ref default, synthetic, attrs } => {
                 name.hash_stable(hcx, hasher);
-                bounds.hash_stable(hcx, hasher);
                 default.hash_stable(hcx, hasher);
                 synthetic.hash_stable(hcx, hasher);
                 attrs.hash_stable(hcx, hasher);
diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs
index b30e5bab968..4d6f2fb41b0 100644
--- a/src/librustc/infer/error_reporting/mod.rs
+++ b/src/librustc/infer/error_reporting/mod.rs
@@ -61,7 +61,7 @@ use super::region_constraints::GenericKind;
 use super::lexical_region_resolve::RegionResolutionError;
 
 use std::fmt;
-use hir::{self, GenericParamKind};
+use hir;
 use hir::map as hir_map;
 use hir::def_id::DefId;
 use middle::region;
@@ -1038,12 +1038,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
                             // instead we suggest `T: 'a + 'b` in that case.
                             let mut has_bounds = false;
                             if let hir_map::NodeGenericParam(ref param) = hir.get(id) {
-                                match param.kind {
-                                    GenericParamKind::Type { ref bounds, .. } => {
-                                        has_bounds = !bounds.is_empty();
-                                    }
-                                    _ => bug!("unexpected non-type NodeGenericParam"),
-                                }
+                                has_bounds = !param.bounds.is_empty();
                             }
                             let sp = hir.span(id);
                             // `sp` only covers `T`, change it so that it covers
diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs
index 561e6094c86..2963227c211 100644
--- a/src/librustc/middle/resolve_lifetime.rs
+++ b/src/librustc/middle/resolve_lifetime.rs
@@ -881,8 +881,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
         for param in &generics.params {
             match param.kind {
                 GenericParamKind::Lifetime { .. } => {}
-                GenericParamKind::Type { ref bounds, ref default, .. } => {
-                    walk_list!(self, visit_ty_param_bound, bounds);
+                GenericParamKind::Type { ref default, .. } => {
+                    walk_list!(self, visit_ty_param_bound, &param.bounds);
                     if let Some(ref ty) = default {
                         self.visit_ty(&ty);
                     }
@@ -1255,9 +1255,9 @@ fn object_lifetime_defaults_for_item(
     tcx: TyCtxt<'_, '_, '_>,
     generics: &hir::Generics,
 ) -> Vec<ObjectLifetimeDefault> {
-    fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::TyParamBound]) {
+    fn add_bounds(set: &mut Set1<hir::LifetimeName>, bounds: &[hir::ParamBound]) {
         for bound in bounds {
-            if let hir::RegionTyParamBound(ref lifetime) = *bound {
+            if let hir::Outlives(ref lifetime) = *bound {
                 set.insert(lifetime.name);
             }
         }
@@ -1265,10 +1265,10 @@ fn object_lifetime_defaults_for_item(
 
     generics.params.iter().filter_map(|param| match param.kind {
         GenericParamKind::Lifetime { .. } => None,
-        GenericParamKind::Type { ref bounds, .. } => {
+        GenericParamKind::Type { .. } => {
             let mut set = Set1::Empty;
 
-            add_bounds(&mut set, &bounds);
+            add_bounds(&mut set, &param.bounds);
 
             let param_def_id = tcx.hir.local_def_id(param.id);
             for predicate in &generics.where_clause.predicates {
@@ -2283,45 +2283,44 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
             // It is a soft error to shadow a lifetime within a parent scope.
             self.check_lifetime_param_for_shadowing(old_scope, &lifetime_i);
 
-            let bounds = match lifetime_i.kind {
-                GenericParamKind::Lifetime { ref bounds, .. } => bounds,
-                _ => bug!(),
-            };
-            for bound in bounds {
-                match bound.name {
-                    hir::LifetimeName::Underscore => {
-                        let mut err = struct_span_err!(
-                            self.tcx.sess,
-                            bound.span,
-                            E0637,
-                            "invalid lifetime bound name: `'_`"
-                        );
-                        err.span_label(bound.span, "`'_` is a reserved lifetime name");
-                        err.emit();
-                    }
-                    hir::LifetimeName::Static => {
-                        self.insert_lifetime(bound, Region::Static);
-                        self.tcx
-                            .sess
-                            .struct_span_warn(
-                                lifetime_i.span.to(bound.span),
-                                &format!(
-                                    "unnecessary lifetime parameter `{}`",
+            for bound in &lifetime_i.bounds {
+                match bound {
+                    hir::ParamBound::Outlives(lt) => match lt.name {
+                        hir::LifetimeName::Underscore => {
+                            let mut err = struct_span_err!(
+                                self.tcx.sess,
+                                lt.span,
+                                E0637,
+                                "invalid lifetime bound name: `'_`"
+                            );
+                            err.span_label(lt.span, "`'_` is a reserved lifetime name");
+                            err.emit();
+                        }
+                        hir::LifetimeName::Static => {
+                            self.insert_lifetime(lt, Region::Static);
+                            self.tcx
+                                .sess
+                                .struct_span_warn(
+                                    lifetime_i.span.to(lt.span),
+                                    &format!(
+                                        "unnecessary lifetime parameter `{}`",
+                                        lifetime_i.name()
+                                    ),
+                                )
+                                .help(&format!(
+                                    "you can use the `'static` lifetime directly, in place \
+                                     of `{}`",
                                     lifetime_i.name()
-                                ),
-                            )
-                            .help(&format!(
-                                "you can use the `'static` lifetime directly, in place \
-                                 of `{}`",
-                                lifetime_i.name()
-                            ))
-                            .emit();
-                    }
-                    hir::LifetimeName::Fresh(_)
-                    | hir::LifetimeName::Implicit
-                    | hir::LifetimeName::Name(_) => {
-                        self.resolve_lifetime_ref(bound);
+                                ))
+                                .emit();
+                        }
+                        hir::LifetimeName::Fresh(_)
+                        | hir::LifetimeName::Implicit
+                        | hir::LifetimeName::Name(_) => {
+                            self.resolve_lifetime_ref(lt);
+                        }
                     }
+                    _ => bug!(),
                 }
             }
         }
@@ -2521,8 +2520,8 @@ fn insert_late_bound_lifetimes(
 
     for param in &generics.params {
         match param.kind {
-            hir::GenericParamKind::Lifetime { ref bounds, .. } => {
-                if !bounds.is_empty() {
+            hir::GenericParamKind::Lifetime { .. } => {
+                if !param.bounds.is_empty() {
                     // `'a: 'b` means both `'a` and `'b` are referenced
                     appears_in_where_clause.regions.insert(lifetime_def.lifetime.name);
                 }
diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs
index 18b7024a898..941fabe26a6 100644
--- a/src/librustc_lint/builtin.rs
+++ b/src/librustc_lint/builtin.rs
@@ -1537,14 +1537,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeAliasBounds {
         }
         // The parameters must not have bounds
         for param in type_alias_generics.params.iter() {
-            let spans: Vec<_> = match param.kind {
-                GenericParamKind::Lifetime { ref bounds, .. } => {
-                    bounds.iter().map(|b| b.span).collect()
-                }
-                GenericParamKind::Type { ref bounds, .. } => {
-                    bounds.iter().map(|b| b.span()).collect()
-                }
-            };
+            let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
             if !spans.is_empty() {
                 let mut err = cx.struct_span_lint(
                     TYPE_ALIAS_BOUNDS,
diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs
index dfcdb688b00..d14a02ec8d1 100644
--- a/src/librustc_passes/ast_validation.rs
+++ b/src/librustc_passes/ast_validation.rs
@@ -99,7 +99,7 @@ impl<'a> AstValidator<'a> {
         }
     }
 
-    fn no_questions_in_bounds(&self, bounds: &TyParamBounds, where_: &str, is_trait: bool) {
+    fn no_questions_in_bounds(&self, bounds: &ParamBounds, where_: &str, is_trait: bool) {
         for bound in bounds {
             if let TraitTyParamBound(ref poly, TraitBoundModifier::Maybe) = *bound {
                 let mut err = self.err_handler().struct_span_err(poly.span,
@@ -142,9 +142,9 @@ impl<'a> AstValidator<'a> {
         // Check only lifetime parameters are present and that the lifetime
         // parameters that are present have no bounds.
         let non_lt_param_spans: Vec<_> = params.iter().filter_map(|param| match param.kind {
-                GenericParamKind::Lifetime { ref bounds, .. } => {
-                    if !bounds.is_empty() {
-                        let spans: Vec<_> = bounds.iter().map(|b| b.ident.span).collect();
+                GenericParamKind::Lifetime { .. } => {
+                    if !param.bounds.is_empty() {
+                        let spans: Vec<_> = param.bounds.iter().map(|b| b.span()).collect();
                         self.err_handler()
                             .span_err(spans, "lifetime bounds cannot be used in this context");
                     }
@@ -190,7 +190,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
             TyKind::TraitObject(ref bounds, ..) => {
                 let mut any_lifetime_bounds = false;
                 for bound in bounds {
-                    if let RegionTyParamBound(ref lifetime) = *bound {
+                    if let Outlives(ref lifetime) = *bound {
                         if any_lifetime_bounds {
                             span_err!(self.session, lifetime.ident.span, E0226,
                                       "only a single explicit lifetime bound is permitted");
@@ -330,8 +330,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                 for param in params {
                     match param.kind {
                         GenericParamKind::Lifetime { .. } => {}
-                        GenericParamKind::Type { ref bounds, ref default, .. } => {
-                            if !bounds.is_empty() {
+                        GenericParamKind::Type { ref default, .. } => {
+                            if !param.bounds.is_empty() {
                                 self.err_handler()
                                     .span_err(param.ident.span, "type parameters on the left \
                                         side of a trait alias cannot be bounded");
diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs
index ba0be974b27..c58b6a96ee7 100644
--- a/src/librustc_passes/hir_stats.rs
+++ b/src/librustc_passes/hir_stats.rs
@@ -203,8 +203,8 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
         hir_visit::walk_impl_item(self, ii)
     }
 
-    fn visit_ty_param_bound(&mut self, bounds: &'v hir::TyParamBound) {
-        self.record("TyParamBound", Id::None, bounds);
+    fn visit_ty_param_bound(&mut self, bounds: &'v hir::ParamBound) {
+        self.record("ParamBound", Id::None, bounds);
         hir_visit::walk_ty_param_bound(self, bounds)
     }
 
@@ -322,8 +322,8 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
         ast_visit::walk_impl_item(self, ii)
     }
 
-    fn visit_ty_param_bound(&mut self, bounds: &'v ast::TyParamBound) {
-        self.record("TyParamBound", Id::None, bounds);
+    fn visit_ty_param_bound(&mut self, bounds: &'v ast::ParamBound) {
+        self.record("ParamBound", Id::None, bounds);
         ast_visit::walk_ty_param_bound(self, bounds)
     }
 
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 388ac5cdb50..2667f68b260 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -1038,7 +1038,7 @@ impl<'a, 'tcx> ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     }
 
     fn check_ty_param_bound(&mut self,
-                            ty_param_bound: &hir::TyParamBound) {
+                            ty_param_bound: &hir::ParamBound) {
         if let hir::TraitTyParamBound(ref trait_ref, _) = *ty_param_bound {
             if self.path_is_private_type(&trait_ref.trait_ref.path) {
                 self.old_error_set.insert(trait_ref.trait_ref.ref_id);
@@ -1270,8 +1270,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> {
     fn visit_generics(&mut self, generics: &'tcx hir::Generics) {
         generics.params.iter().for_each(|param| match param.kind {
             GenericParamKind::Lifetime { .. } => {}
-            GenericParamKind::Type { ref bounds, .. } => {
-                for bound in bounds {
+            GenericParamKind::Type { .. } => {
+                for bound in &param.bounds {
                     self.check_ty_param_bound(bound);
                 }
             }
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index 6561202be51..b51ef904495 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -813,8 +813,8 @@ impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> {
         for param in &generics.params {
             match param.kind {
                 GenericParamKind::Lifetime { .. } => self.visit_generic_param(param),
-                GenericParamKind::Type { ref bounds, ref default, .. } => {
-                    for bound in bounds {
+                GenericParamKind::Type { ref default, .. } => {
+                    for bound in &param.bounds {
                         self.visit_ty_param_bound(bound);
                     }
 
diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs
index 6cfec57f80e..cbae6c1ab1a 100644
--- a/src/librustc_save_analysis/dump_visitor.rs
+++ b/src/librustc_save_analysis/dump_visitor.rs
@@ -718,7 +718,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
         &mut self,
         item: &'l ast::Item,
         generics: &'l ast::Generics,
-        trait_refs: &'l ast::TyParamBounds,
+        trait_refs: &'l ast::ParamBounds,
         methods: &'l [ast::TraitItem],
     ) {
         let name = item.ident.to_string();
@@ -762,7 +762,7 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> DumpVisitor<'l, 'tcx, 'll, O> {
         for super_bound in trait_refs.iter() {
             let trait_ref = match *super_bound {
                 ast::TraitTyParamBound(ref trait_ref, _) => trait_ref,
-                ast::RegionTyParamBound(..) => {
+                ast::Outlives(..) => {
                     continue;
                 }
             };
@@ -1487,8 +1487,8 @@ impl<'l, 'tcx: 'l, 'll, O: DumpOutput + 'll> Visitor<'l> for DumpVisitor<'l, 'tc
     fn visit_generics(&mut self, generics: &'l ast::Generics) {
         generics.params.iter().for_each(|param| match param.kind {
             ast::GenericParamKind::Lifetime { .. } => {}
-            ast::GenericParamKind::Type { ref bounds, ref default, .. } => {
-                for bound in bounds {
+            ast::GenericParamKind::Type { ref default, .. } => {
+                for bound in &param.bounds {
                     if let ast::TraitTyParamBound(ref trait_ref, _) = *bound {
                         self.process_path(trait_ref.trait_ref.ref_id, &trait_ref.trait_ref.path)
                     }
diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs
index 6a63995c0fd..58e2e9b2258 100644
--- a/src/librustc_save_analysis/sig.rs
+++ b/src/librustc_save_analysis/sig.rs
@@ -104,7 +104,7 @@ pub fn assoc_const_signature(
 pub fn assoc_type_signature(
     id: NodeId,
     ident: ast::Ident,
-    bounds: Option<&ast::TyParamBounds>,
+    bounds: Option<&ast::ParamBounds>,
     default: Option<&ast::Ty>,
     scx: &SaveContext,
 ) -> Option<Signature> {
@@ -623,22 +623,22 @@ impl Sig for ast::Generics {
                 start: offset + text.len(),
                 end: offset + text.len() + param_text.len(),
             });
-            match param.kind {
-                ast::GenericParamKind::Lifetime { ref bounds, .. } => {
-                    if !bounds.is_empty() {
-                        param_text.push_str(": ");
-                        let bounds = bounds.iter()
-                            .map(|l| l.ident.to_string())
+            if !param.bounds.is_empty() {
+                param_text.push_str(": ");
+                match param.kind {
+                    ast::GenericParamKind::Lifetime { .. } => {
+                        let bounds = param.bounds.iter()
+                            .map(|bound| match bound {
+                                ast::ParamBound::Outlives(lt) => lt.ident.to_string(),
+                                _ => panic!(),
+                            })
                             .collect::<Vec<_>>()
                             .join(" + ");
                         param_text.push_str(&bounds);
                         // FIXME add lifetime bounds refs.
                     }
-                }
-                ast::GenericParamKind::Type { ref bounds, .. } => {
-                    if !bounds.is_empty() {
-                        param_text.push_str(": ");
-                        param_text.push_str(&pprust::bounds_to_string(bounds));
+                    ast::GenericParamKind::Type { .. } => {
+                        param_text.push_str(&pprust::bounds_to_string(&param.bounds));
                         // FIXME descend properly into bounds.
                     }
                 }
@@ -841,7 +841,7 @@ fn name_and_generics(
 fn make_assoc_type_signature(
     id: NodeId,
     ident: ast::Ident,
-    bounds: Option<&ast::TyParamBounds>,
+    bounds: Option<&ast::ParamBounds>,
     default: Option<&ast::Ty>,
     scx: &SaveContext,
 ) -> Result {
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index 8a64e4a5367..5f8955612e1 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -844,9 +844,9 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                         let bounds = impl_m.generics.params.iter().find_map(|param| {
                             match param.kind {
                                 GenericParamKind::Lifetime { .. } => None,
-                                GenericParamKind::Type { ref bounds, .. } => {
+                                GenericParamKind::Type { .. } => {
                                     if param.id == impl_node_id {
-                                        Some(bounds)
+                                        Some(&param.bounds)
                                     } else {
                                         None
                                     }
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 2e4ceb5a65c..f95f6a26f0b 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -315,9 +315,7 @@ impl<'a, 'tcx> ItemCtxt<'a, 'tcx> {
         let from_ty_params =
             ast_generics.params.iter()
                 .filter_map(|param| match param.kind {
-                    GenericParamKind::Type { ref bounds, .. } if param.id == param_id => {
-                        Some(bounds)
-                    }
+                    GenericParamKind::Type { .. } if param.id == param_id => Some(&param.bounds),
                     _ => None
                 })
                 .flat_map(|bounds| bounds.iter())
@@ -1252,7 +1250,7 @@ fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
 // Is it marked with ?Sized
 fn is_unsized<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
-                                ast_bounds: &[hir::TyParamBound],
+                                ast_bounds: &[hir::ParamBound],
                                 span: Span) -> bool
 {
     let tcx = astconv.tcx();
@@ -1445,13 +1443,15 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
         index += 1;
 
         match param.kind {
-            GenericParamKind::Lifetime { ref bounds, .. } => {
-                for bound in bounds {
-                    let bound_region = AstConv::ast_region_to_region(&icx, bound, None);
-                    let outlives =
-                        ty::Binder::bind(ty::OutlivesPredicate(region, bound_region));
-                    predicates.push(outlives.to_predicate());
-                }
+            GenericParamKind::Lifetime { .. } => {
+                param.bounds.iter().for_each(|bound| match bound {
+                    hir::ParamBound::Outlives(lt) => {
+                        let bound = AstConv::ast_region_to_region(&icx, &lt, None);
+                        let outlives = ty::Binder::bind(ty::OutlivesPredicate(region, bound));
+                        predicates.push(outlives.to_predicate());
+                    }
+                    _ => bug!(),
+                });
             },
             _ => bug!(),
         }
@@ -1461,13 +1461,12 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
     // type parameter (e.g., `<T:Foo>`).
     for param in &ast_generics.params {
         match param.kind {
-            GenericParamKind::Type { ref bounds, .. } => {
-                let param_ty = ty::ParamTy::new(index, param.name().as_interned_str())
-                                           .to_ty(tcx);
+            GenericParamKind::Type { .. } => {
+                let param_ty = ty::ParamTy::new(index, param.name().as_interned_str()).to_ty(tcx);
                 index += 1;
 
-                let bounds =
-                    compute_bounds(&icx, param_ty, bounds, SizedByDefault::Yes, param.span);
+                let sized = SizedByDefault::Yes;
+                let bounds = compute_bounds(&icx, param_ty, &param.bounds, sized, param.span);
                 predicates.extend(bounds.predicates(tcx, param_ty));
             }
             _ => {}
@@ -1483,7 +1482,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
                 for bound in bound_pred.bounds.iter() {
                     match bound {
-                        &hir::TyParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
+                        &hir::ParamBound::TraitTyParamBound(ref poly_trait_ref, _) => {
                             let mut projections = Vec::new();
 
                             let trait_ref =
@@ -1499,7 +1498,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                             }
                         }
 
-                        &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
+                        &hir::ParamBound::Outlives(ref lifetime) => {
                             let region = AstConv::ast_region_to_region(&icx,
                                                                        lifetime,
                                                                        None);
@@ -1578,7 +1577,7 @@ pub enum SizedByDefault { Yes, No, }
 /// built-in trait (formerly known as kind): Send.
 pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
                                         param_ty: Ty<'tcx>,
-                                        ast_bounds: &[hir::TyParamBound],
+                                        ast_bounds: &[hir::ParamBound],
                                         sized_by_default: SizedByDefault,
                                         span: Span)
                                         -> Bounds<'tcx>
@@ -1591,7 +1590,7 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
                 trait_bounds.push(b);
             }
             hir::TraitTyParamBound(_, hir::TraitBoundModifier::Maybe) => {}
-            hir::RegionTyParamBound(ref l) => {
+            hir::Outlives(ref l) => {
                 region_bounds.push(l);
             }
         }
@@ -1625,14 +1624,14 @@ pub fn compute_bounds<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
     }
 }
 
-/// Converts a specific TyParamBound from the AST into a set of
+/// Converts a specific ParamBound from the AST into a set of
 /// predicates that apply to the self-type. A vector is returned
 /// because this can be anywhere from 0 predicates (`T:?Sized` adds no
 /// predicates) to 1 (`T:Foo`) to many (`T:Bar<X=i32>` adds `T:Bar`
 /// and `<T as Bar>::X == i32`).
 fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
                                param_ty: Ty<'tcx>,
-                               bound: &hir::TyParamBound)
+                               bound: &hir::ParamBound)
                                -> Vec<ty::Predicate<'tcx>>
 {
     match *bound {
@@ -1646,7 +1645,7 @@ fn predicates_from_bound<'tcx>(astconv: &AstConv<'tcx, 'tcx>,
                        .chain(Some(pred.to_predicate()))
                        .collect()
         }
-        hir::RegionTyParamBound(ref lifetime) => {
+        hir::Outlives(ref lifetime) => {
             let region = astconv.ast_region_to_region(lifetime, None);
             let pred = ty::Binder::bind(ty::OutlivesPredicate(param_ty, region));
             vec![ty::Predicate::TypeOutlives(pred)]
diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs
index 2a63b124866..2686ad96c6e 100644
--- a/src/librustdoc/clean/auto_trait.rs
+++ b/src/librustdoc/clean/auto_trait.rs
@@ -536,7 +536,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
 
     fn make_final_bounds<'b, 'c, 'cx>(
         &self,
-        ty_to_bounds: FxHashMap<Type, FxHashSet<TyParamBound>>,
+        ty_to_bounds: FxHashMap<Type, FxHashSet<ParamBound>>,
         ty_to_fn: FxHashMap<Type, (Option<PolyTrait>, Option<Type>)>,
         lifetime_to_bounds: FxHashMap<Lifetime, FxHashSet<Lifetime>>,
     ) -> Vec<WherePredicate> {
@@ -589,7 +589,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                         }
                         _ => panic!("Unexpected data: {:?}, {:?}", ty, data),
                     };
-                    bounds.insert(TyParamBound::TraitBound(
+                    bounds.insert(ParamBound::TraitBound(
                         PolyTrait {
                             trait_: new_ty,
                             generic_params: poly_trait.generic_params,
@@ -732,7 +732,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                         // later
 
                         let is_fn = match &mut b {
-                            &mut TyParamBound::TraitBound(ref mut p, _) => {
+                            &mut ParamBound::TraitBound(ref mut p, _) => {
                                 // Insert regions into the for_generics hash map first, to ensure
                                 // that we don't end up with duplicate bounds (e.g. for<'b, 'b>)
                                 for_generics.extend(p.generic_params.clone());
@@ -826,7 +826,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                                         .entry(*ty.clone())
                                         .or_insert_with(|| FxHashSet());
 
-                                    bounds.insert(TyParamBound::TraitBound(
+                                    bounds.insert(ParamBound::TraitBound(
                                         PolyTrait {
                                             trait_: Type::ResolvedPath {
                                                 path: new_trait_path,
@@ -843,7 +843,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                                     // that we don't see a
                                     // duplicate bound like `T: Iterator + Iterator<Item=u8>`
                                     // on the docs page.
-                                    bounds.remove(&TyParamBound::TraitBound(
+                                    bounds.remove(&ParamBound::TraitBound(
                                         PolyTrait {
                                             trait_: *trait_.clone(),
                                             generic_params: Vec::new(),
@@ -877,7 +877,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
                     default.take();
                     let generic_ty = Type::Generic(param.name.clone());
                     if !has_sized.contains(&generic_ty) {
-                        bounds.insert(0, TyParamBound::maybe_sized(self.cx));
+                        bounds.insert(0, ParamBound::maybe_sized(self.cx));
                     }
                 }
                 GenericParamDefKind::Lifetime => {}
@@ -911,7 +911,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
     // both for visual consistency between 'rustdoc' runs, and to
     // make writing tests much easier
     #[inline]
-    fn sort_where_bounds(&self, mut bounds: &mut Vec<TyParamBound>) {
+    fn sort_where_bounds(&self, mut bounds: &mut Vec<ParamBound>) {
         // We should never have identical bounds - and if we do,
         // they're visually identical as well. Therefore, using
         // an unstable sort is fine.
@@ -939,7 +939,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
     // to end users, it makes writing tests much more difficult, as predicates
     // can appear in any order in the final result.
     //
-    // To solve this problem, we sort WherePredicates and TyParamBounds
+    // To solve this problem, we sort WherePredicates and ParamBounds
     // by their Debug string. The thing to keep in mind is that we don't really
     // care what the final order is - we're synthesizing an impl or bound
     // ourselves, so any order can be considered equally valid. By sorting the
@@ -949,7 +949,7 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> {
     // Using the Debug impementation for sorting prevents us from needing to
     // write quite a bit of almost entirely useless code (e.g. how should two
     // Types be sorted relative to each other). It also allows us to solve the
-    // problem for both WherePredicates and TyParamBounds at the same time. This
+    // problem for both WherePredicates and ParamBounds at the same time. This
     // approach is probably somewhat slower, but the small number of items
     // involved (impls rarely have more than a few bounds) means that it
     // shouldn't matter in practice.
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 80eb2d1e214..afe959aaec5 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -474,7 +474,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
             } if *s == "Self" => {
                 bounds.retain(|bound| {
                     match *bound {
-                        clean::TyParamBound::TraitBound(clean::PolyTrait {
+                        clean::ParamBound::TraitBound(clean::PolyTrait {
                             trait_: clean::ResolvedPath { did, .. },
                             ..
                         }, _) => did != trait_did,
@@ -505,7 +505,7 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics) -> clean:
 /// the metadata for a crate, so we want to separate those out and create a new
 /// list of explicit supertrait bounds to render nicely.
 fn separate_supertrait_bounds(mut g: clean::Generics)
-                              -> (clean::Generics, Vec<clean::TyParamBound>) {
+                              -> (clean::Generics, Vec<clean::ParamBound>) {
     let mut ty_bounds = Vec::new();
     g.where_predicates.retain(|pred| {
         match *pred {
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 89835ab6aae..4cc8de91baa 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -14,7 +14,7 @@
 pub use self::Type::*;
 pub use self::Mutability::*;
 pub use self::ItemEnum::*;
-pub use self::TyParamBound::*;
+pub use self::ParamBound::*;
 pub use self::SelfTy::*;
 pub use self::FunctionRetTy::*;
 pub use self::Visibility::{Public, Inherited};
@@ -532,7 +532,7 @@ pub enum ItemEnum {
     MacroItem(Macro),
     PrimitiveItem(PrimitiveType),
     AssociatedConstItem(Type, Option<String>),
-    AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
+    AssociatedTypeItem(Vec<ParamBound>, Option<Type>),
     /// An item that has been stripped by a rustdoc pass
     StrippedItem(Box<ItemEnum>),
     KeywordItem(String),
@@ -1458,13 +1458,13 @@ impl Clean<Attributes> for [ast::Attribute] {
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
-pub enum TyParamBound {
+pub enum ParamBound {
     RegionBound(Lifetime),
     TraitBound(PolyTrait, hir::TraitBoundModifier)
 }
 
-impl TyParamBound {
-    fn maybe_sized(cx: &DocContext) -> TyParamBound {
+impl ParamBound {
+    fn maybe_sized(cx: &DocContext) -> ParamBound {
         let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem);
         let empty = cx.tcx.intern_substs(&[]);
         let path = external_path(cx, &cx.tcx.item_name(did).as_str(),
@@ -1483,7 +1483,7 @@ impl TyParamBound {
 
     fn is_sized_bound(&self, cx: &DocContext) -> bool {
         use rustc::hir::TraitBoundModifier as TBM;
-        if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
+        if let ParamBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
             if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
                 return true;
             }
@@ -1492,7 +1492,7 @@ impl TyParamBound {
     }
 
     fn get_poly_trait(&self) -> Option<PolyTrait> {
-        if let TyParamBound::TraitBound(ref p, _) = *self {
+        if let ParamBound::TraitBound(ref p, _) = *self {
             return Some(p.clone())
         }
         None
@@ -1500,17 +1500,17 @@ impl TyParamBound {
 
     fn get_trait_type(&self) -> Option<Type> {
 
-        if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
+        if let ParamBound::TraitBound(PolyTrait { ref trait_, .. }, _) = *self {
             return Some(trait_.clone());
         }
         None
     }
 }
 
-impl Clean<TyParamBound> for hir::TyParamBound {
-    fn clean(&self, cx: &DocContext) -> TyParamBound {
+impl Clean<ParamBound> for hir::ParamBound {
+    fn clean(&self, cx: &DocContext) -> ParamBound {
         match *self {
-            hir::RegionTyParamBound(lt) => RegionBound(lt.clean(cx)),
+            hir::Outlives(lt) => RegionBound(lt.clean(cx)),
             hir::TraitTyParamBound(ref t, modifier) => TraitBound(t.clean(cx), modifier),
         }
     }
@@ -1570,8 +1570,8 @@ fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self
     }
 }
 
-impl<'a, 'tcx> Clean<TyParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>) {
-    fn clean(&self, cx: &DocContext) -> TyParamBound {
+impl<'a, 'tcx> Clean<ParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>) {
+    fn clean(&self, cx: &DocContext) -> ParamBound {
         let (trait_ref, ref bounds) = *self;
         inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait);
         let path = external_path(cx, &cx.tcx.item_name(trait_ref.def_id).as_str(),
@@ -1614,14 +1614,14 @@ impl<'a, 'tcx> Clean<TyParamBound> for (&'a ty::TraitRef<'tcx>, Vec<TypeBinding>
     }
 }
 
-impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
-    fn clean(&self, cx: &DocContext) -> TyParamBound {
+impl<'tcx> Clean<ParamBound> for ty::TraitRef<'tcx> {
+    fn clean(&self, cx: &DocContext) -> ParamBound {
         (self, vec![]).clean(cx)
     }
 }
 
-impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
-    fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
+impl<'tcx> Clean<Option<Vec<ParamBound>>> for Substs<'tcx> {
+    fn clean(&self, cx: &DocContext) -> Option<Vec<ParamBound>> {
         let mut v = Vec::new();
         v.extend(self.regions().filter_map(|r| r.clean(cx))
                      .map(RegionBound));
@@ -1671,10 +1671,15 @@ impl Clean<Lifetime> for hir::Lifetime {
 impl Clean<Lifetime> for hir::GenericParam {
     fn clean(&self, _: &DocContext) -> Lifetime {
         match self.kind {
-            hir::GenericParamKind::Lifetime { ref bounds, .. } => {
-                if bounds.len() > 0 {
-                    let mut s = format!("{}: {}", self.name(), bounds[0].name.name());
-                    for bound in bounds.iter().skip(1) {
+            hir::GenericParamKind::Lifetime { .. } => {
+                if self.bounds.len() > 0 {
+                    let mut bounds = self.bounds.iter().map(|bound| match bound {
+                        hir::ParamBound::Outlives(lt) => lt,
+                        _ => panic!(),
+                    });
+                    let name = bounds.next().unwrap().name.name();
+                    let mut s = format!("{}: {}", self.name(), name);
+                    for bound in bounds {
                         s.push_str(&format!(" + {}", bound.name.name()));
                     }
                     Lifetime(s)
@@ -1715,7 +1720,7 @@ impl Clean<Option<Lifetime>> for ty::RegionKind {
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)]
 pub enum WherePredicate {
-    BoundPredicate { ty: Type, bounds: Vec<TyParamBound> },
+    BoundPredicate { ty: Type, bounds: Vec<ParamBound> },
     RegionPredicate { lifetime: Lifetime, bounds: Vec<Lifetime>},
     EqPredicate { lhs: Type, rhs: Type },
 }
@@ -1797,7 +1802,7 @@ impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<Ty<'tcx>, ty::Region<
 
         WherePredicate::BoundPredicate {
             ty: ty.clean(cx),
-            bounds: vec![TyParamBound::RegionBound(lt.clean(cx).unwrap())]
+            bounds: vec![ParamBound::RegionBound(lt.clean(cx).unwrap())]
         }
     }
 }
@@ -1814,8 +1819,8 @@ impl<'tcx> Clean<WherePredicate> for ty::ProjectionPredicate<'tcx> {
 impl<'tcx> Clean<Type> for ty::ProjectionTy<'tcx> {
     fn clean(&self, cx: &DocContext) -> Type {
         let trait_ = match self.trait_ref(cx.tcx).clean(cx) {
-            TyParamBound::TraitBound(t, _) => t.trait_,
-            TyParamBound::RegionBound(_) => {
+            ParamBound::TraitBound(t, _) => t.trait_,
+            ParamBound::RegionBound(_) => {
                 panic!("cleaning a trait got a region")
             }
         };
@@ -1832,7 +1837,7 @@ pub enum GenericParamDefKind {
     Lifetime,
     Type {
         did: DefId,
-        bounds: Vec<TyParamBound>,
+        bounds: Vec<ParamBound>,
         default: Option<Type>,
         synthetic: Option<hir::SyntheticTyParamKind>,
     },
@@ -1887,10 +1892,15 @@ impl<'tcx> Clean<GenericParamDef> for ty::GenericParamDef {
 impl Clean<GenericParamDef> for hir::GenericParam {
     fn clean(&self, cx: &DocContext) -> GenericParamDef {
         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) {
+            hir::GenericParamKind::Lifetime { .. } => {
+                let name = if self.bounds.len() > 0 {
+                    let mut bounds = self.bounds.iter().map(|bound| match bound {
+                        hir::ParamBound::Outlives(lt) => lt,
+                        _ => panic!(),
+                    });
+                    let name = bounds.next().unwrap().name.name();
+                    let mut s = format!("{}: {}", self.name(), name);
+                    for bound in bounds {
                         s.push_str(&format!(" + {}", bound.name.name()));
                     }
                     s
@@ -1899,10 +1909,10 @@ impl Clean<GenericParamDef> for hir::GenericParam {
                 };
                 (name, GenericParamDefKind::Lifetime)
             }
-            hir::GenericParamKind::Type { ref bounds, ref default, synthetic, .. } => {
+            hir::GenericParamKind::Type { ref default, synthetic, .. } => {
                 (self.name().clean(cx), GenericParamDefKind::Type {
                     did: cx.tcx.hir.local_def_id(self.id),
-                    bounds: bounds.clean(cx),
+                    bounds: self.bounds.clean(cx),
                     default: default.clean(cx),
                     synthetic: synthetic,
                 })
@@ -2041,7 +2051,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
             if !sized_params.contains(&tp.name) {
                 where_predicates.push(WP::BoundPredicate {
                     ty: Type::Generic(tp.name.clone()),
-                    bounds: vec![TyParamBound::maybe_sized(cx)],
+                    bounds: vec![ParamBound::maybe_sized(cx)],
                 })
             }
         }
@@ -2282,7 +2292,7 @@ pub struct Trait {
     pub unsafety: hir::Unsafety,
     pub items: Vec<Item>,
     pub generics: Generics,
-    pub bounds: Vec<TyParamBound>,
+    pub bounds: Vec<ParamBound>,
     pub is_spotlight: bool,
     pub is_auto: bool,
 }
@@ -2504,7 +2514,7 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
                     // at the end.
                     match bounds.iter().position(|b| b.is_sized_bound(cx)) {
                         Some(i) => { bounds.remove(i); }
-                        None => bounds.push(TyParamBound::maybe_sized(cx)),
+                        None => bounds.push(ParamBound::maybe_sized(cx)),
                     }
 
                     let ty = if self.defaultness.has_value() {
@@ -2559,7 +2569,7 @@ pub enum Type {
     /// structs/enums/traits (most that'd be an hir::TyPath)
     ResolvedPath {
         path: Path,
-        typarams: Option<Vec<TyParamBound>>,
+        typarams: Option<Vec<ParamBound>>,
         did: DefId,
         /// true if is a `T::Name` path for associated types
         is_generic: bool,
@@ -2595,7 +2605,7 @@ pub enum Type {
     Infer,
 
     // impl TraitA+TraitB
-    ImplTrait(Vec<TyParamBound>),
+    ImplTrait(Vec<ParamBound>),
 }
 
 #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
@@ -3147,7 +3157,6 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                         }
                     }
 
-
                     let bounds = bounds.predicates.iter().filter_map(|pred|
                         if let ty::Predicate::Projection(proj) = *pred {
                             let proj = proj.skip_binder();
@@ -3169,7 +3178,7 @@ impl<'tcx> Clean<Type> for Ty<'tcx> {
                 }).collect::<Vec<_>>();
                 bounds.extend(regions);
                 if !has_sized && !bounds.is_empty() {
-                    bounds.insert(0, TyParamBound::maybe_sized(cx));
+                    bounds.insert(0, ParamBound::maybe_sized(cx));
                 }
                 ImplTrait(bounds)
             }
@@ -4465,11 +4474,11 @@ impl AutoTraitResult {
     }
 }
 
-impl From<TyParamBound> for SimpleBound {
-    fn from(bound: TyParamBound) -> Self {
+impl From<ParamBound> for SimpleBound {
+    fn from(bound: ParamBound) -> Self {
         match bound.clone() {
-            TyParamBound::RegionBound(l) => SimpleBound::RegionBound(l),
-            TyParamBound::TraitBound(t, mod_) => match t.trait_ {
+            ParamBound::RegionBound(l) => SimpleBound::RegionBound(l),
+            ParamBound::TraitBound(t, mod_) => match t.trait_ {
                 Type::ResolvedPath { path, typarams, .. } => {
                     SimpleBound::TraitBound(path.segments,
                                             typarams
diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs
index 95ceee85690..81ad2a5bf51 100644
--- a/src/librustdoc/clean/simplify.rs
+++ b/src/librustdoc/clean/simplify.rs
@@ -147,7 +147,7 @@ pub fn ty_params(mut params: Vec<clean::GenericParamDef>) -> Vec<clean::GenericP
     params
 }
 
-fn ty_bounds(bounds: Vec<clean::TyParamBound>) -> Vec<clean::TyParamBound> {
+fn ty_bounds(bounds: Vec<clean::ParamBound>) -> Vec<clean::ParamBound> {
     bounds
 }
 
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index e858f10860b..7147e13805f 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -77,7 +77,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> {
     /// Table node id of lifetime parameter definition -> substituted lifetime
     pub lt_substs: RefCell<FxHashMap<DefId, clean::Lifetime>>,
     /// Table DefId of `impl Trait` in argument position -> bounds
-    pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::TyParamBound>>>,
+    pub impl_trait_bounds: RefCell<FxHashMap<DefId, Vec<clean::ParamBound>>>,
     pub send_trait: Option<DefId>,
     pub fake_def_ids: RefCell<FxHashMap<CrateNum, DefId>>,
     pub all_fake_def_ids: RefCell<FxHashSet<DefId>>,
diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs
index f85a70a6d40..542d753c4f0 100644
--- a/src/librustdoc/doctree.rs
+++ b/src/librustdoc/doctree.rs
@@ -201,7 +201,7 @@ pub struct Trait {
     pub name: Name,
     pub items: hir::HirVec<hir::TraitItem>,
     pub generics: hir::Generics,
-    pub bounds: hir::HirVec<hir::TyParamBound>,
+    pub bounds: hir::HirVec<hir::ParamBound>,
     pub attrs: hir::HirVec<ast::Attribute>,
     pub id: ast::NodeId,
     pub whence: Span,
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 86c312275ff..4174f656995 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -46,7 +46,7 @@ pub struct MutableSpace(pub clean::Mutability);
 #[derive(Copy, Clone)]
 pub struct RawMutableSpace(pub clean::Mutability);
 /// Wrapper struct for emitting type parameter bounds.
-pub struct TyParamBounds<'a>(pub &'a [clean::TyParamBound]);
+pub struct ParamBounds<'a>(pub &'a [clean::ParamBound]);
 /// Wrapper struct for emitting a comma-separated list of items
 pub struct CommaSep<'a, T: 'a>(pub &'a [T]);
 pub struct AbiSpace(pub Abi);
@@ -104,9 +104,9 @@ impl<'a, T: fmt::Display> fmt::Display for CommaSep<'a, T> {
     }
 }
 
-impl<'a> fmt::Display for TyParamBounds<'a> {
+impl<'a> fmt::Display for ParamBounds<'a> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        let &TyParamBounds(bounds) = self;
+        let &ParamBounds(bounds) = self;
         for (i, bound) in bounds.iter().enumerate() {
             if i > 0 {
                 f.write_str(" + ")?;
@@ -126,9 +126,9 @@ impl fmt::Display for clean::GenericParamDef {
 
                 if !bounds.is_empty() {
                     if f.alternate() {
-                        write!(f, ": {:#}", TyParamBounds(bounds))?;
+                        write!(f, ": {:#}", ParamBounds(bounds))?;
                     } else {
-                        write!(f, ":&nbsp;{}", TyParamBounds(bounds))?;
+                        write!(f, ":&nbsp;{}", ParamBounds(bounds))?;
                     }
                 }
 
@@ -190,9 +190,9 @@ impl<'a> fmt::Display for WhereClause<'a> {
                 &clean::WherePredicate::BoundPredicate { ref ty, ref bounds } => {
                     let bounds = bounds;
                     if f.alternate() {
-                        clause.push_str(&format!("{:#}: {:#}", ty, TyParamBounds(bounds)));
+                        clause.push_str(&format!("{:#}: {:#}", ty, ParamBounds(bounds)));
                     } else {
-                        clause.push_str(&format!("{}: {}", ty, TyParamBounds(bounds)));
+                        clause.push_str(&format!("{}: {}", ty, ParamBounds(bounds)));
                     }
                 }
                 &clean::WherePredicate::RegionPredicate { ref lifetime,
@@ -267,7 +267,7 @@ impl fmt::Display for clean::PolyTrait {
     }
 }
 
-impl fmt::Display for clean::TyParamBound {
+impl fmt::Display for clean::ParamBound {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             clean::RegionBound(ref lt) => {
@@ -512,7 +512,7 @@ fn primitive_link(f: &mut fmt::Formatter,
 
 /// Helper to render type parameters
 fn tybounds(w: &mut fmt::Formatter,
-            typarams: &Option<Vec<clean::TyParamBound>>) -> fmt::Result {
+            typarams: &Option<Vec<clean::ParamBound>>) -> fmt::Result {
     match *typarams {
         Some(ref params) => {
             for param in params {
@@ -667,7 +667,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter, use_absolute: bool) -> fmt:
             }
         }
         clean::ImplTrait(ref bounds) => {
-            write!(f, "impl {}", TyParamBounds(bounds))
+            write!(f, "impl {}", ParamBounds(bounds))
         }
         clean::QPath { ref name, ref self_type, ref trait_ } => {
             let should_show_cast = match *trait_ {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index 675d1097bda..21724c2d730 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -69,7 +69,7 @@ use doctree;
 use fold::DocFolder;
 use html::escape::Escape;
 use html::format::{ConstnessSpace};
-use html::format::{TyParamBounds, WhereClause, href, AbiSpace};
+use html::format::{ParamBounds, WhereClause, href, AbiSpace};
 use html::format::{VisSpace, Method, UnsafetySpace, MutableSpace};
 use html::format::fmt_impl_for_trait_page;
 use html::item_type::ItemType;
@@ -2960,14 +2960,14 @@ fn assoc_const(w: &mut fmt::Formatter,
 }
 
 fn assoc_type<W: fmt::Write>(w: &mut W, it: &clean::Item,
-                             bounds: &Vec<clean::TyParamBound>,
+                             bounds: &Vec<clean::ParamBound>,
                              default: Option<&clean::Type>,
                              link: AssocItemLink) -> fmt::Result {
     write!(w, "type <a href='{}' class=\"type\">{}</a>",
            naive_assoc_href(it, link),
            it.name.as_ref().unwrap())?;
     if !bounds.is_empty() {
-        write!(w, ": {}", TyParamBounds(bounds))?
+        write!(w, ": {}", ParamBounds(bounds))?
     }
     if let Some(default) = default {
         write!(w, " = {}", default)?;
diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs
index f589057218c..b082cde5df7 100644
--- a/src/libsyntax/ast.rs
+++ b/src/libsyntax/ast.rs
@@ -10,7 +10,7 @@
 
 // The Rust abstract syntax tree.
 
-pub use self::TyParamBound::*;
+pub use self::ParamBound::*;
 pub use self::UnsafeSource::*;
 pub use self::GenericArgs::*;
 pub use symbol::{Ident, Symbol as Name};
@@ -269,44 +269,42 @@ pub const CRATE_NODE_ID: NodeId = NodeId(0);
 /// small, positive ids.
 pub const DUMMY_NODE_ID: NodeId = NodeId(!0);
 
+/// A modifier on a bound, currently this is only used for `?Sized`, where the
+/// modifier is `Maybe`. Negative bounds should also be handled here.
+#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
+pub enum TraitBoundModifier {
+    None,
+    Maybe,
+}
+
 /// The AST represents all type param bounds as types.
 /// typeck::collect::compute_bounds matches these against
 /// the "special" built-in traits (see middle::lang_items) and
 /// detects Copy, Send and Sync.
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TyParamBound {
+pub enum ParamBound {
     TraitTyParamBound(PolyTraitRef, TraitBoundModifier),
-    RegionTyParamBound(Lifetime)
+    Outlives(Lifetime)
 }
 
-impl TyParamBound {
+impl ParamBound {
     pub fn span(&self) -> Span {
         match self {
             &TraitTyParamBound(ref t, ..) => t.span,
-            &RegionTyParamBound(ref l) => l.ident.span,
+            &Outlives(ref l) => l.ident.span,
         }
     }
 }
 
-/// A modifier on a bound, currently this is only used for `?Sized`, where the
-/// modifier is `Maybe`. Negative bounds should also be handled here.
-#[derive(Copy, Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
-pub enum TraitBoundModifier {
-    None,
-    Maybe,
-}
-
-pub type TyParamBounds = Vec<TyParamBound>;
+pub type ParamBounds = Vec<ParamBound>;
 
 #[derive(Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug)]
 pub enum GenericParamKind {
     /// A lifetime definition, e.g. `'a: 'b+'c+'d`.
     Lifetime {
-        bounds: Vec<Lifetime>,
         lifetime: Lifetime,
     },
     Type {
-        bounds: TyParamBounds,
         default: Option<P<Ty>>,
     }
 }
@@ -316,6 +314,7 @@ pub struct GenericParam {
     pub ident: Ident,
     pub id: NodeId,
     pub attrs: ThinVec<Attribute>,
+    pub bounds: ParamBounds,
 
     pub kind: GenericParamKind,
 }
@@ -384,7 +383,7 @@ pub struct WhereBoundPredicate {
     /// The type being bounded
     pub bounded_ty: P<Ty>,
     /// Trait and lifetime bounds (`Clone+Send+'static`)
-    pub bounds: TyParamBounds,
+    pub bounds: ParamBounds,
 }
 
 /// A lifetime predicate.
@@ -930,7 +929,7 @@ impl Expr {
         }
     }
 
-    fn to_bound(&self) -> Option<TyParamBound> {
+    fn to_bound(&self) -> Option<ParamBound> {
         match &self.node {
             ExprKind::Path(None, path) =>
                 Some(TraitTyParamBound(PolyTraitRef::new(Vec::new(), path.clone(), self.span),
@@ -1355,7 +1354,7 @@ pub struct TraitItem {
 pub enum TraitItemKind {
     Const(P<Ty>, Option<P<Expr>>),
     Method(MethodSig, Option<P<Block>>),
-    Type(TyParamBounds, Option<P<Ty>>),
+    Type(ParamBounds, Option<P<Ty>>),
     Macro(Mac),
 }
 
@@ -1540,10 +1539,10 @@ pub enum TyKind {
     Path(Option<QSelf>, Path),
     /// A trait object type `Bound1 + Bound2 + Bound3`
     /// where `Bound` is a trait or a lifetime.
-    TraitObject(TyParamBounds, TraitObjectSyntax),
+    TraitObject(ParamBounds, TraitObjectSyntax),
     /// An `impl Bound1 + Bound2 + Bound3` type
     /// where `Bound` is a trait or a lifetime.
-    ImplTrait(TyParamBounds),
+    ImplTrait(ParamBounds),
     /// No-op; kept solely so that we can pretty-print faithfully
     Paren(P<Ty>),
     /// Unused for now
@@ -2064,11 +2063,11 @@ pub enum ItemKind {
     /// A Trait declaration (`trait` or `pub trait`).
     ///
     /// E.g. `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`
-    Trait(IsAuto, Unsafety, Generics, TyParamBounds, Vec<TraitItem>),
+    Trait(IsAuto, Unsafety, Generics, ParamBounds, Vec<TraitItem>),
     /// Trait alias
     ///
     /// E.g. `trait Foo = Bar + Quux;`
-    TraitAlias(Generics, TyParamBounds),
+    TraitAlias(Generics, ParamBounds),
     /// An implementation.
     ///
     /// E.g. `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`
diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs
index 695ad9c233f..ea151ca68a8 100644
--- a/src/libsyntax/ext/build.rs
+++ b/src/libsyntax/ext/build.rs
@@ -68,18 +68,18 @@ pub trait AstBuilder {
                span: Span,
                id: ast::Ident,
                attrs: Vec<ast::Attribute>,
-               bounds: ast::TyParamBounds,
+               bounds: ast::ParamBounds,
                default: Option<P<ast::Ty>>) -> ast::GenericParam;
 
     fn trait_ref(&self, path: ast::Path) -> ast::TraitRef;
     fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef;
-    fn typarambound(&self, path: ast::Path) -> ast::TyParamBound;
+    fn ty_param_bound(&self, path: ast::Path) -> ast::ParamBound;
     fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime;
     fn lifetime_def(&self,
                     span: Span,
                     ident: ast::Ident,
                     attrs: Vec<ast::Attribute>,
-                    bounds: Vec<ast::Lifetime>)
+                    bounds: ast::ParamBounds)
                     -> ast::GenericParam;
 
     // statements
@@ -436,14 +436,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                span: Span,
                ident: ast::Ident,
                attrs: Vec<ast::Attribute>,
-               bounds: ast::TyParamBounds,
+               bounds: ast::ParamBounds,
                default: Option<P<ast::Ty>>) -> ast::GenericParam {
         ast::GenericParam {
             ident: ident.with_span_pos(span),
             id: ast::DUMMY_NODE_ID,
             attrs: attrs.into(),
+            bounds,
             kind: ast::GenericParamKind::Type {
-                bounds,
                 default,
             }
         }
@@ -464,7 +464,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
         }
     }
 
-    fn typarambound(&self, path: ast::Path) -> ast::TyParamBound {
+    fn ty_param_bound(&self, path: ast::Path) -> ast::ParamBound {
         ast::TraitTyParamBound(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None)
     }
 
@@ -476,16 +476,16 @@ impl<'a> AstBuilder for ExtCtxt<'a> {
                     span: Span,
                     ident: ast::Ident,
                     attrs: Vec<ast::Attribute>,
-                    bounds: Vec<ast::Lifetime>)
+                    bounds: ast::ParamBounds)
                     -> ast::GenericParam {
         let lifetime = self.lifetime(span, ident);
         ast::GenericParam {
             ident: lifetime.ident,
             id: lifetime.id,
             attrs: attrs.into(),
+            bounds,
             kind: ast::GenericParamKind::Lifetime {
                 lifetime,
-                bounds,
             }
         }
     }
diff --git a/src/libsyntax/fold.rs b/src/libsyntax/fold.rs
index ea147186b18..a0c69d83e84 100644
--- a/src/libsyntax/fold.rs
+++ b/src/libsyntax/fold.rs
@@ -268,17 +268,16 @@ pub trait Folder : Sized {
         noop_fold_interpolated(nt, self)
     }
 
-    fn fold_opt_bounds(&mut self, b: Option<TyParamBounds>)
-                       -> Option<TyParamBounds> {
+    fn fold_opt_bounds(&mut self, b: Option<TyParamBounds>) -> Option<TyParamBounds> {
         noop_fold_opt_bounds(b, self)
     }
 
-    fn fold_bounds(&mut self, b: TyParamBounds)
-                       -> TyParamBounds {
+    fn fold_bounds(&mut self, b: ParamBounds)
+                       -> ParamBounds {
         noop_fold_bounds(b, self)
     }
 
-    fn fold_ty_param_bound(&mut self, tpb: TyParamBound) -> TyParamBound {
+    fn fold_ty_param_bound(&mut self, tpb: ParamBound) -> ParamBound {
         noop_fold_ty_param_bound(tpb, self)
     }
 
@@ -678,12 +677,12 @@ pub fn noop_fold_fn_decl<T: Folder>(decl: P<FnDecl>, fld: &mut T) -> P<FnDecl> {
     })
 }
 
-pub fn noop_fold_ty_param_bound<T>(tpb: TyParamBound, fld: &mut T)
-                                   -> TyParamBound
+pub fn noop_fold_ty_param_bound<T>(tpb: ParamBound, fld: &mut T)
+                                   -> ParamBound
                                    where T: Folder {
     match tpb {
         TraitTyParamBound(ty, modifier) => TraitTyParamBound(fld.fold_poly_trait_ref(ty), modifier),
-        RegionTyParamBound(lifetime) => RegionTyParamBound(noop_fold_lifetime(lifetime, fld)),
+        Outlives(lifetime) => Outlives(noop_fold_lifetime(lifetime, fld)),
     }
 }
 
@@ -850,13 +849,13 @@ pub fn noop_fold_mt<T: Folder>(MutTy {ty, mutbl}: MutTy, folder: &mut T) -> MutT
     }
 }
 
-pub fn noop_fold_opt_bounds<T: Folder>(b: Option<TyParamBounds>, folder: &mut T)
-                                       -> Option<TyParamBounds> {
+pub fn noop_fold_opt_bounds<T: Folder>(b: Option<ParamBounds>, folder: &mut T)
+                                       -> Option<ParamBounds> {
     b.map(|bounds| folder.fold_bounds(bounds))
 }
 
-fn noop_fold_bounds<T: Folder>(bounds: TyParamBounds, folder: &mut T)
-                          -> TyParamBounds {
+fn noop_fold_bounds<T: Folder>(bounds: ParamBounds, folder: &mut T)
+                          -> ParamBounds {
     bounds.move_map(|bound| folder.fold_ty_param_bound(bound))
 }
 
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 203b529222d..ce79735fff5 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -10,7 +10,7 @@
 
 use rustc_target::spec::abi::{self, Abi};
 use ast::{AngleBracketedArgs, ParenthesizedArgData, AttrStyle, BareFnTy};
-use ast::{RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
+use ast::{Outlives, TraitTyParamBound, TraitBoundModifier};
 use ast::Unsafety;
 use ast::{Mod, AnonConst, Arg, Arm, Attribute, BindingMode, TraitItemKind};
 use ast::Block;
@@ -36,7 +36,7 @@ use ast::{VariantData, StructField};
 use ast::StrStyle;
 use ast::SelfKind;
 use ast::{TraitItem, TraitRef, TraitObjectSyntax};
-use ast::{Ty, TyKind, TypeBinding, TyParamBounds};
+use ast::{Ty, TyKind, TypeBinding, ParamBounds};
 use ast::{Visibility, VisibilityKind, WhereClause, CrateSugar};
 use ast::{UseTree, UseTreeKind};
 use ast::{BinOpKind, UnOp};
@@ -4735,7 +4735,7 @@ impl<'a> Parser<'a> {
     // LT_BOUND = LIFETIME (e.g. `'a`)
     // TY_BOUND = TY_BOUND_NOPAREN | (TY_BOUND_NOPAREN)
     // TY_BOUND_NOPAREN = [?] [for<LT_PARAM_DEFS>] SIMPLE_PATH (e.g. `?for<'a: 'b> m::Trait<'a>`)
-    fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, TyParamBounds> {
+    fn parse_ty_param_bounds_common(&mut self, allow_plus: bool) -> PResult<'a, ParamBounds> {
         let mut bounds = Vec::new();
         loop {
             // This needs to be syncronized with `Token::can_begin_bound`.
@@ -4752,7 +4752,7 @@ impl<'a> Parser<'a> {
                         self.span_err(question_span,
                                       "`?` may only modify trait bounds, not lifetime bounds");
                     }
-                    bounds.push(RegionTyParamBound(self.expect_lifetime()));
+                    bounds.push(Outlives(RegionTyParamBound(self.expect_lifetime())));
                     if has_parens {
                         self.expect(&token::CloseDelim(token::Paren))?;
                         self.span_err(self.prev_span,
@@ -4784,7 +4784,7 @@ impl<'a> Parser<'a> {
         return Ok(bounds);
     }
 
-    fn parse_ty_param_bounds(&mut self) -> PResult<'a, TyParamBounds> {
+    fn parse_ty_param_bounds(&mut self) -> PResult<'a, ParamBounds> {
         self.parse_ty_param_bounds_common(true)
     }
 
@@ -4823,17 +4823,17 @@ impl<'a> Parser<'a> {
 
         Ok(GenericParam {
             ident,
-            attrs: preceding_attrs.into(),
             id: ast::DUMMY_NODE_ID,
+            attrs: preceding_attrs.into(),
+            bounds,
             kind: GenericParamKind::Type {
-                bounds,
                 default,
             }
         })
     }
 
     /// Parses the following grammar:
-    ///     TraitItemAssocTy = Ident ["<"...">"] [":" [TyParamBounds]] ["where" ...] ["=" Ty]
+    ///     TraitItemAssocTy = Ident ["<"...">"] [":" [ParamBounds]] ["where" ...] ["=" Ty]
     fn parse_trait_item_assoc_ty(&mut self)
         -> PResult<'a, (Ident, TraitItemKind, ast::Generics)> {
         let ident = self.parse_ident()?;
@@ -4868,7 +4868,9 @@ impl<'a> Parser<'a> {
                 let lifetime = self.expect_lifetime();
                 // Parse lifetime parameter.
                 let bounds = if self.eat(&token::Colon) {
-                    self.parse_lt_param_bounds()
+                    self.parse_lt_param_bounds().iter()
+                        .map(|bound| ast::ParamBound::Outlives(*bound))
+                        .collect()
                 } else {
                     Vec::new()
                 };
@@ -4876,9 +4878,9 @@ impl<'a> Parser<'a> {
                     ident: lifetime.ident,
                     id: lifetime.id,
                     attrs: attrs.into(),
+                    bounds,
                     kind: ast::GenericParamKind::Lifetime {
                         lifetime,
-                        bounds,
                     }
                 });
                 if seen_ty_param {
diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs
index 84a4a51b716..c8d139c7de9 100644
--- a/src/libsyntax/print/pprust.rs
+++ b/src/libsyntax/print/pprust.rs
@@ -12,7 +12,7 @@ pub use self::AnnNode::*;
 
 use rustc_target::spec::abi::{self, Abi};
 use ast::{self, BlockCheckMode, PatKind, RangeEnd, RangeSyntax};
-use ast::{SelfKind, RegionTyParamBound, TraitTyParamBound, TraitBoundModifier};
+use ast::{SelfKind, Outlives, TraitTyParamBound, TraitBoundModifier};
 use ast::{Attribute, MacDelimiter, GenericArg};
 use util::parser::{self, AssocOp, Fixity};
 use attr;
@@ -292,7 +292,7 @@ pub fn ty_to_string(ty: &ast::Ty) -> String {
     to_string(|s| s.print_type(ty))
 }
 
-pub fn bounds_to_string(bounds: &[ast::TyParamBound]) -> String {
+pub fn bounds_to_string(bounds: &[ast::ParamBound]) -> String {
     to_string(|s| s.print_bounds("", bounds))
 }
 
@@ -1178,7 +1178,7 @@ impl<'a> State<'a> {
 
     fn print_associated_type(&mut self,
                              ident: ast::Ident,
-                             bounds: Option<&ast::TyParamBounds>,
+                             bounds: Option<&ast::ParamBounds>,
                              ty: Option<&ast::Ty>)
                              -> io::Result<()> {
         self.word_space("type")?;
@@ -2811,7 +2811,7 @@ impl<'a> State<'a> {
 
     pub fn print_bounds(&mut self,
                         prefix: &str,
-                        bounds: &[ast::TyParamBound])
+                        bounds: &[ast::ParamBound])
                         -> io::Result<()> {
         if !bounds.is_empty() {
             self.s.word(prefix)?;
@@ -2833,7 +2833,7 @@ impl<'a> State<'a> {
                         }
                         self.print_poly_trait_ref(tref)?;
                     }
-                    RegionTyParamBound(lt) => {
+                    Outlives(lt) => {
                         self.print_lifetime(lt)?;
                     }
                 }
@@ -2879,14 +2879,19 @@ impl<'a> State<'a> {
 
         self.commasep(Inconsistent, &generic_params, |s, param| {
             match param.kind {
-                ast::GenericParamKind::Lifetime { ref bounds, ref lifetime } => {
+                ast::GenericParamKind::Lifetime { ref lifetime } => {
                     s.print_outer_attributes_inline(&param.attrs)?;
-                    s.print_lifetime_bounds(lifetime, bounds)
+                    s.print_lifetime_bounds(lifetime, &param.bounds.iter().map(|bound| {
+                        match bound {
+                            ast::ParamBound::Outlives(lt) => *lt,
+                            _ => panic!(),
+                        }
+                    }).collect::<Vec<_>>().as_slice())
                 },
-                ast::GenericParamKind::Type { ref bounds, ref default } => {
+                ast::GenericParamKind::Type { ref default } => {
                     s.print_outer_attributes_inline(&param.attrs)?;
                     s.print_ident(param.ident)?;
-                    s.print_bounds(":", bounds)?;
+                    s.print_bounds(":", &param.bounds)?;
                     match default {
                         Some(ref default) => {
                             s.s.space()?;
diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs
index 95ae9f9bcf8..485775765ab 100644
--- a/src/libsyntax/util/node_count.rs
+++ b/src/libsyntax/util/node_count.rs
@@ -95,7 +95,7 @@ impl<'ast> Visitor<'ast> for NodeCounter {
         self.count += 1;
         walk_trait_ref(self, t)
     }
-    fn visit_ty_param_bound(&mut self, bounds: &TyParamBound) {
+    fn visit_ty_param_bound(&mut self, bounds: &ParamBound) {
         self.count += 1;
         walk_ty_param_bound(self, bounds)
     }
diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs
index e12369a522d..4e0c417d4fb 100644
--- a/src/libsyntax/visit.rs
+++ b/src/libsyntax/visit.rs
@@ -86,7 +86,7 @@ pub trait Visitor<'ast>: Sized {
     fn visit_trait_item(&mut self, ti: &'ast TraitItem) { walk_trait_item(self, ti) }
     fn visit_impl_item(&mut self, ii: &'ast ImplItem) { walk_impl_item(self, ii) }
     fn visit_trait_ref(&mut self, t: &'ast TraitRef) { walk_trait_ref(self, t) }
-    fn visit_ty_param_bound(&mut self, bounds: &'ast TyParamBound) {
+    fn visit_ty_param_bound(&mut self, bounds: &'ast ParamBound) {
         walk_ty_param_bound(self, bounds)
     }
     fn visit_poly_trait_ref(&mut self, t: &'ast PolyTraitRef, m: &'ast TraitBoundModifier) {
@@ -479,31 +479,30 @@ pub fn walk_global_asm<'a, V: Visitor<'a>>(_: &mut V, _: &'a GlobalAsm) {
     // Empty!
 }
 
-pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a TyParamBound) {
+pub fn walk_ty_param_bound<'a, V: Visitor<'a>>(visitor: &mut V, bound: &'a ParamBound) {
     match *bound {
         TraitTyParamBound(ref typ, ref modifier) => {
             visitor.visit_poly_trait_ref(typ, modifier);
         }
-        RegionTyParamBound(ref lifetime) => {
+        Outlives(ref lifetime) => {
             visitor.visit_lifetime(lifetime);
         }
     }
 }
 
 pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a GenericParam) {
+    visitor.visit_ident(param.ident);
     match param.kind {
         GenericParamKind::Lifetime { ref bounds, ref lifetime } => {
-            visitor.visit_ident(param.ident);
             walk_list!(visitor, visit_lifetime, bounds);
-            walk_list!(visitor, visit_attribute, param.attrs.iter());
         }
         GenericParamKind::Type { ref bounds, ref default } => {
             visitor.visit_ident(t.ident);
             walk_list!(visitor, visit_ty_param_bound, bounds);
             walk_list!(visitor, visit_ty, default);
-            walk_list!(visitor, visit_attribute, param.attrs.iter());
         }
     }
+    walk_list!(visitor, visit_attribute, param.attrs.iter());
 }
 
 pub fn walk_generics<'a, V: Visitor<'a>>(visitor: &mut V, generics: &'a Generics) {
diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs
index 1024d445cdb..a7d8156f4a0 100644
--- a/src/libsyntax_ext/deriving/generic/mod.rs
+++ b/src/libsyntax_ext/deriving/generic/mod.rs
@@ -551,22 +551,21 @@ impl<'a> TraitDef<'a> {
         // Create the generic parameters
         params.extend(generics.params.iter().map(|param| match param.kind {
             GenericParamKind::Lifetime { .. } => param.clone(),
-            GenericParamKind::Type { bounds: ref ty_bounds, .. } => {
+            GenericParamKind::Type { .. } => {
                 // I don't think this can be moved out of the loop, since
-                // a TyParamBound requires an ast id
+                // a ParamBound requires an ast id
                 let mut bounds: Vec<_> =
                     // extra restrictions on the generics parameters to the
                     // type being derived upon
                     self.additional_bounds.iter().map(|p| {
-                        cx.typarambound(p.to_path(cx, self.span,
-                                                    type_ident, generics))
+                        cx.ty_param_bound(p.to_path(cx, self.span, type_ident, generics))
                     }).collect();
 
                 // require the current trait
-                bounds.push(cx.typarambound(trait_path.clone()));
+                bounds.push(cx.ty_param_bound(trait_path.clone()));
 
                 // also add in any bounds from the declaration
-                for declared_bound in ty_bounds {
+                for declared_bound in &param.bounds {
                     bounds.push((*declared_bound).clone());
                 }
 
@@ -635,12 +634,12 @@ impl<'a> TraitDef<'a> {
                         let mut bounds: Vec<_> = self.additional_bounds
                             .iter()
                             .map(|p| {
-                                cx.typarambound(p.to_path(cx, self.span, type_ident, generics))
+                                cx.ty_param_bound(p.to_path(cx, self.span, type_ident, generics))
                             })
                             .collect();
 
                         // require the current trait
-                        bounds.push(cx.typarambound(trait_path.clone()));
+                        bounds.push(cx.ty_param_bound(trait_path.clone()));
 
                         let predicate = ast::WhereBoundPredicate {
                             span: self.span,
diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs
index 127ed62b8c5..327a35d39b3 100644
--- a/src/libsyntax_ext/deriving/generic/ty.rs
+++ b/src/libsyntax_ext/deriving/generic/ty.rs
@@ -219,7 +219,7 @@ fn mk_ty_param(cx: &ExtCtxt,
     let bounds = bounds.iter()
         .map(|b| {
             let path = b.to_path(cx, span, self_ident, self_generics);
-            cx.typarambound(path)
+            cx.ty_param_bound(path)
         })
         .collect();
     cx.typaram(span, cx.ident_of(name), attrs.to_owned(), bounds, None)
@@ -261,9 +261,8 @@ impl<'a> LifetimeBounds<'a> {
             .iter()
             .map(|&(lt, ref bounds)| {
                 let bounds = bounds.iter()
-                    .map(|b| cx.lifetime(span, Ident::from_str(b)))
-                    .collect();
-                cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds)
+                    .map(|b| ast::ParamBound::Outlives(cx.lifetime(span, Ident::from_str(b))));
+                cx.lifetime_def(span, Ident::from_str(lt), vec![], bounds.collect())
             })
             .chain(self.bounds
                 .iter()