pub fn into_goal(self) -> GoalKind<'tcx> {
GoalKind::DomainGoal(self)
}
+
+ pub fn into_program_clause(self) -> ProgramClause<'tcx> {
+ ProgramClause {
+ goal: self,
+ hypotheses: &ty::List::empty(),
+ }
+ }
}
impl<'tcx> GoalKind<'tcx> {
pub goal: G,
}
-/// Compute the environment of the given item.
-fn environment<'a, 'tcx>(_tcx: TyCtxt<'a, 'tcx, 'tcx>, _def_id: DefId) -> Environment<'tcx> {
- panic!()
-}
-
pub type Selection<'tcx> = Vtable<'tcx, PredicateObligation<'tcx>>;
#[derive(Clone,Debug)]
codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
vtable_methods,
substitute_normalize_and_test_predicates,
- environment,
..*providers
};
}
// might want to use `reveal_all()` method to change modes.
[] fn param_env: ParamEnv(DefId) -> ty::ParamEnv<'tcx>,
+ // Get the chalk-style environment of the given item.
[] fn environment: Environment(DefId) -> traits::Environment<'tcx>,
// Trait selection queries. These are best used by invoking `ty.moves_by_default()`,
Environment,
};
use rustc::ty::{self, TyCtxt, Ty};
+use rustc::hir::def_id::DefId;
use rustc_data_structures::fx::FxHashSet;
struct ClauseVisitor<'set, 'a, 'tcx: 'a> {
closure.into_iter()
);
}
+
+crate fn environment<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> Environment<'tcx> {
+ use super::{Lower, IntoFromEnvGoal};
+
+ // 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);
+ }
+
+ // 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(|domain_goal| domain_goal.map_bound(|dg| dg.into_from_env_goal()))
+ .map(|domain_goal| domain_goal.map_bound(|dg| dg.into_program_clause()))
+ .map(Clause::ForAll);
+
+ Environment {
+ clauses: tcx.mk_clauses(clauses),
+ }
+}