rustc: use Vec instead of VecPerParamSpace for ty::GenericPredicates.
This commit is contained in:
parent
1bf5fa3269
commit
e314636b86
19 changed files with 109 additions and 148 deletions
|
|
@ -184,7 +184,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
// 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 {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -1214,7 +1214,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
|||
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(
|
||||
|
|
|
|||
|
|
@ -178,7 +178,7 @@ impl<'a, 'gcx, 'tcx> ImplHeader<'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 @@ impl<'tcx> Generics<'tcx> {
|
|||
/// 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 @@ impl<'a, 'gcx, 'tcx> GenericPredicates<'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 @@ impl<'tcx> Predicate<'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 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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 @@ impl<T> VecPerParamSpace<T> {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -917,7 +917,7 @@ impl<'tcx> fmt::Display for ty::TypeVariants<'tcx> {
|
|||
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() {
|
||||
|
|
|
|||
|
|
@ -207,9 +207,8 @@ pub const tag_type_param_def: usize = 0x94;
|
|||
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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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));
|
||||
ty::GenericPredicates {
|
||||
predicates: reader::tagged_docs(doc, tag_predicate).map(|predicate_doc| {
|
||||
doc_predicate(cdata, predicate_doc, tcx)
|
||||
}).collect()
|
||||
}
|
||||
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: predicates }
|
||||
}
|
||||
|
||||
pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool {
|
||||
|
|
|
|||
|
|
@ -26,7 +26,6 @@ use rustc::hir::def;
|
|||
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())));
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -56,7 +56,6 @@ use hir::print as pprust;
|
|||
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 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o {
|
|||
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
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use rustc::infer::{self, InferOk, TypeOrigin};
|
|||
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);
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -799,7 +799,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
|
|||
|
||||
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
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ use middle::lang_items::SizedTraitLangItem;
|
|||
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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -1010,8 +1010,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics<'tcx>,
|
|||
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 @@ impl Clean<Item> for hir::ImplItem {
|
|||
|
||||
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 @@ impl<'tcx> Clean<Type> for ty::Ty<'tcx> {
|
|||
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 @@ impl<'tcx> Clean<Item> for ty::AssociatedType<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -30,11 +30,11 @@ use std::mem;
|
|||
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_))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue