]> git.lizzy.rs Git - rust.git/commitdiff
rustc: split GenericPredicates of a method from its parent predicates.
authorEduard Burtescu <edy.burt@gmail.com>
Thu, 11 Aug 2016 06:19:42 +0000 (09:19 +0300)
committerEduard Burtescu <edy.burt@gmail.com>
Wed, 17 Aug 2016 02:50:57 +0000 (05:50 +0300)
14 files changed:
src/librustc/traits/select.rs
src/librustc/ty/mod.rs
src/librustc/ty/structural_impls.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/compare_method.rs
src/librustc_typeck/check/dropck.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/regionck.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/collect.rs
src/librustdoc/clean/mod.rs
src/test/compile-fail/associated-const-type-parameter-arrays.rs

index 9099d6cd740d13df8689bbc55524d1003d204478..bf6aad98db1a8c4764513e3adac1573db7bc3338 100644 (file)
@@ -2897,20 +2897,18 @@ fn impl_or_trait_obligations(&mut self,
         // obligation will normalize to `<$0 as Iterator>::Item = $1` and
         // `$1: Copy`, so we must ensure the obligations are emitted in
         // that order.
-        let predicates = tcx
-            .lookup_predicates(def_id)
-            .predicates.iter()
-            .flat_map(|predicate| {
-                let predicate =
-                    normalize_with_depth(self, cause.clone(), recursion_depth,
-                                         &predicate.subst(tcx, substs));
-                predicate.obligations.into_iter().chain(
-                    Some(Obligation {
-                        cause: cause.clone(),
-                        recursion_depth: recursion_depth,
-                        predicate: predicate.value
-                    }))
-            }).collect();
+        let predicates = tcx.lookup_predicates(def_id);
+        assert_eq!(predicates.parent, None);
+        let predicates = predicates.predicates.iter().flat_map(|predicate| {
+            let predicate = normalize_with_depth(self, cause.clone(), recursion_depth,
+                                                 &predicate.subst(tcx, substs));
+            predicate.obligations.into_iter().chain(
+                Some(Obligation {
+                    cause: cause.clone(),
+                    recursion_depth: recursion_depth,
+                    predicate: predicate.value
+                }))
+        }).collect();
         self.infcx().plug_leaks(skol_map, snapshot, &predicates)
     }
 }
index 689f2ad02c94c25008e678ae84aeba42a989d71c..b2b8286be2fba041624aebdaaf8efd07debbfa01 100644 (file)
@@ -768,27 +768,38 @@ pub struct Generics<'tcx> {
 /// Bounds on generics.
 #[derive(Clone)]
 pub struct GenericPredicates<'tcx> {
+    pub parent: Option<DefId>,
     pub predicates: Vec<Predicate<'tcx>>,
 }
 
 impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
-    pub fn empty() -> GenericPredicates<'tcx> {
-        GenericPredicates {
-            predicates: vec![]
-        }
-    }
-
     pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
                        -> InstantiatedPredicates<'tcx> {
+        let mut instantiated = InstantiatedPredicates::empty();
+        self.instantiate_into(tcx, &mut instantiated, substs);
+        instantiated
+    }
+    pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
+                           -> InstantiatedPredicates<'tcx> {
         InstantiatedPredicates {
-            predicates: self.predicates.subst(tcx, substs),
+            predicates: self.predicates.subst(tcx, substs)
+        }
+    }
+
+    fn instantiate_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
+                        instantiated: &mut InstantiatedPredicates<'tcx>,
+                        substs: &Substs<'tcx>) {
+        if let Some(def_id) = self.parent {
+            tcx.lookup_predicates(def_id).instantiate_into(tcx, instantiated, substs);
         }
