@@ -84,7 +84,9 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
84
84
assert_eq ! ( path_map_ent, move_path) ;
85
85
move_path
86
86
}
87
+ }
87
88
89
+ impl < ' b , ' a , ' tcx > Gatherer < ' b , ' a , ' tcx > {
88
90
/// This creates a MovePath for a given lvalue, returning an `MovePathError`
89
91
/// if that lvalue can't be moved from.
90
92
///
@@ -97,8 +99,11 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
97
99
{
98
100
debug ! ( "lookup({:?})" , lval) ;
99
101
match * lval {
100
- Lvalue :: Local ( local) => Ok ( self . data . rev_lookup . locals [ local] ) ,
101
- Lvalue :: Static ( ..) => Err ( MoveError :: cannot_move_out_of ( Static ) ) ,
102
+ Lvalue :: Local ( local) => Ok ( self . builder . data . rev_lookup . locals [ local] ) ,
103
+ Lvalue :: Static ( ..) => {
104
+ let span = self . builder . mir . source_info ( self . loc ) . span ;
105
+ Err ( MoveError :: cannot_move_out_of ( span, Static ) )
106
+ }
102
107
Lvalue :: Projection ( ref proj) => {
103
108
self . move_path_for_projection ( lval, proj)
104
109
}
@@ -117,41 +122,49 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
117
122
-> Result < MovePathIndex , MoveError < ' tcx > >
118
123
{
119
124
let base = try!( self . move_path_for ( & proj. base ) ) ;
120
- let lv_ty = proj. base . ty ( self . mir , self . tcx ) . to_ty ( self . tcx ) ;
125
+ let mir = self . builder . mir ;
126
+ let tcx = self . builder . tcx ;
127
+ let lv_ty = proj. base . ty ( mir, tcx) . to_ty ( tcx) ;
121
128
match lv_ty. sty {
122
129
ty:: TyRef ( ..) | ty:: TyRawPtr ( ..) =>
123
- return Err ( MoveError :: cannot_move_out_of ( BorrowedContent ) ) ,
124
- ty:: TyAdt ( adt, _) if adt. has_dtor ( self . tcx ) && !adt. is_box ( ) =>
125
- return Err ( MoveError :: cannot_move_out_of ( InteriorOfTypeWithDestructor {
130
+ return Err ( MoveError :: cannot_move_out_of ( mir. source_info ( self . loc ) . span ,
131
+ BorrowedContent ) ) ,
132
+ ty:: TyAdt ( adt, _) if adt. has_dtor ( tcx) && !adt. is_box ( ) =>
133
+ return Err ( MoveError :: cannot_move_out_of ( mir. source_info ( self . loc ) . span ,
134
+ InteriorOfTypeWithDestructor {
126
135
container_ty : lv_ty
127
136
} ) ) ,
128
137
// move out of union - always move the entire union
129
138
ty:: TyAdt ( adt, _) if adt. is_union ( ) =>
130
139
return Err ( MoveError :: UnionMove { path : base } ) ,
131
140
ty:: TySlice ( elem_ty) =>
132
- return Err ( MoveError :: cannot_move_out_of ( InteriorOfSlice {
133
- elem_ty, is_index : match proj. elem {
134
- ProjectionElem :: Index ( ..) => true ,
135
- _ => false
136
- } ,
137
- } ) ) ,
141
+ return Err ( MoveError :: cannot_move_out_of (
142
+ mir. source_info ( self . loc ) . span ,
143
+ InteriorOfSlice {
144
+ elem_ty, is_index : match proj. elem {
145
+ ProjectionElem :: Index ( ..) => true ,
146
+ _ => false
147
+ } ,
148
+ } ) ) ,
138
149
ty:: TyArray ( elem_ty, _num_elems) => match proj. elem {
139
150
ProjectionElem :: Index ( ..) =>
140
- return Err ( MoveError :: cannot_move_out_of ( InteriorOfArray {
141
- elem_ty, is_index : true
142
- } ) ) ,
151
+ return Err ( MoveError :: cannot_move_out_of (
152
+ mir. source_info ( self . loc ) . span ,
153
+ InteriorOfArray {
154
+ elem_ty, is_index : true
155
+ } ) ) ,
143
156
_ => {
144
157
// FIXME: still badly broken
145
158
}
146
159
} ,
147
160
_ => { }
148
161
} ;
149
- match self . data . rev_lookup . projections . entry ( ( base, proj. elem . lift ( ) ) ) {
162
+ match self . builder . data . rev_lookup . projections . entry ( ( base, proj. elem . lift ( ) ) ) {
150
163
Entry :: Occupied ( ent) => Ok ( * ent. get ( ) ) ,
151
164
Entry :: Vacant ( ent) => {
152
- let path = Self :: new_move_path (
153
- & mut self . data . move_paths ,
154
- & mut self . data . path_map ,
165
+ let path = MoveDataBuilder :: new_move_path (
166
+ & mut self . builder . data . move_paths ,
167
+ & mut self . builder . data . path_map ,
155
168
Some ( base) ,
156
169
lval. clone ( )
157
170
) ;
@@ -160,7 +173,9 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
160
173
}
161
174
}
162
175
}
176
+ }
163
177
178
+ impl < ' a , ' tcx > MoveDataBuilder < ' a , ' tcx > {
164
179
fn finalize ( self ) -> Result < MoveData < ' tcx > , ( MoveData < ' tcx > , Vec < MoveError < ' tcx > > ) > {
165
180
debug ! ( "{}" , {
166
181
debug!( "moves for {:?}:" , self . mir. span) ;
@@ -208,6 +223,22 @@ pub(super) fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
208
223
impl < ' a , ' tcx > MoveDataBuilder < ' a , ' tcx > {
209
224
fn gather_statement ( & mut self , loc : Location , stmt : & Statement < ' tcx > ) {
210
225
debug ! ( "gather_statement({:?}, {:?})" , loc, stmt) ;
226
+ ( Gatherer { builder : self , loc } ) . gather_statement ( stmt) ;
227
+ }
228
+
229
+ fn gather_terminator ( & mut self , loc : Location , term : & Terminator < ' tcx > ) {
230
+ debug ! ( "gather_terminator({:?}, {:?})" , loc, term) ;
231
+ ( Gatherer { builder : self , loc } ) . gather_terminator ( term) ;
232
+ }
233
+ }
234
+
235
+ struct Gatherer < ' b , ' a : ' b , ' tcx : ' a > {
236
+ builder : & ' b mut MoveDataBuilder < ' a , ' tcx > ,
237
+ loc : Location ,
238
+ }
239
+
240
+ impl < ' b , ' a , ' tcx > Gatherer < ' b , ' a , ' tcx > {
241
+ fn gather_statement ( & mut self , stmt : & Statement < ' tcx > ) {
211
242
match stmt. kind {
212
243
StatementKind :: Assign ( ref lval, ref rval) => {
213
244
self . create_move_path ( lval) ;
@@ -217,7 +248,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
217
248
// the exterior.
218
249
self . create_move_path ( & lval. clone ( ) . deref ( ) ) ;
219
250
}
220
- self . gather_rvalue ( loc , rval) ;
251
+ self . gather_rvalue ( rval) ;
221
252
}
222
253
StatementKind :: StorageLive ( _) |
223
254
StatementKind :: StorageDead ( _) => { }
@@ -232,22 +263,22 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
232
263
}
233
264
}
234
265
235
- fn gather_rvalue ( & mut self , loc : Location , rvalue : & Rvalue < ' tcx > ) {
266
+ fn gather_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > ) {
236
267
match * rvalue {
237
268
Rvalue :: Use ( ref operand) |
238
269
Rvalue :: Repeat ( ref operand, _) |
239
270
Rvalue :: Cast ( _, ref operand, _) |
240
271
Rvalue :: UnaryOp ( _, ref operand) => {
241
- self . gather_operand ( loc , operand)
272
+ self . gather_operand ( operand)
242
273
}
243
274
Rvalue :: BinaryOp ( ref _binop, ref lhs, ref rhs) |
244
275
Rvalue :: CheckedBinaryOp ( ref _binop, ref lhs, ref rhs) => {
245
- self . gather_operand ( loc , lhs) ;
246
- self . gather_operand ( loc , rhs) ;
276
+ self . gather_operand ( lhs) ;
277
+ self . gather_operand ( rhs) ;
247
278
}
248
279
Rvalue :: Aggregate ( ref _kind, ref operands) => {
249
280
for operand in operands {
250
- self . gather_operand ( loc , operand) ;
281
+ self . gather_operand ( operand) ;
251
282
}
252
283
}
253
284
Rvalue :: Ref ( ..) |
@@ -269,16 +300,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
269
300
}
270
301
}
271
302
272
- fn gather_terminator ( & mut self , loc : Location , term : & Terminator < ' tcx > ) {
273
- debug ! ( "gather_terminator({:?}, {:?})" , loc, term) ;
303
+ fn gather_terminator ( & mut self , term : & Terminator < ' tcx > ) {
274
304
match term. kind {
275
305
TerminatorKind :: Goto { target : _ } |
276
306
TerminatorKind :: Resume |
277
307
TerminatorKind :: GeneratorDrop |
278
308
TerminatorKind :: Unreachable => { }
279
309
280
310
TerminatorKind :: Return => {
281
- self . gather_move ( loc , & Lvalue :: Local ( RETURN_POINTER ) ) ;
311
+ self . gather_move ( & Lvalue :: Local ( RETURN_POINTER ) ) ;
282
312
}
283
313
284
314
TerminatorKind :: Assert { .. } |
@@ -287,20 +317,20 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
287
317
}
288
318
289
319
TerminatorKind :: Yield { ref value, .. } => {
290
- self . gather_operand ( loc , value) ;
320
+ self . gather_operand ( value) ;
291
321
}
292
322
293
323
TerminatorKind :: Drop { ref location, target : _, unwind : _ } => {
294
- self . gather_move ( loc , location) ;
324
+ self . gather_move ( location) ;
295
325
}
296
326
TerminatorKind :: DropAndReplace { ref location, ref value, .. } => {
297
327
self . create_move_path ( location) ;
298
- self . gather_operand ( loc , value) ;
328
+ self . gather_operand ( value) ;
299
329
}
300
330
TerminatorKind :: Call { ref func, ref args, ref destination, cleanup : _ } => {
301
- self . gather_operand ( loc , func) ;
331
+ self . gather_operand ( func) ;
302
332
for arg in args {
303
- self . gather_operand ( loc , arg) ;
333
+ self . gather_operand ( arg) ;
304
334
}
305
335
if let Some ( ( ref destination, _bb) ) = * destination {
306
336
self . create_move_path ( destination) ;
@@ -309,37 +339,38 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
309
339
}
310
340
}
311
341
312
- fn gather_operand ( & mut self , loc : Location , operand : & Operand < ' tcx > ) {
342
+ fn gather_operand ( & mut self , operand : & Operand < ' tcx > ) {
313
343
match * operand {
314
344
Operand :: Constant ( ..) => { } // not-a-move
315
345
Operand :: Consume ( ref lval) => { // a move
316
- self . gather_move ( loc , lval) ;
346
+ self . gather_move ( lval) ;
317
347
}
318
348
}
319
349
}
320
350
321
- fn gather_move ( & mut self , loc : Location , lval : & Lvalue < ' tcx > ) {
322
- debug ! ( "gather_move({:?}, {:?})" , loc, lval) ;
351
+ fn gather_move ( & mut self , lval : & Lvalue < ' tcx > ) {
352
+ debug ! ( "gather_move({:?}, {:?})" , self . loc, lval) ;
323
353
324
- let lv_ty = lval. ty ( self . mir , self . tcx ) . to_ty ( self . tcx ) ;
325
- if !lv_ty. moves_by_default ( self . tcx , self . param_env , DUMMY_SP ) {
326
- debug ! ( "gather_move({:?}, {:?}) - {:?} is Copy. skipping" , loc, lval, lv_ty) ;
354
+ let tcx = self . builder . tcx ;
355
+ let lv_ty = lval. ty ( self . builder . mir , tcx) . to_ty ( tcx) ;
356
+ if !lv_ty. moves_by_default ( tcx, self . builder . param_env , DUMMY_SP ) {
357
+ debug ! ( "gather_move({:?}, {:?}) - {:?} is Copy. skipping" , self . loc, lval, lv_ty) ;
327
358
return
328
359
}
329
360
330
361
let path = match self . move_path_for ( lval) {
331
362
Ok ( path) | Err ( MoveError :: UnionMove { path } ) => path,
332
363
Err ( error @ MoveError :: IllegalMove { .. } ) => {
333
- self . errors . push ( error) ;
364
+ self . builder . errors . push ( error) ;
334
365
return ;
335
366
}
336
367
} ;
337
- let move_out = self . data . moves . push ( MoveOut { path : path, source : loc } ) ;
368
+ let move_out = self . builder . data . moves . push ( MoveOut { path : path, source : self . loc } ) ;
338
369
339
370
debug ! ( "gather_move({:?}, {:?}): adding move {:?} of {:?}" ,
340
- loc, lval, move_out, path) ;
371
+ self . loc, lval, move_out, path) ;
341
372
342
- self . data . path_map [ path] . push ( move_out) ;
343
- self . data . loc_map [ loc] . push ( move_out) ;
373
+ self . builder . data . path_map [ path] . push ( move_out) ;
374
+ self . builder . data . loc_map [ self . loc ] . push ( move_out) ;
344
375
}
345
376
}
0 commit comments