diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 4889895860129144dc323c6ce52ebde00b364c89..8ddb14e08e31ee9e7653205da3945e718c4515b7 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -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 { diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index aed4f4393241191d1f2d655f2ba594a709d67b10..d580deed0756ab0ccd7acf5e0ad760fffb388978 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -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, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index b61cb0d3eee7217c17243564bee61a911ae706d9..6b9de746f66c39b8e840fff5a98a9f40db68737a 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -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( diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index cfc2e89f9d5a126e10e22681c00076fb29710007..4f39a711010b7a82105e1334a55051ba85e4c7eb 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -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>, + pub predicates: Vec>, } 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> { /// [usize:Bar]]`. #[derive(Clone)] pub struct InstantiatedPredicates<'tcx> { - pub predicates: VecPerParamSpace>, + pub predicates: Vec>, } 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 diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 595d965ffce262eede9050e22016b4c24b4ecb7e..25b108cee27550163a797bdb438365937f4c0dde 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -217,14 +217,6 @@ pub struct VecPerParamSpace { content: Vec, } -/// The `split` function converts one `VecPerParamSpace` into this -/// `SeparateVecsPerParamSpace` structure. -pub struct SeparateVecsPerParamSpace { - pub types: Vec, - pub selfs: Vec, - pub fns: Vec, -} - impl fmt::Debug for VecPerParamSpace { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { write!(f, "[{:?};{:?};{:?}]", @@ -428,18 +420,6 @@ pub fn map_enumerated(&self, pred: P) -> VecPerParamSpace where self.self_limit) } - pub fn split(self) -> SeparateVecsPerParamSpace { - 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 where T: Clone diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 896ef49de6f05240d1bc2749effa35e262ddd9d9..37750b568bba2823c70e5ac24f28ba7455cc5604 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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() { diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs index ff072cce5db9667ccd5cb998ee0cdcb6384cdd78..0011b59c70ed3d5f19ab908e8d5fdc84306c3fba 100644 --- a/src/librustc_metadata/common.rs +++ b/src/librustc_metadata/common.rs @@ -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; diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 64b614b56e12fdffe444b86545fb03c77226adaa..b91fb993f08ee9d931152147fe87458b91690f5b 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -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 { diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index cc1d07b33c7e830b6840e2d4b79045210db44f99..288fb74cc18a13c71c242df7258bbd6f76db6dca 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -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()))); } } diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index acc302430aee68383513650f15f2db85cf1b3aa2..ffacbae1afd6f1dd158744df1d9ef222eb6c8645 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -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; } diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 3d6093d4d6960f16aeeab3e697a71564414bc823..169242fbf7270091f6670a79d89bc020d004e67c 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -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; } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index ed67c9fbe30bee94e3f7ebeb94dc8a0831e28bfe..a0af98dec7298f0153a05a94a51f3d36637ee87e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -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 diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index e6ddc6ad69379922d7f94282c66389683edb8c50..d501a8a184cee57f3c815a0a7e955b32290579ce 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -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); diff --git a/src/librustc_typeck/check/dropck.rs b/src/librustc_typeck/check/dropck.rs index f3a01ef7409fa48fa7a86b600b963d7f9a59e4da..1e2446788adc9383c165974017cac8c4245f6626 100644 --- a/src/librustc_typeck/check/dropck.rs +++ b/src/librustc_typeck/check/dropck.rs @@ -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 diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 99f1b13d4e4ab422a6c218dd0c202da6812b037e..e4701bb119559968e3891c5b1c4f7c6e09d3ee6d 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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 diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index d38065f4f1238912f3624ef2dbff74702f5c0c5e..22da4ab9c43faed0b34eba3a638d365726c47bcd 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -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 ¶m.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 ®ion_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); diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 3d6925041cf5b0e2839e3e1d5fea9e137f406149..cea12404298fc90b212e924ac112bef2421cfcda 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -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, } }); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 99d2732c4bb06c300bad012c7589c08770d94626..0da833d147ee56d9bf331fbca8e3d0b7589c21ec 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1010,8 +1010,7 @@ fn clean(&self, cx: &DocContext) -> Generics { srp.clean(cx) }).collect::>(); - 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 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 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, t: ty::Ty, name: &str, fallback: fn(Box) -> Type) -> Type { diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index c0faa04323e47ddd2435a393f72166920a848757..7ae177439064f9c19d642c82009068b0ded9391c 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -30,11 +30,11 @@ 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) -> Vec { @@ -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_)) }