@@ -66,10 +66,14 @@ struct InvalidationGenerator<'cx, 'tcx: 'cx, 'gcx: 'tcx> {
66
66
/// Visits the whole MIR and generates invalidates() facts
67
67
/// Most of the code implementing this was stolen from borrow_check/mod.rs
68
68
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
+
73
77
match statement. kind {
74
78
StatementKind :: Assign ( ref lhs, ref rhs) => {
75
79
self . consume_rvalue (
@@ -159,6 +163,8 @@ impl<'cx, 'tcx, 'gcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx, 'gcx> {
159
163
terminator : & Terminator < ' tcx > ,
160
164
location : Location
161
165
) {
166
+ self . check_activations ( location) ;
167
+
162
168
match terminator. kind {
163
169
TerminatorKind :: SwitchInt {
164
170
ref discr,
@@ -482,5 +488,41 @@ impl<'cg, 'cx, 'tcx, 'gcx> InvalidationGenerator<'cx, 'tcx, 'gcx> {
482
488
let lidx = self . location_table . start_index ( l) ;
483
489
self . all_facts . invalidates . push ( ( lidx, b) ) ;
484
490
}
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
+ }
485
527
}
486
528
0 commit comments