Skip to content

Commit 30f531b

Browse files
committed
generate invalidations from 2-phase-borrow activations
1 parent 3a31213 commit 30f531b

File tree

1 file changed

+46
-4
lines changed

1 file changed

+46
-4
lines changed

src/librustc_mir/borrow_check/nll/invalidation.rs

+46-4
Original file line numberDiff line numberDiff line change
@@ -66,10 +66,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
6666
/// Visits the whole MIR and generates invalidates() facts
6767
/// Most of the code implementing this was stolen from borrow_check/mod.rs
6868
impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
69-
fn visit_statement(&mut self,
70-
block: BasicBlock,
71-
statement: &Statement<'tcx>,
72-
location: Location) {
69+
fn visit_statement(
70+
&mut self,
71+
block: BasicBlock,
72+
statement: &Statement<'tcx>,
73+
location: Location,
74+
) {
75+
self.check_activations(location);
76+
7377
match statement.kind {
7478
StatementKind::Assign(ref lhs, ref rhs) => {
7579
self.consume_rvalue(
@@ -159,6 +163,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
159163
terminator: &Terminator<'tcx>,
160164
location: Location
161165
) {
166+
self.check_activations(location);
167+
162168
match terminator.kind {
163169
TerminatorKind::SwitchInt {
164170
ref discr,
@@ -482,5 +488,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
482488
let lidx = self.location_table.start_index(l);
483489
self.all_facts.invalidates.push((lidx, b));
484490
}
491+
492+
fn check_activations(
493+
&mut self,
494+
location: Location,
495+
) {
496+
if !self.tcx.two_phase_borrows() {
497+
return;
498+
}
499+
500+
// Two-phase borrow support: For each activation that is newly
501+
// generated at this statement, check if it interferes with
502+
// another borrow.
503+
for &borrow_index in self.borrow_set.activations_at_location(location) {
504+
let borrow = &self.borrow_set[borrow_index];
505+
506+
// only mutable borrows should be 2-phase
507+
assert!(match borrow.kind {
508+
BorrowKind::Shared | BorrowKind::Shallow => false,
509+
BorrowKind::Unique | BorrowKind::Mut { .. } => true,
510+
});
511+
512+
self.access_place(
513+
ContextKind::Activation.new(location),
514+
&borrow.borrowed_place,
515+
(
516+
Deep,
517+
Activation(WriteKind::MutableBorrow(borrow.kind), borrow_index),
518+
),
519+
LocalMutationIsAllowed::No,
520+
);
521+
522+
// We do not need to call `check_if_path_or_subpath_is_moved`
523+
// again, as we already called it when we made the
524+
// initial reservation.
525+
}
526+
}
485527
}
486528

0 commit comments

Comments
 (0)