Skip to content

Commit 5efcff1

Browse files
committed
generate invalidations from 2-phase-borrow activations
1 parent ec19464 commit 5efcff1

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

src/librustc_mir/borrow_check/nll/invalidation.rs

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,10 +56,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
5656
/// Visits the whole MIR and generates invalidates() facts
5757
/// Most of the code implementing this was stolen from borrow_check/mod.rs
5858
impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
59-
fn visit_statement(&mut self,
60-
block: BasicBlock,
61-
statement: &Statement<'tcx>,
62-
location: Location) {
59+
fn visit_statement(
60+
&mut self,
61+
block: BasicBlock,
62+
statement: &Statement<'tcx>,
63+
location: Location,
64+
) {
65+
self.check_activations(location);
66+
6367
match statement.kind {
6468
StatementKind::Assign(ref lhs, ref rhs) => {
6569
self.consume_rvalue(
@@ -148,6 +152,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
148152
terminator: &Terminator<'tcx>,
149153
location: Location
150154
) {
155+
self.check_activations(location);
156+
151157
match terminator.kind {
152158
TerminatorKind::SwitchInt {
153159
ref discr,
@@ -471,5 +477,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
471477
let lidx = self.location_table.start_index(l);
472478
self.all_facts.invalidates.push((lidx, b));
473479
}
480+
481+
fn check_activations(
482+
&mut self,
483+
location: Location,
484+
) {
485+
if !self.tcx.two_phase_borrows() {
486+
return;
487+
}
488+
489+
// Two-phase borrow support: For each activation that is newly
490+
// generated at this statement, check if it interferes with
491+
// another borrow.
492+
for &borrow_index in self.borrow_set.activations_at_location(location) {
493+
let borrow = &self.borrow_set[borrow_index];
494+
495+
// only mutable borrows should be 2-phase
496+
assert!(match borrow.kind {
497+
BorrowKind::Shared | BorrowKind::Shallow => false,
498+
BorrowKind::Unique | BorrowKind::Mut { .. } => true,
499+
});
500+
501+
self.access_place(
502+
ContextKind::Activation.new(location),
503+
&borrow.borrowed_place,
504+
(
505+
Deep,
506+
Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
507+
),
508+
LocalMutationIsAllowed::No,
509+
);
510+
511+
// We do not need to call `check_if_path_or_subpath_is_moved`
512+
// again, as we already called it when we made the
513+
// initial reservation.
514+
}
515+
}
474516
}
475517

0 commit comments

Comments
 (0)