@@ -76,7 +76,7 @@ pub struct RequiresStorage<'mir, 'tcx> {
7676 borrowed_locals : RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
7777}
7878
79- impl < ' mir , ' tcx : ' mir > RequiresStorage < ' mir , ' tcx > {
79+ impl < ' mir , ' tcx > RequiresStorage < ' mir , ' tcx > {
8080 pub fn new (
8181 body : ReadOnlyBodyAndCache < ' mir , ' tcx > ,
8282 borrowed_locals : & ' mir Results < ' tcx , MaybeBorrowedLocals > ,
@@ -86,45 +86,47 @@ impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> {
8686 borrowed_locals : RefCell :: new ( ResultsRefCursor :: new ( * body, borrowed_locals) ) ,
8787 }
8888 }
89-
90- pub fn body ( & self ) -> & Body < ' tcx > {
91- & self . body
92- }
9389}
9490
95- impl < ' mir , ' tcx > BitDenotation < ' tcx > for RequiresStorage < ' mir , ' tcx > {
91+ impl < ' mir , ' tcx > dataflow :: AnalysisDomain < ' tcx > for RequiresStorage < ' mir , ' tcx > {
9692 type Idx = Local ;
97- fn name ( ) -> & ' static str {
98- "requires_storage"
99- }
100- fn bits_per_block ( & self ) -> usize {
101- self . body . local_decls . len ( )
93+
94+ const NAME : & ' static str = "requires_storage" ;
95+
96+ fn bits_per_block ( & self , body : & mir :: Body < ' tcx > ) -> usize {
97+ body. local_decls . len ( )
10298 }
10399
104- fn start_block_effect ( & self , on_entry : & mut BitSet < Local > ) {
100+ fn initialize_start_block ( & self , body : & mir :: Body < ' tcx > , on_entry : & mut BitSet < Self :: Idx > ) {
105101 // The resume argument is live on function entry (we don't care about
106102 // the `self` argument)
107- for arg in self . body . args_iter ( ) . skip ( 1 ) {
103+ for arg in body. args_iter ( ) . skip ( 1 ) {
108104 on_entry. insert ( arg) ;
109105 }
110106 }
107+ }
111108
112- fn before_statement_effect ( & self , sets : & mut GenKillSet < Self :: Idx > , loc : Location ) {
113- let stmt = & self . body [ loc. block ] . statements [ loc. statement_index ] ;
114-
109+ impl < ' mir , ' tcx > dataflow:: GenKillAnalysis < ' tcx > for RequiresStorage < ' mir , ' tcx > {
110+ fn before_statement_effect (
111+ & self ,
112+ trans : & mut impl GenKill < Self :: Idx > ,
113+ stmt : & mir:: Statement < ' tcx > ,
114+ loc : Location ,
115+ ) {
115116 // If a place is borrowed in a statement, it needs storage for that statement.
116- self . borrowed_locals . borrow ( ) . analysis ( ) . statement_effect ( sets , stmt, loc) ;
117+ self . borrowed_locals . borrow ( ) . analysis ( ) . statement_effect ( trans , stmt, loc) ;
117118
118- // If a place is assigned to in a statement, it needs storage for that statement.
119119 match & stmt. kind {
120- StatementKind :: StorageDead ( l) => sets. kill ( * l) ,
120+ StatementKind :: StorageDead ( l) => trans. kill ( * l) ,
121+
122+ // If a place is assigned to in a statement, it needs storage for that statement.
121123 StatementKind :: Assign ( box ( place, _) )
122124 | StatementKind :: SetDiscriminant { box place, .. } => {
123- sets . gen ( place. local ) ;
125+ trans . gen ( place. local ) ;
124126 }
125- StatementKind :: InlineAsm ( box InlineAsm { outputs , .. } ) => {
126- for place in & * * outputs {
127- sets . gen ( place. local ) ;
127+ StatementKind :: InlineAsm ( asm ) => {
128+ for place in & * asm . outputs {
129+ trans . gen ( place. local ) ;
128130 }
129131 }
130132
@@ -138,22 +140,30 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
138140 }
139141 }
140142
141- fn statement_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
143+ fn statement_effect (
144+ & self ,
145+ trans : & mut impl GenKill < Self :: Idx > ,
146+ _: & mir:: Statement < ' tcx > ,
147+ loc : Location ,
148+ ) {
142149 // If we move from a place then only stops needing storage *after*
143150 // that statement.
144- self . check_for_move ( sets , loc) ;
151+ self . check_for_move ( trans , loc) ;
145152 }
146153
147- fn before_terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
148- let terminator = self . body [ loc. block ] . terminator ( ) ;
149-
154+ fn before_terminator_effect (
155+ & self ,
156+ trans : & mut impl GenKill < Self :: Idx > ,
157+ terminator : & mir:: Terminator < ' tcx > ,
158+ loc : Location ,
159+ ) {
150160 // If a place is borrowed in a terminator, it needs storage for that terminator.
151- self . borrowed_locals . borrow ( ) . analysis ( ) . terminator_effect ( sets , terminator, loc) ;
161+ self . borrowed_locals . borrow ( ) . analysis ( ) . terminator_effect ( trans , terminator, loc) ;
152162
153163 match & terminator. kind {
154- TerminatorKind :: Call { destination : Some ( ( Place { local , .. } , _) ) , .. }
155- | TerminatorKind :: Yield { resume_arg : Place { local , .. } , .. } => {
156- sets . gen ( * local) ;
164+ TerminatorKind :: Call { destination : Some ( ( place , _) ) , .. }
165+ | TerminatorKind :: Yield { resume_arg : place , .. } => {
166+ trans . gen ( place . local ) ;
157167 }
158168
159169 // Nothing to do for these. Match exhaustively so this fails to compile when new
@@ -174,14 +184,19 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
174184 }
175185 }
176186
177- fn terminator_effect ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
178- match & self . body [ loc. block ] . terminator ( ) . kind {
187+ fn terminator_effect (
188+ & self ,
189+ trans : & mut impl GenKill < Self :: Idx > ,
190+ terminator : & mir:: Terminator < ' tcx > ,
191+ loc : Location ,
192+ ) {
193+ match & terminator. kind {
179194 // For call terminators the destination requires storage for the call
180195 // and after the call returns successfully, but not after a panic.
181196 // Since `propagate_call_unwind` doesn't exist, we have to kill the
182- // destination here, and then gen it again in `propagate_call_return `.
183- TerminatorKind :: Call { destination : Some ( ( Place { local , .. } , _) ) , .. } => {
184- sets . kill ( * local) ;
197+ // destination here, and then gen it again in `call_return_effect `.
198+ TerminatorKind :: Call { destination : Some ( ( place , _) ) , .. } => {
199+ trans . kill ( place . local ) ;
185200 }
186201
187202 // Nothing to do for these. Match exhaustively so this fails to compile when new
@@ -202,24 +217,25 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
202217 | TerminatorKind :: Unreachable => { }
203218 }
204219
205- self . check_for_move ( sets , loc) ;
220+ self . check_for_move ( trans , loc) ;
206221 }
207222
208- fn propagate_call_return (
223+ fn call_return_effect (
209224 & self ,
210- in_out : & mut BitSet < Local > ,
211- _call_bb : mir:: BasicBlock ,
212- _dest_bb : mir:: BasicBlock ,
213- dest_place : & mir:: Place < ' tcx > ,
225+ trans : & mut impl GenKill < Self :: Idx > ,
226+ _block : BasicBlock ,
227+ _func : & mir:: Operand < ' tcx > ,
228+ _args : & [ mir:: Operand < ' tcx > ] ,
229+ return_place : & mir:: Place < ' tcx > ,
214230 ) {
215- in_out . insert ( dest_place . local ) ;
231+ trans . gen ( return_place . local ) ;
216232 }
217233}
218234
219235impl < ' mir , ' tcx > RequiresStorage < ' mir , ' tcx > {
220236 /// Kill locals that are fully moved and have not been borrowed.
221- fn check_for_move ( & self , sets : & mut GenKillSet < Local > , loc : Location ) {
222- let mut visitor = MoveVisitor { sets , borrowed_locals : & self . borrowed_locals } ;
237+ fn check_for_move ( & self , trans : & mut impl GenKill < Local > , loc : Location ) {
238+ let mut visitor = MoveVisitor { trans , borrowed_locals : & self . borrowed_locals } ;
223239 visitor. visit_location ( self . body , loc) ;
224240 }
225241}
@@ -229,18 +245,21 @@ impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> {
229245 const BOTTOM_VALUE : bool = false ;
230246}
231247
232- struct MoveVisitor < ' a , ' mir , ' tcx > {
248+ struct MoveVisitor < ' a , ' mir , ' tcx , T > {
233249 borrowed_locals : & ' a RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
234- sets : & ' a mut GenKillSet < Local > ,
250+ trans : & ' a mut T ,
235251}
236252
237- impl < ' a , ' mir : ' a , ' tcx > Visitor < ' tcx > for MoveVisitor < ' a , ' mir , ' tcx > {
253+ impl < ' a , ' mir , ' tcx , T > Visitor < ' tcx > for MoveVisitor < ' a , ' mir , ' tcx , T >
254+ where
255+ T : GenKill < Local > ,
256+ {
238257 fn visit_local ( & mut self , local : & Local , context : PlaceContext , loc : Location ) {
239258 if PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move ) == context {
240259 let mut borrowed_locals = self . borrowed_locals . borrow_mut ( ) ;
241260 borrowed_locals. seek_before ( loc) ;
242261 if !borrowed_locals. contains ( * local) {
243- self . sets . kill ( * local) ;
262+ self . trans . kill ( * local) ;
244263 }
245264 }
246265 }
0 commit comments