Skip to content

Commit c30cab8

Browse files
committed
Auto merge of #64801 - nnethercote:improve-find_constraint_paths_between_regions, r=<try>
Avoid `chain()` in `find_constraint_paths_between_regions()`. This iterator can be hot, and chained iterators are slow. The second half of the chain is almost always empty, so this commit specializes the code to avoid the chained iteration. This change reduces instruction counts for the `wg-grammar` benchmark by up to 1.5%.
2 parents a5bc0f0 + 60fa535 commit c30cab8

File tree

1 file changed

+33
-21
lines changed
  • src/librustc_mir/borrow_check/nll/region_infer/error_reporting

1 file changed

+33
-21
lines changed

src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs

+33-21
Original file line numberDiff line numberDiff line change
@@ -253,28 +253,40 @@ impl<'tcx> RegionInferenceContext<'tcx> {
253253
let outgoing_edges_from_graph = self.constraint_graph
254254
.outgoing_edges(r, &self.constraints, fr_static);
255255

256-
257-
// But member constraints can also give rise to `'r: 'x`
258-
// edges that were not part of the graph initially, so
259-
// watch out for those.
260-
let outgoing_edges_from_picks = self.applied_member_constraints(r)
261-
.iter()
262-
.map(|&AppliedMemberConstraint { min_choice, member_constraint_index, .. }| {
263-
let p_c = &self.member_constraints[member_constraint_index];
264-
OutlivesConstraint {
265-
sup: r,
266-
sub: min_choice,
267-
locations: Locations::All(p_c.definition_span),
268-
category: ConstraintCategory::OpaqueType,
256+
macro_rules! handle_constraint {
257+
($constraint:ident) => {
258+
debug_assert_eq!($constraint.sup, r);
259+
let sub_region = $constraint.sub;
260+
if let Trace::NotVisited = context[sub_region] {
261+
context[sub_region] = Trace::FromOutlivesConstraint($constraint);
262+
deque.push_back(sub_region);
269263
}
270-
});
271-
272-
for constraint in outgoing_edges_from_graph.chain(outgoing_edges_from_picks) {
273-
debug_assert_eq!(constraint.sup, r);
274-
let sub_region = constraint.sub;
275-
if let Trace::NotVisited = context[sub_region] {
276-
context[sub_region] = Trace::FromOutlivesConstraint(constraint);
277-
deque.push_back(sub_region);
264+
}
265+
}
266+
267+
for constraint in outgoing_edges_from_graph {
268+
handle_constraint!(constraint);
269+
}
270+
271+
// But member constraints can also give rise to `'r: 'x` edges that
272+
// were not part of the graph initially, so watch out for those.
273+
// (But they are extremely rare.)
274+
let applied_member_constraints = self.applied_member_constraints(r);
275+
if !applied_member_constraints.is_empty() {
276+
let outgoing_edges_from_picks = self.applied_member_constraints(r)
277+
.iter()
278+
.map(|&AppliedMemberConstraint { min_choice, member_constraint_index, .. }| {
279+
let p_c = &self.member_constraints[member_constraint_index];
280+
OutlivesConstraint {
281+
sup: r,
282+
sub: min_choice,
283+
locations: Locations::All(p_c.definition_span),
284+
category: ConstraintCategory::OpaqueType,
285+
}
286+
});
287+
288+
for constraint in outgoing_edges_from_picks {
289+
handle_constraint!(constraint);
278290
}
279291
}
280292
}

0 commit comments

Comments
 (0)