]> git.lizzy.rs Git - rust.git/blobdiff - src/librustc/infer/lexical_region_resolve/mod.rs
Drop "solved" constraints during region expansion
[rust.git] / src / librustc / infer / lexical_region_resolve / mod.rs
index dbf8f270ab0c988fb88e6ebb7c4ffddbbd90ad3b..2a93217b9b423b3efb74eccae15c2e99c785669d 100644 (file)
@@ -13,6 +13,7 @@
     Direction, Graph, NodeIndex, INCOMING, OUTGOING,
 };
 use rustc_data_structures::indexed_vec::{Idx, IndexVec};
+use smallvec::SmallVec;
 use std::fmt;
 use std::u32;
 use ty::fold::TypeFoldable;
@@ -190,19 +191,24 @@ fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
             match *constraint {
                 Constraint::RegSubVar(a_region, b_vid) => {
                     let b_data = var_values.value_mut(b_vid);
-                    self.expand_node(a_region, b_vid, b_data)
+                    (self.expand_node(a_region, b_vid, b_data), false)
                 }
                 Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
-                    VarValue::ErrorValue => false,
+                    VarValue::ErrorValue => (false, false),
                     VarValue::Value(a_region) => {
                         let b_node = var_values.value_mut(b_vid);
-                        self.expand_node(a_region, b_vid, b_node)
+                        let changed = self.expand_node(a_region, b_vid, b_node);
+                        let retain = match *b_node {
+                            VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
+                            _ => true
+                        };
+                        (changed, retain)
                     }
                 },
                 Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
                     // These constraints are checked after expansion
                     // is done, in `collect_errors`.
-                    false
+                    (false, false)
                 }
             }
         })
@@ -710,21 +716,23 @@ fn process_edges<'tcx>(
 
     fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
     where
-        F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> bool,
+        F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> (bool, bool),
     {
+        let mut constraints: SmallVec<[_; 16]> = self.data.constraints.iter().collect();
         let mut iteration = 0;
         let mut changed = true;
         while changed {
             changed = false;
             iteration += 1;
             debug!("---- {} Iteration {}{}", "#", tag, iteration);
-            for (constraint, origin) in &self.data.constraints {
-                let edge_changed = body(constraint, origin);
+            constraints.retain(|(constraint, origin)| {
+                let (edge_changed, retain) = body(constraint, origin);
                 if edge_changed {
                     debug!("Updated due to constraint {:?}", constraint);
                     changed = true;
                 }
-            }
+                retain
+            });
         }
         debug!("---- {} Complete after {} iteration(s)", tag, iteration);
     }