@@ -399,45 +399,42 @@ impl<'tcx> MovePathLookup<'tcx> {
399
399
}
400
400
401
401
impl < ' a , ' tcx > MovePathDataBuilder < ' a , ' tcx > {
402
- // (use of `&self` here is going to necessitate use of e.g. RefCell
403
- // or some other &-safe data accumulator)
404
- //
405
- // Caller must ensure self's RefCells (i.e. `self.pre_move_paths`
406
- // and `self.rev_lookup`) are not mutably borrowed.
407
- fn move_path_for ( & self , lval : & Lvalue < ' tcx > ) -> MovePathIndex {
408
- let lookup = {
402
+ fn lookup ( & mut self , lval : & Lvalue < ' tcx > ) -> Lookup < MovePathIndex > {
403
+ let proj = {
409
404
let mut rev_lookup = self . rev_lookup . borrow_mut ( ) ;
410
405
match * lval {
411
406
Lvalue :: Var ( var_idx) =>
412
- rev_lookup. lookup_var ( var_idx) ,
407
+ return rev_lookup. lookup_var ( var_idx) ,
413
408
Lvalue :: Temp ( temp_idx) =>
414
- rev_lookup. lookup_temp ( temp_idx) ,
409
+ return rev_lookup. lookup_temp ( temp_idx) ,
415
410
Lvalue :: Arg ( arg_idx) =>
416
- rev_lookup. lookup_arg ( arg_idx) ,
411
+ return rev_lookup. lookup_arg ( arg_idx) ,
417
412
Lvalue :: Static ( _def_id) =>
418
- rev_lookup. lookup_static ( ) ,
413
+ return rev_lookup. lookup_static ( ) ,
419
414
Lvalue :: ReturnPointer =>
420
- rev_lookup. lookup_return_pointer ( ) ,
415
+ return rev_lookup. lookup_return_pointer ( ) ,
421
416
Lvalue :: Projection ( ref proj) => {
422
- // Manually drop the rev_lookup ...
423
- drop ( rev_lookup) ;
424
-
425
- // ... so that we can reborrow it here (which may
426
- // well be building new move path) ...
427
- let base_index = self . move_path_for ( & proj. base ) ;
428
-
429
- // ... and restablish exclusive access here.
430
- let mut rev_lookup = self . rev_lookup . borrow_mut ( ) ;
431
- rev_lookup. lookup_proj ( proj, base_index)
417
+ proj
432
418
}
433
419
}
420
+ // drop the rev_lookup here ...
434
421
} ;
435
422
436
- let mut pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
423
+ let base_index = self . move_path_for ( & proj . base ) ;
437
424
438
- // At this point, `lookup` is either the previously assigned
439
- // index or a newly-allocated one.
440
- debug_assert ! ( lookup. idx( ) <= pre_move_paths. len( ) ) ;
425
+ // ... restablish exclusive access to rev_lookup here.
426
+ let mut rev_lookup = self . rev_lookup . borrow_mut ( ) ;
427
+ rev_lookup. lookup_proj ( proj, base_index)
428
+ }
429
+
430
+ // Caller must ensure self's RefCells (i.e. `self.pre_move_paths`
431
+ // and `self.rev_lookup`) are not mutably borrowed.
432
+ fn move_path_for ( & mut self , lval : & Lvalue < ' tcx > ) -> MovePathIndex {
433
+ let lookup: Lookup < MovePathIndex > = self . lookup ( lval) ;
434
+
435
+ // `lookup` is either the previously assigned index or a
436
+ // newly-allocated one.
437
+ debug_assert ! ( lookup. idx( ) <= self . pre_move_paths. borrow( ) . len( ) ) ;
441
438
442
439
if let Lookup ( LookupKind :: Generate , mpi) = lookup {
443
440
let parent;
@@ -462,14 +459,13 @@ impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
462
459
content = Some ( lval) ;
463
460
464
461
// Here, install new MovePath as new first_child.
465
- drop ( pre_move_paths) ;
466
462
467
463
// Note: `parent` previously allocated (Projection
468
464
// case of match above established this).
469
465
let idx = self . move_path_for ( & proj. base ) ;
470
466
parent = Some ( idx) ;
471
467
472
- pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
468
+ let mut pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
473
469
let parent_move_path = & mut pre_move_paths[ idx. idx ( ) ] ;
474
470
475
471
// At last: Swap in the new first_child.
@@ -490,6 +486,7 @@ impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
490
486
first_child : Cell :: new ( None ) ,
491
487
} ;
492
488
489
+ let mut pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
493
490
pre_move_paths. push ( move_path) ;
494
491
}
495
492
@@ -517,7 +514,10 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
517
514
let mut loc_map: Vec < _ > = iter:: repeat ( Vec :: new ( ) ) . take ( bbs. len ( ) ) . collect ( ) ;
518
515
let mut path_map = Vec :: new ( ) ;
519
516
520
- let builder = MovePathDataBuilder {
517
+ // this is mutable only because we will move it to and fro' the
518
+ // BlockContexts constructed on each iteration. (Moving is more
519
+ // straight-forward than mutable borrows in this instance.)
520
+ let mut builder = MovePathDataBuilder {
521
521
mir : mir,
522
522
pre_move_paths : RefCell :: new ( Vec :: new ( ) ) ,
523
523
rev_lookup : RefCell :: new ( MovePathLookup :: new ( ) ) ,
@@ -535,7 +535,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
535
535
let mut bb_ctxt = BlockContext {
536
536
tcx : tcx,
537
537
moves : & mut moves,
538
- builder : & builder,
538
+ builder : builder,
539
539
path_map : & mut path_map,
540
540
loc_map_bb : loc_map_bb,
541
541
} ;
@@ -545,7 +545,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
545
545
match stmt. kind {
546
546
StatementKind :: Assign ( ref lval, ref rval) => {
547
547
// ensure MovePath created for `lval`.
548
- builder. move_path_for ( lval) ;
548
+ bb_ctxt . builder . move_path_for ( lval) ;
549
549
550
550
match * rval {
551
551
Rvalue :: Use ( ref operand) => {
@@ -626,11 +626,13 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
626
626
if let Some ( ( ref destination, _bb) ) = * destination {
627
627
// Create MovePath for `destination`, then
628
628
// discard returned index.
629
- builder. move_path_for ( destination) ;
629
+ bb_ctxt . builder . move_path_for ( destination) ;
630
630
}
631
631
}
632
632
}
633
633
}
634
+
635
+ builder = bb_ctxt. builder ;
634
636
}
635
637
636
638
// At this point, we may have created some MovePaths that do not
@@ -677,7 +679,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
677
679
struct BlockContext < ' b , ' a : ' b , ' tcx : ' a > {
678
680
tcx : & ' b ty:: TyCtxt < ' tcx > ,
679
681
moves : & ' b mut Vec < MoveOut > ,
680
- builder : & ' b MovePathDataBuilder < ' a , ' tcx > ,
682
+ builder : MovePathDataBuilder < ' a , ' tcx > ,
681
683
path_map : & ' b mut Vec < Vec < MoveOutIndex > > ,
682
684
loc_map_bb : & ' b mut Vec < Vec < MoveOutIndex > > ,
683
685
}
@@ -687,9 +689,8 @@ impl<'b, 'a: 'b, 'tcx: 'a> BlockContext<'b, 'a, 'tcx> {
687
689
stmt_kind : StmtKind ,
688
690
lval : & repr:: Lvalue < ' tcx > ,
689
691
source : Location ) {
690
- let builder = self . builder ;
691
692
let tcx = self . tcx ;
692
- let lval_ty = builder. mir . lvalue_ty ( tcx, lval) ;
693
+ let lval_ty = self . builder . mir . lvalue_ty ( tcx, lval) ;
693
694
694
695
// FIXME: does lvalue_ty ever return TyError, or is it
695
696
// guaranteed to always return non-Infer/non-Error values?
@@ -710,7 +711,7 @@ impl<'b, 'a: 'b, 'tcx: 'a> BlockContext<'b, 'a, 'tcx> {
710
711
let i = source. index ;
711
712
let index = MoveOutIndex :: new ( self . moves . len ( ) ) ;
712
713
713
- let path = builder. move_path_for ( lval) ;
714
+ let path = self . builder . move_path_for ( lval) ;
714
715
self . moves . push ( MoveOut { path : path, source : source. clone ( ) } ) ;
715
716
self . path_map . fill_to ( path. idx ( ) ) ;
716
717
0 commit comments