@@ -41,6 +41,7 @@ use util::borrowck_errors::{BorrowckErrors, Origin};
41
41
use self :: MutateMode :: { JustWrite , WriteAndRead } ;
42
42
43
43
use std:: borrow:: Cow ;
44
+ use std:: iter;
44
45
45
46
pub ( crate ) mod nll;
46
47
@@ -733,9 +734,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
733
734
context,
734
735
( sd, place_span. 0 ) ,
735
736
flow_state,
736
- |this, _index , borrow, common_prefix| match ( rw, borrow. kind ) {
737
+ |this, index , borrow, common_prefix| match ( rw, borrow. kind ) {
737
738
( Read ( _) , BorrowKind :: Shared ) => Control :: Continue ,
739
+
738
740
( Read ( kind) , BorrowKind :: Unique ) | ( Read ( kind) , BorrowKind :: Mut ) => {
741
+ // Reading from mere reservations of mutable-borrows is OK.
742
+ if this. tcx . sess . opts . debugging_opts . two_phase_borrows &&
743
+ index. is_reservation ( )
744
+ {
745
+ return Control :: Continue ;
746
+ }
747
+
739
748
match kind {
740
749
ReadKind :: Copy => {
741
750
error_reported = true ;
@@ -1521,9 +1530,17 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
1521
1530
1522
1531
// check for loan restricting path P being used. Accounts for
1523
1532
// borrows of P, P.a.b, etc.
1524
- ' next_borrow: for i in flow_state. borrows . elems_incoming ( ) {
1525
- // FIXME for now, just skip the activation state.
1526
- if i. is_activation ( ) { continue ' next_borrow; }
1533
+ let mut elems_incoming = flow_state. borrows . elems_incoming ( ) ;
1534
+ ' next_borrow: while let Some ( i) = elems_incoming. next ( ) {
1535
+ // Skip any reservation that has a corresponding current
1536
+ // activation. This way, the traversal will visit each
1537
+ // borrow_index at most once.
1538
+ if let Some ( j) = elems_incoming. peek ( ) {
1539
+ if i. is_reservation ( ) && j. is_activation ( ) {
1540
+ assert_eq ! ( i. borrow_index( ) , j. borrow_index( ) ) ;
1541
+ continue ' next_borrow;
1542
+ }
1543
+ }
1527
1544
1528
1545
let borrowed = & data[ i. borrow_index ( ) ] ;
1529
1546
@@ -2585,9 +2602,9 @@ where
2585
2602
self . sets . on_entry . subtract ( & self . sets . kill_set ) ;
2586
2603
}
2587
2604
2588
- fn elems_incoming ( & self ) -> indexed_set:: Elems < BD :: Idx > {
2605
+ fn elems_incoming ( & self ) -> iter :: Peekable < indexed_set:: Elems < BD :: Idx > > {
2589
2606
let univ = self . base_results . sets ( ) . bits_per_block ( ) ;
2590
- self . sets . on_entry . elems ( univ)
2607
+ self . sets . on_entry . elems ( univ) . peekable ( )
2591
2608
}
2592
2609
2593
2610
fn with_elems_outgoing < F > ( & self , f : F )
0 commit comments