Skip to content

Commit dda892a

Browse files
committed
Make fn move_path_for take &mut self instead of &self. This is a
precursor for a number of other simplifying changes (mostly removing uses of `RefCell`). Factor lookup method out of `fn move_path_for`.
1 parent 9901768 commit dda892a

File tree

1 file changed

+37
-36
lines changed

1 file changed

+37
-36
lines changed

src/librustc_borrowck/borrowck/mir/gather_moves.rs

+37-36
Original file line numberDiff line numberDiff line change
@@ -399,45 +399,42 @@ impl<'tcx> MovePathLookup<'tcx> {
399399
}
400400

401401
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 = {
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>
677679
struct 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

Comments
 (0)