+        instantiated.predicates.extend(self.predicates.iter().map(|p| p.subst(tcx, substs)))
     }
 
     pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
                                   poly_trait_ref: &ty::PolyTraitRef<'tcx>)
                                   -> InstantiatedPredicates<'tcx>
     {
+        assert_eq!(self.parent, None);
         InstantiatedPredicates {
             predicates: self.predicates.iter().map(|pred| {
                 pred.subst_supertrait(tcx, poly_trait_ref)
index 248d5d9062d594bacbd10bb2f5c4f6a21768b360..021ae820b87c5c340893e8cf69fb5b3b7730a734 100644 (file)
@@ -832,18 +832,6 @@ fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
     }
 }
 
-impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
-    fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
-        ty::GenericPredicates {
-            predicates: self.predicates.fold_with(folder),
-        }
-    }
-
-    fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
-        self.predicates.visit_with(visitor)
-    }
-}
-
 impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
     fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
         match *self {
index e42825ef1e549e8d7a7900d70a5dba253232bbcd..5488f114db32ff610576f227ed063a70bdda421a 100644 (file)
@@ -1591,6 +1591,7 @@ fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc,
     let doc = reader::get_doc(base_doc, tag);
 
     ty::GenericPredicates {
+        parent: item_parent_item(cdata, doc),
         predicates: reader::tagged_docs(doc, tag_predicate).map(|predicate_doc| {
             doc_predicate(cdata, predicate_doc, tcx)
         }).collect()
index 0cde9b48d6f88eab489857a6566dc26b20f5bb2d..320ba3c8d9dc863c9344c800cc6228cf6a247097 100644 (file)
@@ -525,6 +525,9 @@ fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
                               tag: usize)
 {
     rbml_w.start_tag(tag);
+    if let Some(def_id) = predicates.parent {
+        rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id));
+    }
     for predicate in &predicates.predicates {
         rbml_w.wr_tagged_u32(tag_predicate,
             index.add_xref(XRef::Predicate(predicate.clone())));
index a452b55a7d33d82c1dcb9d83fb59bfad7d334bd0..aec8f8245da5ed62b1f1b766eefcc45da6b1f1cb 100644 (file)
@@ -1726,6 +1726,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 {
+                        parent: None,
                         predicates: predicates
                     });
 
index 5bfe58e78f112a6c96a1daeb53feb1a38100eabe..4cbb2d7f09f022d18f1c544c90d271ee5b4ebb97 100644 (file)
@@ -211,29 +211,18 @@ 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();
 
-        // Normalize the associated types in the trait_bounds.
-        let trait_bounds = trait_m.predicates.instantiate(tcx, trait_to_skol_substs);
-
         // Create obligations for each predicate declared by the impl
         // definition in the context of the trait's parameter
         // 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_predicates = tcx.lookup_predicates(impl_m.predicates.parent.unwrap());
+        let mut hybrid_preds = impl_predicates.instantiate(tcx, impl_to_skol_substs);
 
-        debug!("compare_impl_method: impl_bounds={:?}", impl_bounds);
+        debug!("compare_impl_method: impl_bounds={:?}", hybrid_preds);
 
         // 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
@@ -242,14 +231,14 @@ 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 = impl_bounds.predicates[..impl_method_start].iter()
-                    .chain(trait_bounds.predicates[trait_method_start..].iter());
+        hybrid_preds.predicates.extend(
+            trait_m.predicates.instantiate_own(tcx, trait_to_skol_substs).predicates);
 
         // 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.cloned().collect());
+        let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.predicates);
         let trait_param_env = traits::normalize_param_env_or_error(tcx,
                                                                    trait_param_env,
                                                                    normalize_cause.clone());
@@ -261,12 +250,13 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
 
         let mut selcx = traits::SelectionContext::new(&infcx);
 
-        let (impl_pred_fns, _) =
+        let impl_m_own_bounds = impl_m.predicates.instantiate_own(tcx, impl_to_skol_substs);
+        let (impl_m_own_bounds, _) =
             infcx.replace_late_bound_regions_with_fresh_var(
                 impl_m_span,
                 infer::HigherRankedType,
-                &ty::Binder(impl_bounds.predicates[impl_method_start..].to_vec()));
-        for predicate in impl_pred_fns {
+                &ty::Binder(impl_m_own_bounds.predicates));
+        for predicate in impl_m_own_bounds {
             let traits::Normalized { value: predicate, .. } =
                 traits::normalize(&mut selcx, normalize_cause.clone(), &predicate);
 
index 7d79fc4fbf8782ba5e5369fe18ef82f7e95591d8..d1da95f39df40f37f273b9cc1c048522251ee8ea 100644 (file)
@@ -184,6 +184,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_eq!(dtor_predicates.parent, None);
     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
index d699bafed9a05d1cb15c6d0cbe9827230c9c3762..8c4ec8453177e4598722ac45a06f0a411d3d8aa8 100644 (file)
@@ -1612,8 +1612,14 @@ fn instantiate_bounds(&self,
                           bounds: &ty::GenericPredicates<'tcx>)
                           -> ty::InstantiatedPredicates<'tcx>
     {
+        let result = bounds.instantiate(self.tcx, substs);
+        let result = self.normalize_associated_types_in(span, &result.predicates);
+        debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
+               bounds,
+               substs,
+               result);
         ty::InstantiatedPredicates {
-            predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
+            predicates: result
         }
     }
 
@@ -4210,8 +4216,6 @@ pub fn instantiate_value_path(&self,
             }
             _ => {}
         }
