Skip to content

Commit 9f7d0e9

Browse files
committed
use Vec for region constraints
1 parent 604f185 commit 9f7d0e9

File tree

9 files changed

+50
-33
lines changed

9 files changed

+50
-33
lines changed

Diff for: compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs

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

140+
// Deduplicating constraints is shown to have a positive perf impact.
141+
self.data.constraints.sort_by_key(|(constraint, _)| *constraint);
142+
self.data.constraints.dedup_by_key(|(constraint, _)| *constraint);
143+
140144
if cfg!(debug_assertions) {
141145
self.dump_constraints();
142146
}
@@ -183,7 +187,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
183187
let mut constraints = IndexVec::from_elem(Vec::new(), &var_values.values);
184188
// Tracks the changed region vids.
185189
let mut changes = Vec::new();
186-
for constraint in self.data.constraints.keys() {
190+
for (constraint, _) in &self.data.constraints {
187191
match *constraint {
188192
Constraint::RegSubVar(a_region, b_vid) => {
189193
let b_data = var_values.value_mut(b_vid);
@@ -678,7 +682,7 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
678682
let dummy_source = graph.add_node(());
679683
let dummy_sink = graph.add_node(());
680684

681-
for constraint in self.data.constraints.keys() {
685+
for (constraint, _) in &self.data.constraints {
682686
match *constraint {
683687
Constraint::VarSubVar(a_id, b_id) => {
684688
graph.add_edge(NodeIndex(a_id.index()), NodeIndex(b_id.index()), *constraint);
@@ -885,9 +889,11 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
885889
}
886890

887891
Constraint::RegSubVar(region, _) | Constraint::VarSubReg(_, region) => {
892+
let constraint_idx =
893+
this.constraints.binary_search_by(|(c, _)| c.cmp(&edge.data)).unwrap();
888894
state.result.push(RegionAndOrigin {
889895
region,
890-
origin: this.constraints.get(&edge.data).unwrap().clone(),
896+
origin: this.constraints[constraint_idx].1.clone(),
891897
});
892898
}
893899

Diff for: 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

Diff for: 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>) {

Diff for: 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
{

Diff for: 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
{

Diff for: 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

Diff for: tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ where
4141
// isize>`, we require `T : for<'a> Bar<&'a isize>`, but the where
4242
// clause only specifies `T : Bar<&'b isize>`.
4343
foo_hrtb_bar_not(&mut t);
44-
//~^ ERROR implementation of `Bar` is not general enough
44+
//~^ ERROR mismatched types
4545
//~^^ ERROR lifetime may not live long enough
4646
}
4747

Diff for: tests/ui/higher-ranked/trait-bounds/hrtb-perfect-forwarding.stderr

+10-4
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,19 @@ note: due to current limitations in the borrow checker, this implies a `'static`
5353
LL | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
5454
| ^^^^^^^^^^^^^^^^^^^^^^
5555

56-
error: implementation of `Bar` is not general enough
56+
error[E0308]: mismatched types
5757
--> $DIR/hrtb-perfect-forwarding.rs:43:5
5858
|
5959
LL | foo_hrtb_bar_not(&mut t);
60-
| ^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Bar` is not general enough
60+
| ^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
6161
|
62-
= note: `T` must implement `Bar<&'0 isize>`, for any lifetime `'0`...
63-
= note: ...but it actually implements `Bar<&'1 isize>`, for some specific lifetime `'1`
62+
= note: expected trait `for<'a> <T as Foo<&'a isize>>`
63+
found trait `for<'a> <T as Foo<&'a isize>>`
64+
note: the lifetime requirement is introduced here
65+
--> $DIR/hrtb-perfect-forwarding.rs:37:8
66+
|
67+
LL | T: for<'a> Foo<&'a isize> + Bar<&'b isize>,
68+
| ^^^^^^^^^^^^^^^^^^^^^^
6469

6570
warning: function cannot return without recursing
6671
--> $DIR/hrtb-perfect-forwarding.rs:48:1
@@ -77,3 +82,4 @@ LL | foo_hrtb_bar_hrtb(&mut t);
7782

7883
error: aborting due to 2 previous errors; 4 warnings emitted
7984

85+
For more information about this error, try `rustc --explain E0308`.

Diff for: tests/ui/lifetimes/issue-79187-2.stderr

+14-4
Original file line numberDiff line numberDiff line change
@@ -54,8 +54,13 @@ error[E0308]: mismatched types
5454
LL | take_foo(|a: &i32| a);
5555
| ^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
5656
|
57-
= note: expected reference `&_`
58-
found reference `&_`
57+
= note: expected trait `for<'a> <{closure@$DIR/issue-79187-2.rs:11:14: 11:23} as FnOnce<(&'a i32,)>>`
58+
found trait `for<'a> <{closure@$DIR/issue-79187-2.rs:11:14: 11:23} as FnOnce<(&'a i32,)>>`
59+
note: this closure does not fulfill the lifetime requirements
60+
--> $DIR/issue-79187-2.rs:11:14
61+
|
62+
LL | take_foo(|a: &i32| a);
63+
| ^^^^^^^^^
5964
note: the lifetime requirement is introduced here
6065
--> $DIR/issue-79187-2.rs:5:21
6166
|
@@ -68,8 +73,13 @@ error[E0308]: mismatched types
6873
LL | take_foo(|a: &i32| -> &i32 { a });
6974
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
7075
|
71-
= note: expected reference `&_`
72-
found reference `&_`
76+
= note: expected trait `for<'a> <{closure@$DIR/issue-79187-2.rs:14:14: 14:31} as FnOnce<(&'a i32,)>>`
77+
found trait `for<'a> <{closure@$DIR/issue-79187-2.rs:14:14: 14:31} as FnOnce<(&'a i32,)>>`
78+
note: this closure does not fulfill the lifetime requirements
79+
--> $DIR/issue-79187-2.rs:14:14
80+
|
81+
LL | take_foo(|a: &i32| -> &i32 { a });
82+
| ^^^^^^^^^^^^^^^^^
7383
note: the lifetime requirement is introduced here
7484
--> $DIR/issue-79187-2.rs:5:21
7585
|

0 commit comments

Comments
 (0)