From 2c17af0bf79276cda6d97c19a78f21edcee22d19 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Tue, 20 Nov 2018 10:24:38 -0500 Subject: [PATCH] track if any region constraints involved placeholders --- src/librustc/infer/mod.rs | 7 ++++- src/librustc/infer/region_constraints/mod.rs | 33 ++++++++++++++------ src/librustc/traits/select.rs | 7 ++--- 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 @@ pub fn probe(&self, f: F) -> R 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 { 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 @@ pub fn both() -> Self { } } +pub struct ConstraintInfo {} + impl<'tcx> RegionConstraintCollector<'tcx> { pub fn new() -> Self { Self::default() @@ -485,7 +497,8 @@ pub fn new_region_var( ) -> 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 @@ pub fn pop_placeholders(&mut self, placeholders: &FxHashSet>) { assert!(self.in_snapshot()); - let constraints_to_kill: Vec = self.undo_log + let constraints_to_kill: Vec = self + .undo_log .iter() .enumerate() .rev() @@ -820,17 +834,18 @@ pub fn vars_created_since_snapshot(&self, mark: &RegionSnapshot) -> Vec 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 { 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 @@ fn evaluation_probe( ) -> Result { self.infcx.probe(|snapshot| -> Result { 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)), } }) } -- GitLab