]> git.lizzy.rs Git - rust.git/commitdiff
rustc: use Vec instead of VecPerParamSpace for ty::GenericPredicates.
authorEduard Burtescu <edy.burt@gmail.com>
Mon, 13 Jun 2016 17:10:32 +0000 (20:10 +0300)
committerEduard Burtescu <edy.burt@gmail.com>
Wed, 17 Aug 2016 02:50:57 +0000 (05:50 +0300)
19 files changed:
src/librustc/traits/object_safety.rs
src/librustc/traits/project.rs
src/librustc/traits/select.rs
src/librustc/ty/mod.rs
src/librustc/ty/subst.rs
src/librustc/util/ppaux.rs
src/librustc_metadata/common.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_trans/collector.rs
src/librustc_trans/meth.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/method/probe.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs
src/librustdoc/clean/simplify.rs

index 4889895860129144dc323c6ce52ebde00b364c89..8ddb14e08e31ee9e7653205da3945e718c4515b7 100644 (file)
@@ -184,7 +184,7 @@ fn generics_require_sized_self(self,
         // Search for a predicate like `Self : Sized` amongst the trait bounds.
         let free_substs = self.construct_free_substs(generics,
             self.region_maps.node_extent(ast::DUMMY_NODE_ID));
-        let predicates = predicates.instantiate(self, &free_substs).predicates.into_vec();
+        let predicates = predicates.instantiate(self, &free_substs).predicates;
         elaborate_predicates(self, predicates)
             .any(|predicate| {
                 match predicate {
index aed4f4393241191d1f2d655f2ba594a709d67b10..d580deed0756ab0ccd7acf5e0ad760fffb388978 100644 (file)
@@ -811,7 +811,7 @@ fn assemble_candidates_from_trait_def<'cx, 'gcx, 'tcx>(
     // If so, extract what we know from the trait and try to come up with a good answer.
     let trait_predicates = selcx.tcx().lookup_predicates(def_id);
     let bounds = trait_predicates.instantiate(selcx.tcx(), substs);
-    let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates.into_vec());
+    let bounds = elaborate_predicates(selcx.tcx(), bounds.predicates);
     assemble_candidates_from_predicates(selcx,
                                         obligation,
                                         obligation_trait_ref,
index b61cb0d3eee7217c17243564bee61a911ae706d9..6b9de746f66c39b8e840fff5a98a9f40db68737a 100644 (file)
@@ -1214,7 +1214,7 @@ fn match_projection_obligation_against_definition_bounds(
                bounds);
 
         let matching_bound =
-            util::elaborate_predicates(self.tcx(), bounds.predicates.into_vec())
+            util::elaborate_predicates(self.tcx(), bounds.predicates)
             .filter_to_traits()
             .find(
                 |bound| self.probe(
index cfc2e89f9d5a126e10e22681c00076fb29710007..4f39a711010b7a82105e1334a55051ba85e4c7eb 100644 (file)
@@ -178,7 +178,7 @@ pub fn with_fresh_ty_vars(selcx: &mut traits::SelectionContext<'a, 'gcx, 'tcx>,
             impl_def_id: impl_def_id,
             self_ty: tcx.lookup_item_type(impl_def_id).ty,
             trait_ref: tcx.impl_trait_ref(impl_def_id),
-            predicates: tcx.lookup_predicates(impl_def_id).predicates.into_vec(),
+            predicates: tcx.lookup_predicates(impl_def_id).predicates
         }.subst(tcx, &impl_substs);
 
         let traits::Normalized { value: mut header, obligations } =
@@ -775,13 +775,13 @@ pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
 /// Bounds on generics.
 #[derive(Clone)]
 pub struct GenericPredicates<'tcx> {
-    pub predicates: VecPerParamSpace<Predicate<'tcx>>,
+    pub predicates: Vec<Predicate<'tcx>>,
 }
 
 impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
     pub fn empty() -> GenericPredicates<'tcx> {
         GenericPredicates {
-            predicates: VecPerParamSpace::empty(),
+            predicates: vec![]
         }
     }
 
@@ -797,9 +797,9 @@ pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                   -> InstantiatedPredicates<'tcx>
     {
         InstantiatedPredicates {
-            predicates: self.predicates.map(|pred| {
+            predicates: self.predicates.iter().map(|pred| {
                 pred.subst_supertrait(tcx, poly_trait_ref)
-            })
+            }).collect()
         }
     }
 }
@@ -1193,12 +1193,12 @@ pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
 /// [usize:Bar<isize>]]`.
 #[derive(Clone)]
 pub struct InstantiatedPredicates<'tcx> {
-    pub predicates: VecPerParamSpace<Predicate<'tcx>>,
+    pub predicates: Vec<Predicate<'tcx>>,
 }
 
 impl<'tcx> InstantiatedPredicates<'tcx> {
     pub fn empty() -> InstantiatedPredicates<'tcx> {
-        InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
+        InstantiatedPredicates { predicates: vec![] }
     }
 
     pub fn is_empty(&self) -> bool {
@@ -2909,7 +2909,7 @@ pub fn construct_parameter_environment(self,
         let tcx = self.global_tcx();
         let bounds = generic_predicates.instantiate(tcx, &free_substs);
         let bounds = tcx.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
-        let predicates = bounds.predicates.into_vec();
+        let predicates = bounds.predicates;
 
         // Finally, we have to normalize the bounds in the environment, in
         // case they contain any associated type projections. This process
index 595d965ffce262eede9050e22016b4c24b4ecb7e..25b108cee27550163a797bdb438365937f4c0dde 100644 (file)
@@ -217,14 +217,6 @@ pub struct VecPerParamSpace<T> {
     content: Vec<T>,
 }
 
-/// The `split` function converts one `VecPerParamSpace` into this
-/// `SeparateVecsPerParamSpace` structure.
-pub struct SeparateVecsPerParamSpace<T> {
-    pub types: Vec<T>,
-    pub selfs: Vec<T>,
-    pub fns: Vec<T>,
-}
-
 impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         write!(f, "[{:?};{:?};{:?}]",
@@ -428,18 +420,6 @@ pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
                                        self.self_limit)
     }
 
-    pub fn split(self) -> SeparateVecsPerParamSpace<T> {
-        let VecPerParamSpace { type_limit, self_limit, content } = self;
-
-        let mut content_iter = content.into_iter();
-
-        SeparateVecsPerParamSpace {
-            types: content_iter.by_ref().take(type_limit).collect(),
-            selfs: content_iter.by_ref().take(self_limit - type_limit).collect(),
-            fns: content_iter.collect()
-        }
-    }
-
     pub fn with_slice(mut self, space: ParamSpace, slice: &[T])
                     -> VecPerParamSpace<T>
         where T: Clone
index 896ef49de6f05240d1bc2749effa35e262ddd9d9..37750b568bba2823c70e5ac24f28ba7455cc5604 100644 (file)
@@ -917,7 +917,7 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
                     let mut first = true;
                     let mut is_sized = false;
                     write!(f, "impl")?;
-                    for predicate in bounds.predicates.into_vec() {
+                    for predicate in bounds.predicates {
                         if let Some(trait_ref) = predicate.to_opt_poly_trait_ref() {
                             // Don't print +Sized, but rather +?Sized if absent.
                             if Some(trait_ref.def_id()) == tcx.lang_items.sized_trait() {
index ff072cce5db9667ccd5cb998ee0cdcb6384cdd78..0011b59c70ed3d5f19ab908e8d5fdc84306c3fba 100644 (file)
@@ -207,9 +207,8 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
 pub const tag_item_generics: usize = 0x95;
 pub const tag_method_ty_generics: usize = 0x96;
 
-pub const tag_type_predicate: usize = 0x97;
-pub const tag_self_predicate: usize = 0x98;
-pub const tag_fn_predicate: usize = 0x99;
+pub const tag_predicate: usize = 0x97;
+// GAP 0x98, 0x99
 
 pub const tag_unsafety: usize = 0x9a;
 
index 64b614b56e12fdffe444b86545fb03c77226adaa..b91fb993f08ee9d931152147fe87458b91690f5b 100644 (file)
@@ -1622,21 +1622,11 @@ fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc,
 {
     let doc = reader::get_doc(base_doc, tag);
 
-    let mut predicates = subst::VecPerParamSpace::empty();
-    for predicate_doc in reader::tagged_docs(doc, tag_type_predicate) {
-        predicates.push(subst::TypeSpace,
-                        doc_predicate(cdata, predicate_doc, tcx));
-    }
-    for predicate_doc in reader::tagged_docs(doc, tag_self_predicate) {
-        predicates.push(subst::SelfSpace,
-                        doc_predicate(cdata, predicate_doc, tcx));
-    }
-    for predicate_doc in reader::tagged_docs(doc, tag_fn_predicate) {
-        predicates.push(subst::FnSpace,
-                        doc_predicate(cdata, predicate_doc, tcx));
+    ty::GenericPredicates {
+        predicates: reader::tagged_docs(doc, tag_predicate).map(|predicate_doc| {
+            doc_predicate(cdata, predicate_doc, tcx)
+        }).collect()
     }
-
-    ty::GenericPredicates { predicates: predicates }
 }
 
 pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool {
index cc1d07b33c7e830b6840e2d4b79045210db44f99..288fb74cc18a13c71c242df7258bbd6f76db6dca 100644 (file)
@@ -26,7 +26,6 @@
 use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::dependency_format::Linkage;
 use rustc::dep_graph::{DepGraph, DepNode, DepTask};
-use rustc::ty::subst;
 use rustc::traits::specialization_graph;
 use rustc::ty::{self, Ty, TyCtxt};
 use rustc::ty::util::IntTypeExt;
@@ -541,14 +540,8 @@ fn encode_predicates_in_current_doc<'a,'tcx>(rbml_w: &mut Encoder,
                                              index: &mut CrateIndex<'a, 'tcx>,
                                              predicates: &ty::GenericPredicates<'tcx>)
 {
-    for (space, _, predicate) in predicates.predicates.iter_enumerated() {
-        let tag = match space {
-            subst::TypeSpace => tag_type_predicate,
-            subst::SelfSpace => tag_self_predicate,
-            subst::FnSpace => tag_fn_predicate
-        };
-
-        rbml_w.wr_tagged_u32(tag,
+    for predicate in &predicates.predicates {
+        rbml_w.wr_tagged_u32(tag_predicate,
             index.add_xref(XRef::Predicate(predicate.clone())));
     }
 }
index acc302430aee68383513650f15f2db85cf1b3aa2..ffacbae1afd6f1dd158744df1d9ef222eb6c8645 100644 (file)
@@ -1257,7 +1257,7 @@ fn create_trans_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                     assert!(mth.is_provided);
 
                     let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs);
-                    if !normalize_and_test_predicates(tcx, predicates.into_vec()) {
+                    if !normalize_and_test_predicates(tcx, predicates) {
                         continue;
                     }
 
index 3d6093d4d6960f16aeeab3e697a71564414bc823..169242fbf7270091f6670a79d89bc020d004e67c 100644 (file)
@@ -289,7 +289,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
             // try and trans it, in that case. Issue #23435.
             if mth.is_provided {
                 let predicates = mth.method.predicates.predicates.subst(tcx, &mth.substs);
-                if !normalize_and_test_predicates(tcx, predicates.into_vec()) {
+                if !normalize_and_test_predicates(tcx, predicates) {
                     debug!("get_vtable_methods: predicates do not hold");
                     return None;
                 }
index ed67c9fbe30bee94e3f7ebeb94dc8a0831e28bfe..a0af98dec7298f0153a05a94a51f3d36637ee87e 100644 (file)
@@ -56,7 +56,6 @@
 use middle::resolve_lifetime as rl;
 use rustc::lint;
 use rustc::ty::subst::{FnSpace, TypeSpace, SelfSpace, Subst, Substs, ParamSpace};
-use rustc::ty::subst::VecPerParamSpace;
 use rustc::traits;
 use rustc::ty::{self, Ty, TyCtxt, ToPredicate, TypeFoldable};
 use rustc::ty::wf::object_region_bounds;
@@ -1778,7 +1777,7 @@ pub fn ast_ty_to_ty(&self, rscope: &RegionScope, ast_ty: &hir::Ty) -> Ty<'tcx> {
                     let predicates = bounds.predicates(tcx, ty);
                     let predicates = tcx.lift_to_global(&predicates).unwrap();
                     tcx.predicates.borrow_mut().insert(def_id, ty::GenericPredicates {
-                        predicates: VecPerParamSpace::new(vec![], vec![], predicates)
+                        predicates: predicates
                     });
 
                     ty
index e6ddc6ad69379922d7f94282c66389683edb8c50..d501a8a184cee57f3c815a0a7e955b32290579ce 100644 (file)
@@ -13,7 +13,7 @@
 use rustc::ty;
 use rustc::traits::{self, Reveal};
 use rustc::ty::error::ExpectedFound;
-use rustc::ty::subst::{self, Subst, Substs, VecPerParamSpace};
+use rustc::ty::subst::{self, Subst, Substs};
 use rustc::hir::map::Node;
 use rustc::hir::{ImplItemKind, TraitItem_};
 
@@ -213,6 +213,15 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         return;
     }
 
+    // Depend on trait/impl predicates always being before method's own predicates,
+    // to be able to split method predicates into "inherited" and method-specific.
+    let trait_predicates = tcx.lookup_predicates(trait_m.container_id()).predicates;
+    let impl_predicates = tcx.lookup_predicates(impl_m.container_id()).predicates;
+    let trait_method_start = trait_predicates.len();
+    let impl_method_start = impl_predicates.len();
+    assert_eq!(&trait_predicates[..], &trait_m.predicates.predicates[..trait_method_start]);
+    assert_eq!(&impl_predicates[..], &impl_m.predicates.predicates[..impl_method_start]);
+
     tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|mut infcx| {
         let mut fulfillment_cx = traits::FulfillmentContext::new();
 
@@ -224,15 +233,10 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         // environment. We can't just use `impl_env.caller_bounds`,
         // however, because we want to replace all late-bound regions with
         // region variables.
-        let impl_bounds =
-            impl_m.predicates.instantiate(tcx, impl_to_skol_substs);
+        let impl_bounds = impl_m.predicates.instantiate(tcx, impl_to_skol_substs);
 
         debug!("compare_impl_method: impl_bounds={:?}", impl_bounds);
 
-        // Obtain the predicate split predicate sets for each.
-        let trait_pred = trait_bounds.predicates.split();
-        let impl_pred = impl_bounds.predicates.split();
-
         // This is the only tricky bit of the new way we check implementation methods
         // We need to build a set of predicates where only the FnSpace bounds
         // are from the trait and we assume all other bounds from the implementation
@@ -240,24 +244,21 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         //
         // We then register the obligations from the impl_m and check to see
         // if all constraints hold.
-        let hybrid_preds = VecPerParamSpace::new(
-            impl_pred.types,
-            impl_pred.selfs,
-            trait_pred.fns
-        );
+        let hybrid_preds = impl_bounds.predicates[..impl_method_start].iter()
+                    .chain(trait_bounds.predicates[trait_method_start..].iter());
 
         // Construct trait parameter environment and then shift it into the skolemized viewpoint.
         // The key step here is to update the caller_bounds's predicates to be
         // the new hybrid bounds we computed.
         let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_body_id);
-        let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.into_vec());
+        let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.cloned().collect());
         let trait_param_env = traits::normalize_param_env_or_error(tcx,
                                                                    trait_param_env,
                                                                    normalize_cause.clone());
         // FIXME(@jroesch) this seems ugly, but is a temporary change
         infcx.parameter_environment = trait_param_env;
 
-        debug!("compare_impl_method: trait_bounds={:?}",
+        debug!("compare_impl_method: caller_bounds={:?}",
             infcx.parameter_environment.caller_bounds);
 
         let mut selcx = traits::SelectionContext::new(&infcx);
@@ -266,7 +267,7 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             infcx.replace_late_bound_regions_with_fresh_var(
                 impl_m_span,
                 infer::HigherRankedType,
-                &ty::Binder(impl_pred.fns));
+                &ty::Binder(impl_bounds.predicates[impl_method_start..].to_vec()));
         for predicate in impl_pred_fns {
             let traits::Normalized { value: predicate, .. } =
                 traits::normalize(&mut selcx, normalize_cause.clone(), &predicate);
index f3a01ef7409fa48fa7a86b600b963d7f9a59e4da..1e2446788adc9383c165974017cac8c4245f6626 100644 (file)
@@ -179,10 +179,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
     let generic_assumptions = tcx.lookup_predicates(self_type_did);
 
     let assumptions_in_impl_context = generic_assumptions.instantiate(tcx, &self_to_impl_substs);
-    assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::SelfSpace));
-    assert!(assumptions_in_impl_context.predicates.is_empty_in(subst::FnSpace));
-    let assumptions_in_impl_context =
-        assumptions_in_impl_context.predicates.get_slice(subst::TypeSpace);
+    let assumptions_in_impl_context = assumptions_in_impl_context.predicates;
 
     // An earlier version of this code attempted to do this checking
     // via the traits::fulfill machinery. However, it ran into trouble
@@ -190,10 +187,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
     // 'a:'b and T:'b into region inference constraints. It is simpler
     // just to look for all the predicates directly.
 
-    assert!(dtor_predicates.predicates.is_empty_in(subst::SelfSpace));
-    assert!(dtor_predicates.predicates.is_empty_in(subst::FnSpace));
-    let predicates = dtor_predicates.predicates.get_slice(subst::TypeSpace);
-    for predicate in predicates {
+    for predicate in &dtor_predicates.predicates {
         // (We do not need to worry about deep analysis of type
         // expressions etc because the Drop impls are already forced
         // to take on a structure that is roughly an alpha-renaming of
index 99f1b13d4e4ab422a6c218dd0c202da6812b037e..e4701bb119559968e3891c5b1c4f7c6e09d3ee6d 100644 (file)
@@ -799,7 +799,7 @@ fn assemble_projection_candidates(&mut self,
 
             let trait_predicates = self.tcx.lookup_predicates(def_id);
             let bounds = trait_predicates.instantiate(self.tcx, substs);
-            let predicates = bounds.predicates.into_vec();
+            let predicates = bounds.predicates;
             debug!("assemble_projection_candidates: predicates={:?}",
                    predicates);
             for poly_bound in
index d38065f4f1238912f3624ef2dbff74702f5c0c5e..22da4ab9c43faed0b34eba3a638d365726c47bcd 100644 (file)
@@ -65,7 +65,7 @@
 use middle::const_val::ConstVal;
 use rustc_const_eval::EvalHint::UncheckedExprHint;
 use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
-use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
+use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace};
 use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
 use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
 use rustc::ty::{VariantKind};
@@ -1185,9 +1185,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
         // generic types:
         let trait_def = trait_def_of_item(ccx, item);
         let self_predicate = ty::GenericPredicates {
-            predicates: VecPerParamSpace::new(vec![],
-                                              vec![trait_def.trait_ref.to_predicate()],
-                                              vec![])
+            predicates: vec![trait_def.trait_ref.to_predicate()]
         };
         let scope = &(generics, &self_predicate);
 
@@ -1209,7 +1207,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
         // Combine the two lists to form the complete set of superbounds:
         let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
         let superpredicates = ty::GenericPredicates {
-            predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
+            predicates: superbounds
         };
         debug!("superpredicates for trait {:?} = {:?}",
                tcx.map.local_def_id(item.id),
@@ -1368,7 +1366,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
     // Add in a predicate that `Self:Trait` (where `Trait` is the
     // current trait).  This is needed for builtin bounds.
     let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
-    base_predicates.predicates.push(SelfSpace, self_predicate);
+    base_predicates.predicates.push(self_predicate);
 
     // add in the explicit where-clauses
     let mut trait_predicates =
@@ -1379,7 +1377,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
                                                            &trait_predicates,
                                                            trait_def.trait_ref,
                                                            items);
-    trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
+    trait_predicates.predicates.extend(assoc_predicates);
 
     let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
     assert!(prev_predicates.is_none());
@@ -1784,8 +1782,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                     SizedByDefault::Yes,
                                     None,
                                     param.span);
-        let predicates = bounds.predicates(ccx.tcx, param_ty);
-        result.predicates.extend(space, predicates.into_iter());
+        result.predicates.extend(bounds.predicates(ccx.tcx, param_ty));
     }
 
     // Collect the region predicates that were declared inline as
@@ -1803,7 +1800,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         for bound in &param.bounds {
             let bound_region = ast_region_to_region(ccx.tcx, bound);
             let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
-            result.predicates.push(space, outlives.to_predicate());
+            result.predicates.push(outlives.to_predicate());
         }
     }
 
@@ -1827,17 +1824,17 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                                     poly_trait_ref,
                                                     &mut projections);
 
-                            result.predicates.push(space, trait_ref.to_predicate());
+                            result.predicates.push(trait_ref.to_predicate());
 
                             for projection in &projections {
-                                result.predicates.push(space, projection.to_predicate());
+                                result.predicates.push(projection.to_predicate());
                             }
                         }
 
                         &hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
                             let region = ast_region_to_region(tcx, lifetime);
                             let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
-                            result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
+                            result.predicates.push(ty::Predicate::TypeOutlives(pred))
                         }
                     }
                 }
@@ -1848,7 +1845,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                 for bound in &region_pred.bounds {
                     let r2 = ast_region_to_region(tcx, bound);
                     let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
-                    result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
+                    result.predicates.push(ty::Predicate::RegionOutlives(pred))
                 }
             }
 
@@ -1861,7 +1858,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         }
     }
 
-    return result;
+    result
 }
 
 fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
