Skip to content

Commit d6d7a93

Browse files
committed
Auto merge of rust-lang#118824 - aliemjay:perf-region-cons, r=compiler-errors
use Vec for region constraints instead of BTreeMap ~1% perf gain Diagnostic regressions need more investigation. r? `@ghost`
2 parents 398fd92 + 8c215e7 commit d6d7a93

File tree

7 files changed

+37
-31
lines changed

7 files changed

+37
-31
lines changed

compiler/rustc_borrowck/src/diagnostics/bound_region_errors.rs

+12-7
Original file line numberDiff line numberDiff line change
@@ -408,30 +408,35 @@ fn try_extract_error_from_region_constraints<'tcx>(
408408
mut region_var_origin: impl FnMut(RegionVid) -> RegionVariableOrigin,
409409
mut universe_of_region: impl FnMut(RegionVid) -> UniverseIndex,
410410
) -> Option<DiagnosticBuilder<'tcx, ErrorGuaranteed>> {
411+
let placeholder_universe = match placeholder_region.kind() {
412+
ty::RePlaceholder(p) => p.universe,
413+
ty::ReVar(vid) => universe_of_region(vid),
414+
_ => ty::UniverseIndex::ROOT,
415+
};
411416
let matches =
412417
|a_region: Region<'tcx>, b_region: Region<'tcx>| match (a_region.kind(), b_region.kind()) {
413418
(RePlaceholder(a_p), RePlaceholder(b_p)) => a_p.bound == b_p.bound,
414419
_ => a_region == b_region,
415420
};
416-
let check = |constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| {
417-
match *constraint {
421+
let mut check =
422+
|constraint: &Constraint<'tcx>, cause: &SubregionOrigin<'tcx>, exact| match *constraint {
418423
Constraint::RegSubReg(sub, sup)
419424
if ((exact && sup == placeholder_region)
420425
|| (!exact && matches(sup, placeholder_region)))
421426
&& sup != sub =>
422427
{
423428
Some((sub, cause.clone()))
424429
}
425-
// FIXME: Should this check the universe of the var?
426430
Constraint::VarSubReg(vid, sup)
427-
if ((exact && sup == placeholder_region)
428-
|| (!exact && matches(sup, placeholder_region))) =>
431+
if (exact
432+
&& sup == placeholder_region
433+
&& !universe_of_region(vid).can_name(placeholder_universe))
434+
|| (!exact && matches(sup, placeholder_region)) =>
429435
{
430436
Some((ty::Region::new_var(infcx.tcx, vid), cause.clone()))
431437
}
432438
_ => None,
433-
}
434-
};
439+
};
435440
let mut info = region_constraints
436441
.constraints
437442
.iter()

compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

+9-3
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,10 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
135135
) -> LexicalRegionResolutions<'tcx> {
136136
let mut var_data = self.construct_var_data();
137137

