@@ -76,7 +76,7 @@ pub struct RequiresStorage<'mir, 'tcx> {
76
76
borrowed_locals : RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
77
77
}
78
78
79
- impl < ' mir , ' tcx : ' mir > RequiresStorage < ' mir , ' tcx > {
79
+ impl < ' mir , ' tcx > RequiresStorage < ' mir , ' tcx > {
80
80
pub fn new (
81
81
body : ReadOnlyBodyAndCache < ' mir , ' tcx > ,
82
82
borrowed_locals : & ' mir Results < ' tcx , MaybeBorrowedLocals > ,
@@ -86,45 +86,47 @@ impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> {
86
86
borrowed_locals : RefCell :: new ( ResultsRefCursor :: new ( * body, borrowed_locals) ) ,
87
87
}
88
88
}
89
-
90
- pub fn body ( & self ) -> & Body < ' tcx > {
91
- & self . body
92
- }
93
89
}
94
90
95
- impl < ' mir , ' tcx > BitDenotation < ' tcx > for RequiresStorage < ' mir , ' tcx > {
91
+ impl < ' mir , ' tcx > dataflow :: AnalysisDomain < ' tcx > for RequiresStorage < ' mir , ' tcx > {
96
92
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 ( )
102
98
}
103
99
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 > ) {
105
101
// The resume argument is live on function entry (we don't care about
106
102
// the `self` argument)
107
- for arg in self . body . args_iter ( ) . skip ( 1 ) {
103
+ for arg in body. args_iter ( ) . skip ( 1 ) {
108
104
on_entry. insert ( arg) ;
109
105
}
110
106
}
107
+ }
111
108
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
+ ) {
115
116
// 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) ;
117
118
118
- // If a place is assigned to in a statement, it needs storage for that statement.
119
119
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.
121
123
StatementKind :: Assign ( box ( place, _) )
122
124
| StatementKind :: SetDiscriminant { box place, .. } => {
123
- sets . gen ( place. local ) ;
125
+ trans . gen ( place. local ) ;
124
126
}
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 ) ;
128
130
}
129
131
}
130
132
@@ -138,22 +140,30 @@ impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
138
140
}
139
141
}
140
142
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
+ ) {
142
149
// If we move from a place then only stops needing storage *after*
143
150
// that statement.
144
- self . check_for_move ( sets , loc) ;
151
+ self . check_for_move ( trans , loc) ;
145
152
}
146
153
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
+ ) {
150
160
// 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) ;
152
162
153
163
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 ) ;
157
167
}
158
168
159
169
// 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> {
174
184
}
175
185
}
176
186
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 {
179
194
// For call terminators the destination requires storage for the call
180
195
// and after the call returns successfully, but not after a panic.
181
196
// 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 ) ;
185
200
}
186
201
187
202
// 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> {
202
217
| TerminatorKind :: Unreachable => { }
203
218
}
204
219
205
- self . check_for_move ( sets , loc) ;
220
+ self . check_for_move ( trans , loc) ;
206
221
}
207
222
208
- fn propagate_call_return (
223
+ fn call_return_effect (
209
224
& 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 > ,
214
230
) {
215
- in_out . insert ( dest_place . local ) ;
231
+ trans . gen ( return_place . local ) ;
216
232
}
217
233
}
218
234
219
235
impl < ' mir , ' tcx > RequiresStorage < ' mir , ' tcx > {
220
236
/// 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 } ;
223
239
visitor. visit_location ( self . body , loc) ;
224
240
}
225
241
}
@@ -229,18 +245,21 @@ impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> {
229
245
const BOTTOM_VALUE : bool = false ;
230
246
}
231
247
232
- struct MoveVisitor < ' a , ' mir , ' tcx > {
248
+ struct MoveVisitor < ' a , ' mir , ' tcx , T > {
233
249
borrowed_locals : & ' a RefCell < BorrowedLocalsResults < ' mir , ' tcx > > ,
234
- sets : & ' a mut GenKillSet < Local > ,
250
+ trans : & ' a mut T ,
235
251
}
236
252
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
+ {
238
257
fn visit_local ( & mut self , local : & Local , context : PlaceContext , loc : Location ) {
239
258
if PlaceContext :: NonMutatingUse ( NonMutatingUseContext :: Move ) == context {
240
259
let mut borrowed_locals = self . borrowed_locals . borrow_mut ( ) ;
241
260
borrowed_locals. seek_before ( loc) ;
242
261
if !borrowed_locals. contains ( * local) {
243
- self . sets . kill ( * local) ;
262
+ self . trans . kill ( * local) ;
244
263
}
245
264
}
246
265
}
0 commit comments