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;
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)
}
}
})
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);
}