flowistry_ide/focus/
direct_influence.rs

1use 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}