11//! Random access inspection of the results of a dataflow analysis.
22
33use std:: cmp:: Ordering ;
4+ use std:: ops:: Deref ;
45
56#[ cfg( debug_assertions) ]
67use rustc_index:: bit_set:: BitSet ;
78use rustc_middle:: mir:: { self , BasicBlock , Location } ;
89
910use super :: { Analysis , Direction , Effect , EffectIndex , Results } ;
1011
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+
1137/// Allows random access inspection of the results of a dataflow analysis.
1238///
1339/// This cursor only has linear performance within a basic block when its statements are visited in
1945 A : Analysis < ' tcx > ,
2046{
2147 body : & ' mir mir:: Body < ' tcx > ,
22- results : Results < ' tcx , A > ,
48+ results : ResultsHandle < ' mir , ' tcx , A > ,
2349 state : A :: Domain ,
2450
2551 pos : CursorPosition ,
4773 self . body
4874 }
4975
50- /// Unwraps this cursor, returning the underlying `Results`.
51- pub fn into_results ( self ) -> Results < ' tcx , A > {
52- self . results
53- }
54-
5576 /// 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 {
5778 let bottom_value = results. analysis . bottom_value ( body) ;
5879 ResultsCursor {
5980 body,
@@ -83,21 +104,11 @@ where
83104 & self . results
84105 }
85106
86- /// Returns the underlying `Results`.
87- pub fn mut_results ( & mut self ) -> & mut Results < ' tcx , A > {
88- & mut self . results
89- }
90-
91107 /// Returns the `Analysis` used to generate the underlying `Results`.
92108 pub fn analysis ( & self ) -> & A {
93109 & self . results . analysis
94110 }
95111
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-
101112 /// Resets the cursor to hold the entry set for the given basic block.
102113 ///
103114 /// For forward dataflow analyses, this is the dataflow state prior to the first statement.
@@ -199,7 +210,7 @@ where
199210 let target_effect_index = effect. at_index ( target. statement_index ) ;
200211
201212 A :: Direction :: apply_effects_in_range (
202- & mut self . results . analysis ,
213+ & self . results . analysis ,
203214 & mut self . state ,
204215 target. block ,
205216 block_data,
@@ -214,8 +225,8 @@ where
214225 ///
215226 /// This can be used, e.g., to apply the call return effect directly to the cursor without
216227 /// 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 ) ;
219230 self . state_needs_reset = true ;
220231 }
221232}
0 commit comments