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