]> git.lizzy.rs Git - rust.git/commitdiff
Return an instantiated environment instead of a generic one
authorscalexm <alexandre@scalexm.fr>
Fri, 23 Nov 2018 20:03:27 +0000 (21:03 +0100)
committerscalexm <alexandre@scalexm.fr>
Thu, 27 Dec 2018 18:21:15 +0000 (19:21 +0100)
src/librustc/ty/query/mod.rs
src/librustc_traits/chalk_context/program_clauses.rs
src/librustc_traits/lowering/environment.rs
src/librustc_traits/lowering/mod.rs

index 023a3b049501d60b8fe01c90075de1b5248d8124..1c92f6bc0916fa4e15f7e77392b04f449507ea53 100644 (file)
         ) -> Clauses<'tcx>,
 
         // Get the chalk-style environment of the given item.
-        [] fn environment: Environment(DefId) -> ty::Binder<traits::Environment<'tcx>>,
+        [] fn environment: Environment(DefId) -> traits::Environment<'tcx>,
     },
 
     Linking {
index b685266947b7f3f46d868e743c061fa1c6da90cc..2b4970124e3d66fbcb4c093022387cd15ddac087 100644 (file)
@@ -256,6 +256,8 @@ pub(super) fn program_clauses_impl(
     ) -> 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:
@@ -345,20 +347,21 @@ pub(super) fn program_clauses_impl(
                         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))
                     }
@@ -415,7 +418,6 @@ pub(super) fn program_clauses_impl(
                     ty::UnnormalizedProjection(..) |
                     ty::Infer(..) |
                     ty::Bound(..) |
-                    ty::Param(..) |
                     ty::Error => {
                         bug!("unexpected type {:?}", ty)
                     }
@@ -458,13 +460,18 @@ pub(super) fn program_clauses_impl(
             }
         };
 
+        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
     }
 }
index 0a474b5e7ef188ea58d8fb14c79feb5c4a2ce6f1..e21428acf63cdda2520afbc603f1485c0d90e5d3 100644 (file)
@@ -105,11 +105,11 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
             ty::Never |
             ty::Infer(..) |
             ty::Placeholder(..) |
+            ty::Param(..) |
             ty::Bound(..) => (),
 
             ty::GeneratorWitness(..) |
             ty::UnnormalizedProjection(..) |
-            ty::Param(..) |
             ty::Error => {
                 bug!("unexpected type {:?}", ty);
             }
@@ -192,25 +192,23 @@ fn visit_clause(&mut self, clause: Clause<'tcx>) {
 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()))
 
@@ -255,20 +253,18 @@ fn visit_clause(&mut self, clause: Clause<'tcx>) {
     // 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())
@@ -277,17 +273,14 @@ fn visit_clause(&mut self, clause: Clause<'tcx>) {
 
     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),
-    })
+    }
 }
index 28455a1d807a968af0d5aadf0e514b382064ec5e..51d2894cbf45a814ba5ebc23e492750d4582e41f 100644 (file)
@@ -626,7 +626,7 @@ fn process_attrs(&mut self, node_id: ast::NodeId, attrs: &[ast::Attribute]) {
 
             if attr.check_name("rustc_dump_env_program_clauses") {
                 let environment = self.tcx.environment(def_id);
-                clauses = Some(self.tcx.program_clauses_for_env(*environment.skip_binder()));
+                clauses = Some(self.tcx.program_clauses_for_env(environment));
             }
 
             if let Some(clauses) = clauses {