Skip to content
/ rust Public
forked from rust-lang/rust

Commit 372366d

Browse files
committed
Only consider places with the same local in each_borrow_involving_path.
1 parent f42f19b commit 372366d

File tree

3 files changed

+20
-14
lines changed

3 files changed

+20
-14
lines changed

compiler/rustc_borrowck/src/invalidation.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -353,15 +353,14 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
353353
let tcx = self.tcx;
354354
let body = self.body;
355355
let borrow_set = self.borrow_set;
356-
let indices = self.borrow_set.indices();
357356
each_borrow_involving_path(
358357
self,
359358
tcx,
360359
body,
361360
location,
362361
(sd, place),
363362
borrow_set,
364-
indices,
363+
|_| true,
365364
|this, borrow_index, borrow| {
366365
match (rw, borrow.kind) {
367366
// Obviously an activation is compatible with its own

compiler/rustc_borrowck/src/lib.rs

+10-7
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, Subdiagnost
2323
use rustc_fluent_macro::fluent_messages;
2424
use rustc_hir as hir;
2525
use rustc_hir::def_id::LocalDefId;
26-
use rustc_index::bit_set::ChunkedBitSet;
26+
use rustc_index::bit_set::{BitSet, ChunkedBitSet};
2727
use rustc_index::{IndexSlice, IndexVec};
2828
use rustc_infer::infer::{
2929
InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
@@ -42,7 +42,6 @@ use rustc_session::lint::builtin::UNUSED_MUT;
4242
use rustc_span::{Span, Symbol};
4343
use rustc_target::abi::FieldIdx;
4444

45-
use either::Either;
4645
use smallvec::SmallVec;
4746
use std::cell::RefCell;
4847
use std::collections::BTreeMap;
@@ -1035,12 +1034,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10351034
let borrow_set = self.borrow_set.clone();
10361035

10371036
// Use polonius output if it has been enabled.
1038-
let polonius_output = self.polonius_output.clone();
1039-
let borrows_in_scope = if let Some(polonius) = &polonius_output {
1037+
let mut polonius_output;
1038+
let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
10401039
let location = self.location_table.start_index(location);
1041-
Either::Left(polonius.errors_at(location).iter().copied())
1040+
polonius_output = BitSet::new_empty(borrow_set.len());
1041+
for &idx in polonius.errors_at(location) {
1042+
polonius_output.insert(idx);
1043+
}
1044+
&polonius_output
10421045
} else {
1043-
Either::Right(flow_state.borrows.iter())
1046+
&flow_state.borrows
10441047
};
10451048

10461049
each_borrow_involving_path(
@@ -1050,7 +1053,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
10501053
location,
10511054
(sd, place_span.0),
10521055
&borrow_set,
1053-
borrows_in_scope,
1056+
|borrow_index| borrows_in_scope.contains(borrow_index),
10541057
|this, borrow_index, borrow| match (rw, borrow.kind) {
10551058
// Obviously an activation is compatible with its own
10561059
// reservation (or even prior activating uses of same

compiler/rustc_borrowck/src/path_utils.rs

+9-5
Original file line numberDiff line numberDiff line change
@@ -33,20 +33,24 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
3333
_location: Location,
3434
access_place: (AccessDepth, Place<'tcx>),
3535
borrow_set: &BorrowSet<'tcx>,
36-
candidates: I,
36+
is_candidate: I,
3737
mut op: F,
3838
) where
3939
F: FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> Control,
40-
I: Iterator<Item = BorrowIndex>,
40+
I: Fn(BorrowIndex) -> bool,
4141
{
4242
let (access, place) = access_place;
4343

44-
// FIXME: analogous code in check_loans first maps `place` to
45-
// its base_path.
44+
// The number of candidates can be large, but borrows for different locals cannot conflict with
45+
// each other, so we restrict the working set a priori.
46+
let Some(borrows_for_place_base) = borrow_set.local_map.get(&place.local) else { return };
4647

4748
// check for loan restricting path P being used. Accounts for
4849
// borrows of P, P.a.b, etc.
49-
for i in candidates {
50+
for &i in borrows_for_place_base {
51+
if !is_candidate(i) {
52+
continue;
53+
}
5054
let borrowed = &borrow_set[i];
5155

5256
if places_conflict::borrow_conflicts_with_place(

0 commit comments

Comments
 (0)