@@ -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
5858impl < ' 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