]> git.lizzy.rs Git - rust.git/commitdiff
Gather region constraints not coming from unification
authorscalexm <alexandre@scalexm.fr>
Fri, 8 Feb 2019 10:21:03 +0000 (11:21 +0100)
committerscalexm <alexandre@scalexm.fr>
Wed, 20 Mar 2019 19:03:20 +0000 (20:03 +0100)
src/librustc_traits/chalk_context/program_clauses.rs
src/librustc_traits/chalk_context/resolvent_ops.rs
src/librustc_traits/lowering/environment.rs
src/test/ui/chalkify/lower_env3.stderr

index 8d5d2b8a9a255ce1e4efa70b2a3913dc59cc0b56..fb7bba32d395e9a51e3a717c00668fb7b9e148c1 100644 (file)
@@ -326,15 +326,12 @@ fn wf_clause_for_ref<'tcx>(
         mutbl,
     });
 
-    let _outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
+    let outlives: DomainGoal<'_> = ty::OutlivesPredicate(ty, region).lower();
     let wf_clause = ProgramClause {
         goal: DomainGoal::WellFormed(WellFormed::Ty(ref_ty)),
-        hypotheses: ty::List::empty(),
-
-        // FIXME: restore this later once we get better at handling regions
-        // hypotheses: tcx.mk_goals(
-        //     iter::once(tcx.mk_goal(outlives.into_goal()))
-        // ),
+        hypotheses: tcx.mk_goals(
+            iter::once(tcx.mk_goal(outlives.into_goal()))
+        ),
         category: ProgramClauseCategory::WellFormed,
     };
     let wf_clause = Clause::ForAll(ty::Binder::bind(wf_clause));
@@ -432,22 +429,14 @@ pub(super) fn program_clauses_impl(
                 clauses
             }
 
-            DomainGoal::Holds(RegionOutlives(..)) => {
-                // These come from:
-                // * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
-                // * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
-
-                // All of these rules are computed in the environment.
-                vec![]
-            }
-
-            DomainGoal::Holds(TypeOutlives(..)) => {
-                // These come from:
-                // * implied bounds from trait definitions (rule `Implied-Bound-From-Trait`)
-                // * implied bounds from type definitions (rule `Implied-Bound-From-Type`)
-
-                // All of these rules are computed in the environment.
-                vec![]
+            // For outlive requirements, just assume they hold. `ResolventOps::resolvent_clause`
+            // will register them as actual region constraints later.
+            DomainGoal::Holds(RegionOutlives(..)) | DomainGoal::Holds(TypeOutlives(..)) => {
+                vec![Clause::Implies(ProgramClause {
+                    goal,
+                    hypotheses: ty::List::empty(),
+                    category: ProgramClauseCategory::Other,
+                })]
             }
 
             DomainGoal::WellFormed(WellFormed::Trait(trait_predicate)) => {
@@ -485,7 +474,7 @@ pub(super) fn program_clauses_impl(
                     ty::Error |
                     ty::Never => {
                         let wf_clause = ProgramClause {
-                            goal: DomainGoal::WellFormed(WellFormed::Ty(ty)),
+                            goal,
                             hypotheses: ty::List::empty(),
                             category: ProgramClauseCategory::WellFormed,
                         };
index 932501cc04fe0dd8c4fa471042023fcb2d0af705..41f983e6acac81c3129da0199b230129dcb3e7b1 100644 (file)
@@ -8,6 +8,7 @@
 use rustc::infer::canonical::{Canonical, CanonicalVarValues};
 use rustc::traits::{
     DomainGoal,
+    WhereClause,
     Goal,
     GoalKind,
     Clause,
@@ -75,6 +76,23 @@ fn resolvent_clause(
                 })
             );
 
+            // If we have a goal of the form `T: 'a` or `'a: 'b`, then just
+            // assume it is true (no subgoals) and register it as a constraint
+            // instead.
+            match goal {
+                DomainGoal::Holds(WhereClause::RegionOutlives(pred)) => {
+                    assert_eq!(ex_clause.subgoals.len(), 0);
+                    ex_clause.constraints.push(ty::OutlivesPredicate(pred.0.into(), pred.1));
+                }
+
+                DomainGoal::Holds(WhereClause::TypeOutlives(pred)) => {
+                    assert_eq!(ex_clause.subgoals.len(), 0);
+                    ex_clause.constraints.push(ty::OutlivesPredicate(pred.0.into(), pred.1));
+                }
+
+                _ => (),
+            };
+
             let canonical_ex_clause = self.canonicalize_ex_clause(&ex_clause);
             Ok(canonical_ex_clause)
         });
@@ -112,10 +130,8 @@ fn apply_answer_subst(
         substitutor.relate(&answer_table_goal.value, &selected_goal)
             .map_err(|_| NoSolution)?;
 
-        let ex_clause = substitutor.ex_clause;
-
-        // FIXME: restore this later once we get better at handling regions
-        // ex_clause.constraints.extend(answer_subst.constraints);
+        let mut ex_clause = substitutor.ex_clause;
+        ex_clause.constraints.extend(answer_subst.constraints);
 
         debug!("apply_answer_subst: ex_clause = {:?}", ex_clause);
         Ok(ex_clause)
index c908c6993e19e883e8230a903382a6feda561858..3570cb102460002a3596fa49179a14266fd4082b 100644 (file)
@@ -10,9 +10,6 @@
 use rustc::ty::{self, TyCtxt, Ty};
 use rustc::hir::def_id::DefId;
 use rustc_data_structures::fx::FxHashSet;
-use super::Lower;
-use crate::generic_types;
-use std::iter;
 
 struct ClauseVisitor<'set, 'a, 'tcx: 'a + 'set> {
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
@@ -38,30 +35,6 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
                 );
             }
 
