) -> Vec<Clause<'tcx>> {
use rustc::traits::WhereClause::*;
+ debug!("program_clauses(goal = {:?})", goal);
+
let mut clauses = match goal {
DomainGoal::Holds(Implemented(trait_predicate)) => {
// These come from:
self.infcx.tcx.program_clauses_for(data.item_def_id)
}
- // These types are always WF and non-parametric.
+ // These types are always WF.
ty::Bool |
ty::Char |
ty::Int(..) |
ty::Uint(..) |
ty::Float(..) |
ty::Str |
+ ty::Param(..) |
ty::Never => {
let wf_clause = ProgramClause {
goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
hypotheses: ty::List::empty(),
category: ProgramClauseCategory::WellFormed,
};
- let wf_clause = Clause::ForAll(ty::Binder::dummy(wf_clause));
+ let wf_clause = Clause::Implies(wf_clause);
self.infcx.tcx.mk_clauses(iter::once(wf_clause))
}
ty::UnnormalizedProjection(..) |
ty::Infer(..) |
ty::Bound(..) |
- ty::Param(..) |
ty::Error => {
bug!("unexpected type {:?}", ty)
}
}
};
+ debug!("program_clauses: clauses = {:?}", clauses);
+ debug!("program_clauses: adding clauses from environment = {:?}", environment);
+
let environment = self.infcx.tcx.lift_to_global(environment)
.expect("environment is not global");
- clauses.extend(
- self.infcx.tcx.program_clauses_for_env(environment)
- .into_iter()
- .cloned()
- );
+
+ let env_clauses = self.infcx.tcx.program_clauses_for_env(environment);
+
+ debug!("program_clauses: env_clauses = {:?}", env_clauses);
+
+ clauses.extend(env_clauses.into_iter().cloned());
+ clauses.extend(environment.clauses.iter().cloned());
clauses
}
}
ty::Never |
ty::Infer(..) |
ty::Placeholder(..) |
+ ty::Param(..) |
ty::Bound(..) => (),
ty::GeneratorWitness(..) |
ty::UnnormalizedProjection(..) |
- ty::Param(..) |
ty::Error => {
bug!("unexpected type {:?}", ty);
}
crate fn environment<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId
-) -> ty::Binder<Environment<'tcx>> {
+) -> Environment<'tcx> {
use super::{Lower, IntoFromEnvGoal};
use rustc::hir::{Node, TraitItemKind, ImplItemKind, ItemKind, ForeignItemKind};
- use rustc::ty::subst::{Subst, Substs};
+
+ debug!("environment(def_id = {:?})", def_id);
// The environment of an impl Trait type is its defining function's environment.
if let Some(parent) = ty::is_impl_trait_defn(tcx, def_id) {
return environment(tcx, parent);
}
- let bound_vars = Substs::bound_vars_for_item(tcx, def_id);
-
// Compute the bounds on `Self` and the type parameters.
let ty::InstantiatedPredicates { predicates } = tcx.predicates_of(def_id)
.instantiate_identity(tcx);
let clauses = predicates.into_iter()
.map(|predicate| predicate.lower())
- .map(|predicate| predicate.subst(tcx, bound_vars))
.map(|domain_goal| domain_goal.map_bound(|bound| bound.into_from_env_goal()))
.map(|domain_goal| domain_goal.map_bound(|bound| bound.into_program_clause()))
// are well-formed.
if is_impl {
let trait_ref = tcx.impl_trait_ref(def_id)
- .expect("not an impl")
- .subst(tcx, bound_vars);
+ .expect("not an impl");
input_tys.extend(
- trait_ref.substs.types().flat_map(|ty| ty.walk())
+ trait_ref.input_types().flat_map(|ty| ty.walk())
);
}
// In an fn, we assume that the arguments and all their constituents are
// well-formed.
if is_fn {
- // `skip_binder` because we move region parameters to the root binder,
- // restored in the return type of this query
- let fn_sig = tcx.fn_sig(def_id).skip_binder().subst(tcx, bound_vars);
+ let fn_sig = tcx.fn_sig(def_id);
+ let fn_sig = tcx.liberate_late_bound_regions(def_id, &fn_sig);
input_tys.extend(
fn_sig.inputs().iter().flat_map(|ty| ty.walk())
let clauses = clauses.chain(
input_tys.into_iter()
- // Filter out type parameters
- .filter(|ty| match ty.sty {
- ty::Bound(..) => false,
- _ => true,
- })
.map(|ty| DomainGoal::FromEnv(FromEnv::Ty(ty)))
.map(|domain_goal| domain_goal.into_program_clause())
.map(Clause::Implies)
);
- ty::Binder::bind(Environment {
+ debug!("environment: clauses = {:?}", clauses);
+
+ Environment {
clauses: tcx.mk_clauses(clauses),
- })
+ }
}