use the activations_at_location map to check activations
Not gen bits
This commit is contained in:
parent
e1f82aa590
commit
d32e5aac3d
3 changed files with 34 additions and 33 deletions
|
|
@ -35,7 +35,7 @@ crate struct BorrowSet<'tcx> {
|
|||
/// NOTE: A given location may activate more than one borrow in the future
|
||||
/// when more general two-phase borrow support is introduced, but for now we
|
||||
/// only need to store one borrow index
|
||||
crate activation_map: FxHashMap<Location, FxHashSet<BorrowIndex>>,
|
||||
crate activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
|
||||
|
||||
/// Every borrow has a region; this maps each such regions back to
|
||||
/// its borrow-indexes.
|
||||
|
|
@ -131,7 +131,7 @@ struct GatherBorrows<'a, 'gcx: 'tcx, 'tcx: 'a> {
|
|||
mir: &'a Mir<'tcx>,
|
||||
idx_vec: IndexVec<BorrowIndex, BorrowData<'tcx>>,
|
||||
location_map: FxHashMap<Location, BorrowIndex>,
|
||||
activation_map: FxHashMap<Location, FxHashSet<BorrowIndex>>,
|
||||
activation_map: FxHashMap<Location, Vec<BorrowIndex>>,
|
||||
region_map: FxHashMap<Region<'tcx>, FxHashSet<BorrowIndex>>,
|
||||
local_map: FxHashMap<mir::Local, FxHashSet<BorrowIndex>>,
|
||||
region_span_map: FxHashMap<RegionKind, Span>,
|
||||
|
|
@ -230,8 +230,8 @@ impl<'a, 'gcx, 'tcx> Visitor<'tcx> for GatherBorrows<'a, 'gcx, 'tcx> {
|
|||
borrow_data.activation_location = Some(location);
|
||||
self.activation_map
|
||||
.entry(location)
|
||||
.or_insert(FxHashSet())
|
||||
.insert(borrow_index);
|
||||
.or_insert(Vec::new())
|
||||
.push(borrow_index);
|
||||
}
|
||||
|
||||
None => {}
|
||||
|
|
|
|||
|
|
@ -1267,36 +1267,30 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
|
|||
// Two-phase borrow support: For each activation that is newly
|
||||
// generated at this statement, check if it interferes with
|
||||
// another borrow.
|
||||
let domain = flow_state.borrows.operator();
|
||||
let data = domain.borrows();
|
||||
flow_state.borrows.each_gen_bit(|gen| {
|
||||
if gen.is_activation() {
|
||||
let borrow_index = gen.borrow_index();
|
||||
let borrow = &data[borrow_index];
|
||||
// currently the flow analysis registers
|
||||
// activations for both mutable and immutable
|
||||
// borrows. So make sure we are talking about a
|
||||
// mutable borrow before we check it.
|
||||
match borrow.kind {
|
||||
BorrowKind::Shared => return,
|
||||
BorrowKind::Unique | BorrowKind::Mut { .. } => {}
|
||||
}
|
||||
let borrows = flow_state.borrows.operator();
|
||||
for &borrow_index in borrows.activations_at_location(location) {
|
||||
let borrow = &borrows.borrows()[borrow_index];
|
||||
|
||||
self.access_place(
|
||||
ContextKind::Activation.new(location),
|
||||
(&borrow.borrowed_place, span),
|
||||
(
|
||||
Deep,
|
||||
Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
|
||||
),
|
||||
LocalMutationIsAllowed::No,
|
||||
flow_state,
|
||||
);
|
||||
// We do not need to call `check_if_path_or_subpath_is_moved`
|
||||
// again, as we already called it when we made the
|
||||
// initial reservation.
|
||||
}
|
||||
});
|
||||
// only mutable borrows should be 2-phase
|
||||
assert!(match borrow.kind {
|
||||
BorrowKind::Shared => false,
|
||||
BorrowKind::Unique | BorrowKind::Mut { .. } => true,
|
||||
});
|
||||
|
||||
self.access_place(
|
||||
ContextKind::Activation.new(location),
|
||||
(&borrow.borrowed_place, span),
|
||||
(
|
||||
Deep,
|
||||
Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
|
||||
),
|
||||
LocalMutationIsAllowed::No,
|
||||
flow_state,
|
||||
);
|
||||
// We do not need to call `check_if_path_or_subpath_is_moved`
|
||||
// again, as we already called it when we made the
|
||||
// initial reservation.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -156,6 +156,13 @@ impl<'a, 'gcx, 'tcx> Borrows<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
crate fn activations_at_location(&self, location: Location) -> &[BorrowIndex] {
|
||||
self.borrow_set.activation_map
|
||||
.get(&location)
|
||||
.map(|activations| &activations[..])
|
||||
.unwrap_or(&[])
|
||||
}
|
||||
|
||||
/// Performs the activations for a given location
|
||||
fn perform_activations_at_location(&self,
|
||||
sets: &mut BlockSets<ReserveOrActivateIndex>,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue