rustc_mir_dataflow/framework/
visitor.rs

1use rustc_middle::mir::{self, BasicBlock, Location};
2
3use super::{Analysis, Direction, Results};
4
5/// Calls the corresponding method in `ResultsVisitor` for every location in a `mir::Body` with the
6/// dataflow state at that location.
7pub fn visit_results<'mir, 'tcx, A>(
8    body: &'mir mir::Body<'tcx>,
9    blocks: impl IntoIterator<Item = BasicBlock>,
10    results: &mut Results<'tcx, A>,
11    vis: &mut impl ResultsVisitor<'mir, 'tcx, A>,
12) where
13    A: Analysis<'tcx>,
14{
15    let mut state = results.analysis.bottom_value(body);
16
17    #[cfg(debug_assertions)]
18    let reachable_blocks = mir::traversal::reachable_as_bitset(body);
19
20    for block in blocks {
21        #[cfg(debug_assertions)]
22        assert!(reachable_blocks.contains(block));
23
24        let block_data = &body[block];
25        A::Direction::visit_results_in_block(&mut state, block, block_data, results, vis);
26    }
27}
28
29/// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in
30/// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain
31/// locations.
32pub trait ResultsVisitor<'mir, 'tcx, A>
33where
34    A: Analysis<'tcx>,
35{
36    fn visit_block_start(&mut self, _state: &A::Domain) {}
37
38    /// Called after the "early" effect of the given statement is applied to `state`.
39    fn visit_after_early_statement_effect(
40        &mut self,
41        _results: &mut Results<'tcx, A>,
42        _state: &A::Domain,
43        _statement: &'mir mir::Statement<'tcx>,
44        _location: Location,
45    ) {
46    }
47
48    /// Called after the "primary" effect of the given statement is applied to `state`.
49    fn visit_after_primary_statement_effect(
50        &mut self,
51        _results: &mut Results<'tcx, A>,
52        _state: &A::Domain,
53        _statement: &'mir mir::Statement<'tcx>,
54        _location: Location,
55    ) {
56    }
57
58    /// Called after the "early" effect of the given terminator is applied to `state`.
59    fn visit_after_early_terminator_effect(
60        &mut self,
61        _results: &mut Results<'tcx, A>,
62        _state: &A::Domain,
63        _terminator: &'mir mir::Terminator<'tcx>,
64        _location: Location,
65    ) {
66    }
67
68    /// Called after the "primary" effect of the given terminator is applied to `state`.
69    ///
70    /// The `call_return_effect` (if one exists) will *not* be applied to `state`.
71    fn visit_after_primary_terminator_effect(
72        &mut self,
73        _results: &mut Results<'tcx, A>,
74        _state: &A::Domain,
75        _terminator: &'mir mir::Terminator<'tcx>,
76        _location: Location,
77    ) {
78    }
79
80    fn visit_block_end(&mut self, _state: &A::Domain) {}
81}