138+
// Deduplicating constraints is shown to have a positive perf impact.
139+
self.data.constraints.sort_by_key(|(constraint, _)| *constraint);
140+
self.data.constraints.dedup_by_key(|(constraint, _)| *constraint);
141+
138142
if cfg!(debug_assertions) {
139143
self.dump_constraints();
140144
}
@@ -181,7 +185,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
181185
let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
182186
// Tracks the changed region vids.
183187
let mut changes = Vec::new();
184-
for constraint in self.data.constraints.keys() {
188+
for (constraint, _) in &self.data.constraints {
185189
match *constraint {
186190
Constraint::RegSubVar(a_region, b_vid) => {
187191
let b_data = var_values.value_mut(b_vid);
@@ -676,7 +680,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
676680
let dummy_source = graph.add_node(());
677681
let dummy_sink = graph.add_node(());
678682

679-
for constraint in self.data.constraints.keys() {
683+
for (constraint, _) in &self.data.constraints {
680684
match *constraint {
681685
Constraint::VarSubVar(a_id, b_id) => {
682686
graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
@@ -883,9 +887,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
883887
}
884888

885889
Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
890+
let constraint_idx =
891+
this.constraints.binary_search_by(|(c, _)| c.cmp(&edge.data)).unwrap();
886892
state.result.push(RegionAndOrigin {
887893
region,
888-
origin: this.constraints.get(&edge.data).unwrap().clone(),
894+
origin: this.constraints[constraint_idx].1.clone(),
889895
});
890896
}
891897

compiler/rustc_infer/src/infer/region_constraints/leak_check.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -416,8 +416,8 @@ impl<'tcx> MiniGraph<'tcx> {
416416
region_constraints.undo_log.region_constraints_in_snapshot(&snapshot.undo_snapshot)
417417
{
418418
match undo_entry {
419-
AddConstraint(constraint) => {
420-
each_constraint(constraint);
419+
&AddConstraint(i) => {
420+
each_constraint(&region_constraints.data().constraints[i].0);
421421
}
422422
&AddVerify(i) => span_bug!(
423423
region_constraints.data().verifys[i].origin.span(),
@@ -430,8 +430,8 @@ impl<'tcx> MiniGraph<'tcx> {
430430
region_constraints
431431
.data()
432432
.constraints
433-
.keys()
434-
.for_each(|constraint| each_constraint(constraint));
433+
.iter()
434+
.for_each(|(constraint, _)| each_constraint(constraint));
435435
}
436436
}
437437

compiler/rustc_infer/src/infer/region_constraints/mod.rs

+8-13
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ use rustc_middle::ty::{ReBound, ReVar};
2020
use rustc_middle::ty::{Region, RegionVid};
2121
use rustc_span::Span;
2222

23-
use std::collections::BTreeMap;
2423
use std::ops::Range;
2524
use std::{cmp, fmt, mem};
2625

@@ -90,7 +89,7 @@ pub type VarInfos = IndexVec<RegionVid, RegionVariableInfo>;
9089
pub struct RegionConstraintData<'tcx> {
9190
/// Constraints of the form `A <= B`, where either `A` or `B` can
9291
/// be a region variable (or neither, as it happens).
93-
pub constraints: BTreeMap<Constraint<'tcx>, SubregionOrigin<'tcx>>,
92+
pub constraints: Vec<(Constraint<'tcx>, SubregionOrigin<'tcx>)>,
9493

9594
/// Constraints of the form `R0 member of [R1, ..., Rn]`, meaning that
9695
/// `R0` must be equal to one of the regions `R1..Rn`. These occur
@@ -273,7 +272,7 @@ pub(crate) enum UndoLog<'tcx> {
273272
AddVar(RegionVid),
274273

275274
/// We added the given `constraint`.
276-
AddConstraint(Constraint<'tcx>),
275+
AddConstraint(usize),
277276

278277
/// We added the given `verify`.
279278
AddVerify(usize),
@@ -319,8 +318,9 @@ impl<'tcx> RegionConstraintStorage<'tcx> {
319318
self.var_infos.pop().unwrap();
320319
assert_eq!(self.var_infos.len(), vid.index());
321320
}
322-
AddConstraint(ref constraint) => {
323-
self.data.constraints.remove(constraint);
321+
AddConstraint(index) => {
322+
self.data.constraints.pop().unwrap();
323+
assert_eq!(self.data.constraints.len(), index);
324324
}
325325
AddVerify(index) => {
326326
self.data.verifys.pop();
@@ -443,14 +443,9 @@ impl<'tcx> RegionConstraintCollector<'_, 'tcx> {
443443
// cannot add constraints once regions are resolved
444444
debug!("RegionConstraintCollector: add_constraint({:?})", constraint);
445445

446-
// never overwrite an existing (constraint, origin) - only insert one if it isn't
447-
// present in the map yet. This prevents origins from outside the snapshot being
448-
// replaced with "less informative" origins e.g., during calls to `can_eq`
449-
let undo_log = &mut self.undo_log;
450-
self.storage.data.constraints.entry(constraint).or_insert_with(|| {
451-
undo_log.push(AddConstraint(constraint));
452-
origin
453-
});
446+
let index = self.storage.data.constraints.len();
447+
self.storage.data.constraints.push((constraint, origin));
448+
self.undo_log.push(AddConstraint(index));
454449
}
455450

456451
fn add_verify(&mut self, verify: Verify<'tcx>) {

compiler/rustc_trait_selection/src/traits/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
477477
let mut vid_map: FxHashMap<RegionTarget<'cx>, RegionDeps<'cx>> = FxHashMap::default();
478478
let mut finished_map = FxHashMap::default();
479479

480-
for constraint in regions.constraints.keys() {
480+
for (constraint, _) in &regions.constraints {
481481
match constraint {
482482
&Constraint::VarSubVar(r1, r2) => {
483483
{

src/librustdoc/clean/auto_trait.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -195,7 +195,7 @@ where
195195
// into a map. Each RegionTarget (either a RegionVid or a Region) maps
196196
// to its smaller and larger regions. Note that 'larger' regions correspond
197197
// to sub-regions in Rust code (e.g., in 'a: 'b, 'a is the larger region).
198-
for constraint in regions.constraints.keys() {
198+
for (constraint, _) in &regions.constraints {
199199
match *constraint {
200200
Constraint::VarSubVar(r1, r2) => {
201201
{

tests/ui/higher-ranked/higher-ranked-lifetime-error.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ error[E0308]: mismatched types
44
LL | assert_all::<_, &String>(id);
55
| ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
66
|
7-
= note: expected reference `&String`
8-
found reference `&String`
7+
= note: expected trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
8+
found trait `for<'a> <for<'a> fn(&'a String) -> &'a String {id} as FnMut<(&'a String,)>>`
99

1010
error: aborting due to 1 previous error
1111

0 commit comments

Comments
 (0)