1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
use rustc::mir::visit::{PlaceContext, Visitor};
use rustc::mir::{Local, Location, Place};
use rustc_data_structures::fx::FxHashSet;
use borrow_check::MirBorrowckCtxt;
use util::collect_writes::is_place_assignment;
impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> {
crate fn gather_used_muts(&mut self, locals: FxHashSet<Local>) {
let mut visitor = GatherUsedMutsVisitor {
needles: locals,
mbcx: self,
};
visitor.visit_mir(visitor.mbcx.mir);
}
}
struct GatherUsedMutsVisitor<'visit, 'cx: 'visit, 'gcx: 'tcx, 'tcx: 'cx> {
needles: FxHashSet<Local>,
mbcx: &'visit mut MirBorrowckCtxt<'cx, 'gcx, 'tcx>,
}
impl<'visit, 'cx, 'gcx, 'tcx> Visitor<'tcx> for GatherUsedMutsVisitor<'visit, 'cx, 'gcx, 'tcx> {
fn visit_local(
&mut self,
local: &Local,
place_context: PlaceContext<'tcx>,
location: Location,
) {
if !self.needles.contains(local) {
return;
}
if is_place_assignment(&place_context) {
for moi in &self.mbcx.move_data.loc_map[location] {
let mpi = &self.mbcx.move_data.moves[*moi].path;
let path = &self.mbcx.move_data.move_paths[*mpi];
debug!(
"assignment of {:?} to {:?}, adding {:?} to used mutable set",
path.place, local, path.place
);
if let Place::Local(user_local) = path.place {
self.mbcx.used_mut.insert(user_local);
}
}
}
}
}