1
1
//! Random access inspection of the results of a dataflow analysis.
2
2
3
3
use std:: cmp:: Ordering ;
4
+ use std:: ops:: Deref ;
4
5
5
6
#[ cfg( debug_assertions) ]
6
7
use rustc_index:: bit_set:: BitSet ;
7
8
use rustc_middle:: mir:: { self , BasicBlock , Location } ;
8
9
9
10
use super :: { Analysis , Direction , Effect , EffectIndex , Results } ;
10
11
12
+ /// Some `ResultsCursor`s want to own a `Results`, and some want to borrow a `Results`. This type
13
+ /// allows either. We could use `Cow` but that would require `Results` and `A` to impl `Clone`. So
14
+ /// this is a greatly cut-down alternative to `Cow`.
15
+ pub enum ResultsHandle < ' a , ' tcx , A >
16
+ where
17
+ A : Analysis < ' tcx > ,
18
+ {
19
+ Borrowed ( & ' a Results < ' tcx , A > ) ,
20
+ Owned ( Results < ' tcx , A > ) ,
21
+ }
22
+
23
+ impl < ' tcx , A > Deref for ResultsHandle < ' _ , ' tcx , A >
24
+ where
25
+ A : Analysis < ' tcx > ,
26
+ {
27
+ type Target = Results < ' tcx , A > ;
28
+
29
+ fn deref ( & self ) -> & Results < ' tcx , A > {
30
+ match self {
31
+ ResultsHandle :: Borrowed ( borrowed) => borrowed,
32
+ ResultsHandle :: Owned ( owned) => owned,
33
+ }
34
+ }
35
+ }
36
+
11
37
/// Allows random access inspection of the results of a dataflow analysis.
12
38
///
13
39
/// This cursor only has linear performance within a basic block when its statements are visited in
19
45
A : Analysis < ' tcx > ,
20
46
{
21
47
body : & ' mir mir:: Body < ' tcx > ,
22
- results : Results < ' tcx , A > ,
48
+ results : ResultsHandle < ' mir , ' tcx , A > ,
23
49
state : A :: Domain ,
24
50
25
51
pos : CursorPosition ,
47
73
self . body
48
74
}
49
75
50
- /// Unwraps this cursor, returning the underlying `Results`.
51
- pub fn into_results ( self ) -> Results < ' tcx , A > {
52
- self . results
53
- }
54
-
55
76
/// Returns a new cursor that can inspect `results`.
56
- pub fn new ( body : & ' mir mir:: Body < ' tcx > , results : Results < ' tcx , A > ) -> Self {
77
+ pub fn new ( body : & ' mir mir:: Body < ' tcx > , results : ResultsHandle < ' mir , ' tcx , A > ) -> Self {
57
78
let bottom_value = results. analysis . bottom_value ( body) ;
58
79
ResultsCursor {
59
80
body,
@@ -83,21 +104,11 @@ where
83
104
& self . results
84
105
}
85
106
86
- /// Returns the underlying `Results`.
87
- pub fn mut_results ( & mut self ) -> & mut Results < ' tcx , A > {
88
- & mut self . results
89
- }
90
-
91
107
/// Returns the `Analysis` used to generate the underlying `Results`.
92
108
pub fn analysis ( & self ) -> & A {
93
109
& self . results . analysis
94
110
}
95
111
96
- /// Returns the `Analysis` used to generate the underlying `Results`.
97
- pub fn mut_analysis ( & mut self ) -> & mut A {
98
- & mut self . results . analysis
99
- }
100
-
101
112
/// Resets the cursor to hold the entry set for the given basic block.
102
113
///
103
114
/// For forward dataflow analyses, this is the dataflow state prior to the first statement.
@@ -199,7 +210,7 @@ where
199
210
let target_effect_index = effect. at_index ( target. statement_index ) ;
200
211
201
212
A :: Direction :: apply_effects_in_range (
202
- & mut self . results . analysis ,
213
+ & self . results . analysis ,
203
214
& mut self . state ,
204
215
target. block ,
205
216
block_data,
@@ -214,8 +225,8 @@ where
214
225
///
215
226
/// This can be used, e.g., to apply the call return effect directly to the cursor without
216
227
/// creating an extra copy of the dataflow state.
217
- pub fn apply_custom_effect ( & mut self , f : impl FnOnce ( & mut A , & mut A :: Domain ) ) {
218
- f ( & mut self . results . analysis , & mut self . state ) ;
228
+ pub fn apply_custom_effect ( & mut self , f : impl FnOnce ( & A , & mut A :: Domain ) ) {
229
+ f ( & self . results . analysis , & mut self . state ) ;
219
230
self . state_needs_reset = true ;
220
231
}
221
232
}
0 commit comments