@@ -2221,9 +2218,6 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let impl_scheme = ccx.tcx.lookup_item_type(impl_def_id);
     let impl_trait_ref = ccx.tcx.impl_trait_ref(impl_def_id);
 
-    assert!(impl_predicates.predicates.is_empty_in(FnSpace));
-    assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
-
     // The trait reference is an input, so find all type parameters
     // reachable from there, to start (if this is an inherent impl,
     // then just examine the self type).
@@ -2233,7 +2227,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
         input_parameters.extend(ctp::parameters_for(trait_ref, false));
     }
 
-    ctp::setup_constraining_predicates(impl_predicates.predicates.get_mut_slice(TypeSpace),
+    ctp::setup_constraining_predicates(&mut impl_predicates.predicates,
                                        impl_trait_ref,
                                        &mut input_parameters);
 
index 3d6925041cf5b0e2839e3e1d5fea9e137f406149..cea12404298fc90b212e924ac112bef2421cfcda 100644 (file)
@@ -395,8 +395,12 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext,
                 };
                 // Not sure the choice of ParamSpace actually matters here,
                 // because an associated type won't have generics on the LHS
-                let typedef = (type_scheme, ty::GenericPredicates::empty(),
-                               subst::ParamSpace::TypeSpace).clean(cx);
+                let typedef = clean::Typedef {
+                    type_: type_scheme.ty.clean(cx),
+                    generics: (&type_scheme.generics,
+                               &ty::GenericPredicates::empty(),
+                               subst::TypeSpace).clean(cx)
+                };
                 Some(clean::Item {
                     name: Some(assoc_ty.name.clean(cx)),
                     inner: clean::TypedefItem(typedef, true),
@@ -512,11 +516,32 @@ fn build_static<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>,
 /// its associated types as well. We specifically move these clauses to the
 /// associated types instead when displaying, so when we're genering the
 /// generics for the trait itself we need to be sure to remove them.
+/// We also need to remove the implied "recursive" Self: Trait bound.
 ///
 /// The inverse of this filtering logic can be found in the `Clean`
 /// implementation for `AssociatedType`
 fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics)
                              -> clean::Generics {
+    for pred in &mut g.where_predicates {
+        match *pred {
+            clean::WherePredicate::BoundPredicate {
+                ty: clean::Generic(ref s),
+                ref mut bounds
+            } if *s == "Self" => {
+                bounds.retain(|bound| {
+                    match *bound {
+                        clean::TyParamBound::TraitBound(clean::PolyTrait {
+                            trait_: clean::ResolvedPath { did, .. },
+                            ..
+                        }, _) => did != trait_did,
+                        _ => true
+                    }
+                });
+            }
+            _ => {}
+        }
+    }
+
     g.where_predicates.retain(|pred| {
         match *pred {
             clean::WherePredicate::BoundPredicate {
@@ -524,8 +549,8 @@ fn filter_non_trait_generics(trait_did: DefId, mut g: clean::Generics)
                     self_type: box clean::Generic(ref s),
                     trait_: box clean::ResolvedPath { did, .. },
                     name: ref _name,
-                }, ..
-            } => *s != "Self" || did != trait_did,
+                }, ref bounds
+            } => !(*s == "Self" && did == trait_did) && !bounds.is_empty(),
             _ => true,
         }
     });
