Skip to content

Commit 5ed7b90

Browse files
committed
Hash borrows in scope for better performance
1 parent 1558ae7 commit 5ed7b90

16 files changed

+79
-79
lines changed

src/librustc_mir/borrow_check/flows.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ use dataflow::Borrows;
2727
use dataflow::{EverInitializedPlaces, MovingOutStatements};
2828
use dataflow::{FlowAtLocation, FlowsAtLocation};
2929
use dataflow::MaybeUninitializedPlaces;
30-
use either::Either;
3130
use std::fmt;
3231
use std::rc::Rc;
3332

@@ -62,11 +61,12 @@ impl<'b, 'gcx, 'tcx> Flows<'b, 'gcx, 'tcx> {
6261
crate fn borrows_in_scope(
6362
&self,
6463
location: LocationIndex,
65-
) -> impl Iterator<Item = BorrowIndex> + '_ {
64+
borrow_index: BorrowIndex,
65+
) -> bool {// impl Iterator<Item = BorrowIndex> + '_ {
6666
if let Some(ref polonius) = self.polonius_output {
67-
Either::Left(polonius.errors_at(location).iter().cloned())
67+
polonius.errors_at(location).contains(&borrow_index)
6868
} else {
69-
Either::Right(self.borrows.iter_incoming())
69+
self.borrows.contains(&borrow_index)
7070
}
7171
}
7272

