Skip to content

Commit

Permalink
generate invalidations from 2-phase-borrow activations
Browse files Browse the repository at this point in the history
  • Loading branch information
nikomatsakis committed Dec 11, 2018
1 parent 3a31213 commit 30f531b
Showing 1 changed file with 46 additions and 4 deletions.
50 changes: 46 additions & 4 deletions src/librustc_mir/borrow_check/nll/invalidation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
/// Visits the whole MIR and generates invalidates() facts
/// Most of the code implementing this was stolen from borrow_check/mod.rs
impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
fn visit_statement(&mut self,
block: BasicBlock,
statement: &Statement<'tcx>,
location: Location) {
fn visit_statement(
&mut self,
block: BasicBlock,
statement: &Statement<'tcx>,
location: Location,
) {
self.check_activations(location);

match statement.kind {
StatementKind::Assign(ref lhs, ref rhs) => {
self.consume_rvalue(
Expand Down Expand Up @@ -159,6 +163,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
terminator: &Terminator<'tcx>,
location: Location
) {
self.check_activations(location);

match terminator.kind {
TerminatorKind::SwitchInt {
ref discr,
Expand Down Expand Up @@ -482,5 +488,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
let lidx = self.location_table.start_index(l);
self.all_facts.invalidates.push((lidx, b));
}

fn check_activations(
&mut self,
location: Location,
) {
if !self.tcx.two_phase_borrows() {
return;
}

// Two-phase borrow support: For each activation that is newly
// generated at this statement, check if it interferes with
// another borrow.
for &borrow_index in self.borrow_set.activations_at_location(location) {
let borrow = &self.borrow_set[borrow_index];

// only mutable borrows should be 2-phase
assert!(match borrow.kind {
BorrowKind::Shared | BorrowKind::Shallow => false,
BorrowKind::Unique | BorrowKind::Mut { .. } => true,
});

self.access_place(
ContextKind::Activation.new(location),
&borrow.borrowed_place,
(
Deep,
Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
),
LocalMutationIsAllowed::No,
);

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

0 comments on commit 30f531b

Please sign in to comment.