// 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 {
// 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,
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(
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 } =
/// 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![]
}
}
-> InstantiatedPredicates<'tcx>
{
InstantiatedPredicates {
- predicates: self.predicates.map(|pred| {
+ predicates: self.predicates.iter().map(|pred| {
pred.subst_supertrait(tcx, poly_trait_ref)
- })
+ }).collect()
}
}
}
/// [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 {
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
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, "[{:?};{:?};{:?}]",
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
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() {
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;
{
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 {
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;
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())));
}
}
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;
}
// 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;
}
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;
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
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_};
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();
// 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
//
// 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);
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);
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
// '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
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
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};
// 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);
// 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),
// 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 =
&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());
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
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());
}
}
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))
}
}
}
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))
}
}
}
}
- return result;
+ result
}
fn ty_generics<'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).
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);
};
// 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),
/// 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 {
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,
}
});
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
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 {
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())
}
}
}
-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 {
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> {
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_))
}