]> git.lizzy.rs Git - rust.git/commitdiff
Make `fn move_path_for` take `&mut self` instead of `&self`. This is a
authorFelix S. Klock II <pnkfelix@pnkfx.org>
Tue, 15 Mar 2016 14:03:21 +0000 (15:03 +0100)
committerFelix S. Klock II <pnkfelix@pnkfx.org>
Mon, 21 Mar 2016 17:36:23 +0000 (18:36 +0100)
precursor for a number of other simplifying changes (mostly removing
uses of `RefCell`).

Factor lookup method out of `fn move_path_for`.

src/librustc_borrowck/borrowck/mir/gather_moves.rs

index 309efeba3205de1b22061fdcf7a4dfaf90de9e42..0e9419544e104d711195e0d7a1b27cfa73985514 100644 (file)
@@ -399,45 +399,42 @@ pub fn find(&self, lval: &Lvalue<'tcx>) -> MovePathIndex {
 }
 
 impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
-    // (use of `&self` here is going to necessitate use of e.g. RefCell
-    //  or some other &-safe data accumulator)
-    //
-    // Caller must ensure self's RefCells (i.e. `self.pre_move_paths`
-    // and `self.rev_lookup`) are not mutably borrowed.
-    fn move_path_for(&self, lval: &Lvalue<'tcx>) -> MovePathIndex {
-        let lookup = {
+    fn lookup(&mut self, lval: &Lvalue<'tcx>) -> Lookup<MovePathIndex> {
+        let proj = {
             let mut rev_lookup = self.rev_lookup.borrow_mut();
             match *lval {
                 Lvalue::Var(var_idx) =>
-                    rev_lookup.lookup_var(var_idx),
+                    return rev_lookup.lookup_var(var_idx),
                 Lvalue::Temp(temp_idx) =>
-                    rev_lookup.lookup_temp(temp_idx),
+                    return rev_lookup.lookup_temp(temp_idx),
                 Lvalue::Arg(arg_idx) =>
-                    rev_lookup.lookup_arg(arg_idx),
+                    return rev_lookup.lookup_arg(arg_idx),
                 Lvalue::Static(_def_id) =>
-                    rev_lookup.lookup_static(),
+                    return rev_lookup.lookup_static(),
                 Lvalue::ReturnPointer =>
-                    rev_lookup.lookup_return_pointer(),
+                    return rev_lookup.lookup_return_pointer(),
                 Lvalue::Projection(ref proj) => {
-                    // Manually drop the rev_lookup ...
-                    drop(rev_lookup);
-
-                    // ... so that we can reborrow it here (which may
-                    //     well be building new move path) ...
-                    let base_index = self.move_path_for(&proj.base);
-
-                    // ... and restablish exclusive access here.
-                    let mut rev_lookup = self.rev_lookup.borrow_mut();
-                    rev_lookup.lookup_proj(proj, base_index)
+                    proj
                 }
             }
+            // drop the rev_lookup here ...
         };
 
-        let mut pre_move_paths = self.pre_move_paths.borrow_mut();
+        let base_index = self.move_path_for(&proj.base);
 
-        // At this point, `lookup` is either the previously assigned
-        // index or a newly-allocated one.
-        debug_assert!(lookup.idx() <= pre_move_paths.len());
+        // ... restablish exclusive access to rev_lookup here.
+        let mut rev_lookup = self.rev_lookup.borrow_mut();
+        rev_lookup.lookup_proj(proj, base_index)
+    }
+
+    // Caller must ensure self's RefCells (i.e. `self.pre_move_paths`
+    // and `self.rev_lookup`) are not mutably borrowed.
+    fn move_path_for(&mut self, lval: &Lvalue<'tcx>) -> MovePathIndex {
+        let lookup: Lookup<MovePathIndex> = self.lookup(lval);
+
+        // `lookup` is either the previously assigned index or a
+        // newly-allocated one.
+        debug_assert!(lookup.idx() <= self.pre_move_paths.borrow().len());
 
         if let Lookup(LookupKind::Generate, mpi) = lookup {
             let parent;
@@ -462,14 +459,13 @@ fn move_path_for(&self, lval: &Lvalue<'tcx>) -> MovePathIndex {
                     content = Some(lval);
 
                     // Here, install new MovePath as new first_child.
-                    drop(pre_move_paths);
 
                     // Note: `parent` previously allocated (Projection
                     // case of match above established this).
                     let idx = self.move_path_for(&proj.base);
                     parent = Some(idx);
 
-                    pre_move_paths = self.pre_move_paths.borrow_mut();
+                    let mut pre_move_paths = self.pre_move_paths.borrow_mut();
                     let parent_move_path = &mut pre_move_paths[idx.idx()];
 
                     // At last: Swap in the new first_child.
@@ -490,6 +486,7 @@ fn move_path_for(&self, lval: &Lvalue<'tcx>) -> MovePathIndex {
                 first_child: Cell::new(None),
             };
 
+            let mut pre_move_paths = self.pre_move_paths.borrow_mut();
             pre_move_paths.push(move_path);
         }
 
@@ -517,7 +514,10 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
     let mut loc_map: Vec<_> = iter::repeat(Vec::new()).take(bbs.len()).collect();
     let mut path_map = Vec::new();
 
-    let builder = MovePathDataBuilder {
+    // this is mutable only because we will move it to and fro' the
+    // BlockContexts constructed on each iteration. (Moving is more
+    // straight-forward than mutable borrows in this instance.)
+    let mut builder = MovePathDataBuilder {
         mir: mir,
         pre_move_paths: RefCell::new(Vec::new()),
         rev_lookup: RefCell::new(MovePathLookup::new()),
@@ -535,7 +535,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
         let mut bb_ctxt = BlockContext {
             tcx: tcx,
             moves: &mut moves,
-            builder: &builder,
+            builder: builder,
             path_map: &mut path_map,
             loc_map_bb: loc_map_bb,
         };
@@ -545,7 +545,7 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
             match stmt.kind {
                 StatementKind::Assign(ref lval, ref rval) => {
                     // ensure MovePath created for `lval`.
-                    builder.move_path_for(lval);
+                    bb_ctxt.builder.move_path_for(lval);
 
                     match *rval {
                         Rvalue::Use(ref operand) => {
@@ -626,11 +626,13 @@ fn gather_moves<'tcx>(mir: &Mir<'tcx>, tcx: &ty::TyCtxt<'tcx>) -> MoveData<'tcx>
                     if let Some((ref destination, _bb)) = *destination {
                         // Create MovePath for `destination`, then
                         // discard returned index.
-                        builder.move_path_for(destination);
+                        bb_ctxt.builder.move_path_for(destination);
                     }
                 }
             }
         }
+
+        builder = bb_ctxt.builder;
     }
 
     // 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>
 struct BlockContext<'b, 'a: 'b, 'tcx: 'a> {
     tcx: &'b ty::TyCtxt<'tcx>,
     moves: &'b mut Vec<MoveOut>,
-    builder: &'b MovePathDataBuilder<'a, 'tcx>,
+    builder: MovePathDataBuilder<'a, 'tcx>,
     path_map: &'b mut Vec<Vec<MoveOutIndex>>,
     loc_map_bb: &'b mut Vec<Vec<MoveOutIndex>>,
 }
@@ -687,9 +689,8 @@ fn on_move_out_lval(&mut self,
                         stmt_kind: StmtKind,
                         lval: &repr::Lvalue<'tcx>,
                         source: Location) {
-        let builder = self.builder;
         let tcx = self.tcx;
-        let lval_ty = builder.mir.lvalue_ty(tcx, lval);
+        let lval_ty = self.builder.mir.lvalue_ty(tcx, lval);
 
         // FIXME: does lvalue_ty ever return TyError, or is it
         // guaranteed to always return non-Infer/non-Error values?
@@ -710,7 +711,7 @@ fn on_move_out_lval(&mut self,
         let i = source.index;
         let index = MoveOutIndex::new(self.moves.len());
 
-        let path = builder.move_path_for(lval);
+        let path = self.builder.move_path_for(lval);
         self.moves.push(MoveOut { path: path, source: source.clone() });
         self.path_map.fill_to(path.idx());