rustc: split GenericPredicates of a method from its parent predicates.
This commit is contained in:
parent
3e74e5bffe
commit
6f5e455c2d
@ -2897,20 +2897,18 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
|
||||
// obligation will normalize to `<$0 as Iterator>::Item = $1` and
|
||||
// `$1: Copy`, so we must ensure the obligations are emitted in
|
||||
// that order.
|
||||
let predicates = tcx
|
||||
.lookup_predicates(def_id)
|
||||
.predicates.iter()
|
||||
.flat_map(|predicate| {
|
||||
let predicate =
|
||||
normalize_with_depth(self, cause.clone(), recursion_depth,
|
||||
&predicate.subst(tcx, substs));
|
||||
predicate.obligations.into_iter().chain(
|
||||
Some(Obligation {
|
||||
cause: cause.clone(),
|
||||
recursion_depth: recursion_depth,
|
||||
predicate: predicate.value
|
||||
}))
|
||||
}).collect();
|
||||
let predicates = tcx.lookup_predicates(def_id);
|
||||
assert_eq!(predicates.parent, None);
|
||||
let predicates = predicates.predicates.iter().flat_map(|predicate| {
|
||||
let predicate = normalize_with_depth(self, cause.clone(), recursion_depth,
|
||||
&predicate.subst(tcx, substs));
|
||||
predicate.obligations.into_iter().chain(
|
||||
Some(Obligation {
|
||||
cause: cause.clone(),
|
||||
recursion_depth: recursion_depth,
|
||||
predicate: predicate.value
|
||||
}))
|
||||
}).collect();
|
||||
self.infcx().plug_leaks(skol_map, snapshot, &predicates)
|
||||
}
|
||||
}
|
||||
|
@ -768,27 +768,38 @@ pub struct Generics<'tcx> {
|
||||
/// Bounds on generics.
|
||||
#[derive(Clone)]
|
||||
pub struct GenericPredicates<'tcx> {
|
||||
pub parent: Option<DefId>,
|
||||
pub predicates: Vec<Predicate<'tcx>>,
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> GenericPredicates<'tcx> {
|
||||
pub fn empty() -> GenericPredicates<'tcx> {
|
||||
GenericPredicates {
|
||||
predicates: vec![]
|
||||
pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
|
||||
-> InstantiatedPredicates<'tcx> {
|
||||
let mut instantiated = InstantiatedPredicates::empty();
|
||||
self.instantiate_into(tcx, &mut instantiated, substs);
|
||||
instantiated
|
||||
}
|
||||
pub fn instantiate_own(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
|
||||
-> InstantiatedPredicates<'tcx> {
|
||||
InstantiatedPredicates {
|
||||
predicates: self.predicates.subst(tcx, substs)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn instantiate(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, substs: &Substs<'tcx>)
|
||||
-> InstantiatedPredicates<'tcx> {
|
||||
InstantiatedPredicates {
|
||||
predicates: self.predicates.subst(tcx, substs),
|
||||
fn instantiate_into(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
instantiated: &mut InstantiatedPredicates<'tcx>,
|
||||
substs: &Substs<'tcx>) {
|
||||
if let Some(def_id) = self.parent {
|
||||
tcx.lookup_predicates(def_id).instantiate_into(tcx, instantiated, substs);
|
||||
}
|
||||
instantiated.predicates.extend(self.predicates.iter().map(|p| p.subst(tcx, substs)))
|
||||
}
|
||||
|
||||
pub fn instantiate_supertrait(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>,
|
||||
poly_trait_ref: &ty::PolyTraitRef<'tcx>)
|
||||
-> InstantiatedPredicates<'tcx>
|
||||
{
|
||||
assert_eq!(self.parent, None);
|
||||
InstantiatedPredicates {
|
||||
predicates: self.predicates.iter().map(|pred| {
|
||||
pred.subst_supertrait(tcx, poly_trait_ref)
|
||||
|
@ -832,18 +832,6 @@ impl<'tcx> TypeFoldable<'tcx> for ty::RegionParameterDef {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::GenericPredicates<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
ty::GenericPredicates {
|
||||
predicates: self.predicates.fold_with(folder),
|
||||
}
|
||||
}
|
||||
|
||||
fn super_visit_with<V: TypeVisitor<'tcx>>(&self, visitor: &mut V) -> bool {
|
||||
self.predicates.visit_with(visitor)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> TypeFoldable<'tcx> for ty::Predicate<'tcx> {
|
||||
fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self {
|
||||
match *self {
|
||||
|
@ -1591,6 +1591,7 @@ fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc,
|
||||
let doc = reader::get_doc(base_doc, tag);
|
||||
|
||||
ty::GenericPredicates {
|
||||
parent: item_parent_item(cdata, doc),
|
||||
predicates: reader::tagged_docs(doc, tag_predicate).map(|predicate_doc| {
|
||||
doc_predicate(cdata, predicate_doc, tcx)
|
||||
}).collect()
|
||||
|
@ -525,6 +525,9 @@ fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
|
||||
tag: usize)
|
||||
{
|
||||
rbml_w.start_tag(tag);
|
||||
if let Some(def_id) = predicates.parent {
|
||||
rbml_w.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id));
|
||||
}
|
||||
for predicate in &predicates.predicates {
|
||||
rbml_w.wr_tagged_u32(tag_predicate,
|
||||
index.add_xref(XRef::Predicate(predicate.clone())));
|
||||
|
@ -1726,6 +1726,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 {
|
||||
parent: None,
|
||||
predicates: predicates
|
||||
});
|
||||
|
||||
|
@ -211,29 +211,18 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
return;
|
||||
}
|
||||
|
||||
// Depend on trait/impl predicates always being before method's own predicates,
|
||||
// to be able to split method predicates into "inherited" and method-specific.
|
||||
let trait_predicates = tcx.lookup_predicates(trait_m.container_id()).predicates;
|
||||
let impl_predicates = tcx.lookup_predicates(impl_m.container_id()).predicates;
|
||||
let trait_method_start = trait_predicates.len();
|
||||
let impl_method_start = impl_predicates.len();
|
||||
assert_eq!(&trait_predicates[..], &trait_m.predicates.predicates[..trait_method_start]);
|
||||
assert_eq!(&impl_predicates[..], &impl_m.predicates.predicates[..impl_method_start]);
|
||||
|
||||
tcx.infer_ctxt(None, None, Reveal::NotSpecializable).enter(|mut infcx| {
|
||||
let mut fulfillment_cx = traits::FulfillmentContext::new();
|
||||
|
||||
// Normalize the associated types in the trait_bounds.
|
||||
let trait_bounds = trait_m.predicates.instantiate(tcx, trait_to_skol_substs);
|
||||
|
||||
// Create obligations for each predicate declared by the impl
|
||||
// definition in the context of the trait's parameter
|
||||
// environment. We can't just use `impl_env.caller_bounds`,
|
||||
// however, because we want to replace all late-bound regions with
|
||||
// region variables.
|
||||
let impl_bounds = impl_m.predicates.instantiate(tcx, impl_to_skol_substs);
|
||||
let impl_predicates = tcx.lookup_predicates(impl_m.predicates.parent.unwrap());
|
||||
let mut hybrid_preds = impl_predicates.instantiate(tcx, impl_to_skol_substs);
|
||||
|
||||
debug!("compare_impl_method: impl_bounds={:?}", impl_bounds);
|
||||
debug!("compare_impl_method: impl_bounds={:?}", hybrid_preds);
|
||||
|
||||
// This is the only tricky bit of the new way we check implementation methods
|
||||
// We need to build a set of predicates where only the FnSpace bounds
|
||||
@ -242,14 +231,14 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
//
|
||||
// We then register the obligations from the impl_m and check to see
|
||||
// if all constraints hold.
|
||||
let hybrid_preds = impl_bounds.predicates[..impl_method_start].iter()
|
||||
.chain(trait_bounds.predicates[trait_method_start..].iter());
|
||||
hybrid_preds.predicates.extend(
|
||||
trait_m.predicates.instantiate_own(tcx, trait_to_skol_substs).predicates);
|
||||
|
||||
// Construct trait parameter environment and then shift it into the skolemized viewpoint.
|
||||
// The key step here is to update the caller_bounds's predicates to be
|
||||
// the new hybrid bounds we computed.
|
||||
let normalize_cause = traits::ObligationCause::misc(impl_m_span, impl_m_body_id);
|
||||
let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.cloned().collect());
|
||||
let trait_param_env = impl_param_env.with_caller_bounds(hybrid_preds.predicates);
|
||||
let trait_param_env = traits::normalize_param_env_or_error(tcx,
|
||||
trait_param_env,
|
||||
normalize_cause.clone());
|
||||
@ -261,12 +250,13 @@ pub fn compare_impl_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
|
||||
let mut selcx = traits::SelectionContext::new(&infcx);
|
||||
|
||||
let (impl_pred_fns, _) =
|
||||
let impl_m_own_bounds = impl_m.predicates.instantiate_own(tcx, impl_to_skol_substs);
|
||||
let (impl_m_own_bounds, _) =
|
||||
infcx.replace_late_bound_regions_with_fresh_var(
|
||||
impl_m_span,
|
||||
infer::HigherRankedType,
|
||||
&ty::Binder(impl_bounds.predicates[impl_method_start..].to_vec()));
|
||||
for predicate in impl_pred_fns {
|
||||
&ty::Binder(impl_m_own_bounds.predicates));
|
||||
for predicate in impl_m_own_bounds {
|
||||
let traits::Normalized { value: predicate, .. } =
|
||||
traits::normalize(&mut selcx, normalize_cause.clone(), &predicate);
|
||||
|
||||
|
@ -184,6 +184,7 @@ fn ensure_drop_predicates_are_implied_by_item_defn<'a, 'tcx>(
|
||||
// 'a:'b and T:'b into region inference constraints. It is simpler
|
||||
// just to look for all the predicates directly.
|
||||
|
||||
assert_eq!(dtor_predicates.parent, None);
|
||||
for predicate in &dtor_predicates.predicates {
|
||||
// (We do not need to worry about deep analysis of type
|
||||
// expressions etc because the Drop impls are already forced
|
||||
|
@ -1612,8 +1612,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
bounds: &ty::GenericPredicates<'tcx>)
|
||||
-> ty::InstantiatedPredicates<'tcx>
|
||||
{
|
||||
let result = bounds.instantiate(self.tcx, substs);
|
||||
let result = self.normalize_associated_types_in(span, &result.predicates);
|
||||
debug!("instantiate_bounds(bounds={:?}, substs={:?}) = {:?}",
|
||||
bounds,
|
||||
substs,
|
||||
result);
|
||||
ty::InstantiatedPredicates {
|
||||
predicates: self.instantiate_type_scheme(span, substs, &bounds.predicates)
|
||||
predicates: result
|
||||
}
|
||||
}
|
||||
|
||||
@ -4210,8 +4216,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
let scheme = self.tcx.lookup_item_type(def.def_id());
|
||||
let type_predicates = self.tcx.lookup_predicates(def.def_id());
|
||||
|
||||
// Now we have to compare the types that the user *actually*
|
||||
// provided against the types that were *expected*. If the user
|
||||
@ -4296,6 +4300,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
||||
|
||||
// The things we are substituting into the type should not contain
|
||||
// escaping late-bound regions, and nor should the base type scheme.
|
||||
let scheme = self.tcx.lookup_item_type(def.def_id());
|
||||
let type_predicates = self.tcx.lookup_predicates(def.def_id());
|
||||
assert!(!substs.has_escaping_regions());
|
||||
assert!(!scheme.ty.has_escaping_regions());
|
||||
|
||||
|
@ -1754,6 +1754,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
|
||||
//
|
||||
// we can thus deduce that `<T as SomeTrait<'a>>::SomeType : 'a`.
|
||||
let trait_predicates = self.tcx.lookup_predicates(projection_ty.trait_ref.def_id);
|
||||
assert_eq!(trait_predicates.parent, None);
|
||||
let predicates = trait_predicates.predicates.as_slice().to_vec();
|
||||
traits::elaborate_predicates(self.tcx, predicates)
|
||||
.filter_map(|predicate| {
|
||||
|
@ -454,6 +454,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
|
||||
|
||||
let item_def_id = self.tcx().map.local_def_id(item.id);
|
||||
let ty_predicates = self.tcx().lookup_predicates(item_def_id);
|
||||
assert_eq!(ty_predicates.parent, None);
|
||||
let variances = self.tcx().item_variances(item_def_id);
|
||||
|
||||
let mut constrained_parameters: HashSet<_> =
|
||||
|
@ -459,35 +459,38 @@ impl<'tcx> GetTypeParameterBounds<'tcx> for () {
|
||||
impl<'tcx> GetTypeParameterBounds<'tcx> for ty::GenericPredicates<'tcx> {
|
||||
fn get_type_parameter_bounds(&self,
|
||||
astconv: &AstConv<'tcx, 'tcx>,
|
||||
_span: Span,
|
||||
span: Span,
|
||||
node_id: ast::NodeId)
|
||||
-> Vec<ty::Predicate<'tcx>>
|
||||
{
|
||||
let def = astconv.tcx().type_parameter_def(node_id);
|
||||
|
||||
self.predicates
|
||||
.iter()
|
||||
.filter(|predicate| {
|
||||
match **predicate {
|
||||
ty::Predicate::Trait(ref data) => {
|
||||
data.skip_binder().self_ty().is_param(def.space, def.index)
|
||||
}
|
||||
ty::Predicate::TypeOutlives(ref data) => {
|
||||
data.skip_binder().0.is_param(def.space, def.index)
|
||||
}
|
||||
ty::Predicate::Rfc1592(..) |
|
||||
ty::Predicate::Equate(..) |
|
||||
ty::Predicate::RegionOutlives(..) |
|
||||
ty::Predicate::WellFormed(..) |
|
||||
ty::Predicate::ObjectSafe(..) |
|
||||
ty::Predicate::ClosureKind(..) |
|
||||
ty::Predicate::Projection(..) => {
|
||||
false
|
||||
}
|
||||
let mut results = self.parent.map_or(vec![], |def_id| {
|
||||
let parent = astconv.tcx().lookup_predicates(def_id);
|
||||
parent.get_type_parameter_bounds(astconv, span, node_id)
|
||||
});
|
||||
|
||||
results.extend(self.predicates.iter().filter(|predicate| {
|
||||
match **predicate {
|
||||
ty::Predicate::Trait(ref data) => {
|
||||
data.skip_binder().self_ty().is_param(def.space, def.index)
|
||||
}
|
||||
})
|
||||
.cloned()
|
||||
.collect()
|
||||
ty::Predicate::TypeOutlives(ref data) => {
|
||||
data.skip_binder().0.is_param(def.space, def.index)
|
||||
}
|
||||
ty::Predicate::Rfc1592(..) |
|
||||
ty::Predicate::Equate(..) |
|
||||
ty::Predicate::RegionOutlives(..) |
|
||||
ty::Predicate::WellFormed(..) |
|
||||
ty::Predicate::ObjectSafe(..) |
|
||||
ty::Predicate::ClosureKind(..) |
|
||||
ty::Predicate::Projection(..) => {
|
||||
false
|
||||
}
|
||||
}
|
||||
}).cloned());
|
||||
|
||||
results
|
||||
}
|
||||
}
|
||||
|
||||
@ -568,7 +571,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
let ty_generics = generics_of_def_id(ccx, def_id);
|
||||
|
||||
let ty_generic_predicates =
|
||||
ty_generic_predicates_for_fn(ccx, &sig.generics, rcvr_ty_predicates);
|
||||
ty_generic_predicates(ccx, FnSpace, &sig.generics, ty_generics.parent, vec![], false);
|
||||
|
||||
let (fty, explicit_self_category) = {
|
||||
let anon_scope = match container {
|
||||
@ -634,8 +637,12 @@ fn convert_associated_const<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
ty: ty::Ty<'tcx>,
|
||||
has_value: bool)
|
||||
{
|
||||
let predicates = ty::GenericPredicates {
|
||||
parent: Some(container.id()),
|
||||
predicates: vec![]
|
||||
};
|
||||
ccx.tcx.predicates.borrow_mut().insert(ccx.tcx.map.local_def_id(id),
|
||||
ty::GenericPredicates::empty());
|
||||
predicates);
|
||||
|
||||
write_ty_to_tcx(ccx, id, ty);
|
||||
|
||||
@ -744,7 +751,8 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
|
||||
debug!("convert: ast_generics={:?}", generics);
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
let ty_generics = generics_of_def_id(ccx, def_id);
|
||||
let mut ty_predicates = ty_generic_predicates_for_type_or_impl(ccx, generics);
|
||||
let mut ty_predicates =
|
||||
ty_generic_predicates(ccx, TypeSpace, generics, None, vec![], false);
|
||||
|
||||
debug!("convert: impl_bounds={:?}", ty_predicates);
|
||||
|
||||
@ -1187,6 +1195,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
|
||||
// generic types:
|
||||
let trait_def = trait_def_of_item(ccx, item);
|
||||
let self_predicate = ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates: vec![trait_def.trait_ref.to_predicate()]
|
||||
};
|
||||
let scope = &(generics, &self_predicate);
|
||||
@ -1209,6 +1218,7 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
|
||||
// Combine the two lists to form the complete set of superbounds:
|
||||
let superbounds = superbounds1.into_iter().chain(superbounds2).collect();
|
||||
let superpredicates = ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates: superbounds
|
||||
};
|
||||
debug!("superpredicates for trait {:?} = {:?}",
|
||||
@ -1327,16 +1337,16 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
|
||||
// but to get the full set of predicates on a trait we need to add
|
||||
// in the supertrait bounds and anything declared on the
|
||||
// associated types.
|
||||
let mut base_predicates = super_predicates;
|
||||
let mut base_predicates = super_predicates.predicates;
|
||||
|
||||
// Add in a predicate that `Self:Trait` (where `Trait` is the
|
||||
// current trait). This is needed for builtin bounds.
|
||||
let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
|
||||
base_predicates.predicates.push(self_predicate);
|
||||
base_predicates.push(self_predicate);
|
||||
|
||||
// add in the explicit where-clauses
|
||||
let mut trait_predicates =
|
||||
ty_generic_predicates(ccx, TypeSpace, generics, &base_predicates, true);
|
||||
ty_generic_predicates(ccx, TypeSpace, generics, None, base_predicates, true);
|
||||
|
||||
let assoc_predicates = predicates_for_associated_types(ccx,
|
||||
generics,
|
||||
@ -1619,32 +1629,17 @@ fn predicates_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
it: &hir::Item)
|
||||
-> ty::GenericPredicates<'tcx> {
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
let predicates = match it.node {
|
||||
hir::ItemStatic(..) | hir::ItemConst(..) => {
|
||||
ty::GenericPredicates::empty()
|
||||
}
|
||||
hir::ItemFn(_, _, _, _, ref ast_generics, _) => {
|
||||
ty_generic_predicates_for_fn(ccx, ast_generics, &ty::GenericPredicates::empty())
|
||||
}
|
||||
|
||||
let no_generics = hir::Generics::empty();
|
||||
let (space, generics) = match it.node {
|
||||
hir::ItemFn(_, _, _, _, ref generics, _) => (FnSpace, generics),
|
||||
hir::ItemTy(_, ref generics) |
|
||||
hir::ItemEnum(_, ref generics) |
|
||||
hir::ItemStruct(_, ref generics) => {
|
||||
ty_generic_predicates_for_type_or_impl(ccx, generics)
|
||||
}
|
||||
hir::ItemDefaultImpl(..) |
|
||||
hir::ItemTrait(..) |
|
||||
hir::ItemExternCrate(..) |
|
||||
hir::ItemUse(..) |
|
||||
hir::ItemImpl(..) |
|
||||
hir::ItemMod(..) |
|
||||
hir::ItemForeignMod(..) => {
|
||||
span_bug!(
|
||||
it.span,
|
||||
"predicates_of_item: unexpected item type: {:?}",
|
||||
it.node);
|
||||
}
|
||||
hir::ItemStruct(_, ref generics) => (TypeSpace, generics),
|
||||
_ => (TypeSpace, &no_generics)
|
||||
};
|
||||
|
||||
let predicates = ty_generic_predicates(ccx, space, generics, None, vec![], false);
|
||||
let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id,
|
||||
predicates.clone());
|
||||
assert!(prev_predicates.is_none());
|
||||
@ -1662,34 +1657,17 @@ fn convert_foreign_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
|
||||
let def_id = ccx.tcx.map.local_def_id(it.id);
|
||||
type_scheme_of_def_id(ccx, def_id);
|
||||
|
||||
let predicates = match it.node {
|
||||
hir::ForeignItemFn(_, ref generics) => {
|
||||
ty_generic_predicates_for_fn(ccx, generics, &ty::GenericPredicates::empty())
|
||||
}
|
||||
hir::ForeignItemStatic(..) => {
|
||||
ty::GenericPredicates::empty()
|
||||
}
|
||||
let no_generics = hir::Generics::empty();
|
||||
let (space, generics) = match it.node {
|
||||
hir::ForeignItemFn(_, ref generics) => (FnSpace, generics),
|
||||
hir::ForeignItemStatic(..) => (TypeSpace, &no_generics)
|
||||
};
|
||||
|
||||
let predicates = ty_generic_predicates(ccx, space, generics, None, vec![], false);
|
||||
let prev_predicates = ccx.tcx.predicates.borrow_mut().insert(def_id, predicates);
|
||||
assert!(prev_predicates.is_none());
|
||||
}
|
||||
|
||||
fn ty_generic_predicates_for_type_or_impl<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
generics: &hir::Generics)
|
||||
-> ty::GenericPredicates<'tcx>
|
||||
{
|
||||
ty_generic_predicates(ccx, TypeSpace, generics, &ty::GenericPredicates::empty(), false)
|
||||
}
|
||||
|
||||
fn ty_generic_predicates_for_fn<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
generics: &hir::Generics,
|
||||
base_predicates: &ty::GenericPredicates<'tcx>)
|
||||
-> ty::GenericPredicates<'tcx>
|
||||
{
|
||||
ty_generic_predicates(ccx, FnSpace, generics, base_predicates, false)
|
||||
}
|
||||
|
||||
// Add the Sized bound, unless the type parameter is marked as `?Sized`.
|
||||
fn add_unsized_bound<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
|
||||
bounds: &mut ty::BuiltinBounds,
|
||||
@ -1757,12 +1735,25 @@ fn early_bound_lifetimes_from_generics<'a, 'tcx, 'hir>(
|
||||
fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
space: ParamSpace,
|
||||
ast_generics: &hir::Generics,
|
||||
base_predicates: &ty::GenericPredicates<'tcx>,
|
||||
parent: Option<DefId>,
|
||||
super_predicates: Vec<ty::Predicate<'tcx>>,
|
||||
has_self: bool)
|
||||
-> ty::GenericPredicates<'tcx>
|
||||
{
|
||||
let tcx = ccx.tcx;
|
||||
let mut result = base_predicates.clone();
|
||||
let ref base_predicates = match parent {
|
||||
Some(def_id) => {
|
||||
assert_eq!(super_predicates, vec![]);
|
||||
tcx.lookup_predicates(def_id)
|
||||
}
|
||||
None => {
|
||||
ty::GenericPredicates {
|
||||
parent: None,
|
||||
predicates: super_predicates.clone()
|
||||
}
|
||||
}
|
||||
};
|
||||
let mut predicates = super_predicates;
|
||||
|
||||
// Collect the predicates that were written inline by the user on each
|
||||
// type parameter (e.g., `<T:Foo>`).
|
||||
@ -1775,7 +1766,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
SizedByDefault::Yes,
|
||||
None,
|
||||
param.span);
|
||||
result.predicates.extend(bounds.predicates(ccx.tcx, param_ty));
|
||||
predicates.extend(bounds.predicates(ccx.tcx, param_ty));
|
||||
}
|
||||
|
||||
// Collect the region predicates that were declared inline as
|
||||
@ -1793,7 +1784,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
for bound in ¶m.bounds {
|
||||
let bound_region = ast_region_to_region(ccx.tcx, bound);
|
||||
let outlives = ty::Binder(ty::OutlivesPredicate(region, bound_region));
|
||||
result.predicates.push(outlives.to_predicate());
|
||||
predicates.push(outlives.to_predicate());
|
||||
}
|
||||
}
|
||||
|
||||
@ -1819,17 +1810,17 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
ty,
|
||||
&mut projections);
|
||||
|
||||
result.predicates.push(trait_ref.to_predicate());
|
||||
predicates.push(trait_ref.to_predicate());
|
||||
|
||||
for projection in &projections {
|
||||
result.predicates.push(projection.to_predicate());
|
||||
predicates.push(projection.to_predicate());
|
||||
}
|
||||
}
|
||||
|
||||
&hir::TyParamBound::RegionTyParamBound(ref lifetime) => {
|
||||
let region = ast_region_to_region(tcx, lifetime);
|
||||
let pred = ty::Binder(ty::OutlivesPredicate(ty, region));
|
||||
result.predicates.push(ty::Predicate::TypeOutlives(pred))
|
||||
predicates.push(ty::Predicate::TypeOutlives(pred))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -1840,7 +1831,7 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
for bound in ®ion_pred.bounds {
|
||||
let r2 = ast_region_to_region(tcx, bound);
|
||||
let pred = ty::Binder(ty::OutlivesPredicate(r1, r2));
|
||||
result.predicates.push(ty::Predicate::RegionOutlives(pred))
|
||||
predicates.push(ty::Predicate::RegionOutlives(pred))
|
||||
}
|
||||
}
|
||||
|
||||
@ -1853,7 +1844,10 @@ fn ty_generic_predicates<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
}
|
||||
}
|
||||
|
||||
result
|
||||
ty::GenericPredicates {
|
||||
parent: parent,
|
||||
predicates: predicates
|
||||
}
|
||||
}
|
||||
|
||||
fn get_or_create_type_parameter_def<'a,'tcx>(ccx: &CrateCtxt<'a,'tcx>,
|
||||
|
@ -1348,17 +1348,7 @@ impl Clean<Item> for hir::ImplItem {
|
||||
|
||||
impl<'tcx> Clean<Item> for ty::Method<'tcx> {
|
||||
fn clean(&self, cx: &DocContext) -> Item {
|
||||
// Depend on trait/impl predicates always being before method's own predicates,
|
||||
// to be able to split method predicates into "inherited" and method-specific.
|
||||
let outer_predicates = cx.tcx().lookup_predicates(self.container_id()).predicates;
|
||||
let method_start = outer_predicates.len();
|
||||
assert_eq!(&outer_predicates[..], &self.predicates.predicates[..method_start]);
|
||||
|
||||
let method_predicates = ty::GenericPredicates {
|
||||
predicates: self.predicates.predicates[method_start..].to_vec()
|
||||
};
|
||||
|
||||
let generics = (self.generics, &method_predicates).clean(cx);
|
||||
let generics = (self.generics, &self.predicates).clean(cx);
|
||||
let mut decl = (self.def_id, &self.fty.sig).clean(cx);
|
||||
match self.explicit_self {
|
||||
ty::ExplicitSelfCategory::ByValue => {
|
||||
|
@ -25,7 +25,8 @@ impl Foo for Def {
|
||||
}
|
||||
|
||||
pub fn test<A: Foo, B: Foo>() {
|
||||
let _array: [u32; <A as Foo>::Y]; //~ error: the parameter type
|
||||
let _array: [u32; <A as Foo>::Y];
|
||||
//~^ ERROR the trait bound `A: Foo` is not satisfied
|
||||
}
|
||||
|
||||
fn main() {
|
||||
|
Loading…
Reference in New Issue
Block a user