src/librustc_mir/borrow_check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1137,7 +1137,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
11371137
context,
11381138
(sd, place_span.0),
11391139
&borrow_set,
1140-
flow_state.borrows_in_scope(location),
1140+
|i| flow_state.borrows_in_scope(location, i),
11411141
|this, borrow_index, borrow| match (rw, borrow.kind) {
11421142
// Obviously an activation is compatible with its own
11431143
// reservation (or even prior activating uses of same

src/librustc_mir/borrow_check/nll/invalidation.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -495,15 +495,15 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cg, 'cx, 'tcx, 'gcx> {
495495
let tcx = self.infcx.tcx;
496496
let mir = self.mir;
497497
let borrow_set = self.borrow_set.clone();
498-
let indices = self.borrow_set.borrows.indices();
498+
//let indices = self.borrow_set.borrows.indices();
499499
each_borrow_involving_path(
500500
self,
501501
tcx,
502502
mir,
503503
context,
504504
(sd, place),
505505
&borrow_set.clone(),
506-
indices,
506+
|_| true,
507507
|this, borrow_index, borrow| {
508508
match (rw, borrow.kind) {
509509
// Obviously an activation is compatible with its own

src/librustc_mir/borrow_check/path_utils.rs

+22-17
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ use rustc::mir::{ProjectionElem, BorrowKind};
1818
use rustc::ty::TyCtxt;
1919
use rustc_data_structures::graph::dominators::Dominators;
2020

21+
use super::place_ext::PlaceExt;
22+
2123
/// Returns true if the borrow represented by `kind` is
2224
/// allowed to be split into separate Reservation and
2325
/// Activation phases.
@@ -38,37 +40,40 @@ pub(super) enum Control {
3840
}
3941

4042
/// Encapsulates the idea of iterating over every borrow that involves a particular path
41-
pub(super) fn each_borrow_involving_path<'a, 'tcx, 'gcx: 'tcx, F, I, S> (
43+
pub(super) fn each_borrow_involving_path<'a, 'tcx, 'gcx: 'tcx, S> (
4244
s: &mut S,
4345
tcx: TyCtxt<'a, 'gcx, 'tcx>,
4446
mir: &Mir<'tcx>,
4547
_context: Context,
4648
access_place: (ShallowOrDeep, &Place<'tcx>),
4749
borrow_set: &BorrowSet<'tcx>,
48-
candidates: I,
49-
mut op: F,
50-
) where
51-
F: FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> Control,
52-
I: Iterator<Item=BorrowIndex>
53-
{
50+
is_borrow_in_scope: impl Fn(BorrowIndex) -> bool,
51+
mut op: impl FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> Control,
52+
) {
5453
let (access, place) = access_place;
5554

5655
// FIXME: analogous code in check_loans first maps `place` to
5756
// its base_path.
5857

5958
// check for loan restricting path P being used. Accounts for
6059
// borrows of P, P.a.b, etc.
61-
for i in candidates {
62-
let borrowed = &borrow_set[i];
60+
if let Some(ref local) = place.root_local() {
61+
if let Some(borrow_indices) = borrow_set.local_map.get(local) {
62+
for i in borrow_indices.iter() {
63+
let borrowed = &borrow_set[*i];
6364

64-
if places_conflict::places_conflict(tcx, mir, &borrowed.borrowed_place, place, access) {
65-
debug!(
66-
"each_borrow_involving_path: {:?} @ {:?} vs. {:?}/{:?}",
67-
i, borrowed, place, access
68-
);
69-
let ctrl = op(s, i, borrowed);
70-
if ctrl == Control::Break {
71-
return;
65+
if is_borrow_in_scope(*i) &&
66+
places_conflict::places_conflict(
67+
tcx, mir, &borrowed.borrowed_place, place, access) {
68+
debug!(
69+
"each_borrow_involving_path: {:?} @ {:?} vs. {:?}/{:?}",
70+
i, borrowed, place, access
71+
);
72+
let ctrl = op(s, *i, borrowed);
73+
if ctrl == Control::Break {
74+
return;
75+
}
76+
}
7277
}
7378
}
7479
}

src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.ast.nll.stderr

+10-11
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,29 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
22
--> $DIR/borrowck-mut-borrow-linear-errors.rs:23:30
33
|
44
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
5-
| ---- ^^^^^^ second mutable borrow occurs here
6-
| |
7-
| borrow used here in later iteration of loop
8-
...
9-
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
10-
| ------ first mutable borrow occurs here
5+
| ^^^^^^ mutable borrow starts here in previous iteration of loop
116

127
error[E0499]: cannot borrow `x` as mutable more than once at a time
138
--> $DIR/borrowck-mut-borrow-linear-errors.rs:25:30
149
|
1510
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
16-
| ---- borrow used here in later iteration of loop
11+
| ---- ------ first mutable borrow occurs here
12+
| |
13+
| borrow used here in later iteration of loop
1714
LL | //[mir]~^ ERROR [E0499]
1815
LL | 2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
1916
| ^^^^^^ second mutable borrow occurs here
20-
LL | //[mir]~^ ERROR [E0499]
21-
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
22-
| ------ first mutable borrow occurs here
2317

2418
error[E0499]: cannot borrow `x` as mutable more than once at a time
2519
--> $DIR/borrowck-mut-borrow-linear-errors.rs:27:30
2620
|
21+
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
22+
| ---- ------ first mutable borrow occurs here
23+
| |
24+
| borrow used here in later iteration of loop
25+
...
2726
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
28-
| ^^^^^^ mutable borrow starts here in previous iteration of loop
27+
| ^^^^^^ second mutable borrow occurs here
2928

3029
error: aborting due to 3 previous errors
3130

src/test/ui/borrowck/borrowck-mut-borrow-linear-errors.mir.stderr

+10-11
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,29 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time
22
--> $DIR/borrowck-mut-borrow-linear-errors.rs:23:30
33
|
44
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
5-
| ---- ^^^^^^ second mutable borrow occurs here
6-
| |
7-
| borrow used here in later iteration of loop
8-
...
9-
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
10-
| ------ first mutable borrow occurs here
5+
| ^^^^^^ mutable borrow starts here in previous iteration of loop
116

127
error[E0499]: cannot borrow `x` as mutable more than once at a time
138
--> $DIR/borrowck-mut-borrow-linear-errors.rs:25:30
149
|
1510
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
16-
| ---- borrow used here in later iteration of loop
11+
| ---- ------ first mutable borrow occurs here
12+
| |
13+
| borrow used here in later iteration of loop
1714
LL | //[mir]~^ ERROR [E0499]
1815
LL | 2 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
1916
| ^^^^^^ second mutable borrow occurs here
20-
LL | //[mir]~^ ERROR [E0499]
21-
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
22-
| ------ first mutable borrow occurs here
2317

2418
error[E0499]: cannot borrow `x` as mutable more than once at a time
2519
--> $DIR/borrowck-mut-borrow-linear-errors.rs:27:30
2620
|
21+
LL | 1 => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
22+
| ---- ------ first mutable borrow occurs here
23+
| |
24+
| borrow used here in later iteration of loop
25+
...
2726
LL | _ => { addr.push(&mut x); } //[ast]~ ERROR [E0499]
28-
| ^^^^^^ mutable borrow starts here in previous iteration of loop
27+
| ^^^^^^ second mutable borrow occurs here
2928

3029
error: aborting due to 3 previous errors
3130

src/test/ui/borrowck/borrowck-slice-pattern-element-loan.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -77,12 +77,12 @@ error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as im
7777
--> $DIR/borrowck-slice-pattern-element-loan.rs:75:21
7878
|
7979
LL | if let [ref from_begin0, ref from_begin1, _, ref from_begin3, _, ..] = *s {
80-
| --------------- immutable borrow occurs here
80+
| --------------- immutable borrow occurs here
8181
...
8282
LL | if let [.., ref mut from_end4, _, _, _] = *s { //~ERROR
8383
| ^^^^^^^^^^^^^^^^^ mutable borrow occurs here
8484
LL | nop(&[from_begin0, from_begin1, from_begin3, from_end4]);
85-
| ----------- borrow later used here
85+
| ----------- borrow later used here
8686

8787
error[E0502]: cannot borrow `s[..]` as mutable because it is also borrowed as immutable
8888
--> $DIR/borrowck-slice-pattern-element-loan.rs:92:20

src/test/ui/coercion/coerce-overloaded-autoderef.ast.nll.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ LL | drop((y, z));
1212
error[E0506]: cannot assign to `**x` because it is borrowed
1313
--> $DIR/coerce-overloaded-autoderef.rs:31:5
1414
|
15-
LL | let y = borrow(x);
16-
| - borrow of `**x` occurs here
1715
LL | let z = borrow(x);
16+
| - borrow of `**x` occurs here
1817
LL | **x += 1;
1918
| ^^^^^^^^ assignment to borrowed `**x` occurs here
2019
...
2120
LL | drop((y, z));
22-
| - borrow later used here
21+
| - borrow later used here
2322

2423
error[E0499]: cannot borrow `*x` as mutable more than once at a time
2524
--> $DIR/coerce-overloaded-autoderef.rs:38:20

src/test/ui/coercion/coerce-overloaded-autoderef.mir.nll.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ LL | drop((y, z));
1212
error[E0506]: cannot assign to `**x` because it is borrowed
1313
--> $DIR/coerce-overloaded-autoderef.rs:31:5
1414
|
15-
LL | let y = borrow(x);
16-
| - borrow of `**x` occurs here
1715
LL | let z = borrow(x);
16+
| - borrow of `**x` occurs here
1817
LL | **x += 1;
1918
| ^^^^^^^^ assignment to borrowed `**x` occurs here
2019
...
2120
LL | drop((y, z));
22-
| - borrow later used here
21+
| - borrow later used here
2322

2423
error[E0499]: cannot borrow `*x` as mutable more than once at a time
2524
--> $DIR/coerce-overloaded-autoderef.rs:38:20

src/test/ui/coercion/coerce-overloaded-autoderef.mir.stderr

+2-3
Original file line numberDiff line numberDiff line change
@@ -12,14 +12,13 @@ LL | drop((y, z));
1212
error[E0506]: cannot assign to `**x` because it is borrowed
1313
--> $DIR/coerce-overloaded-autoderef.rs:31:5
1414
|
15-
LL | let y = borrow(x);
16-
| - borrow of `**x` occurs here
1715
LL | let z = borrow(x);
16+
| - borrow of `**x` occurs here
1817
LL | **x += 1;
1918
| ^^^^^^^^ assignment to borrowed `**x` occurs here
2019
...
2120
LL | drop((y, z));
22-
| - borrow later used here
21+
| - borrow later used here
2322

2423
error[E0499]: cannot borrow `*x` as mutable more than once at a time
2524
--> $DIR/coerce-overloaded-autoderef.rs:38:20

src/test/ui/dropck/dropck-eyepatch-extern-crate.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0597]: `c_shortest` does not live long enough
2-
--> $DIR/dropck-eyepatch-extern-crate.rs:47:19
2+
--> $DIR/dropck-eyepatch-extern-crate.rs:59:28
33
|
4-
LL | dt = Dt("dt", &c_shortest);
5-
| ^^^^^^^^^^^ borrowed value does not live long enough
4+
LL | pr = Pr("pr", &c_long, &c_shortest);
5+
| ^^^^^^^^^^^ borrowed value does not live long enough
66
...
77
LL | }
88
| -
99
| |
1010
| `c_shortest` dropped here while still borrowed
11-
| borrow later used here, when `dt` is dropped
11+
| borrow later used here, when `pr` is dropped
1212
|
1313
= note: values in a scope are dropped in the opposite order they are defined
1414

src/test/ui/dropck/dropck-eyepatch-reorder.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0597]: `c_shortest` does not live long enough
2-
--> $DIR/dropck-eyepatch-reorder.rs:64:19
2+
--> $DIR/dropck-eyepatch-reorder.rs:76:28
33
|
4-
LL | dt = Dt("dt", &c_shortest);
5-
| ^^^^^^^^^^^ borrowed value does not live long enough
4+
LL | pr = Pr("pr", &c_long, &c_shortest);
5+
| ^^^^^^^^^^^ borrowed value does not live long enough
66
...
77
LL | }
88
| -
99
| |
1010
| `c_shortest` dropped here while still borrowed
11-
| borrow later used here, when `dt` is dropped
11+
| borrow later used here, when `pr` is dropped
1212
|
1313
= note: values in a scope are dropped in the opposite order they are defined
1414

src/test/ui/dropck/dropck-eyepatch.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
error[E0597]: `c_shortest` does not live long enough
2-
--> $DIR/dropck-eyepatch.rs:87:19
2+
--> $DIR/dropck-eyepatch.rs:100:28
33
|
4-
LL | dt = Dt("dt", &c_shortest);
5-
| ^^^^^^^^^^^ borrowed value does not live long enough
4+
LL | pr = Pr("pr", &c_long, &c_shortest);
5+
| ^^^^^^^^^^^ borrowed value does not live long enough
66
...
77
LL | }
88
| -
99
| |
1010
| `c_shortest` dropped here while still borrowed
11-
| borrow later used here, when `dt` is dropped
11+
| borrow later used here, when `pr` is dropped
1212
|
1313
= note: values in a scope are dropped in the opposite order they are defined
1414

src/test/ui/span/dropck_arr_cycle_checked.nll.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ LL | }
1111
| borrow later used here, when `b1` is dropped
1212

1313
error[E0597]: `b3` does not live long enough
14-
--> $DIR/dropck_arr_cycle_checked.rs:105:24
14+
--> $DIR/dropck_arr_cycle_checked.rs:109:24
1515
|
16-
LL | b1.a[1].v.set(Some(&b3));
16+
LL | b2.a[1].v.set(Some(&b3));
1717
| ^^^ borrowed value does not live long enough
1818
...
1919
LL | }
2020
| -
2121
| |
2222
| `b3` dropped here while still borrowed
23-
| borrow later used here, when `b1` is dropped
23+
| borrow later used here, when `b2` is dropped
2424

2525
error[E0597]: `b1` does not live long enough
2626
--> $DIR/dropck_arr_cycle_checked.rs:111:24

src/test/ui/span/dropck_vec_cycle_checked.nll.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,16 @@ LL | }
1111
| borrow later used here, when `c1` is dropped
1212

1313
error[E0597]: `c3` does not live long enough
14-
--> $DIR/dropck_vec_cycle_checked.rs:115:24
14+
--> $DIR/dropck_vec_cycle_checked.rs:119:24
1515
|
16-
LL | c1.v[1].v.set(Some(&c3));
16+
LL | c2.v[1].v.set(Some(&c3));
1717
| ^^^ borrowed value does not live long enough
1818
...
1919
LL | }
2020
| -
2121
| |
2222
| `c3` dropped here while still borrowed
23-
| borrow later used here, when `c1` is dropped
23+
| borrow later used here, when `c2` is dropped
2424

2525
error[E0597]: `c1` does not live long enough
2626
--> $DIR/dropck_vec_cycle_checked.rs:121:24

src/test/ui/span/issue-25199.nll.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
error[E0597]: `container` does not live long enough
2-
--> $DIR/issue-25199.rs:80:27
2+
--> $DIR/issue-25199.rs:83:5
33
|
4-
LL | let test = Test{test: &container};
5-
| ^^^^^^^^^^ borrowed value does not live long enough
6-
...
4+
LL | container.store(test);
5+
| ^^^^^^^^^ borrowed value does not live long enough
6+
LL | //~^ ERROR `container` does not live long enough
77
LL | }
88
| -
99
| |

0 commit comments

Comments
 (0)