use the activations_at_location map to check activations

Not gen bits
This commit is contained in:
Niko Matsakis 2018-04-07 05:43:36 -04:00
parent e1f82aa590
commit d32e5aac3d
3 changed files with 34 additions and 33 deletions

View file

@ -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 => {}

View file

@ -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.
}
}
}

View file

@ -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>,