about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2015-02-11 10:28:52 -0500
committerNiko Matsakis <niko@alum.mit.edu>2015-02-12 13:29:51 -0500
commit3e88b5bbf907bdb7d7610d66c27504be92330030 (patch)
tree5410d982cad54118f93fe1788a7158e3f754fef1
parent3764699c83387df254f220b4c85121010413aeff (diff)
downloadrust-3e88b5bbf907bdb7d7610d66c27504be92330030.tar.gz
rust-3e88b5bbf907bdb7d7610d66c27504be92330030.zip
Rote changes to fix fallout throughout the compiler from splitting the
predicates and renaming some things.
-rw-r--r--src/librustc/middle/traits/mod.rs2
-rw-r--r--src/librustc/middle/traits/object_safety.rs5
-rw-r--r--src/librustc/middle/traits/project.rs4
-rw-r--r--src/librustc/middle/traits/select.rs8
-rw-r--r--src/librustc/middle/traits/util.rs2
-rw-r--r--src/librustc/middle/ty.rs31
-rw-r--r--src/librustc/middle/ty_fold.rs13
-rw-r--r--src/librustc_typeck/check/_match.rs13
-rw-r--r--src/librustc_typeck/check/compare_method.rs4
-rw-r--r--src/librustc_typeck/check/dropck.rs3
-rw-r--r--src/librustc_typeck/check/method/confirm.rs29
-rw-r--r--src/librustc_typeck/check/method/mod.rs2
-rw-r--r--src/librustc_typeck/check/method/probe.rs9
-rw-r--r--src/librustc_typeck/check/mod.rs112
-rw-r--r--src/librustc_typeck/check/regionck.rs4
-rw-r--r--src/librustc_typeck/check/wf.rs34
-rw-r--r--src/librustc_typeck/coherence/mod.rs3
-rw-r--r--src/librustc_typeck/lib.rs12
-rw-r--r--src/librustdoc/clean/inline.rs20
-rw-r--r--src/librustdoc/clean/mod.rs19
20 files changed, 180 insertions, 149 deletions
diff --git a/src/librustc/middle/traits/mod.rs b/src/librustc/middle/traits/mod.rs
index bddbb7c02ba..395e486059e 100644
--- a/src/librustc/middle/traits/mod.rs
+++ b/src/librustc/middle/traits/mod.rs
@@ -283,7 +283,7 @@ pub fn overlapping_impls(infcx: &InferCtxt,
 /// Creates predicate obligations from the generic bounds.
 pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      cause: ObligationCause<'tcx>,
-                                     generic_bounds: &ty::GenericBounds<'tcx>)
+                                     generic_bounds: &ty::InstantiatedPredicates<'tcx>)
                                      -> PredicateObligations<'tcx>
 {
     util::predicates_for_generics(tcx, cause, 0, generic_bounds)
diff --git a/src/librustc/middle/traits/object_safety.rs b/src/librustc/middle/traits/object_safety.rs
index c88e58266a0..b2701ae875c 100644
--- a/src/librustc/middle/traits/object_safety.rs
+++ b/src/librustc/middle/traits/object_safety.rs
@@ -130,7 +130,10 @@ fn trait_has_sized_self<'tcx>(tcx: &ty::ctxt<'tcx>,
     // Search for a predicate like `Self : Sized` amongst the trait bounds.
     let trait_def = ty::lookup_trait_def(tcx, trait_def_id);
     let free_substs = ty::construct_free_substs(tcx, &trait_def.generics, ast::DUMMY_NODE_ID);
-    let predicates = trait_def.generics.to_bounds(tcx, &free_substs).predicates.into_vec();
+
+    let trait_predicates = ty::lookup_predicates(tcx, trait_def_id);
+    let predicates = trait_predicates.instantiate(tcx, &free_substs).predicates.into_vec();
+
     elaborate_predicates(tcx, predicates)
         .any(|predicate| {
             match predicate {
diff --git a/src/librustc/middle/traits/project.rs b/src/librustc/middle/traits/project.rs
index 7d02adea1fa..13f309e129a 100644
--- a/src/librustc/middle/traits/project.rs
+++ b/src/librustc/middle/traits/project.rs
@@ -561,8 +561,8 @@ fn assemble_candidates_from_trait_def<'cx,'tcx>(
     };
 
     // If so, extract what we know from the trait and try to come up with a good answer.
-    let trait_def = ty::lookup_trait_def(selcx.tcx(), trait_ref.def_id);
-    let bounds = trait_def.generics.to_bounds(selcx.tcx(), trait_ref.substs);
+    let trait_predicates = ty::lookup_predicates(selcx.tcx(), trait_ref.def_id);
+    let bounds = trait_predicates.instantiate(selcx.tcx(), trait_ref.substs);
     assemble_candidates_from_predicates(selcx, obligation, obligation_trait_ref,
                                         candidate_set, bounds.predicates.into_vec());
 }
diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs
index 5323a322436..5f659aa303e 100644
--- a/src/librustc/middle/traits/select.rs
+++ b/src/librustc/middle/traits/select.rs
@@ -923,8 +923,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 projection_trait_ref={}",
                projection_trait_ref.repr(self.tcx()));
 
-        let trait_def = ty::lookup_trait_def(self.tcx(), projection_trait_ref.def_id);
-        let bounds = trait_def.generics.to_bounds(self.tcx(), projection_trait_ref.substs);
+        let trait_predicates = ty::lookup_predicates(self.tcx(), projection_trait_ref.def_id);
+        let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
         debug!("match_projection_obligation_against_bounds_from_trait: \
                 bounds={}",
                bounds.repr(self.tcx()));
@@ -2314,8 +2314,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                         snapshot: &infer::CombinedSnapshot)
                         -> VecPerParamSpace<PredicateObligation<'tcx>>
     {
-        let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
-        let bounds = impl_generics.to_bounds(self.tcx(), impl_substs);
+        let impl_bounds = ty::lookup_predicates(self.tcx(), impl_def_id);
+        let bounds = impl_bounds.instantiate(self.tcx(), impl_substs);
         let normalized_bounds =
             project::normalize_with_depth(self, cause.clone(), recursion_depth, &bounds);
         let normalized_bounds =
diff --git a/src/librustc/middle/traits/util.rs b/src/librustc/middle/traits/util.rs
index 573efa72756..6c54da1c134 100644
--- a/src/librustc/middle/traits/util.rs
+++ b/src/librustc/middle/traits/util.rs
@@ -290,7 +290,7 @@ impl<'tcx> fmt::Debug for super::VtableObjectData<'tcx> {
 pub fn predicates_for_generics<'tcx>(tcx: &ty::ctxt<'tcx>,
                                      cause: ObligationCause<'tcx>,
                                      recursion_depth: uint,
-                                     generic_bounds: &ty::GenericBounds<'tcx>)
+                                     generic_bounds: &ty::InstantiatedPredicates<'tcx>)
                                      -> VecPerParamSpace<PredicateObligation<'tcx>>
 {
     debug!("predicates_for_generics(generic_bounds={})",
diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs
index af80ce65474..6026359ddac 100644
--- a/src/librustc/middle/ty.rs
+++ b/src/librustc/middle/ty.rs
@@ -2153,10 +2153,12 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                         match ty::impl_or_trait_item(cx, method_def_id) {
                             MethodTraitItem(ref method_ty) => {
                                 let method_generics = &method_ty.generics;
+                                let method_bounds = &method_ty.predicates;
                                 construct_parameter_environment(
                                     cx,
                                     method.span,
                                     method_generics,
+                                    method_bounds,
                                     method.pe_body().id)
                             }
                             TypeTraitItem(_) => {
@@ -2188,10 +2190,12 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                         match ty::impl_or_trait_item(cx, method_def_id) {
                             MethodTraitItem(ref method_ty) => {
                                 let method_generics = &method_ty.generics;
+                                let method_bounds = &method_ty.predicates;
                                 construct_parameter_environment(
                                     cx,
                                     method.span,
                                     method_generics,
+                                    method_bounds,
                                     method.pe_body().id)
                             }
                             TypeTraitItem(_) => {
@@ -2214,11 +2218,13 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                     ast::ItemFn(_, _, _, _, ref body) => {
                         // We assume this is a function.
                         let fn_def_id = ast_util::local_def(id);
-                        let fn_pty = ty::lookup_item_type(cx, fn_def_id);
+                        let fn_scheme = lookup_item_type(cx, fn_def_id);
+                        let fn_predicates = lookup_predicates(cx, fn_def_id);
 
                         construct_parameter_environment(cx,
                                                         item.span,
-                                                        &fn_pty.generics,
+                                                        &fn_scheme.generics,
+                                                        &fn_predicates,
                                                         body.id)
                     }
                     ast::ItemEnum(..) |
@@ -2227,8 +2233,13 @@ impl<'a, 'tcx> ParameterEnvironment<'a, 'tcx> {
                     ast::ItemConst(..) |
                     ast::ItemStatic(..) => {
                         let def_id = ast_util::local_def(id);
-                        let pty = ty::lookup_item_type(cx, def_id);
-                        construct_parameter_environment(cx, item.span, &pty.generics, id)
+                        let scheme = lookup_item_type(cx, def_id);
+                        let predicates = lookup_predicates(cx, def_id);
+                        construct_parameter_environment(cx,
+                                                        item.span,
+                                                        &scheme.generics,
+                                                        &predicates,
+                                                        id)
                     }
                     _ => {
                         cx.sess.span_bug(item.span,
@@ -6320,7 +6331,7 @@ pub fn empty_parameter_environment<'a,'tcx>(cx: &'a ctxt<'tcx>) -> ParameterEnvi
 /// parameters in the same way, this only has an effect on regions.
 pub fn construct_free_substs<'a,'tcx>(
     tcx: &'a ctxt<'tcx>,
-    generics: &ty::Generics<'tcx>,
+    generics: &Generics<'tcx>,
     free_id: ast::NodeId)
     -> Substs<'tcx>
 {
@@ -6365,6 +6376,7 @@ pub fn construct_parameter_environment<'a,'tcx>(
     tcx: &'a ctxt<'tcx>,
     span: Span,
     generics: &ty::Generics<'tcx>,
+    generic_predicates: &ty::GenericPredicates<'tcx>,
     free_id: ast::NodeId)
     -> ParameterEnvironment<'a, 'tcx>
 {
@@ -6379,7 +6391,7 @@ pub fn construct_parameter_environment<'a,'tcx>(
     // Compute the bounds on Self and the type parameters.
     //
 
-    let bounds = generics.to_bounds(tcx, &free_substs);
+    let bounds = generic_predicates.instantiate(tcx, &free_substs);
     let bounds = liberate_late_bound_regions(tcx, free_id_outlive, &ty::Binder(bounds));
     let predicates = bounds.predicates.into_vec();
 
@@ -7013,8 +7025,7 @@ impl<'tcx,T:RegionEscape> RegionEscape for VecPerParamSpace<T> {
 
 impl<'tcx> RegionEscape for TypeScheme<'tcx> {
     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
-        self.ty.has_regions_escaping_depth(depth) ||
-            self.generics.has_regions_escaping_depth(depth)
+        self.ty.has_regions_escaping_depth(depth)
     }
 }
 
@@ -7024,7 +7035,7 @@ impl RegionEscape for Region {
     }
 }
 
-impl<'tcx> RegionEscape for Generics<'tcx> {
+impl<'tcx> RegionEscape for GenericPredicates<'tcx> {
     fn has_regions_escaping_depth(&self, depth: u32) -> bool {
         self.predicates.has_regions_escaping_depth(depth)
     }
@@ -7133,7 +7144,7 @@ impl<'tcx> HasProjectionTypes for ClosureUpvar<'tcx> {
     }
 }
 
-impl<'tcx> HasProjectionTypes for ty::GenericBounds<'tcx> {
+impl<'tcx> HasProjectionTypes for ty::InstantiatedPredicates<'tcx> {
     fn has_projection_types(&self) -> bool {
         self.predicates.has_projection_types()
     }
diff --git a/src/librustc/middle/ty_fold.rs b/src/librustc/middle/ty_fold.rs
index 69d32c3f5fc..645a7ab9440 100644
--- a/src/librustc/middle/ty_fold.rs
+++ b/src/librustc/middle/ty_fold.rs
@@ -400,6 +400,13 @@ impl<'tcx> TypeFoldable<'tcx> for ty::Generics<'tcx> {
         ty::Generics {
             types: self.types.fold_with(folder),
             regions: self.regions.fold_with(folder),
+        }
+    }
+}
+
+impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::GenericPredicates<'tcx> {
+        ty::GenericPredicates {
             predicates: self.predicates.fold_with(folder),
         }
     }
@@ -440,9 +447,9 @@ impl<'tcx> TypeFoldable<'tcx> for ty::ProjectionTy<'tcx> {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::GenericBounds<'tcx> {
-    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::GenericBounds<'tcx> {
-        ty::GenericBounds {
+impl<'tcx> TypeFoldable<'tcx> for ty::InstantiatedPredicates<'tcx> {
+    fn fold_with<F: TypeFolder<'tcx>>(&self, folder: &mut F) -> ty::InstantiatedPredicates<'tcx> {
+        ty::InstantiatedPredicates {
             predicates: self.predicates.fold_with(folder),
         }
     }
diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs
index 1249e0d8ce1..3ea2743c63e 100644
--- a/src/librustc_typeck/check/_match.rs
+++ b/src/librustc_typeck/check/_match.rs
@@ -467,8 +467,14 @@ pub fn check_pat_struct<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>, pat: &'tcx ast::Pat,
         }
     };
 
-    instantiate_path(pcx.fcx, path, ty::lookup_item_type(tcx, enum_def_id),
-                     None, def, pat.span, pat.id);
+    instantiate_path(pcx.fcx,
+                     path,
+                     ty::lookup_item_type(tcx, enum_def_id),
+                     &ty::lookup_predicates(tcx, enum_def_id),
+                     None,
+                     def,
+                     pat.span,
+                     pat.id);
 
     let pat_ty = fcx.node_ty(pat.id);
     demand::eqtype(fcx, pat.span, expected, pat_ty);
@@ -499,6 +505,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
         .map_or_else(|| def.def_id(), |(enum_def, _)| enum_def);
 
     let ctor_scheme = ty::lookup_item_type(tcx, enum_def);
+    let ctor_predicates = ty::lookup_predicates(tcx, enum_def);
     let path_scheme = if ty::is_fn_ty(ctor_scheme.ty) {
         let fn_ret = ty::assert_no_late_bound_regions(tcx, &ty::ty_fn_ret(ctor_scheme.ty));
         ty::TypeScheme {
@@ -508,7 +515,7 @@ pub fn check_pat_enum<'a, 'tcx>(pcx: &pat_ctxt<'a, 'tcx>,
     } else {
         ctor_scheme
     };
-    instantiate_path(pcx.fcx, path, path_scheme, None, def, pat.span, pat.id);
+    instantiate_path(pcx.fcx, path, path_scheme, &ctor_predicates, None, def, pat.span, pat.id);
 
     let pat_ty = fcx.node_ty(pat.id);
     demand::eqtype(fcx, pat.span, expected, pat_ty);
diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs
index a5b938c7600..1e1d7e09260 100644
--- a/src/librustc_typeck/check/compare_method.rs
+++ b/src/librustc_typeck/check/compare_method.rs
@@ -205,7 +205,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
     // however, because we want to replace all late-bound regions with
     // region variables.
     let impl_bounds =
-        impl_m.generics.to_bounds(tcx, impl_to_skol_substs);
+        impl_m.predicates.instantiate(tcx, impl_to_skol_substs);
 
     let (impl_bounds, _) =
         infcx.replace_late_bound_regions_with_fresh_var(
@@ -216,7 +216,7 @@ pub fn compare_impl_method<'tcx>(tcx: &ty::ctxt<'tcx>,
            impl_bounds.repr(tcx));
 
     // Normalize the associated types in the trait_bounds.
-    let trait_bounds = trait_m.generics.to_bounds(tcx, &trait_to_skol_substs);
+    let trait_bounds = trait_m.predicates.instantiate(tcx, &trait_to_skol_substs);
 
     // Obtain the predicate split predicate sets for each.
     let trait_pred = trait_bounds.predicates.split();
diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs
index 1be6bf05c99..ce67369ca9d 100644
--- a/src/librustc_typeck/check/dropck.rs
+++ b/src/librustc_typeck/check/dropck.rs
@@ -131,8 +131,9 @@ fn iterate_over_potentially_unsafe_regions_in_type<'a, 'tcx>(
 
             let dtor_typescheme = ty::lookup_item_type(rcx.tcx(), impl_did);
             let dtor_generics = dtor_typescheme.generics;
+            let dtor_predicates = ty::lookup_predicates(rcx.tcx(), impl_did);
 
-            let has_pred_of_interest = dtor_generics.predicates.iter().any(|pred| {
+            let has_pred_of_interest = dtor_predicates.predicates.iter().any(|pred| {
                 // In `impl<T> Drop where ...`, we automatically
                 // assume some predicate will be meaningful and thus
                 // represents a type through which we could reach
diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs
index 77701af25d3..dfbfc86c659 100644
--- a/src/librustc_typeck/check/method/confirm.rs
+++ b/src/librustc_typeck/check/method/confirm.rs
@@ -46,7 +46,7 @@ struct InstantiatedMethodSig<'tcx> {
 
     /// Generic bounds on the method's parameters which must be added
     /// as pending obligations.
-    method_bounds: ty::GenericBounds<'tcx>,
+    method_predicates: ty::InstantiatedPredicates<'tcx>,
 }
 
 pub fn confirm<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
@@ -99,7 +99,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
 
         // Create the final signature for the method, replacing late-bound regions.
         let InstantiatedMethodSig {
-            method_sig, all_substs, method_bounds
+            method_sig, all_substs, method_predicates
         } = self.instantiate_method_sig(&pick, all_substs);
         let method_self_ty = method_sig.inputs[0];
 
@@ -107,7 +107,7 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
         self.unify_receivers(self_ty, method_self_ty);
 
         // Add any trait/regions obligations specified on the method's type parameters.
-        self.add_obligations(&pick, &all_substs, &method_bounds);
+        self.add_obligations(&pick, &all_substs, &method_predicates);
 
         // Create the final `MethodCallee`.
         let fty = ty::mk_bare_fn(self.tcx(), None, self.tcx().mk_bare_fn(ty::BareFnTy {
@@ -416,18 +416,19 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
         // that obligation is not necessarily satisfied. (In the
         // future, it would be.) But we know that the true `Self` DOES implement
         // the trait. So we just delete this requirement. Hack hack hack.
-        let mut method_bounds = pick.method_ty.generics.to_bounds(self.tcx(), &all_substs);
+        let mut method_predicates = pick.method_ty.predicates.instantiate(self.tcx(), &all_substs);
         match pick.kind {
             probe::ObjectPick(..) => {
-                assert_eq!(method_bounds.predicates.get_slice(subst::SelfSpace).len(), 1);
-                method_bounds.predicates.pop(subst::SelfSpace);
+                assert_eq!(method_predicates.predicates.get_slice(subst::SelfSpace).len(), 1);
+                method_predicates.predicates.pop(subst::SelfSpace);
             }
             _ => { }
         }
-        let method_bounds = self.fcx.normalize_associated_types_in(self.span, &method_bounds);
+        let method_predicates = self.fcx.normalize_associated_types_in(self.span,
+                                                                       &method_predicates);
 
-        debug!("method_bounds after subst = {}",
-               method_bounds.repr(self.tcx()));
+        debug!("method_predicates after subst = {}",
+               method_predicates.repr(self.tcx()));
 
         // Instantiate late-bound regions and substitute the trait
         // parameters into the method type to get the actual method type.
@@ -446,22 +447,22 @@ impl<'a,'tcx> ConfirmContext<'a,'tcx> {
         InstantiatedMethodSig {
             method_sig: method_sig,
             all_substs: all_substs,
-            method_bounds: method_bounds,
+            method_predicates: method_predicates,
         }
     }
 
     fn add_obligations(&mut self,
                        pick: &probe::Pick<'tcx>,
                        all_substs: &subst::Substs<'tcx>,
-                       method_bounds: &ty::GenericBounds<'tcx>) {
-        debug!("add_obligations: pick={} all_substs={} method_bounds={}",
+                       method_predicates: &ty::InstantiatedPredicates<'tcx>) {
+        debug!("add_obligations: pick={} all_substs={} method_predicates={}",
                pick.repr(self.tcx()),
                all_substs.repr(self.tcx()),
-               method_bounds.repr(self.tcx()));
+               method_predicates.repr(self.tcx()));
 
         self.fcx.add_obligations_for_parameters(
             traits::ObligationCause::misc(self.span, self.fcx.body_id),
-            method_bounds);
+            method_predicates);
 
         self.fcx.add_default_region_param_bounds(
             all_substs,
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index 88455b3385a..55b4dae5b9e 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -221,7 +221,7 @@ pub fn lookup_in_trait_adjusted<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
     //
     // Note that as the method comes from a trait, it should not have
     // any late-bound regions appearing in its bounds.
-    let method_bounds = fcx.instantiate_bounds(span, trait_ref.substs, &method_ty.generics);
+    let method_bounds = fcx.instantiate_bounds(span, trait_ref.substs, &method_ty.predicates);
     assert!(!method_bounds.has_escaping_regions());
     fcx.add_obligations_for_parameters(
         traits::ObligationCause::misc(span, fcx.body_id),
diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs
index cfc04a9a92f..82bd4ae87ff 100644
--- a/src/librustc_typeck/check/method/probe.rs
+++ b/src/librustc_typeck/check/method/probe.rs
@@ -666,8 +666,9 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
             debug!("assemble_projection_candidates: projection_trait_ref={}",
                    projection_trait_ref.repr(self.tcx()));
 
-            let trait_def = ty::lookup_trait_def(self.tcx(), projection_trait_ref.def_id);
-            let bounds = trait_def.generics.to_bounds(self.tcx(), projection_trait_ref.substs);
+            let trait_predicates = ty::lookup_predicates(self.tcx(),
+                                                         projection_trait_ref.def_id);
+            let bounds = trait_predicates.instantiate(self.tcx(), projection_trait_ref.substs);
             let predicates = bounds.predicates.into_vec();
             debug!("assemble_projection_candidates: predicates={}",
                    predicates.repr(self.tcx()));
@@ -943,8 +944,8 @@ impl<'a,'tcx> ProbeContext<'a,'tcx> {
                     let cause = traits::ObligationCause::misc(self.span, self.fcx.body_id);
 
                     // Check whether the impl imposes obligations we have to worry about.
-                    let impl_generics = ty::lookup_item_type(self.tcx(), impl_def_id).generics;
-                    let impl_bounds = impl_generics.to_bounds(self.tcx(), substs);
+                    let impl_bounds = ty::lookup_predicates(self.tcx(), impl_def_id);
+                    let impl_bounds = impl_bounds.instantiate(self.tcx(), substs);
                     let traits::Normalized { value: impl_bounds,
                                              obligations: norm_obligations } =
                         traits::normalize(selcx, cause.clone(), &impl_bounds);
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index d90ed7eda59..00bc3375fdd 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -93,7 +93,7 @@ use middle::pat_util::{self, pat_id_map};
 use middle::region::{self, CodeExtent};
 use middle::subst::{self, Subst, Substs, VecPerParamSpace, ParamSpace, TypeSpace};
 use middle::traits;
-use middle::ty::{FnSig, VariantInfo, TypeScheme};
+use middle::ty::{FnSig, GenericPredicates, VariantInfo, TypeScheme};
 use middle::ty::{Disr, ParamTy, ParameterEnvironment};
 use middle::ty::{self, HasProjectionTypes, RegionEscape, Ty};
 use middle::ty::liberate_late_bound_regions;
@@ -101,7 +101,7 @@ use middle::ty::{MethodCall, MethodCallee, MethodMap, ObjectCastMap};
 use middle::ty_fold::{TypeFolder, TypeFoldable};
 use rscope::RegionScope;
 use session::Session;
-use {CrateCtxt, lookup_def_ccx, no_params, require_same_types};
+use {CrateCtxt, lookup_def_ccx, require_same_types};
 use TypeAndSubsts;
 use lint;
 use util::common::{block_query, indenter, loop_query};
@@ -1446,11 +1446,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     fn instantiate_bounds(&self,
                           span: Span,
                           substs: &Substs<'tcx>,
-                          generics: &ty::Generics<'tcx>)
-                          -> ty::GenericBounds<'tcx>
+                          bounds: &ty::GenericPredicates<'tcx>)
+                          -> ty::InstantiatedPredicates<'tcx>
     {
-        ty::GenericBounds {
-            predicates: self.instantiate_type_scheme(span, substs, &generics.predicates)
+        ty::InstantiatedPredicates {
+            predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
         }
     }
 
@@ -1561,12 +1561,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     {
         let type_scheme =
             ty::lookup_item_type(self.tcx(), def_id);
+        let type_predicates =
+            ty::lookup_predicates(self.tcx(), def_id);
         let substs =
             self.infcx().fresh_substs_for_generics(
                 span,
                 &type_scheme.generics);
         let bounds =
-            self.instantiate_bounds(span, &substs, &type_scheme.generics);
+            self.instantiate_bounds(span, &substs, &type_predicates);
         self.add_obligations_for_parameters(
             traits::ObligationCause::new(
                 span,
@@ -1594,7 +1596,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     {
         let tcx = self.tcx();
 
-        let ty::TypeScheme { generics, ty: decl_ty } = ty::lookup_item_type(tcx, did);
+        let ty::TypeScheme { generics, ty: decl_ty } =
+            ty::lookup_item_type(tcx, did);
 
         let wants_params =
             generics.has_type_params(TypeSpace) || generics.has_region_params(TypeSpace);
@@ -1843,16 +1846,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// and `T`. This routine will add a region obligation `$1:'$0` and register it locally.
     pub fn add_obligations_for_parameters(&self,
                                           cause: traits::ObligationCause<'tcx>,
-                                          generic_bounds: &ty::GenericBounds<'tcx>)
+                                          predicates: &ty::InstantiatedPredicates<'tcx>)
     {
-        assert!(!generic_bounds.has_escaping_regions());
+        assert!(!predicates.has_escaping_regions());
 
-        debug!("add_obligations_for_parameters(generic_bounds={})",
-               generic_bounds.repr(self.tcx()));
+        debug!("add_obligations_for_parameters(predicates={})",
+               predicates.repr(self.tcx()));
 
         let obligations = traits::predicates_for_generics(self.tcx(),
                                                           cause,
-                                                          generic_bounds);
+                                                          predicates);
 
         obligations.map_move(|o| self.register_predicate(o));
     }
@@ -3616,8 +3619,8 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
       }
       ast::ExprPath(ref path) => {
           let defn = lookup_def(fcx, path.span, id);
-          let pty = type_scheme_for_def(fcx, expr.span, defn);
-          instantiate_path(fcx, path, pty, None, defn, expr.span, expr.id);
+          let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
+          instantiate_path(fcx, path, scheme, &predicates, None, defn, expr.span, expr.id);
 
           // We always require that the type provided as the value for
           // a type parameter outlives the moment of instantiation.
@@ -3629,10 +3632,10 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
           astconv::instantiate_trait_ref(fcx, fcx, &*qpath.trait_ref, Some(self_ty), None);
 
           let defn = lookup_def(fcx, expr.span, id);
-          let pty = type_scheme_for_def(fcx, expr.span, defn);
+          let (scheme, predicates) = type_scheme_and_predicates_for_def(fcx, expr.span, defn);
           let mut path = qpath.trait_ref.path.clone();
           path.segments.push(qpath.item_path.clone());
-          instantiate_path(fcx, &path, pty, Some(self_ty), defn, expr.span, expr.id);
+          instantiate_path(fcx, &path, scheme, &predicates, Some(self_ty), defn, expr.span, expr.id);
 
           // We always require that the type provided as the value for
           // a type parameter outlives the moment of instantiation.
@@ -4048,9 +4051,9 @@ fn check_expr_with_unifier<'a, 'tcx, F>(fcx: &FnCtxt<'a, 'tcx>,
                 };
 
                 if let Some(did) = did {
-                    let polytype = ty::lookup_item_type(tcx, did);
+                    let predicates = ty::lookup_predicates(tcx, did);
                     let substs = Substs::new_type(vec![idx_type], vec![]);
-                    let bounds = fcx.instantiate_bounds(expr.span, &substs, &polytype.generics);
+                    let bounds = fcx.instantiate_bounds(expr.span, &substs, &predicates);
                     fcx.add_obligations_for_parameters(
                         traits::ObligationCause::new(expr.span,
                                                      fcx.body_id,
@@ -4631,46 +4634,36 @@ pub fn lookup_def(fcx: &FnCtxt, sp: Span, id: ast::NodeId) -> def::Def {
 }
 
 // Returns the type parameter count and the type for the given definition.
-pub fn type_scheme_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
-                                     sp: Span,
-                                     defn: def::Def)
-                                     -> TypeScheme<'tcx> {
+fn type_scheme_and_predicates_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
+                                                sp: Span,
+                                                defn: def::Def)
+                                                -> (TypeScheme<'tcx>, GenericPredicates<'tcx>) {
     match defn {
-      def::DefLocal(nid) | def::DefUpvar(nid, _) => {
-          let typ = fcx.local_ty(sp, nid);
-          return no_params(typ);
-      }
-      def::DefFn(id, _) | def::DefStaticMethod(id, _) | def::DefMethod(id, _, _) |
-      def::DefStatic(id, _) | def::DefVariant(_, id, _) |
-      def::DefStruct(id) | def::DefConst(id) => {
-        return ty::lookup_item_type(fcx.ccx.tcx, id);
-      }
-      def::DefTrait(_) |
-      def::DefTy(..) |
-      def::DefAssociatedTy(..) |
-      def::DefAssociatedPath(..) |
-      def::DefPrimTy(_) |
-      def::DefTyParam(..) => {
-        fcx.ccx.tcx.sess.span_bug(sp, "expected value, found type");
-      }
-      def::DefMod(..) | def::DefForeignMod(..) => {
-        fcx.ccx.tcx.sess.span_bug(sp, "expected value, found module");
-      }
-      def::DefUse(..) => {
-        fcx.ccx.tcx.sess.span_bug(sp, "expected value, found use");
-      }
-      def::DefRegion(..) => {
-        fcx.ccx.tcx.sess.span_bug(sp, "expected value, found region");
-      }
-      def::DefTyParamBinder(..) => {
-        fcx.ccx.tcx.sess.span_bug(sp, "expected value, found type parameter");
-      }
-      def::DefLabel(..) => {
-        fcx.ccx.tcx.sess.span_bug(sp, "expected value, found label");
-      }
-      def::DefSelfTy(..) => {
-        fcx.ccx.tcx.sess.span_bug(sp, "expected value, found self ty");
-      }
+        def::DefLocal(nid) | def::DefUpvar(nid, _) => {
+            let typ = fcx.local_ty(sp, nid);
+            (ty::TypeScheme { generics: ty::Generics::empty(), ty: typ },
+             ty::GenericPredicates::empty())
+        }
+        def::DefFn(id, _) | def::DefStaticMethod(id, _) | def::DefMethod(id, _, _) |
+        def::DefStatic(id, _) | def::DefVariant(_, id, _) |
+        def::DefStruct(id) | def::DefConst(id) => {
+            (ty::lookup_item_type(fcx.tcx(), id), ty::lookup_predicates(fcx.tcx(), id))
+        }
+        def::DefTrait(_) |
+        def::DefTy(..) |
+        def::DefAssociatedTy(..) |
+        def::DefAssociatedPath(..) |
+        def::DefPrimTy(_) |
+        def::DefTyParam(..) |
+        def::DefMod(..) |
+        def::DefForeignMod(..) |
+        def::DefUse(..) |
+        def::DefRegion(..) |
+        def::DefTyParamBinder(..) |
+        def::DefLabel(..) |
+        def::DefSelfTy(..) => {
+            fcx.ccx.tcx.sess.span_bug(sp, &format!("expected value, found {:?}", defn));
+        }
     }
 }
 
@@ -4679,6 +4672,7 @@ pub fn type_scheme_for_def<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
                                   path: &ast::Path,
                                   type_scheme: TypeScheme<'tcx>,
+                                  type_predicates: &ty::GenericPredicates<'tcx>,
                                   opt_self_ty: Option<Ty<'tcx>>,
                                   def: def::Def,
                                   span: Span,
@@ -4864,7 +4858,7 @@ pub fn instantiate_path<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
 
     // Add all the obligations that are required, substituting and
     // normalized appropriately.
-    let bounds = fcx.instantiate_bounds(span, &substs, &type_scheme.generics);
+    let bounds = fcx.instantiate_bounds(span, &substs, &type_predicates);
     fcx.add_obligations_for_parameters(
         traits::ObligationCause::new(span, fcx.body_id, traits::ItemObligation(def.def_id())),
         &bounds);
diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs
index 80f6e3800f7..bcb2ba6231d 100644
--- a/src/librustc_typeck/check/regionck.rs
+++ b/src/librustc_typeck/check/regionck.rs
@@ -1588,8 +1588,8 @@ fn projection_bounds<'a,'tcx>(rcx: &Rcx<'a, 'tcx>,
     // ```
     //
     // we can thus deduce that `<T as SomeTrait<'a>>::SomeType : 'a`.
-    let trait_def = ty::lookup_trait_def(tcx, projection_ty.trait_ref.def_id);
-    let predicates = trait_def.generics.predicates.as_slice().to_vec();
+    let trait_predicates = ty::lookup_predicates(tcx, projection_ty.trait_ref.def_id);
+    let predicates = trait_predicates.predicates.as_slice().to_vec();
     traits::elaborate_predicates(tcx, predicates)
         .filter_map(|predicate| {
             // we're only interesting in `T : 'a` style predicates:
diff --git a/src/librustc_typeck/check/wf.rs b/src/librustc_typeck/check/wf.rs
index 923614f9e8a..94670305be7 100644
--- a/src/librustc_typeck/check/wf.rs
+++ b/src/librustc_typeck/check/wf.rs
@@ -107,12 +107,12 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                 });
             }
             ast::ItemTrait(..) => {
-                let trait_def =
-                    ty::lookup_trait_def(ccx.tcx, local_def(item.id));
+                let trait_predicates =
+                    ty::lookup_predicates(ccx.tcx, local_def(item.id));
                 reject_non_type_param_bounds(
                     ccx.tcx,
                     item.span,
-                    &trait_def.generics);
+                    &trait_predicates);
             }
             _ => {}
         }
@@ -124,11 +124,13 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
         let ccx = self.ccx;
         let item_def_id = local_def(item.id);
         let type_scheme = ty::lookup_item_type(ccx.tcx, item_def_id);
-        reject_non_type_param_bounds(ccx.tcx, item.span, &type_scheme.generics);
+        let type_predicates = ty::lookup_predicates(ccx.tcx, item_def_id);
+        reject_non_type_param_bounds(ccx.tcx, item.span, &type_predicates);
         let param_env =
             ty::construct_parameter_environment(ccx.tcx,
                                                 item.span,
                                                 &type_scheme.generics,
+                                                &type_predicates,
                                                 item.id);
         let inh = Inherited::new(ccx.tcx, param_env);
         let fcx = blank_fn_ctxt(ccx, &inh, ty::FnConverging(type_scheme.ty), item.id);
@@ -283,9 +285,8 @@ impl<'ccx, 'tcx> CheckTypeWellFormedVisitor<'ccx, 'tcx> {
 // Reject any predicates that do not involve a type parameter.
 fn reject_non_type_param_bounds<'tcx>(tcx: &ty::ctxt<'tcx>,
                                       span: Span,
-                                      generics: &ty::Generics<'tcx>) {
-
-    for predicate in generics.predicates.iter() {
+                                      predicates: &ty::GenericPredicates<'tcx>) {
+    for predicate in predicates.predicates.iter() {
         match predicate {
             &ty::Predicate::Trait(ty::Binder(ref tr)) => {
                 let found_param = tr.input_types().iter()
@@ -367,7 +368,7 @@ impl<'ccx, 'tcx, 'v> Visitor<'v> for CheckTypeWellFormedVisitor<'ccx, 'tcx> {
                         reject_non_type_param_bounds(
                             self.ccx.tcx,
                             method.span,
-                            &ty_method.generics);
+                            &ty_method.predicates);
                         reject_shadowing_type_parameters(
                             self.ccx.tcx,
                             method.span,
@@ -415,9 +416,11 @@ impl<'cx,'tcx> BoundsChecker<'cx,'tcx> {
     /// Note that it does not (currently, at least) check that `A : Copy` (that check is delegated
     /// to the point where impl `A : Trait<B>` is implemented).
     pub fn check_trait_ref(&mut self, trait_ref: &ty::TraitRef<'tcx>) {
-        let trait_def = ty::lookup_trait_def(self.fcx.tcx(), trait_ref.def_id);
+        let trait_predicates = ty::lookup_predicates(self.fcx.tcx(), trait_ref.def_id);
 
-        let bounds = self.fcx.instantiate_bounds(self.span, trait_ref.substs, &trait_def.generics);
+        let bounds = self.fcx.instantiate_bounds(self.span,
+                                                 trait_ref.substs,
+                                                 &trait_predicates);
 
         self.fcx.add_obligations_for_parameters(
             traits::ObligationCause::new(
@@ -482,8 +485,9 @@ impl<'cx,'tcx> TypeFolder<'tcx> for BoundsChecker<'cx,'tcx> {
         match t.sty{
             ty::ty_struct(type_id, substs) |
             ty::ty_enum(type_id, substs) => {
-                let type_scheme = ty::lookup_item_type(self.fcx.tcx(), type_id);
-                let bounds = self.fcx.instantiate_bounds(self.span, substs, &type_scheme.generics);
+                let type_predicates = ty::lookup_predicates(self.fcx.tcx(), type_id);
+                let bounds = self.fcx.instantiate_bounds(self.span, substs,
+                                                         &type_predicates);
 
                 if self.binding_count == 0 {
                     self.fcx.add_obligations_for_parameters(
@@ -603,10 +607,10 @@ fn enum_variants<'a, 'tcx>(fcx: &FnCtxt<'a, 'tcx>,
         .collect()
 }
 
-fn filter_to_trait_obligations<'tcx>(bounds: ty::GenericBounds<'tcx>)
-                                     -> ty::GenericBounds<'tcx>
+fn filter_to_trait_obligations<'tcx>(bounds: ty::InstantiatedPredicates<'tcx>)
+                                     -> ty::InstantiatedPredicates<'tcx>
 {
-    let mut result = ty::GenericBounds::empty();
+    let mut result = ty::InstantiatedPredicates::empty();
     for (space, _, predicate) in bounds.predicates.iter_enumerated() {
         match *predicate {
             ty::Predicate::Trait(..) |
diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs
index ed340b0882c..1542e74ff81 100644
--- a/src/librustc_typeck/coherence/mod.rs
+++ b/src/librustc_typeck/coherence/mod.rs
@@ -247,6 +247,7 @@ impl<'a, 'tcx> CoherenceChecker<'a, 'tcx> {
             debug!("new_polytype={}", new_polytype.repr(tcx));
 
             tcx.tcache.borrow_mut().insert(new_did, new_polytype);
+            tcx.predicates.borrow_mut().insert(new_did, new_method_ty.predicates.clone());
             tcx.impl_or_trait_items
                .borrow_mut()
                .insert(new_did, ty::MethodTraitItem(new_method_ty));
@@ -555,6 +556,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
     debug!("subst_receiver_types_in_method_ty: combined_substs={}",
            combined_substs.repr(tcx));
 
+    let method_predicates = method.predicates.subst(tcx, &combined_substs);
     let mut method_generics = method.generics.subst(tcx, &combined_substs);
 
     // replace the type parameters declared on the trait with those
@@ -579,6 +581,7 @@ fn subst_receiver_types_in_method_ty<'tcx>(tcx: &ty::ctxt<'tcx>,
     ty::Method::new(
         method.name,
         method_generics,
+        method_predicates,
         method_fty,
         method.explicit_self,
         method.vis,
diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs
index 5ad2dc2871c..ccfadaba244 100644
--- a/src/librustc_typeck/lib.rs
+++ b/src/librustc_typeck/lib.rs
@@ -102,7 +102,6 @@ pub use rustc::util;
 use middle::def;
 use middle::infer;
 use middle::subst;
-use middle::subst::VecPerParamSpace;
 use middle::ty::{self, Ty};
 use session::config;
 use util::common::time;
@@ -177,17 +176,6 @@ fn lookup_def_ccx(ccx: &CrateCtxt, sp: Span, id: ast::NodeId)
     lookup_def_tcx(ccx.tcx, sp, id)
 }
 
-fn no_params<'tcx>(t: Ty<'tcx>) -> ty::TypeScheme<'tcx> {
-    ty::TypeScheme {
-        generics: ty::Generics {
-            types: VecPerParamSpace::empty(),
-            regions: VecPerParamSpace::empty(),
-            predicates: VecPerParamSpace::empty(),
-        },
-        ty: t
-    }
-}
-
 fn require_same_types<'a, 'tcx, M>(tcx: &ty::ctxt<'tcx>,
                                    maybe_infcx: Option<&infer::InferCtxt<'a, 'tcx>>,
                                    t1_is_expected: bool,
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index dfa5b01270e..d1283d6f46b 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -166,10 +166,11 @@ pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt,
         }
     });
     let trait_def = ty::lookup_trait_def(tcx, did);
+    let predicates = ty::lookup_predicates(tcx, did);
     let bounds = trait_def.bounds.clean(cx);
     clean::Trait {
         unsafety: def.unsafety,
-        generics: (&def.generics, subst::TypeSpace).clean(cx),
+        generics: (&def.generics, &predicates, subst::TypeSpace).clean(cx),
         items: items.collect(),
         bounds: bounds,
     }
@@ -181,9 +182,10 @@ fn build_external_function(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) ->
         ty::ty_bare_fn(_, ref f) => ((did, &f.sig).clean(cx), f.unsafety),
         _ => panic!("bad function"),
     };
+    let predicates = ty::lookup_predicates(tcx, did);
     clean::Function {
         decl: decl,
-        generics: (&t.generics, subst::FnSpace).clean(cx),
+        generics: (&t.generics, &predicates, subst::FnSpace).clean(cx),
         unsafety: style,
     }
 }
@@ -192,6 +194,7 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru
     use syntax::parse::token::special_idents::unnamed_field;
 
     let t = ty::lookup_item_type(tcx, did);
+    let predicates = ty::lookup_predicates(tcx, did);
     let fields = ty::lookup_struct_fields(tcx, did);
 
     clean::Struct {
@@ -201,7 +204,7 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru
             [ref f, ..] if f.name == unnamed_field.name => doctree::Tuple,
             _ => doctree::Plain,
         },
-        generics: (&t.generics, subst::TypeSpace).clean(cx),
+        generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
         fields: fields.clean(cx),
         fields_stripped: false,
     }
@@ -209,10 +212,11 @@ fn build_struct(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Stru
 
 fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
     let t = ty::lookup_item_type(tcx, did);
+    let predicates = ty::lookup_predicates(tcx, did);
     match t.ty.sty {
         ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
             return clean::EnumItem(clean::Enum {
-                generics: (&t.generics, subst::TypeSpace).clean(cx),
+                generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
                 variants_stripped: false,
                 variants: ty::enum_variants(tcx, edid).clean(cx),
             })
@@ -222,7 +226,7 @@ fn build_type(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEn
 
     clean::TypedefItem(clean::Typedef {
         type_: t.ty.clean(cx),
-        generics: (&t.generics, subst::TypeSpace).clean(cx),
+        generics: (&t.generics, &predicates, subst::TypeSpace).clean(cx),
     })
 }
 
@@ -293,6 +297,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
 
     let attrs = load_attrs(cx, tcx, did);
     let ty = ty::lookup_item_type(tcx, did);
+    let predicates = ty::lookup_predicates(tcx, did);
     let trait_items = csearch::get_impl_items(&tcx.sess.cstore, did)
             .iter()
             .filter_map(|did| {
@@ -323,9 +328,10 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
             ty::TypeTraitItem(ref assoc_ty) => {
                 let did = assoc_ty.def_id;
                 let type_scheme = ty::lookup_item_type(tcx, did);
+                let predicates = ty::lookup_predicates(tcx, did);
                 // Not sure the choice of ParamSpace actually matters here, because an
                 // associated type won't have generics on the LHS
-                let typedef = (type_scheme, subst::ParamSpace::TypeSpace).clean(cx);
+                let typedef = (type_scheme, predicates, subst::ParamSpace::TypeSpace).clean(cx);
                 Some(clean::Item {
                     name: Some(assoc_ty.name.clean(cx)),
                     inner: clean::TypedefItem(typedef),
@@ -349,7 +355,7 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt,
                 }
             }),
             for_: ty.ty.clean(cx),
-            generics: (&ty.generics, subst::TypeSpace).clean(cx),
+            generics: (&ty.generics, &predicates, subst::TypeSpace).clean(cx),
             items: trait_items,
             polarity: polarity.map(|p| { p.clean(cx) }),
         }),
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 7ab9d8c6672..6c3d2d8fa19 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -860,7 +860,9 @@ impl Clean<Generics> for ast::Generics {
     }
 }
 
-impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>, subst::ParamSpace) {
+impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
+                                    &'a ty::GenericPredicates<'tcx>,
+                                    subst::ParamSpace) {
     fn clean(&self, cx: &DocContext) -> Generics {
         use std::collections::HashSet;
         use syntax::ast::TraitBoundModifier as TBM;
@@ -885,7 +887,8 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>, subst::ParamSpace) {
             false
         }
 
-        let (gens, space) = *self;
+        let (gens, preds, space) = *self;
+
         // Bounds in the type_params and lifetimes fields are repeated in the predicates
         // field (see rustc_typeck::collect::ty_generics), so remove them.
         let stripped_typarams = gens.types.get_slice(space).iter().map(|tp| {
@@ -899,7 +902,8 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>, subst::ParamSpace) {
             srp.clean(cx)
         }).collect::<Vec<_>>();
 
-        let where_predicates = gens.predicates.get_slice(space).to_vec().clean(cx);
+        let where_predicates = preds.predicates.get_slice(space).to_vec().clean(cx);
+
         // Type parameters have a Sized bound by default unless removed with ?Sized.
         // Scan through the predicates and mark any type parameter with a Sized
         // bound, removing the bounds as we find them.
@@ -913,6 +917,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>, subst::ParamSpace) {
             }
             Some(pred)
         }).collect::<Vec<_>>();
+
         // Finally, run through the type parameters again and insert a ?Sized unbound for
         // any we didn't find to be Sized.
         for tp in &stripped_typarams {
@@ -1303,7 +1308,7 @@ impl<'tcx> Clean<Item> for ty::Method<'tcx> {
             source: Span::empty(),
             inner: TyMethodItem(TyMethod {
                 unsafety: self.fty.unsafety,
-                generics: (&self.generics, subst::FnSpace).clean(cx),
+                generics: (&self.generics, &self.predicates, subst::FnSpace).clean(cx),
                 self_: self_,
                 decl: (self.def_id, &sig).clean(cx),
                 abi: self.fty.abi
@@ -2560,12 +2565,12 @@ impl Clean<Item> for ast::Typedef {
     }
 }
 
-impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ParamSpace) {
+impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>, ParamSpace) {
     fn clean(&self, cx: &DocContext) -> Typedef {
-        let (ref ty_scheme, ps) = *self;
+        let (ref ty_scheme, ref predicates, ps) = *self;
         Typedef {
             type_: ty_scheme.ty.clean(cx),
-            generics: (&ty_scheme.generics, ps).clean(cx)
+            generics: (&ty_scheme.generics, predicates, ps).clean(cx)
         }
     }
 }