1
Fork 0

Only consider places with the same local in each_borrow_involving_path.

This commit is contained in:
Camille GILLOT 2023-05-19 08:26:31 +00:00
parent f42f19b6d3
commit 372366d686
3 changed files with 20 additions and 14 deletions

View file

@ -353,7 +353,6 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
let tcx = self.tcx; let tcx = self.tcx;
let body = self.body; let body = self.body;
let borrow_set = self.borrow_set; let borrow_set = self.borrow_set;
let indices = self.borrow_set.indices();
each_borrow_involving_path( each_borrow_involving_path(
self, self,
tcx, tcx,
@ -361,7 +360,7 @@ impl<'cx, 'tcx> InvalidationGenerator<'cx, 'tcx> {
location, location,
(sd, place), (sd, place),
borrow_set, borrow_set,
indices, |_| true,
|this, borrow_index, borrow| { |this, borrow_index, borrow| {
match (rw, borrow.kind) { match (rw, borrow.kind) {
// Obviously an activation is compatible with its own // Obviously an activation is compatible with its own

View file

@ -23,7 +23,7 @@ use rustc_errors::{Diagnostic, DiagnosticBuilder, DiagnosticMessage, Subdiagnost
use rustc_fluent_macro::fluent_messages; use rustc_fluent_macro::fluent_messages;
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId; use rustc_hir::def_id::LocalDefId;
use rustc_index::bit_set::ChunkedBitSet; use rustc_index::bit_set::{BitSet, ChunkedBitSet};
use rustc_index::{IndexSlice, IndexVec}; use rustc_index::{IndexSlice, IndexVec};
use rustc_infer::infer::{ use rustc_infer::infer::{
InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt, InferCtxt, NllRegionVariableOrigin, RegionVariableOrigin, TyCtxtInferExt,
@ -42,7 +42,6 @@ use rustc_session::lint::builtin::UNUSED_MUT;
use rustc_span::{Span, Symbol}; use rustc_span::{Span, Symbol};
use rustc_target::abi::FieldIdx; use rustc_target::abi::FieldIdx;
use either::Either;
use smallvec::SmallVec; use smallvec::SmallVec;
use std::cell::RefCell; use std::cell::RefCell;
use std::collections::BTreeMap; use std::collections::BTreeMap;
@ -1035,12 +1034,16 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let borrow_set = self.borrow_set.clone(); let borrow_set = self.borrow_set.clone();
// Use polonius output if it has been enabled. // Use polonius output if it has been enabled.
let polonius_output = self.polonius_output.clone(); let mut polonius_output;
let borrows_in_scope = if let Some(polonius) = &polonius_output { let borrows_in_scope = if let Some(polonius) = &self.polonius_output {
let location = self.location_table.start_index(location); let location = self.location_table.start_index(location);
Either::Left(polonius.errors_at(location).iter().copied()) polonius_output = BitSet::new_empty(borrow_set.len());
for &idx in polonius.errors_at(location) {
polonius_output.insert(idx);
}
&polonius_output
} else { } else {
Either::Right(flow_state.borrows.iter()) &flow_state.borrows
}; };
each_borrow_involving_path( each_borrow_involving_path(
@ -1050,7 +1053,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
location, location,
(sd, place_span.0), (sd, place_span.0),
&borrow_set, &borrow_set,
borrows_in_scope, |borrow_index| borrows_in_scope.contains(borrow_index),
|this, borrow_index, borrow| match (rw, borrow.kind) { |this, borrow_index, borrow| match (rw, borrow.kind) {
// Obviously an activation is compatible with its own // Obviously an activation is compatible with its own
// reservation (or even prior activating uses of same // reservation (or even prior activating uses of same

View file

@ -33,20 +33,24 @@ pub(super) fn each_borrow_involving_path<'tcx, F, I, S>(
_location: Location, _location: Location,
access_place: (AccessDepth, Place<'tcx>), access_place: (AccessDepth, Place<'tcx>),
borrow_set: &BorrowSet<'tcx>, borrow_set: &BorrowSet<'tcx>,
candidates: I, is_candidate: I,
mut op: F, mut op: F,
) where ) where
F: FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> Control, F: FnMut(&mut S, BorrowIndex, &BorrowData<'tcx>) -> Control,
I: Iterator<Item = BorrowIndex>, I: Fn(BorrowIndex) -> bool,
{ {
let (access, place) = access_place; let (access, place) = access_place;
// FIXME: analogous code in check_loans first maps `place` to // The number of candidates can be large, but borrows for different locals cannot conflict with
// its base_path. // each other, so we restrict the working set a priori.
let Some(borrows_for_place_base) = borrow_set.local_map.get(&place.local) else { return };
// check for loan restricting path P being used. Accounts for // check for loan restricting path P being used. Accounts for
// borrows of P, P.a.b, etc. // borrows of P, P.a.b, etc.
for i in candidates { for &i in borrows_for_place_base {
if !is_candidate(i) {
continue;
}
let borrowed = &borrow_set[i]; let borrowed = &borrow_set[i];
if places_conflict::borrow_conflicts_with_place( if places_conflict::borrow_conflicts_with_place(