about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/librustc/traits/mod.rs13
-rw-r--r--src/librustc/ty/query/mod.rs1
-rw-r--r--src/librustc_traits/lowering/environment.rs24
-rw-r--r--src/librustc_traits/lowering/mod.rs1
4 files changed, 33 insertions, 6 deletions
diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs
index d95b0844e87..7bfb6f060cd 100644
--- a/src/librustc/traits/mod.rs
+++ b/src/librustc/traits/mod.rs
@@ -337,6 +337,13 @@ impl<'tcx> DomainGoal<'tcx> {
     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> {
@@ -402,11 +409,6 @@ pub struct InEnvironment<'tcx, G> {
     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)]
@@ -1109,7 +1111,6 @@ pub fn provide(providers: &mut ty::query::Providers<'_>) {
         codegen_fulfill_obligation: codegen::codegen_fulfill_obligation,
         vtable_methods,
         substitute_normalize_and_test_predicates,
-        environment,
         ..*providers
     };
 }
diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs
index 83c8eab0f39..adb5883fd5e 100644
--- a/src/librustc/ty/query/mod.rs
+++ b/src/librustc/ty/query/mod.rs
@@ -377,6 +377,7 @@ define_queries! { <'tcx>
         // 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()`,
diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs
index 338cad8154f..1774db3d85a 100644
--- a/src/librustc_traits/lowering/environment.rs
+++ b/src/librustc_traits/lowering/environment.rs
@@ -17,6 +17,7 @@ use rustc::traits::{
     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> {
@@ -162,3 +163,26 @@ crate fn program_clauses_for_env<'a, 'tcx>(
         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),
+    }
+}
diff --git a/src/librustc_traits/lowering/mod.rs b/src/librustc_traits/lowering/mod.rs
index 07a5d6a31dd..a6bf28b6ad8 100644
--- a/src/librustc_traits/lowering/mod.rs
+++ b/src/librustc_traits/lowering/mod.rs
@@ -35,6 +35,7 @@ crate fn provide(p: &mut Providers) {
     *p = Providers {
         program_clauses_for,
         program_clauses_for_env: environment::program_clauses_for_env,
+        environment: environment::environment,
         ..*p
     };
 }