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`.
This commit is contained in:
parent
9901768b4c
commit
dda892a83d
1 changed files with 37 additions and 36 deletions
|
@ -399,45 +399,42 @@ impl<'tcx> MovePathLookup<'tcx> {
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
|
impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
|
||||||
// (use of `&self` here is going to necessitate use of e.g. RefCell
|
fn lookup(&mut self, lval: &Lvalue<'tcx>) -> Lookup<MovePathIndex> {
|
||||||
// or some other &-safe data accumulator)
|
let proj = {
|
||||||
//
|
|
||||||
// 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 = {
|
|
||||||
let mut rev_lookup = self.rev_lookup.borrow_mut();
|
let mut rev_lookup = self.rev_lookup.borrow_mut();
|
||||||
match *lval {
|
match *lval {
|
||||||
Lvalue::Var(var_idx) =>
|
Lvalue::Var(var_idx) =>
|
||||||
rev_lookup.lookup_var(var_idx),
|
return rev_lookup.lookup_var(var_idx),
|
||||||
Lvalue::Temp(temp_idx) =>
|
Lvalue::Temp(temp_idx) =>
|
||||||
rev_lookup.lookup_temp(temp_idx),
|
return rev_lookup.lookup_temp(temp_idx),
|
||||||
Lvalue::Arg(arg_idx) =>
|
Lvalue::Arg(arg_idx) =>
|
||||||
rev_lookup.lookup_arg(arg_idx),
|
return rev_lookup.lookup_arg(arg_idx),
|
||||||
Lvalue::Static(_def_id) =>
|
Lvalue::Static(_def_id) =>
|
||||||
rev_lookup.lookup_static(),
|
return rev_lookup.lookup_static(),
|
||||||
Lvalue::ReturnPointer =>
|
Lvalue::ReturnPointer =>
|
||||||
rev_lookup.lookup_return_pointer(),
|
return rev_lookup.lookup_return_pointer(),
|
||||||
Lvalue::Projection(ref proj) => {
|
Lvalue::Projection(ref proj) => {
|
||||||
// Manually drop the rev_lookup ...
|
proj
|
||||||
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)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
// 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
|
// ... restablish exclusive access to rev_lookup here.
|
||||||
// index or a newly-allocated one.
|
let mut rev_lookup = self.rev_lookup.borrow_mut();
|
||||||
debug_assert!(lookup.idx() <= pre_move_paths.len());
|
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 {
|
if let Lookup(LookupKind::Generate, mpi) = lookup {
|
||||||
let parent;
|
let parent;
|
||||||
|
@ -462,14 +459,13 @@ impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
|
||||||
content = Some(lval);
|
content = Some(lval);
|
||||||
|
|
||||||
// Here, install new MovePath as new first_child.
|
// Here, install new MovePath as new first_child.
|
||||||
drop(pre_move_paths);
|
|
||||||
|
|
||||||
// Note: `parent` previously allocated (Projection
|
// Note: `parent` previously allocated (Projection
|
||||||
// case of match above established this).
|
// case of match above established this).
|
||||||
let idx = self.move_path_for(&proj.base);
|
let idx = self.move_path_for(&proj.base);
|
||||||
parent = Some(idx);
|
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()];
|
let parent_move_path = &mut pre_move_paths[idx.idx()];
|
||||||
|
|
||||||
// At last: Swap in the new first_child.
|
// At last: Swap in the new first_child.
|
||||||
|
@ -490,6 +486,7 @@ impl<'a, 'tcx> MovePathDataBuilder<'a, 'tcx> {
|
||||||
first_child: Cell::new(None),
|
first_child: Cell::new(None),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let mut pre_move_paths = self.pre_move_paths.borrow_mut();
|
||||||
pre_move_paths.push(move_path);
|
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 loc_map: Vec<_> = iter::repeat(Vec::new()).take(bbs.len()).collect();
|
||||||
let mut path_map = Vec::new();
|
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,
|
mir: mir,
|
||||||
pre_move_paths: RefCell::new(Vec::new()),
|
pre_move_paths: RefCell::new(Vec::new()),
|
||||||
rev_lookup: RefCell::new(MovePathLookup::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 {
|
let mut bb_ctxt = BlockContext {
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
moves: &mut moves,
|
moves: &mut moves,
|
||||||
builder: &builder,
|
builder: builder,
|
||||||
path_map: &mut path_map,
|
path_map: &mut path_map,
|
||||||
loc_map_bb: loc_map_bb,
|
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 {
|
match stmt.kind {
|
||||||
StatementKind::Assign(ref lval, ref rval) => {
|
StatementKind::Assign(ref lval, ref rval) => {
|
||||||
// ensure MovePath created for `lval`.
|
// ensure MovePath created for `lval`.
|
||||||
builder.move_path_for(lval);
|
bb_ctxt.builder.move_path_for(lval);
|
||||||
|
|
||||||
match *rval {
|
match *rval {
|
||||||
Rvalue::Use(ref operand) => {
|
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 {
|
if let Some((ref destination, _bb)) = *destination {
|
||||||
// Create MovePath for `destination`, then
|
// Create MovePath for `destination`, then
|
||||||
// discard returned index.
|
// 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
|
// 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> {
|
struct BlockContext<'b, 'a: 'b, 'tcx: 'a> {
|
||||||
tcx: &'b ty::TyCtxt<'tcx>,
|
tcx: &'b ty::TyCtxt<'tcx>,
|
||||||
moves: &'b mut Vec<MoveOut>,
|
moves: &'b mut Vec<MoveOut>,
|
||||||
builder: &'b MovePathDataBuilder<'a, 'tcx>,
|
builder: MovePathDataBuilder<'a, 'tcx>,
|
||||||
path_map: &'b mut Vec<Vec<MoveOutIndex>>,
|
path_map: &'b mut Vec<Vec<MoveOutIndex>>,
|
||||||
loc_map_bb: &'b mut Vec<Vec<MoveOutIndex>>,
|
loc_map_bb: &'b mut Vec<Vec<MoveOutIndex>>,
|
||||||
}
|
}
|
||||||
|
@ -687,9 +689,8 @@ impl<'b, 'a: 'b, 'tcx: 'a> BlockContext<'b, 'a, 'tcx> {
|
||||||
stmt_kind: StmtKind,
|
stmt_kind: StmtKind,
|
||||||
lval: &repr::Lvalue<'tcx>,
|
lval: &repr::Lvalue<'tcx>,
|
||||||
source: Location) {
|
source: Location) {
|
||||||
let builder = self.builder;
|
|
||||||
let tcx = self.tcx;
|
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
|
// FIXME: does lvalue_ty ever return TyError, or is it
|
||||||
// guaranteed to always return non-Infer/non-Error values?
|
// guaranteed to always return non-Infer/non-Error values?
|
||||||
|
@ -710,7 +711,7 @@ impl<'b, 'a: 'b, 'tcx: 'a> BlockContext<'b, 'a, 'tcx> {
|
||||||
let i = source.index;
|
let i = source.index;
|
||||||
let index = MoveOutIndex::new(self.moves.len());
|
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.moves.push(MoveOut { path: path, source: source.clone() });
|
||||||
self.path_map.fill_to(path.idx());
|
self.path_map.fill_to(path.idx());
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue