Auto merge of #148324 - Zalathar:rollup-yp35ktq, r=Zalathar · rust-lang/rust@51f5892 (original) (raw)
1
1
`//! Random access inspection of the results of a dataflow analysis.
`
2
2
``
3
``
`-
use std::borrow::Cow;
`
4
3
`use std::cmp::Ordering;
`
5
``
`-
use std::ops::{Deref, DerefMut};
`
``
4
`+
use std::ops::Deref;
`
6
5
``
7
6
`#[cfg(debug_assertions)]
`
8
7
`use rustc_index::bit_set::DenseBitSet;
`
9
8
`use rustc_middle::mir::{self, BasicBlock, Location};
`
10
9
``
11
10
`use super::{Analysis, Direction, Effect, EffectIndex, Results};
`
12
11
``
13
``
`` -
/// Some ResultsCursors want to own an Analysis, and some want to borrow an Analysis, either
``
14
``
`` -
/// mutable or immutably. This type allows all of the above. It's similar to Cow, but Cow
``
15
``
`-
/// doesn't allow mutable borrowing.
`
16
``
`-
enum CowMut<'a, T> {
`
17
``
`-
BorrowedMut(&'a mut T),
`
``
12
`` +
/// This is like Cow, but it lacks the T: ToOwned bound and doesn't support
``
``
13
`` +
/// to_owned/into_owned.
``
``
14
`+
enum SimpleCow<'a, T> {
`
``
15
`+
Borrowed(&'a T),
`
18
16
`Owned(T),
`
19
17
`}
`
20
18
``
21
``
`-
impl Deref for CowMut<'_, T> {
`
``
19
`+
impl Deref for SimpleCow<'_, T> {
`
22
20
`type Target = T;
`
23
21
``
24
22
`fn deref(&self) -> &T {
`
25
23
`match self {
`
26
``
`-
CowMut::BorrowedMut(borrowed) => borrowed,
`
27
``
`-
CowMut::Owned(owned) => owned,
`
28
``
`-
}
`
29
``
`-
}
`
30
``
`-
}
`
31
``
-
32
``
`-
impl DerefMut for CowMut<'_, T> {
`
33
``
`-
fn deref_mut(&mut self) -> &mut T {
`
34
``
`-
match self {
`
35
``
`-
CowMut::BorrowedMut(borrowed) => borrowed,
`
36
``
`-
CowMut::Owned(owned) => owned,
`
``
24
`+
SimpleCow::Borrowed(borrowed) => borrowed,
`
``
25
`+
SimpleCow::Owned(owned) => owned,
`
37
26
`}
`
38
27
`}
`
39
28
`}
`
`@@ -53,8 +42,7 @@ where
`
53
42
`A: Analysis<'tcx>,
`
54
43
`{
`
55
44
`body: &'mir mir::Body<'tcx>,
`
56
``
`-
analysis: CowMut<'mir, A>,
`
57
``
`-
results: Cow<'mir, Results<A::Domain>>,
`
``
45
`+
results: SimpleCow<'mir, Results<'tcx, A>>,
`
58
46
`state: A::Domain,
`
59
47
``
60
48
`pos: CursorPosition,
`
`@@ -82,15 +70,10 @@ where
`
82
70
`self.body
`
83
71
`}
`
84
72
``
85
``
`-
fn new(
`
86
``
`-
body: &'mir mir::Body<'tcx>,
`
87
``
`-
analysis: CowMut<'mir, A>,
`
88
``
`-
results: Cow<'mir, Results<A::Domain>>,
`
89
``
`-
) -> Self {
`
90
``
`-
let bottom_value = analysis.bottom_value(body);
`
``
73
`+
fn new(body: &'mir mir::Body<'tcx>, results: SimpleCow<'mir, Results<'tcx, A>>) -> Self {
`
``
74
`+
let bottom_value = results.analysis.bottom_value(body);
`
91
75
`ResultsCursor {
`
92
76
` body,
`
93
``
`-
analysis,
`
94
77
` results,
`
95
78
``
96
79
`` // Initialize to the bottom_value and set state_needs_reset to tell the cursor that
``
`@@ -106,21 +89,13 @@ where
`
106
89
`}
`
107
90
``
108
91
`/// Returns a new cursor that takes ownership of and inspects analysis results.
`
109
``
`-
pub fn new_owning(
`
110
``
`-
body: &'mir mir::Body<'tcx>,
`
111
``
`-
analysis: A,
`
112
``
`-
results: Results<A::Domain>,
`
113
``
`-
) -> Self {
`
114
``
`-
Self::new(body, CowMut::Owned(analysis), Cow::Owned(results))
`
``
92
`+
pub fn new_owning(body: &'mir mir::Body<'tcx>, results: Results<'tcx, A>) -> Self {
`
``
93
`+
Self::new(body, SimpleCow::Owned(results))
`
115
94
`}
`
116
95
``
117
96
`/// Returns a new cursor that borrows and inspects analysis results.
`
118
``
`-
pub fn new_borrowing(
`
119
``
`-
body: &'mir mir::Body<'tcx>,
`
120
``
`-
analysis: &'mir mut A,
`
121
``
`-
results: &'mir Results<A::Domain>,
`
122
``
`-
) -> Self {
`
123
``
`-
Self::new(body, CowMut::BorrowedMut(analysis), Cow::Borrowed(results))
`
``
97
`+
pub fn new_borrowing(body: &'mir mir::Body<'tcx>, results: &'mir Results<'tcx, A>) -> Self {
`
``
98
`+
Self::new(body, SimpleCow::Borrowed(results))
`
124
99
`}
`
125
100
``
126
101
`` /// Allows inspection of unreachable basic blocks even with debug_assertions enabled.
``
`@@ -132,7 +107,7 @@ where
`
132
107
``
133
108
`` /// Returns the Analysis used to generate the underlying Results.
``
134
109
`pub fn analysis(&self) -> &A {
`
135
``
`-
&self.analysis
`
``
110
`+
&self.results.analysis
`
136
111
`}
`
137
112
``
138
113
`/// Resets the cursor to hold the entry set for the given basic block.
`
`@@ -144,7 +119,7 @@ where
`
144
119
`#[cfg(debug_assertions)]
`
145
120
`assert!(self.reachable_blocks.contains(block));
`
146
121
``
147
``
`-
self.state.clone_from(&self.results[block]);
`
``
122
`+
self.state.clone_from(&self.results.entry_states[block]);
`
148
123
`self.pos = CursorPosition::block_entry(block);
`
149
124
`self.state_needs_reset = false;
`
150
125
`}
`
`@@ -236,7 +211,7 @@ where
`
236
211
`let target_effect_index = effect.at_index(target.statement_index);
`
237
212
``
238
213
`A::Direction::apply_effects_in_range(
`
239
``
`-
&mut *self.analysis,
`
``
214
`+
&self.results.analysis,
`
240
215
`&mut self.state,
`
241
216
` target.block,
`
242
217
` block_data,
`
`@@ -251,8 +226,8 @@ where
`
251
226
`///
`
252
227
`/// This can be used, e.g., to apply the call return effect directly to the cursor without
`
253
228
`/// creating an extra copy of the dataflow state.
`
254
``
`-
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&mut A, &mut A::Domain)) {
`
255
``
`-
f(&mut self.analysis, &mut self.state);
`
``
229
`+
pub fn apply_custom_effect(&mut self, f: impl FnOnce(&A, &mut A::Domain)) {
`
``
230
`+
f(&self.results.analysis, &mut self.state);
`
256
231
`self.state_needs_reset = true;
`
257
232
`}
`
258
233
`}
`