11//! Random access inspection of the results of a dataflow analysis.
22
3- use crate :: { framework:: BitSetExt , CloneAnalysis } ;
3+ use crate :: framework:: BitSetExt ;
44
5- use std:: borrow:: { Borrow , BorrowMut } ;
65use std:: cmp:: Ordering ;
76
87#[ cfg( debug_assertions) ]
98use rustc_index:: bit_set:: BitSet ;
109use rustc_middle:: mir:: { self , BasicBlock , Location } ;
1110
12- use super :: { Analysis , Direction , Effect , EffectIndex , EntrySets , Results , ResultsCloned } ;
13-
14- // `AnalysisResults` is needed as an impl such as the following has an unconstrained type
15- // parameter:
16- // ```
17- // impl<'tcx, A, E, R> ResultsCursor<'_, 'tcx, A, R>
18- // where
19- // A: Analysis<'tcx>,
20- // E: Borrow<EntrySets<'tcx, A>>,
21- // R: Results<'tcx, A, E>,
22- // {}
23- // ```
24-
25- /// A type representing the analysis results consumed by a `ResultsCursor`.
26- pub trait AnalysisResults < ' tcx , A > : BorrowMut < Results < ' tcx , A , Self :: EntrySets > >
27- where
28- A : Analysis < ' tcx > ,
29- {
30- /// The type containing the entry sets for this `Results` type.
31- ///
32- /// Should be either `EntrySets<'tcx, A>` or `&EntrySets<'tcx, A>`.
33- type EntrySets : Borrow < EntrySets < ' tcx , A > > ;
34- }
35- impl < ' tcx , A , E > AnalysisResults < ' tcx , A > for Results < ' tcx , A , E >
36- where
37- A : Analysis < ' tcx > ,
38- E : Borrow < EntrySets < ' tcx , A > > ,
39- {
40- type EntrySets = E ;
41- }
42- impl < ' a , ' tcx , A , E > AnalysisResults < ' tcx , A > for & ' a mut Results < ' tcx , A , E >
43- where
44- A : Analysis < ' tcx > ,
45- E : Borrow < EntrySets < ' tcx , A > > ,
46- {
47- type EntrySets = E ;
48- }
49-
50- /// A `ResultsCursor` that borrows the underlying `Results`.
51- pub type ResultsRefCursor < ' res , ' mir , ' tcx , A > =
52- ResultsCursor < ' mir , ' tcx , A , & ' res mut Results < ' tcx , A > > ;
53-
54- /// A `ResultsCursor` which uses a cloned `Analysis` while borrowing the underlying `Results`. This
55- /// allows multiple cursors over the same `Results`.
56- pub type ResultsClonedCursor < ' res , ' mir , ' tcx , A > =
57- ResultsCursor < ' mir , ' tcx , A , ResultsCloned < ' res , ' tcx , A > > ;
11+ use super :: { Analysis , Direction , Effect , EffectIndex , Results } ;
5812
5913/// Allows random access inspection of the results of a dataflow analysis.
6014///
6115/// This cursor only has linear performance within a basic block when its statements are visited in
6216/// the same order as the `DIRECTION` of the analysis. In the worst case—when statements are
6317/// visited in *reverse* order—performance will be quadratic in the number of statements in the
6418/// block. The order in which basic blocks are inspected has no impact on performance.
65- ///
66- /// A `ResultsCursor` can either own (the default) or borrow the dataflow results it inspects. The
67- /// type of ownership is determined by `R` (see `ResultsRefCursor` above).
68- pub struct ResultsCursor < ' mir , ' tcx , A , R = Results < ' tcx , A > >
19+ pub struct ResultsCursor < ' mir , ' tcx , A >
6920where
7021 A : Analysis < ' tcx > ,
7122{
7223 body : & ' mir mir:: Body < ' tcx > ,
73- results : R ,
24+ results : Results < ' tcx , A > ,
7425 state : A :: Domain ,
7526
7627 pos : CursorPosition ,
8435 reachable_blocks : BitSet < BasicBlock > ,
8536}
8637
87- impl < ' mir , ' tcx , A , R > ResultsCursor < ' mir , ' tcx , A , R >
38+ impl < ' mir , ' tcx , A > ResultsCursor < ' mir , ' tcx , A >
8839where
8940 A : Analysis < ' tcx > ,
9041{
@@ -99,30 +50,13 @@ where
9950 }
10051
10152 /// Unwraps this cursor, returning the underlying `Results`.
102- pub fn into_results ( self ) -> R {
53+ pub fn into_results ( self ) -> Results < ' tcx , A > {
10354 self . results
10455 }
105- }
10656
107- impl < ' res , ' mir , ' tcx , A > ResultsCursor < ' mir , ' tcx , A , ResultsCloned < ' res , ' tcx , A > >
108- where
109- A : Analysis < ' tcx > + CloneAnalysis ,
110- {
111- /// Creates a new cursor over the same `Results`. Note that the cursor's position is *not*
112- /// copied.
113- pub fn new_cursor ( & self ) -> Self {
114- Self :: new ( self . body , self . results . reclone_analysis ( ) )
115- }
116- }
117-
118- impl < ' mir , ' tcx , A , R > ResultsCursor < ' mir , ' tcx , A , R >
119- where
120- A : Analysis < ' tcx > ,
121- R : AnalysisResults < ' tcx , A > ,
122- {
12357 /// Returns a new cursor that can inspect `results`.
124- pub fn new ( body : & ' mir mir:: Body < ' tcx > , results : R ) -> Self {
125- let bottom_value = results. borrow ( ) . analysis . bottom_value ( body) ;
58+ pub fn new ( body : & ' mir mir:: Body < ' tcx > , results : Results < ' tcx , A > ) -> Self {
59+ let bottom_value = results. analysis . bottom_value ( body) ;
12660 ResultsCursor {
12761 body,
12862 results,
@@ -147,28 +81,23 @@ where
14781 }
14882
14983 /// Returns the underlying `Results`.
150- pub fn results ( & mut self ) -> & Results < ' tcx , A , R :: EntrySets > {
151- self . results . borrow ( )
84+ pub fn results ( & self ) -> & Results < ' tcx , A > {
85+ & self . results
15286 }
15387
15488 /// Returns the underlying `Results`.
155- pub fn mut_results ( & mut self ) -> & mut Results < ' tcx , A , R :: EntrySets > {
156- self . results . borrow_mut ( )
89+ pub fn mut_results ( & mut self ) -> & mut Results < ' tcx , A > {
90+ & mut self . results
15791 }
15892
15993 /// Returns the `Analysis` used to generate the underlying `Results`.
16094 pub fn analysis ( & self ) -> & A {
161- & self . results . borrow ( ) . analysis
95+ & self . results . analysis
16296 }
16397
16498 /// Returns the `Analysis` used to generate the underlying `Results`.
16599 pub fn mut_analysis ( & mut self ) -> & mut A {
166- & mut self . results . borrow_mut ( ) . analysis
167- }
168-
169- /// Returns both the dataflow state at the current location and the `Analysis`.
170- pub fn get_with_analysis ( & mut self ) -> ( & A :: Domain , & mut A ) {
171- ( & self . state , & mut self . results . borrow_mut ( ) . analysis )
100+ & mut self . results . analysis
172101 }
173102
174103 /// Resets the cursor to hold the entry set for the given basic block.
@@ -180,7 +109,7 @@ where
180109 #[ cfg( debug_assertions) ]
181110 assert ! ( self . reachable_blocks. contains( block) ) ;
182111
183- self . state . clone_from ( self . results . borrow ( ) . entry_set_for_block ( block) ) ;
112+ self . state . clone_from ( self . results . entry_set_for_block ( block) ) ;
184113 self . pos = CursorPosition :: block_entry ( block) ;
185114 self . state_needs_reset = false ;
186115 }
@@ -269,11 +198,10 @@ where
269198 )
270199 } ;
271200
272- let analysis = & mut self . results . borrow_mut ( ) . analysis ;
273201 let target_effect_index = effect. at_index ( target. statement_index ) ;
274202
275203 A :: Direction :: apply_effects_in_range (
276- analysis,
204+ & mut self . results . analysis ,
277205 & mut self . state ,
278206 target. block ,
279207 block_data,
@@ -289,12 +217,12 @@ where
289217 /// This can be used, e.g., to apply the call return effect directly to the cursor without
290218 /// creating an extra copy of the dataflow state.
291219 pub fn apply_custom_effect ( & mut self , f : impl FnOnce ( & mut A , & mut A :: Domain ) ) {
292- f ( & mut self . results . borrow_mut ( ) . analysis , & mut self . state ) ;
220+ f ( & mut self . results . analysis , & mut self . state ) ;
293221 self . state_needs_reset = true ;
294222 }
295223}
296224
297- impl < ' mir , ' tcx , A , R > ResultsCursor < ' mir , ' tcx , A , R >
225+ impl < ' mir , ' tcx , A > ResultsCursor < ' mir , ' tcx , A >
298226where
299227 A : crate :: GenKillAnalysis < ' tcx > ,
300228 A :: Domain : BitSetExt < A :: Idx > ,
0 commit comments