1use rustc_middle::mir::{self, BasicBlock, Location, traversal};
23use super::{Analysis, Direction, Results};
45/// 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: &Results<'tcx, A>,
11 vis: &mut impl ResultsVisitor<'tcx, A>,
12) where
13A: Analysis<'tcx>,
14{
15let mut state = results.analysis.bottom_value(body);
1617#[cfg(debug_assertions)]
18let reachable_blocks = mir::traversal::reachable_as_bitset(body);
1920for block in blocks {
21#[cfg(debug_assertions)]
22if !reachable_blocks.contains(block) {
::core::panicking::panic("assertion failed: reachable_blocks.contains(block)")
};assert!(reachable_blocks.contains(block));
2324let block_data = &body[block];
25 state.clone_from(&results.entry_states[block]);
26 A::Direction::visit_results_in_block(&results.analysis, &mut state, block, block_data, vis);
27 }
28}
2930/// Like `visit_results`, but only for reachable blocks.
31pub fn visit_reachable_results<'mir, 'tcx, A>(
32 body: &'mir mir::Body<'tcx>,
33 results: &Results<'tcx, A>,
34 vis: &mut impl ResultsVisitor<'tcx, A>,
35) where
36A: Analysis<'tcx>,
37{
38let blocks = traversal::reachable(body).map(|(bb, _)| bb);
39visit_results(body, blocks, results, vis)
40}
4142/// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in
43/// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain
44/// locations.
45pub trait ResultsVisitor<'tcx, A>
46where
47A: Analysis<'tcx>,
48{
49/// Called after the "early" effect of the given statement is applied to `state`.
50fn visit_after_early_statement_effect(
51&mut self,
52 _analysis: &A,
53 _state: &A::Domain,
54 _statement: &mir::Statement<'tcx>,
55 _location: Location,
56 ) {
57 }
5859/// Called after the "primary" effect of the given statement is applied to `state`.
60fn visit_after_primary_statement_effect(
61&mut self,
62 _analysis: &A,
63 _state: &A::Domain,
64 _statement: &mir::Statement<'tcx>,
65 _location: Location,
66 ) {
67 }
6869/// Called after the "early" effect of the given terminator is applied to `state`.
70fn visit_after_early_terminator_effect(
71&mut self,
72 _analysis: &A,
73 _state: &A::Domain,
74 _terminator: &mir::Terminator<'tcx>,
75 _location: Location,
76 ) {
77 }
7879/// Called after the "primary" effect of the given terminator is applied to `state`.
80 ///
81 /// The `call_return_effect` (if one exists) will *not* be applied to `state`.
82fn visit_after_primary_terminator_effect(
83&mut self,
84 _analysis: &A,
85 _state: &A::Domain,
86 _terminator: &mir::Terminator<'tcx>,
87 _location: Location,
88 ) {
89 }
90}