@@ -84,7 +84,9 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
8484 assert_eq ! ( path_map_ent, move_path) ;
8585 move_path
8686 }
87+ }
8788
89+ impl < ' b , ' a , ' tcx > Gatherer < ' b , ' a , ' tcx > {
8890 /// This creates a MovePath for a given lvalue, returning an `MovePathError`
8991 /// if that lvalue can't be moved from.
9092 ///
@@ -97,8 +99,11 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
9799 {
98100 debug ! ( "lookup({:?})" , lval) ;
99101 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+ }
102107 Lvalue :: Projection ( ref proj) => {
103108 self . move_path_for_projection ( lval, proj)
104109 }
@@ -117,41 +122,49 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
117122 -> Result < MovePathIndex , MoveError < ' tcx > >
118123 {
119124 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) ;
121128 match lv_ty. sty {
122129 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 {
126135 container_ty : lv_ty
127136 } ) ) ,
128137 // move out of union - always move the entire union
129138 ty:: TyAdt ( adt, _) if adt. is_union ( ) =>
130139 return Err ( MoveError :: UnionMove { path : base } ) ,
131140 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+ } ) ) ,
138149 ty:: TyArray ( elem_ty, _num_elems) => match proj. elem {
139150 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+ } ) ) ,
143156 _ => {
144157 // FIXME: still badly broken
145158 }
146159 } ,
147160 _ => { }
148161 } ;
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 ( ) ) ) {
150163 Entry :: Occupied ( ent) => Ok ( * ent. get ( ) ) ,
151164 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 ,
155168 Some ( base) ,
156169 lval. clone ( )
157170 ) ;
@@ -160,7 +173,9 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
160173 }
161174 }
162175 }
176+ }
163177
178+ impl < ' a , ' tcx > MoveDataBuilder < ' a , ' tcx > {
164179 fn finalize ( self ) -> Result < MoveData < ' tcx > , ( MoveData < ' tcx > , Vec < MoveError < ' tcx > > ) > {
165180 debug ! ( "{}" , {
166181 debug!( "moves for {:?}:" , self . mir. span) ;
@@ -208,6 +223,22 @@ pub(super) fn gather_moves<'a, 'tcx>(mir: &Mir<'tcx>,
208223impl < ' a , ' tcx > MoveDataBuilder < ' a , ' tcx > {
209224 fn gather_statement ( & mut self , loc : Location , stmt : & Statement < ' tcx > ) {
210225 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 > ) {
211242 match stmt. kind {
212243 StatementKind :: Assign ( ref lval, ref rval) => {
213244 self . create_move_path ( lval) ;
@@ -217,7 +248,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
217248 // the exterior.
218249 self . create_move_path ( & lval. clone ( ) . deref ( ) ) ;
219250 }
220- self . gather_rvalue ( loc , rval) ;
251+ self . gather_rvalue ( rval) ;
221252 }
222253 StatementKind :: StorageLive ( _) |
223254 StatementKind :: StorageDead ( _) => { }
@@ -232,22 +263,22 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
232263 }
233264 }
234265
235- fn gather_rvalue ( & mut self , loc : Location , rvalue : & Rvalue < ' tcx > ) {
266+ fn gather_rvalue ( & mut self , rvalue : & Rvalue < ' tcx > ) {
236267 match * rvalue {
237268 Rvalue :: Use ( ref operand) |
238269 Rvalue :: Repeat ( ref operand, _) |
239270 Rvalue :: Cast ( _, ref operand, _) |
240271 Rvalue :: UnaryOp ( _, ref operand) => {
241- self . gather_operand ( loc , operand)
272+ self . gather_operand ( operand)
242273 }
243274 Rvalue :: BinaryOp ( ref _binop, ref lhs, ref rhs) |
244275 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) ;
247278 }
248279 Rvalue :: Aggregate ( ref _kind, ref operands) => {
249280 for operand in operands {
250- self . gather_operand ( loc , operand) ;
281+ self . gather_operand ( operand) ;
251282 }
252283 }
253284 Rvalue :: Ref ( ..) |
@@ -269,16 +300,15 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
269300 }
270301 }
271302
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 > ) {
274304 match term. kind {
275305 TerminatorKind :: Goto { target : _ } |
276306 TerminatorKind :: Resume |
277307 TerminatorKind :: GeneratorDrop |
278308 TerminatorKind :: Unreachable => { }
279309
280310 TerminatorKind :: Return => {
281- self . gather_move ( loc , & Lvalue :: Local ( RETURN_POINTER ) ) ;
311+ self . gather_move ( & Lvalue :: Local ( RETURN_POINTER ) ) ;
282312 }
283313
284314 TerminatorKind :: Assert { .. } |
@@ -287,20 +317,20 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
287317 }
288318
289319 TerminatorKind :: Yield { ref value, .. } => {
290- self . gather_operand ( loc , value) ;
320+ self . gather_operand ( value) ;
291321 }
292322
293323 TerminatorKind :: Drop { ref location, target : _, unwind : _ } => {
294- self . gather_move ( loc , location) ;
324+ self . gather_move ( location) ;
295325 }
296326 TerminatorKind :: DropAndReplace { ref location, ref value, .. } => {
297327 self . create_move_path ( location) ;
298- self . gather_operand ( loc , value) ;
328+ self . gather_operand ( value) ;
299329 }
300330 TerminatorKind :: Call { ref func, ref args, ref destination, cleanup : _ } => {
301- self . gather_operand ( loc , func) ;
331+ self . gather_operand ( func) ;
302332 for arg in args {
303- self . gather_operand ( loc , arg) ;
333+ self . gather_operand ( arg) ;
304334 }
305335 if let Some ( ( ref destination, _bb) ) = * destination {
306336 self . create_move_path ( destination) ;
@@ -309,37 +339,38 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
309339 }
310340 }
311341
312- fn gather_operand ( & mut self , loc : Location , operand : & Operand < ' tcx > ) {
342+ fn gather_operand ( & mut self , operand : & Operand < ' tcx > ) {
313343 match * operand {
314344 Operand :: Constant ( ..) => { } // not-a-move
315345 Operand :: Consume ( ref lval) => { // a move
316- self . gather_move ( loc , lval) ;
346+ self . gather_move ( lval) ;
317347 }
318348 }
319349 }
320350
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) ;
323353
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) ;
327358 return
328359 }
329360
330361 let path = match self . move_path_for ( lval) {
331362 Ok ( path) | Err ( MoveError :: UnionMove { path } ) => path,
332363 Err ( error @ MoveError :: IllegalMove { .. } ) => {
333- self . errors . push ( error) ;
364+ self . builder . errors . push ( error) ;
334365 return ;
335366 }
336367 } ;
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 } ) ;
338369
339370 debug ! ( "gather_move({:?}, {:?}): adding move {:?} of {:?}" ,
340- loc, lval, move_out, path) ;
371+ self . loc, lval, move_out, path) ;
341372
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) ;
344375 }
345376}
0 commit comments