Skip to content

Commit 07600c9

Browse files
committed
Drop "solved" constraints during region expansion
Once a region has been expanded to cover a fixed region, a corresponding RegSubVar constraint won't have any effect on the expansion anymore, the same is true for constraints where the variable on the RHS has already reached static scope. By removing those constraints from the set that we're iterating over, we remove a lot of needless overhead in case of slow convergences (i.e. lots of iterations). For the unicode_normalization crate, this about cuts the time required for item_bodies checking in half.
1 parent 664c779 commit 07600c9

File tree

1 file changed

+16
-8
lines changed
  • src/librustc/infer/lexical_region_resolve

1 file changed

+16
-8
lines changed

Diff for: src/librustc/infer/lexical_region_resolve/mod.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use rustc_data_structures::graph::implementation::{
1313
Direction, Graph, NodeIndex, INCOMING, OUTGOING,
1414
};
1515
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
16+
use smallvec::SmallVec;
1617
use std::fmt;
1718
use std::u32;
1819
use ty::fold::TypeFoldable;
@@ -190,19 +191,24 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
190191
match *constraint {
191192
Constraint::RegSubVar(a_region, b_vid) => {
192193
let b_data = var_values.value_mut(b_vid);
193-
self.expand_node(a_region, b_vid, b_data)
194+
(self.expand_node(a_region, b_vid, b_data), false)
194195
}
195196
Constraint::VarSubVar(a_vid, b_vid) => match *var_values.value(a_vid) {
196-
VarValue::ErrorValue => false,
197+
VarValue::ErrorValue => (false, false),
197198
VarValue::Value(a_region) => {
198199
let b_node = var_values.value_mut(b_vid);
199-
self.expand_node(a_region, b_vid, b_node)
200+
let changed = self.expand_node(a_region, b_vid, b_node);
201+
let retain = match *b_node {
202+
VarValue::Value(ReStatic) | VarValue::ErrorValue => false,
203+
_ => true
204+
};
205+
(changed, retain)
200206
}
201207
},
202208
Constraint::RegSubReg(..) | Constraint::VarSubReg(..) => {
203209
// These constraints are checked after expansion
204210
// is done, in `collect_errors`.
205-
false
211+
(false, false)
206212
}
207213
}
208214
})
@@ -710,21 +716,23 @@ impl<'cx, 'gcx, 'tcx> LexicalResolver<'cx, 'gcx, 'tcx> {
710716

711717
fn iterate_until_fixed_point<F>(&self, tag: &str, mut body: F)
712718
where
713-
F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> bool,
719+
F: FnMut(&Constraint<'tcx>, &SubregionOrigin<'tcx>) -> (bool, bool),
714720
{
721+
let mut constraints: SmallVec<[_; 16]> = self.data.constraints.iter().collect();
715722
let mut iteration = 0;
716723
let mut changed = true;
717724
while changed {
718725
changed = false;
719726
iteration += 1;
720727
debug!("---- {} Iteration {}{}", "#", tag, iteration);
721-
for (constraint, origin) in &self.data.constraints {
722-
let edge_changed = body(constraint, origin);
728+
constraints.retain(|(constraint, origin)| {
729+
let (edge_changed, retain) = body(constraint, origin);
723730
if edge_changed {
724731
debug!("Updated due to constraint {:?}", constraint);
725732
changed = true;
726733
}
727-
}
734+
retain
735+
});
728736
}
729737
debug!("---- {} Complete after {} iteration(s)", tag, iteration);
730738
}

0 commit comments

Comments
 (0)