index 99d2732c4bb06c300bad012c7589c08770d94626..0da833d147ee56d9bf331fbca8e3d0b7589c21ec 100644 (file)
@@ -1010,8 +1010,7 @@ fn clean(&self, cx: &DocContext) -> Generics {
             srp.clean(cx)
         }).collect::<Vec<_>>();
 
-        let mut where_predicates = preds.predicates.get_slice(space)
-                                                   .to_vec().clean(cx);
+        let mut where_predicates = preds.predicates.to_vec().clean(cx);
 
         // Type parameters and have a Sized bound by default unless removed with
         // ?Sized.  Scan through the predicates and mark any type parameter with
@@ -1363,7 +1362,17 @@ fn clean(&self, cx: &DocContext) -> Item {
 
 impl<'tcx> Clean<Item> for ty::Method<'tcx> {
     fn clean(&self, cx: &DocContext) -> Item {
-        let generics = (&self.generics, &self.predicates,
+        // Depend on trait/impl predicates always being before method's own predicates,
+        // to be able to split method predicates into "inherited" and method-specific.
+        let outer_predicates = cx.tcx().lookup_predicates(self.container_id()).predicates;
+        let method_start = outer_predicates.len();
+        assert_eq!(&outer_predicates[..], &self.predicates.predicates[..method_start]);
+
+        let method_predicates = ty::GenericPredicates {
+            predicates: self.predicates.predicates[method_start..].to_vec()
+        };
+
+        let generics = (&self.generics, &method_predicates,
                         subst::FnSpace).clean(cx);
         let mut decl = (self.def_id, &self.fty.sig).clean(cx);
         match self.explicit_self {
@@ -1863,8 +1872,7 @@ fn clean(&self, cx: &DocContext) -> Type {
                 let item_predicates = cx.tcx().lookup_predicates(def_id);
                 let substs = cx.tcx().lift(&substs).unwrap();
                 let bounds = item_predicates.instantiate(cx.tcx(), substs);
-                let predicates = bounds.predicates.into_vec();
-                ImplTrait(predicates.into_iter().filter_map(|predicate| {
+                ImplTrait(bounds.predicates.into_iter().filter_map(|predicate| {
                     predicate.to_opt_poly_trait_ref().clean(cx)
                 }).collect())
             }
@@ -2967,17 +2975,6 @@ fn clean(&self, cx: &DocContext) -> Item {
     }
 }
 
-impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>,
-                             ParamSpace) {
-    fn clean(&self, cx: &DocContext) -> Typedef {
-        let (ref ty_scheme, ref predicates, ps) = *self;
-        Typedef {
-            type_: ty_scheme.ty.clean(cx),
-            generics: (&ty_scheme.generics, predicates, ps).clean(cx)
-        }
-    }
-}
-
 fn lang_struct(cx: &DocContext, did: Option<DefId>,
                t: ty::Ty, name: &str,
                fallback: fn(Box<Type>) -> Type) -> Type {
index c0faa04323e47ddd2435a393f72166920a848757..7ae177439064f9c19d642c82009068b0ded9391c 100644 (file)
 use std::collections::BTreeMap;
 
 use rustc::hir::def_id::DefId;
-use rustc::ty::subst;
+use rustc::ty;
 
 use clean::PathParameters as PP;
 use clean::WherePredicate as WP;
-use clean::{self, Clean};
+use clean;
 use core::DocContext;
 
 pub fn where_clauses(cx: &DocContext, clauses: Vec<WP>) -> Vec<WP> {
@@ -153,27 +153,16 @@ fn trait_is_same_or_supertrait(cx: &DocContext, child: DefId,
     if child == trait_ {
         return true
     }
-    let def = cx.tcx().lookup_trait_def(child);
-    let predicates = cx.tcx().lookup_predicates(child);
-    let generics = (&def.generics, &predicates, subst::TypeSpace).clean(cx);
-    generics.where_predicates.iter().filter_map(|pred| {
-        match *pred {
-            clean::WherePredicate::BoundPredicate {
-                ty: clean::Generic(ref s),
-                ref bounds
-            } if *s == "Self" => Some(bounds),
-            _ => None,
-        }
-    }).flat_map(|bounds| bounds).any(|bound| {
-        let poly_trait = match *bound {
-            clean::TraitBound(ref t, _) => t,
-            _ => return false,
-        };
-        match poly_trait.trait_ {
-            clean::ResolvedPath { did, .. } => {
-                trait_is_same_or_supertrait(cx, did, trait_)
+    let predicates = cx.tcx().lookup_super_predicates(child).predicates;
+    predicates.iter().filter_map(|pred| {
+        if let ty::Predicate::Trait(ref pred) = *pred {
+            if pred.0.trait_ref.self_ty().is_self() {
+                Some(pred.def_id())
+            } else {
+                None
             }
-            _ => false,
+        } else {
+            None
         }
-    })
+    }).any(|did| trait_is_same_or_supertrait(cx, did, trait_))
 }