about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorNiko Matsakis <niko@alum.mit.edu>2018-11-20 10:24:38 -0500
committerNiko Matsakis <niko@alum.mit.edu>2019-01-02 17:35:06 -0500
commit2c17af0bf79276cda6d97c19a78f21edcee22d19 (patch)
tree1b843079f0af0cc1fb14b090a060b7847c563501 /src
parent13ea9b877c68c62a52140f47d5e38adf5ee6c808 (diff)
downloadrust-2c17af0bf79276cda6d97c19a78f21edcee22d19.tar.gz
rust-2c17af0bf79276cda6d97c19a78f21edcee22d19.zip
track if any region constraints involved placeholders
Diffstat (limited to 'src')
-rw-r--r--src/librustc/infer/mod.rs7
-rw-r--r--src/librustc/infer/region_constraints/mod.rs33
-rw-r--r--src/librustc/traits/select.rs7
3 files changed, 33 insertions, 14 deletions
diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs
index 461e09819d9..0a5e399aaad 100644
--- a/src/librustc/infer/mod.rs
+++ b/src/librustc/infer/mod.rs
@@ -867,10 +867,15 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         r
     }
 
+    /// Scan the constraints produced since `snapshot` began and returns:
+    ///
+    /// - None -- if none of them involve "region outlives" constraints
+    /// - Some(true) -- if there are `'a: 'b` constraints where `'a` or `'b` is a placehodler
+    /// - Some(false) -- if there are `'a: 'b` constraints but none involve placeholders
     pub fn region_constraints_added_in_snapshot(
         &self,
         snapshot: &CombinedSnapshot<'a, 'tcx>,
-    ) -> bool {
+    ) -> Option<bool> {
         self.borrow_region_constraints().region_constraints_added_in_snapshot(
             &snapshot.region_constraints_snapshot,
         )
diff --git a/src/librustc/infer/region_constraints/mod.rs b/src/librustc/infer/region_constraints/mod.rs
index b29eb67dfa2..56ae850226c 100644
--- a/src/librustc/infer/region_constraints/mod.rs
+++ b/src/librustc/infer/region_constraints/mod.rs
@@ -128,6 +128,16 @@ pub enum Constraint<'tcx> {
     RegSubReg(Region<'tcx>, Region<'tcx>),
 }
 
+impl Constraint<'_> {
+    pub fn involves_placeholders(&self) -> bool {
+        match self {
+            Constraint::VarSubVar(_, _) => false,
+            Constraint::VarSubReg(_, r) | Constraint::RegSubVar(r, _) => r.is_placeholder(),
+            Constraint::RegSubReg(r, s) => r.is_placeholder() || s.is_placeholder(),
+        }
+    }
+}
+
 /// VerifyGenericBound(T, _, R, RS): The parameter type `T` (or
 /// associated type) must outlive the region `R`. `T` is known to
 /// outlive `RS`. Therefore verify that `R <= RS[i]` for some
@@ -324,6 +334,8 @@ impl TaintDirections {
     }
 }
 
+pub struct ConstraintInfo {}
+
 impl<'tcx> RegionConstraintCollector<'tcx> {
     pub fn new() -> Self {
         Self::default()
@@ -485,7 +497,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
     ) -> RegionVid {
         let vid = self.var_infos.push(RegionVariableInfo { origin, universe });
 
-        let u_vid = self.unification_table
+        let u_vid = self
+            .unification_table
             .new_key(unify_key::RegionVidKey { min_vid: vid });
         assert_eq!(vid, u_vid);
         if self.in_snapshot() {
@@ -517,7 +530,8 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
 
         assert!(self.in_snapshot());
 
-        let constraints_to_kill: Vec<usize> = self.undo_log
+        let constraints_to_kill: Vec<usize> = self
+            .undo_log
             .iter()
             .enumerate()
             .rev()
@@ -820,17 +834,18 @@ impl<'tcx> RegionConstraintCollector<'tcx> {
             .filter_map(|&elt| match elt {
                 AddVar(vid) => Some(vid),
                 _ => None,
-            })
-            .collect()
+            }).collect()
     }
 
-    pub fn region_constraints_added_in_snapshot(&self, mark: &RegionSnapshot) -> bool {
+    /// See [`RegionInference::region_constraints_added_in_snapshot`]
+    pub fn region_constraints_added_in_snapshot(&self, mark: &RegionSnapshot) -> Option<bool> {
         self.undo_log[mark.length..]
             .iter()
-            .any(|&elt| match elt {
-                AddConstraint(_) => true,
-                _ => false,
-            })
+            .map(|&elt| match elt {
+                AddConstraint(constraint) => Some(constraint.involves_placeholders()),
+                _ => None,
+            }).max()
+            .unwrap_or(None)
     }
 }
 
diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs
index f5e96286d18..373ec2d5e49 100644
--- a/src/librustc/traits/select.rs
+++ b/src/librustc/traits/select.rs
@@ -639,10 +639,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
     ) -> Result<EvaluationResult, OverflowError> {
         self.infcx.probe(|snapshot| -> Result<EvaluationResult, OverflowError> {
             let result = op(self)?;
-            if !self.infcx.region_constraints_added_in_snapshot(snapshot) {
-                Ok(result)
-            } else {
-                Ok(result.max(EvaluatedToOkModuloRegions))
+            match self.infcx.region_constraints_added_in_snapshot(snapshot) {
+                None => Ok(result),
+                Some(_) => Ok(result.max(EvaluatedToOkModuloRegions)),
             }
         })
     }