提交 e314636b 编写于 作者: E Eduard Burtescu

rustc: use Vec instead of VecPerParamSpace for ty::GenericPredicates.

上级 1bf5fa32
......@@ -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 {
......
......@@ -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 @@ 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(
......
......@@ -178,7 +178,7 @@ pub fn with_fresh_ty_vars(selcx: &mut traits::SelectionContext<'a, 'gcx, 'tcx>,
impl_def_id: impl_def_id,
self_ty: tcx.lookup_item_type(impl_def_id).ty,
trait_ref: tcx.impl_trait_ref(impl_def_id),
predicates: tcx.lookup_predicates(impl_def_id).predicates.into_vec(),
predicates: tcx.lookup_predicates(impl_def_id).predicates
}.subst(tcx, &impl_substs);
let traits::Normalized { value: mut header, obligations } =
......@@ -775,13 +775,13 @@ pub fn has_region_params(&self, space: subst::ParamSpace) -> bool {
/// Bounds on generics.
#[derive(Clone)]
pub struct GenericPredicates<'tcx> {
pub predicates: VecPerParamSpace<Predicate<'tcx>>,
pub predicates: Vec<Predicate<'tcx>>,
}
impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
pub fn empty() -> GenericPredicates<'tcx> {
GenericPredicates {
predicates: VecPerParamSpace::empty(),
predicates: vec![]
}
}
......@@ -797,9 +797,9 @@ pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
-> InstantiatedPredicates<'tcx>
{
InstantiatedPredicates {
predicates: self.predicates.map(|pred| {
predicates: self.predicates.iter().map(|pred| {
pred.subst_supertrait(tcx, poly_trait_ref)
})
}).collect()
}
}
}
......@@ -1193,12 +1193,12 @@ pub fn to_opt_poly_trait_ref(&self) -> Option<PolyTraitRef<'tcx>> {
/// [usize:Bar<isize>]]`.
#[derive(Clone)]
pub struct InstantiatedPredicates<'tcx> {
pub predicates: VecPerParamSpace<Predicate<'tcx>>,
pub predicates: Vec<Predicate<'tcx>>,
}
impl<'tcx> InstantiatedPredicates<'tcx> {
pub fn empty() -> InstantiatedPredicates<'tcx> {
InstantiatedPredicates { predicates: VecPerParamSpace::empty() }
InstantiatedPredicates { predicates: vec![] }
}
pub fn is_empty(&self) -> bool {
......@@ -2909,7 +2909,7 @@ pub fn construct_parameter_environment(self,
let tcx = self.global_tcx();
let bounds = generic_predicates.instantiate(tcx, &free_substs);
let bounds = tcx.liberate_late_bound_regions(free_id_outlive, &ty::Binder(bounds));
let predicates = bounds.predicates.into_vec();
let predicates = bounds.predicates;
// Finally, we have to normalize the bounds in the environment, in
// case they contain any associated type projections. This process
......
......@@ -217,14 +217,6 @@ pub struct VecPerParamSpace<T> {
content: Vec<T>,
}
/// The `split` function converts one `VecPerParamSpace` into this
/// `SeparateVecsPerParamSpace` structure.
pub struct SeparateVecsPerParamSpace<T> {
pub types: Vec<T>,
pub selfs: Vec<T>,
pub fns: Vec<T>,
}
impl<T: fmt::Debug> fmt::Debug for VecPerParamSpace<T> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(f, "[{:?};{:?};{:?}]",
......@@ -428,18 +420,6 @@ pub fn map_enumerated<U, P>(&self, pred: P) -> VecPerParamSpace<U> where
self.self_limit)
}
pub fn split(self) -> SeparateVecsPerParamSpace<T> {
let VecPerParamSpace { type_limit, self_limit, content } = self;
let mut content_iter = content.into_iter();
SeparateVecsPerParamSpace {
types: content_iter.by_ref().take(type_limit).collect(),
selfs: content_iter.by_ref().take(self_limit - type_limit).collect(),
fns: content_iter.collect()
}
}
pub fn with_slice(mut self, space: ParamSpace, slice: &[T])
-> VecPerParamSpace<T>
where T: Clone
......
......@@ -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() {
......
......@@ -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;
......
......@@ -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 {
......
......@@ -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())));
}
}
......
......@@ -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 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
......
......@@ -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);
......
......@@ -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 @@ 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
......
......@@ -65,7 +65,7 @@
use middle::const_val::ConstVal;
use rustc_const_eval::EvalHint::UncheckedExprHint;
use rustc_const_eval::{eval_const_expr_partial, report_const_eval_err};
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace, VecPerParamSpace};
use rustc::ty::subst::{Substs, FnSpace, ParamSpace, SelfSpace, TypeSpace};
use rustc::ty::{ToPredicate, ImplContainer, ImplOrTraitItemContainer, TraitContainer};
use rustc::ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeScheme};
use rustc::ty::{VariantKind};
......@@ -1185,9 +1185,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
// generic types:
let trait_def = trait_def_of_item(ccx, item);
let self_predicate = ty::GenericPredicates {
predicates: VecPerParamSpace::new(vec![],
vec![trait_def.trait_ref.to_predicate()],
vec![])
predicates: vec![trait_def.trait_ref.to_predicate()]
};
let scope = &(generics, &self_predicate);
......@@ -1209,7 +1207,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
// Combine the two lists to form the complete set of superbounds:
let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
let superpredicates = ty::GenericPredicates {
predicates: VecPerParamSpace::new(superbounds, vec![], vec![])
predicates: superbounds
};
debug!("superpredicates for trait {:?} = {:?}",
tcx.map.local_def_id(item.id),
......@@ -1368,7 +1366,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
// Add in a predicate that `Self:Trait` (where `Trait` is the
// current trait). This is needed for builtin bounds.
let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
base_predicates.predicates.push(SelfSpace, self_predicate);
base_predicates.predicates.push(self_predicate);
// add in the explicit where-clauses
let mut trait_predicates =
......@@ -1379,7 +1377,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
&trait_predicates,
trait_def.trait_ref,
items);
trait_predicates.predicates.extend(TypeSpace, assoc_predicates.into_iter());
trait_predicates.predicates.extend(assoc_predicates);
let prev_predicates = tcx.predicates.borrow_mut().insert(def_id, trait_predicates);
assert!(prev_predicates.is_none());
......@@ -1784,8 +1782,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
SizedByDefault::Yes,
None,
param.span);
let predicates = bounds.predicates(ccx.tcx, param_ty);
result.predicates.extend(space, predicates.into_iter());
result.predicates.extend(bounds.predicates(ccx.tcx, param_ty));
}
// Collect the region predicates that were declared inline as
......@@ -1803,7 +1800,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
for bound in &param.bounds {
let bound_region = ast_region_to_region(ccx.tcx, bound);
let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
result.predicates.push(space, outlives.to_predicate());
result.predicates.push(outlives.to_predicate());
}
}
......@@ -1827,17 +1824,17 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
poly_trait_ref,
&mut projections);
result.predicates.push(space, trait_ref.to_predicate());
result.predicates.push(trait_ref.to_predicate());
for projection in &projections {
result.predicates.push(space, projection.to_predicate());
result.predicates.push(projection.to_predicate());
}
}
&hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
let region = ast_region_to_region(tcx, lifetime);
let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
result.predicates.push(space, ty::Predicate::TypeOutlives(pred))
result.predicates.push(ty::Predicate::TypeOutlives(pred))
}
}
}
......@@ -1848,7 +1845,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
for bound in &region_pred.bounds {
let r2 = ast_region_to_region(tcx, bound);
let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
result.predicates.push(space, ty::Predicate::RegionOutlives(pred))
result.predicates.push(ty::Predicate::RegionOutlives(pred))
}
}
......@@ -1861,7 +1858,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
}
}
return result;
result
}
fn ty_generics<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
......@@ -2221,9 +2218,6 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
let impl_scheme = ccx.tcx.lookup_item_type(impl_def_id);
let impl_trait_ref = ccx.tcx.impl_trait_ref(impl_def_id);
assert!(impl_predicates.predicates.is_empty_in(FnSpace));
assert!(impl_predicates.predicates.is_empty_in(SelfSpace));
// The trait reference is an input, so find all type parameters
// reachable from there, to start (if this is an inherent impl,
// then just examine the self type).
......@@ -2233,7 +2227,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
input_parameters.extend(ctp::parameters_for(trait_ref, false));
}
ctp::setup_constraining_predicates(impl_predicates.predicates.get_mut_slice(TypeSpace),
ctp::setup_constraining_predicates(&mut impl_predicates.predicates,
impl_trait_ref,
&mut input_parameters);
......
......@@ -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 @@ fn clean(&self, cx: &DocContext) -> Generics {
srp.clean(cx)
}).collect::<Vec<_>>();
let mut where_predicates = preds.predicates.get_slice(space)
.to_vec().clean(cx);
let mut where_predicates = preds.predicates.to_vec().clean(cx);
// Type parameters and have a Sized bound by default unless removed with
// ?Sized. Scan through the predicates and mark any type parameter with
......@@ -1363,7 +1362,17 @@ fn clean(&self, cx: &DocContext) -> Item {
impl<'tcx> Clean<Item> for ty::Method<'tcx> {
fn clean(&self, cx: &DocContext) -> Item {
let generics = (&self.generics, &self.predicates,
// Depend on trait/impl predicates always being before method's own predicates,
// to be able to split method predicates into "inherited" and method-specific.
let outer_predicates = cx.tcx().lookup_predicates(self.container_id()).predicates;
let method_start = outer_predicates.len();
assert_eq!(&outer_predicates[..], &self.predicates.predicates[..method_start]);
let method_predicates = ty::GenericPredicates {
predicates: self.predicates.predicates[method_start..].to_vec()
};
let generics = (&self.generics, &method_predicates,
subst::FnSpace).clean(cx);
let mut decl = (self.def_id, &self.fty.sig).clean(cx);
match self.explicit_self {
......@@ -1863,8 +1872,7 @@ fn clean(&self, cx: &DocContext) -> Type {
let item_predicates = cx.tcx().lookup_predicates(def_id);
let substs = cx.tcx().lift(&substs).unwrap();
let bounds = item_predicates.instantiate(cx.tcx(), substs);
let predicates = bounds.predicates.into_vec();
ImplTrait(predicates.into_iter().filter_map(|predicate| {
ImplTrait(bounds.predicates.into_iter().filter_map(|predicate| {
predicate.to_opt_poly_trait_ref().clean(cx)
}).collect())
}
......@@ -2967,17 +2975,6 @@ fn clean(&self, cx: &DocContext) -> Item {
}
}
impl<'a> Clean<Typedef> for (ty::TypeScheme<'a>, ty::GenericPredicates<'a>,
ParamSpace) {
fn clean(&self, cx: &DocContext) -> Typedef {
let (ref ty_scheme, ref predicates, ps) = *self;
Typedef {
type_: ty_scheme.ty.clean(cx),
generics: (&ty_scheme.generics, predicates, ps).clean(cx)
}
}
}
fn lang_struct(cx: &DocContext, did: Option<DefId>,
t: ty::Ty, name: &str,
fallback: fn(Box<Type>) -> Type) -> Type {
......
......@@ -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<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_))
}
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册