mod environment;
+use rustc::hir::def::DefKind;
use rustc::hir::def_id::DefId;
use rustc::hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc::hir::map::definitions::DefPathData;
tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,
) -> Clauses<'tcx> {
+ // FIXME(eddyb) this should only be using `def_kind`.
match tcx.def_key(def_id).disambiguated_data.data {
- DefPathData::Trait(_) |
- DefPathData::TraitAlias(_) => program_clauses_for_trait(tcx, def_id),
+ DefPathData::TypeNs(..) => match tcx.def_kind(def_id) {
+ Some(DefKind::Trait)
+ | Some(DefKind::TraitAlias) => program_clauses_for_trait(tcx, def_id),
+ // FIXME(eddyb) deduplicate this `associated_item` call with
+ // `program_clauses_for_associated_type_{value,def}`.
+ Some(DefKind::AssociatedTy) => match tcx.associated_item(def_id).container {
+ ty::AssociatedItemContainer::ImplContainer(_) =>
+ program_clauses_for_associated_type_value(tcx, def_id),
+ ty::AssociatedItemContainer::TraitContainer(_) =>
+ program_clauses_for_associated_type_def(tcx, def_id)
+ },
+ Some(DefKind::Struct)
+ | Some(DefKind::Enum)
+ | Some(DefKind::TyAlias)
+ | Some(DefKind::Union)
+ | Some(DefKind::Existential) => program_clauses_for_type_def(tcx, def_id),
+ _ => List::empty(),
+ },
DefPathData::Impl => program_clauses_for_impl(tcx, def_id),
- DefPathData::AssocTypeInImpl(..) => program_clauses_for_associated_type_value(tcx, def_id),
- DefPathData::AssocTypeInTrait(..) => program_clauses_for_associated_type_def(tcx, def_id),
- DefPathData::TypeNs(..) => program_clauses_for_type_def(tcx, def_id),
_ => List::empty(),
}
}
let implemented_from_env = Clause::ForAll(ty::Binder::bind(implemented_from_env));
let predicates = &tcx.predicates_defined_on(def_id).predicates;
+
+ // Warning: these where clauses are not substituted for bound vars yet,
+ // so that we don't need to adjust binders in the `FromEnv` rules below
+ // (see the FIXME).
let where_clauses = &predicates
.iter()
.map(|(wc, _)| wc.lower())
// `WellFormed(WC)`
let wf_conditions = where_clauses
.into_iter()
+ .map(|wc| wc.subst(tcx, bound_vars))
.map(|wc| wc.map_bound(|goal| goal.into_well_formed_goal()));
// `WellFormed(Self: Trait<P1..Pn>) :- Implemented(Self: Trait<P1..Pn>) && WellFormed(WC)`
//
// ```
// forall<P1..Pn> {
- // WellFormed(Ty<...>) :- WC1, ..., WCm`
+ // WellFormed(Ty<...>) :- WellFormed(WC1), ..., WellFormed(WCm)`
// }
// ```
// `Ty<...>`
let ty = tcx.type_of(def_id).subst(tcx, bound_vars);
- // `WC`
+ // Warning: these where clauses are not substituted for bound vars yet,
+ // so that we don't need to adjust binders in the `FromEnv` rules below
+ // (see the FIXME).
let where_clauses = tcx.predicates_of(def_id).predicates
.iter()
.map(|(wc, _)| wc.lower())
.collect::<Vec<_>>();
- // `WellFormed(Ty<...>) :- WC1, ..., WCm`
+ // `WellFormed(Ty<...>) :- WellFormed(WC1), ..., WellFormed(WCm)`
let well_formed_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
hypotheses: tcx.mk_goals(
where_clauses
.iter()
.map(|wc| wc.subst(tcx, bound_vars))
+ .map(|wc| wc.map_bound(|bound| bound.into_well_formed_goal()))
.map(|wc| tcx.mk_goal(GoalKind::from_poly_domain_goal(wc, tcx))),
),
category: ProgramClauseCategory::WellFormed,
// ```
// forall<Self, P1..Pn, Pn+1..Pm> {
// WellFormed((Trait::AssocType)<Self, P1..Pn, Pn+1..Pm>)
- // :- Implemented(Self: Trait<P1..Pn>)
+ // :- WellFormed(Self: Trait<P1..Pn>)
// }
// ```
let trait_predicate = ty::TraitPredicate { trait_ref };
let hypothesis = tcx.mk_goal(
- DomainGoal::Holds(WhereClause::Implemented(trait_predicate)).into_goal()
+ DomainGoal::WellFormed(WellFormed::Trait(trait_predicate)).into_goal()
);
let wf_clause = ProgramClause {