-        let scheme = self.tcx.lookup_item_type(def.def_id());
-        let type_predicates = self.tcx.lookup_predicates(def.def_id());
 
         // Now we have to compare the types that the user *actually*
         // provided against the types that were *expected*. If the user
@@ -4296,6 +4300,8 @@ pub fn instantiate_value_path(&self,
 
         // The things we are substituting into the type should not contain
         // escaping late-bound regions, and nor should the base type scheme.
+        let scheme = self.tcx.lookup_item_type(def.def_id());
+        let type_predicates = self.tcx.lookup_predicates(def.def_id());
         assert!(!substs.has_escaping_regions());
         assert!(!scheme.ty.has_escaping_regions());
 
index 8e34b0b8c55595ed8be6e1e7e38f5329d22bfb55..f6ffbc60c2836cd19c4b16b0ab0b95487f75309a 100644 (file)
@@ -1754,6 +1754,7 @@ fn declared_projection_bounds_from_trait(&self,
         //
         // we can thus deduce that `<T as SomeTrait<'a>>::SomeType : 'a`.
         let trait_predicates = self.tcx.lookup_predicates(projection_ty.trait_ref.def_id);
+        assert_eq!(trait_predicates.parent, None);
         let predicates = trait_predicates.predicates.as_slice().to_vec();
         traits::elaborate_predicates(self.tcx, predicates)
             .filter_map(|predicate| {
index f793ce7acb7c798f61f8e74cc48c4440783c9672..ef5e1a26f415034b4dda716dce52cfc66ca0aa1c 100644 (file)
@@ -454,6 +454,7 @@ fn check_variances_for_type_defn(&self,
 
         let item_def_id = self.tcx().map.local_def_id(item.id);
         let ty_predicates = self.tcx().lookup_predicates(item_def_id);
+        assert_eq!(ty_predicates.parent, None);
         let variances = self.tcx().item_variances(item_def_id);
 
         let mut constrained_parameters: HashSet<_> =
index 9e8fe710cc1cd90668ccff545295539737c7a1ad..939f8ac50a6c6502fc169289e38ba65e1dbd1883 100644 (file)
@@ -459,35 +459,38 @@ fn get_type_parameter_bounds(&self,
 impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
     fn get_type_parameter_bounds(&self,
                                  astconv: &AstConv<'tcx, 'tcx>,
-                                 _span: Span,
+                                 span: Span,
                                  node_id: ast::NodeId)
                                  -> Vec<ty::Predicate<'tcx>>
     {
         let def = astconv.tcx().type_parameter_def(node_id);
 
-        self.predicates
-            .iter()
-            .filter(|predicate| {
-                match **predicate {
-                    ty::Predicate::Trait(ref data) => {
-                        data.skip_binder().self_ty().is_param(def.space, def.index)
-                    }
-                    ty::Predicate::TypeOutlives(ref data) => {
-                        data.skip_binder().0.is_param(def.space, def.index)
-                    }
-                    ty::Predicate::Rfc1592(..) |
-                    ty::Predicate::Equate(..) |
-                    ty::Predicate::RegionOutlives(..) |
-                    ty::Predicate::WellFormed(..) |
-                    ty::Predicate::ObjectSafe(..) |
-                    ty::Predicate::ClosureKind(..) |
-                    ty::Predicate::Projection(..) => {
-                        false
-                    }
+        let mut results = self.parent.map_or(vec![], |def_id| {
+            let parent = astconv.tcx().lookup_predicates(def_id);
+            parent.get_type_parameter_bounds(astconv, span, node_id)
+        });
+
+        results.extend(self.predicates.iter().filter(|predicate| {
+            match **predicate {
+                ty::Predicate::Trait(ref data) => {
+                    data.skip_binder().self_ty().is_param(def.space, def.index)
+                }
+                ty::Predicate::TypeOutlives(ref data) => {
+                    data.skip_binder().0.is_param(def.space, def.index)
                 }
-            })
-            .cloned()
-            .collect()
+                ty::Predicate::Rfc1592(..) |
+                ty::Predicate::Equate(..) |
+                ty::Predicate::RegionOutlives(..) |
+                ty::Predicate::WellFormed(..) |
+                ty::Predicate::ObjectSafe(..) |
+                ty::Predicate::ClosureKind(..) |
+                ty::Predicate::Projection(..) => {
+                    false
+                }
+            }
+        }).cloned());
+
+        results
     }
 }
 
@@ -568,7 +571,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let ty_generics = generics_of_def_id(ccx, def_id);
 
     let ty_generic_predicates =
-        ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
+        ty_generic_predicates(ccx, FnSpace, &sig.generics, ty_generics.parent, vec![], false);
 
     let (fty, explicit_self_category) = {
         let anon_scope = match container {
@@ -634,8 +637,12 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                       ty: ty::Ty<'tcx>,
                                       has_value: bool)
 {
+    let predicates = ty::GenericPredicates {
+        parent: Some(container.id()),
+        predicates: vec![]
+    };
     ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
-                                           ty::GenericPredicates::empty());
+                                           predicates);
 
     write_ty_to_tcx(ccx, id, ty);
 
@@ -744,7 +751,8 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
             debug!("convert: ast_generics={:?}", generics);
             let def_id = ccx.tcx.map.local_def_id(it.id);
             let ty_generics = generics_of_def_id(ccx, def_id);
-            let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
+            let mut ty_predicates =
+                ty_generic_predicates(ccx, TypeSpace, generics, None, vec![], false);
 
             debug!("convert: impl_bounds={:?}", ty_predicates);
 
@@ -1187,6 +1195,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
         // generic types:
         let trait_def = trait_def_of_item(ccx, item);
         let self_predicate = ty::GenericPredicates {
+            parent: None,
             predicates: vec![trait_def.trait_ref.to_predicate()]
         };
         let scope = &(generics, &self_predicate);
@@ -1209,6 +1218,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 {
+            parent: None,
             predicates: superbounds
         };
         debug!("superpredicates for trait {:?} = {:?}",
@@ -1327,16 +1337,16 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
     // but to get the full set of predicates on a trait we need to add
     // in the supertrait bounds and anything declared on the
     // associated types.
-    let mut base_predicates = super_predicates;
+    let mut base_predicates = super_predicates.predicates;
 
     // 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(self_predicate);
+    base_predicates.push(self_predicate);
 
     // add in the explicit where-clauses
     let mut trait_predicates =
-        ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates, true);
+        ty_generic_predicates(ccx, TypeSpace, generics, None, base_predicates, true);
 
     let assoc_predicates = predicates_for_associated_types(ccx,
                                                            generics,
@@ -1619,32 +1629,17 @@ fn predicates_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
                                 it: &hir::Item)
                                 -> ty::GenericPredicates<'tcx> {
     let def_id = ccx.tcx.map.local_def_id(it.id);
-    let predicates = match it.node {
-        hir::ItemStatic(..) | hir::ItemConst(..) => {
-            ty::GenericPredicates::empty()
-        }
-        hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
-            ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
-        }
+
+    let no_generics = hir::Generics::empty();
+    let (space, generics) = match it.node {
+        hir::ItemFn(_, _, _, _, ref generics, _) => (FnSpace, generics),
         hir::ItemTy(_, ref generics) |
         hir::ItemEnum(_, ref generics) |
-        hir::ItemStruct(_, ref generics) => {
-            ty_generic_predicates_for_type_or_impl(ccx, generics)
-        }
-        hir::ItemDefaultImpl(..) |
-        hir::ItemTrait(..) |
-        hir::ItemExternCrate(..) |
-        hir::ItemUse(..) |
-        hir::ItemImpl(..) |
-        hir::ItemMod(..) |
-        hir::ItemForeignMod(..) => {
-            span_bug!(
-                it.span,
-                "predicates_of_item: unexpected item type: {:?}",
-                it.node);
-        }
+        hir::ItemStruct(_, ref generics) => (TypeSpace, generics),
+        _ => (TypeSpace, &no_generics)
     };
 
+    let predicates = ty_generic_predicates(ccx, space, generics, None, vec![], false);
     let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id,
                                                                  predicates.clone());
     assert!(prev_predicates.is_none());
@@ -1662,34 +1657,17 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
     let def_id = ccx.tcx.map.local_def_id(it.id);
     type_scheme_of_def_id(ccx, def_id);
 
-    let predicates = match it.node {
-        hir::ForeignItemFn(_, ref generics) => {
-            ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
-        }
-        hir::ForeignItemStatic(..) => {
-            ty::GenericPredicates::empty()
-        }
+    let no_generics = hir::Generics::empty();
+    let (space, generics) = match it.node {
+        hir::ForeignItemFn(_, ref generics) => (FnSpace, generics),
+        hir::ForeignItemStatic(..) => (TypeSpace, &no_generics)
     };
 
+    let predicates = ty_generic_predicates(ccx, space, generics, None, vec![], false);
     let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
     assert!(prev_predicates.is_none());
 }
 
-fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
-                                                   generics: &hir::Generics)
-                                                   -> ty::GenericPredicates<'tcx>
-{
-    ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty(), false)
-}
-
-fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
-                                         generics: &hir::Generics,
-                                         base_predicates: &ty::GenericPredicates<'tcx>)
-                                         -> ty::GenericPredicates<'tcx>
-{
-    ty_generic_predicates(ccx, FnSpace, generics, base_predicates, false)
-}
-
 // Add the Sized bound, unless the type parameter is marked as `?Sized`.
 fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
                                        bounds: &mut ty::BuiltinBounds,
@@ -1757,12 +1735,25 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx, 'hir>(
 fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                   space: ParamSpace,
                                   ast_generics: &hir::Generics,
-                                  base_predicates: &ty::GenericPredicates<'tcx>,
+                                  parent: Option<DefId>,
+                                  super_predicates: Vec<ty::Predicate<'tcx>>,
                                   has_self: bool)
                                   -> ty::GenericPredicates<'tcx>
 {
     let tcx = ccx.tcx;
-    let mut result = base_predicates.clone();
+    let ref base_predicates = match parent {
+        Some(def_id) => {
+            assert_eq!(super_predicates, vec![]);
+            tcx.lookup_predicates(def_id)
+        }
+        None => {
+            ty::GenericPredicates {
+                parent: None,
+                predicates: super_predicates.clone()
+            }
+        }
+    };
+    let mut predicates = super_predicates;
 
     // Collect the predicates that were written inline by the user on each
     // type parameter (e.g., `<T:Foo>`).
@@ -1775,7 +1766,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                     SizedByDefault::Yes,
                                     None,
                                     param.span);
-        result.predicates.extend(bounds.predicates(ccx.tcx, param_ty));
+        predicates.extend(bounds.predicates(ccx.tcx, param_ty));
     }
 
     // Collect the region predicates that were declared inline as
@@ -1793,7 +1784,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(outlives.to_predicate());
+            predicates.push(outlives.to_predicate());
         }
     }
 
