@@ -399,45 +399,42 @@ impl<'tcx> MovePathLookup<'tcx> {
399399}
400400
401401impl < ' 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 = {
409404 let mut rev_lookup = self . rev_lookup . borrow_mut ( ) ;
410405 match * lval {
411406 Lvalue :: Var ( var_idx) =>
412- rev_lookup. lookup_var ( var_idx) ,
407+ return rev_lookup. lookup_var ( var_idx) ,
413408 Lvalue :: Temp ( temp_idx) =>
414- rev_lookup. lookup_temp ( temp_idx) ,
409+ return rev_lookup. lookup_temp ( temp_idx) ,
415410 Lvalue :: Arg ( arg_idx) =>
416- rev_lookup. lookup_arg ( arg_idx) ,
411+ return rev_lookup. lookup_arg ( arg_idx) ,
417412 Lvalue :: Static ( _def_id) =>
418- rev_lookup. lookup_static ( ) ,
413+ return rev_lookup. lookup_static ( ) ,
419414 Lvalue :: ReturnPointer =>
420- rev_lookup. lookup_return_pointer ( ) ,
415+ return rev_lookup. lookup_return_pointer ( ) ,
421416 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
432418 }
433419 }
420+ // drop the rev_lookup here ...
434421 } ;
435422
436- let mut pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
423+ let base_index = self . move_path_for ( & proj . base ) ;
437424
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( ) ) ;
441438
442439 if let Lookup ( LookupKind :: Generate , mpi) = lookup {
443440 let parent;
@@ -462,14 +459,13 @@ impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
462459 content = Some ( lval) ;
463460
464461 // Here, install new MovePath as new first_child.
465- drop ( pre_move_paths) ;
466462
467463 // Note: `parent` previously allocated (Projection
468464 // case of match above established this).
469465 let idx = self . move_path_for ( & proj. base ) ;
470466 parent = Some ( idx) ;
471467
472- pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
468+ let mut pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
473469 let parent_move_path = & mut pre_move_paths[ idx. idx ( ) ] ;
474470
475471 // At last: Swap in the new first_child.
@@ -490,6 +486,7 @@ impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
490486 first_child : Cell :: new ( None ) ,
491487 } ;
492488
489+ let mut pre_move_paths = self . pre_move_paths . borrow_mut ( ) ;
493490 pre_move_paths. push ( move_path) ;
494491 }
495492
@@ -517,7 +514,10 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
517514 let mut loc_map: Vec < _ > = iter:: repeat ( Vec :: new ( ) ) . take ( bbs. len ( ) ) . collect ( ) ;
518515 let mut path_map = Vec :: new ( ) ;
519516
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 {
521521 mir : mir,
522522 pre_move_paths : RefCell :: new ( Vec :: new ( ) ) ,
523523 rev_lookup : RefCell :: new ( MovePathLookup :: new ( ) ) ,
@@ -535,7 +535,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
535535 let mut bb_ctxt = BlockContext {
536536 tcx : tcx,
537537 moves : & mut moves,
538- builder : & builder,
538+ builder : builder,
539539 path_map : & mut path_map,
540540 loc_map_bb : loc_map_bb,
541541 } ;
@@ -545,7 +545,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
545545 match stmt. kind {
546546 StatementKind :: Assign ( ref lval, ref rval) => {
547547 // ensure MovePath created for `lval`.
548- builder. move_path_for ( lval) ;
548+ bb_ctxt . builder . move_path_for ( lval) ;
549549
550550 match * rval {
551551 Rvalue :: Use ( ref operand) => {
@@ -626,11 +626,13 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
626626 if let Some ( ( ref destination, _bb) ) = * destination {
627627 // Create MovePath for `destination`, then
628628 // discard returned index.
629- builder. move_path_for ( destination) ;
629+ bb_ctxt . builder . move_path_for ( destination) ;
630630 }
631631 }
632632 }
633633 }
634+
635+ builder = bb_ctxt. builder ;
634636 }
635637
636638 // 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>
677679struct BlockContext < ' b , ' a : ' b , ' tcx : ' a > {
678680 tcx : & ' b ty:: TyCtxt < ' tcx > ,
679681 moves : & ' b mut Vec < MoveOut > ,
680- builder : & ' b MovePathDataBuilder < ' a , ' tcx > ,
682+ builder : MovePathDataBuilder < ' a , ' tcx > ,
681683 path_map : & ' b mut Vec < Vec < MoveOutIndex > > ,
682684 loc_map_bb : & ' b mut Vec < Vec < MoveOutIndex > > ,
683685}
@@ -687,9 +689,8 @@ impl<'b, 'a: 'b, 'tcx: 'a> BlockContext<'b, 'a, 'tcx> {
687689 stmt_kind : StmtKind ,
688690 lval : & repr:: Lvalue < ' tcx > ,
689691 source : Location ) {
690- let builder = self . builder ;
691692 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) ;
693694
694695 // FIXME: does lvalue_ty ever return TyError, or is it
695696 // guaranteed to always return non-Infer/non-Error values?
@@ -710,7 +711,7 @@ impl<'b, 'a: 'b, 'tcx: 'a> BlockContext<'b, 'a, 'tcx> {
710711 let i = source. index ;
711712 let index = MoveOutIndex :: new ( self . moves . len ( ) ) ;
712713
713- let path = builder. move_path_for ( lval) ;
714+ let path = self . builder . move_path_for ( lval) ;
714715 self . moves . push ( MoveOut { path : path, source : source. clone ( ) } ) ;
715716 self . path_map . fill_to ( path. idx ( ) ) ;
716717
0 commit comments