@@ -56,10 +56,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
56
56
/// Visits the whole MIR and generates invalidates() facts
57
57
/// Most of the code implementing this was stolen from borrow_check/mod.rs
58
58
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
+
63
67
match statement. kind {
64
68
StatementKind :: Assign ( ref lhs, ref rhs) => {
65
69
self . consume_rvalue (
@@ -148,6 +152,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
148
152
terminator : & Terminator < ' tcx > ,
149
153
location : Location
150
154
) {
155
+ self . check_activations ( location) ;
156
+
151
157
match terminator. kind {
152
158
TerminatorKind :: SwitchInt {
153
159
ref discr,
@@ -471,5 +477,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
471
477
let lidx = self . location_table . start_index ( l) ;
472
478
self . all_facts . invalidates . push ( ( lidx, b) ) ;
473
479
}
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
+ }
474
516
}
475
517
0 commit comments