@@ -1819,17 +1810,17 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
                                                                     ty,
                                                                     &mut projections);
 
-                            result.predicates.push(trait_ref.to_predicate());
+                            predicates.push(trait_ref.to_predicate());
 
                             for projection in &projections {
-                                result.predicates.push(projection.to_predicate());
+                                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(ty::Predicate::TypeOutlives(pred))
+                            predicates.push(ty::Predicate::TypeOutlives(pred))
                         }
                     }
                 }
@@ -1840,7 +1831,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(ty::Predicate::RegionOutlives(pred))
+                    predicates.push(ty::Predicate::RegionOutlives(pred))
                 }
             }
 
@@ -1853,7 +1844,10 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
         }
     }
 
-    result
+    ty::GenericPredicates {
+        parent: parent,
+        predicates: predicates
+    }
 }
 
 fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
index 07821a730ccf6f0d3a5b3fc3844ac2bcf83f4921..90288b17dfcce32d4524dffcb77711c9f546f85b 100644 (file)
@@ -1348,17 +1348,7 @@ fn clean(&self, cx: &DocContext) -> Item {
 
 impl<'tcx> Clean<Item> for ty::Method<'tcx> {
     fn clean(&self, cx: &DocContext) -> Item {
-        // 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).clean(cx);
+        let generics = (self.generics, &self.predicates).clean(cx);
         let mut decl = (self.def_id, &self.fty.sig).clean(cx);
         match self.explicit_self {
             ty::ExplicitSelfCategory::ByValue => {
index 3d3b795b2291a095241b5a94b59dd9575a07d231..ddf16a2278e5bd140cca704c6992e27dafb09f8e 100644 (file)
@@ -25,7 +25,8 @@ impl Foo for Def {
 }
 
 pub fn test<A: Foo, B: Foo>() {
-    let _array: [u32; <A as Foo>::Y]; //~ error: the parameter type
+    let _array: [u32; <A as Foo>::Y];
+    //~^ ERROR the trait bound `A: Foo` is not satisfied
 }
 
 fn main() {