-            // forall<'a, T> { `Outlives(T: 'a) :- FromEnv(&'a T)` }
-            ty::Ref(_, _, mutbl) => {
-                let region = self.tcx.mk_region(
-                    ty::ReLateBound(ty::INNERMOST, ty::BoundRegion::BrAnon(0))
-                );
-                let ty = generic_types::bound(self.tcx, 1);
-                let ref_ty = self.tcx.mk_ref(region, ty::TypeAndMut {
-                    ty,
-                    mutbl,
-                });
-
-                let from_env = DomainGoal::FromEnv(FromEnv::Ty(ref_ty));
-
-                let clause = ProgramClause {
-                    goal: ty::OutlivesPredicate(ty, region).lower(),
-                    hypotheses: self.tcx.mk_goals(
-                        iter::once(self.tcx.mk_goal(from_env.into_goal()))
-                    ),
-                    category: ProgramClauseCategory::ImpliedBound,
-                };
-                let clause = Clause::ForAll(ty::Binder::bind(clause));
-                self.round.insert(clause);
-            }
-
             ty::Dynamic(..) => {
                 // FIXME: trait object rules are not yet implemented
             }
@@ -99,6 +72,7 @@ fn visit_ty(&mut self, ty: Ty<'tcx>) {
             ty::RawPtr(..) |
             ty::FnPtr(..) |
             ty::Tuple(..) |
+            ty::Ref(..) |
             ty::Never |
             ty::Infer(..) |
             ty::Placeholder(..) |
index 46e083686895d8c615fcc75b0a3ec732481a1b45..a1fc83bfea8a3a0b5a6c7d4a034e92b6cb451eba 100644 (file)
@@ -4,7 +4,6 @@ error: program clause dump
 LL |     #[rustc_dump_env_program_clauses]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
    = note: forall<Self> { Implemented(Self: Foo) :- FromEnv(Self: Foo). }
 
 error: program clause dump
@@ -13,7 +12,6 @@ error: program clause dump
 LL |     #[rustc_dump_env_program_clauses]
    |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |
-   = note: forall<'^0, ^1> { TypeOutlives(^1: '^0) :- FromEnv(&^1). }
    = note: forall<Self> { FromEnv(Self: std::marker::Sized) :- FromEnv(Self: std::clone::Clone). }
    = note: forall<Self> { Implemented(Self: std::clone::Clone) :- FromEnv(Self: std::clone::Clone). }
    = note: forall<Self> { Implemented(Self: std::marker::Sized) :- FromEnv(Self: std::marker::Sized). }