flowistry_ide/focus/
direct_influence.rs1use flowistry::{
2 infoflow::mutation::{ModularMutationVisitor, Mutation},
3 mir::placeinfo::PlaceInfo,
4};
5use indexical::bitset::rustc::IndexMatrix;
6use rustc_middle::mir::{Body, Mutability, Place, visit::Visitor};
7use rustc_utils::mir::location_or_arg::LocationOrArg;
8
9pub struct DirectInfluence<'a, 'tcx> {
10 place_info: &'a PlaceInfo<'a, 'tcx>,
11 influence: IndexMatrix<Place<'tcx>, LocationOrArg>,
12}
13
14impl<'a, 'tcx> DirectInfluence<'a, 'tcx> {
15 pub fn build(body: &Body<'tcx>, place_info: &'a PlaceInfo<'a, 'tcx>) -> Self {
16 let mut influence = IndexMatrix::new(place_info.location_domain());
17
18 ModularMutationVisitor::new(place_info, |location, mutations| {
19 let mut add = |place: Place<'tcx>, mutability: Mutability| {
20 for alias in place_info.reachable_values(place, mutability) {
21 influence.insert(*alias, location);
22 }
23 };
24
25 for Mutation {
26 mutated, inputs, ..
27 } in mutations
28 {
29 for input in inputs {
30 add(input, Mutability::Not);
31 }
32
33 add(mutated, Mutability::Mut);
34 }
35 })
36 .visit_body(body);
37
38 DirectInfluence {
39 place_info,
40 influence,
41 }
42 }
43
44 pub fn lookup(&self, target: Place<'tcx>) -> Vec<LocationOrArg> {
45 let aliases = self.place_info.reachable_values(target, Mutability::Not);
46 aliases
47 .iter()
48 .flat_map(|target_alias| {
49 self
50 .influence
51 .row_set(target_alias)
52 .iter()
53 .copied()
54 .collect::<Vec<_>>()
55 })
56 .collect::<Vec<_>>()
57 }
58}