1- use  crate :: move_paths:: FxHashMap ; 
2- use  crate :: un_derefer:: UnDerefer ; 
31use  rustc_index:: IndexVec ; 
42use  rustc_middle:: mir:: tcx:: RvalueInitializationState ; 
53use  rustc_middle:: mir:: * ; 
64use  rustc_middle:: ty:: { self ,  TyCtxt } ; 
75use  smallvec:: { smallvec,  SmallVec } ; 
86
7+ use  std:: iter; 
98use  std:: mem; 
109
1110use  super :: abs_domain:: Lift ; 
@@ -21,7 +20,6 @@ struct MoveDataBuilder<'a, 'tcx> {
2120    param_env :  ty:: ParamEnv < ' tcx > , 
2221    data :  MoveData < ' tcx > , 
2322    errors :  Vec < ( Place < ' tcx > ,  MoveError < ' tcx > ) > , 
24-     un_derefer :  UnDerefer < ' tcx > , 
2523} 
2624
2725impl < ' a ,  ' tcx >  MoveDataBuilder < ' a ,  ' tcx >  { 
@@ -35,25 +33,29 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
3533            tcx, 
3634            param_env, 
3735            errors :  Vec :: new ( ) , 
38-             un_derefer :  UnDerefer  {  tcx :  tcx,  derefer_sidetable :  Default :: default ( )  } , 
3936            data :  MoveData  { 
4037                moves :  IndexVec :: new ( ) , 
4138                loc_map :  LocationMap :: new ( body) , 
4239                rev_lookup :  MovePathLookup  { 
4340                    locals :  body
4441                        . local_decls 
45-                         . indices ( ) 
46-                         . map ( |i| { 
47-                             Self :: new_move_path ( 
48-                                 & mut  move_paths, 
49-                                 & mut  path_map, 
50-                                 & mut  init_path_map, 
51-                                 None , 
52-                                 Place :: from ( i) , 
42+                         . iter_enumerated ( ) 
43+                         . filter ( |( _,  l) | !l. is_deref_temp ( ) ) 
44+                         . map ( |( i,  _) | { 
45+                             ( 
46+                                 i, 
47+                                 Self :: new_move_path ( 
48+                                     & mut  move_paths, 
49+                                     & mut  path_map, 
50+                                     & mut  init_path_map, 
51+                                     None , 
52+                                     Place :: from ( i) , 
53+                                 ) , 
5354                            ) 
5455                        } ) 
5556                        . collect ( ) , 
5657                    projections :  Default :: default ( ) , 
58+                     derefer_sidetable :  Default :: default ( ) , 
5759                } , 
5860                move_paths, 
5961                path_map, 
@@ -98,13 +100,11 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
98100/// 
99101/// Maybe we should have separate "borrowck" and "moveck" modes. 
100102fn  move_path_for ( & mut  self ,  place :  Place < ' tcx > )  -> Result < MovePathIndex ,  MoveError < ' tcx > >  { 
101-         if  let  Some ( new_place)  = self . builder . un_derefer . derefer ( place. as_ref ( ) ,  self . builder . body ) 
102-         { 
103-             return  self . move_path_for ( new_place) ; 
104-         } 
103+         let  deref_chain = self . builder . data . rev_lookup . deref_chain ( place. as_ref ( ) ) ; 
105104
106105        debug ! ( "lookup({:?})" ,  place) ; 
107-         let  mut  base = self . builder . data . rev_lookup . locals [ place. local ] ; 
106+         let  mut  base =
107+             self . builder . data . rev_lookup . find_local ( deref_chain. first ( ) . unwrap_or ( & place) . local ) ; 
108108
109109        // The move path index of the first union that we find. Once this is 
110110        // some we stop creating child move paths, since moves from unions 
@@ -113,51 +113,55 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
113113        // from `*(u.f: &_)` isn't allowed. 
114114        let  mut  union_path = None ; 
115115
116-         for  ( place_ref,  elem)  in  place. as_ref ( ) . iter_projections ( )  { 
117-             let  body = self . builder . body ; 
118-             let  tcx = self . builder . tcx ; 
119-             let  place_ty = place_ref. ty ( body,  tcx) . ty ; 
120- 
121-             match  place_ty. kind ( )  { 
122-                 ty:: Ref ( ..)  | ty:: RawPtr ( ..)  => { 
123-                     return  Err ( MoveError :: cannot_move_out_of ( 
124-                         self . loc , 
125-                         BorrowedContent  {  target_place :  place_ref. project_deeper ( & [ elem] ,  tcx)  } , 
126-                     ) ) ; 
127-                 } 
128-                 ty:: Adt ( adt,  _)  if  adt. has_dtor ( tcx)  && !adt. is_box ( )  => { 
129-                     return  Err ( MoveError :: cannot_move_out_of ( 
130-                         self . loc , 
131-                         InteriorOfTypeWithDestructor  {  container_ty :  place_ty } , 
132-                     ) ) ; 
133-                 } 
134-                 ty:: Adt ( adt,  _)  if  adt. is_union ( )  => { 
135-                     union_path. get_or_insert ( base) ; 
136-                 } 
137-                 ty:: Slice ( _)  => { 
138-                     return  Err ( MoveError :: cannot_move_out_of ( 
139-                         self . loc , 
140-                         InteriorOfSliceOrArray  { 
141-                             ty :  place_ty, 
142-                             is_index :  matches ! ( elem,  ProjectionElem :: Index ( ..) ) , 
143-                         } , 
144-                     ) ) ; 
145-                 } 
146- 
147-                 ty:: Array ( ..)  => { 
148-                     if  let  ProjectionElem :: Index ( ..)  = elem { 
116+         for  place in  deref_chain. into_iter ( ) . chain ( iter:: once ( place) )  { 
117+             for  ( place_ref,  elem)  in  place. as_ref ( ) . iter_projections ( )  { 
118+                 let  body = self . builder . body ; 
119+                 let  tcx = self . builder . tcx ; 
120+                 let  place_ty = place_ref. ty ( body,  tcx) . ty ; 
121+                 match  place_ty. kind ( )  { 
122+                     ty:: Ref ( ..)  | ty:: RawPtr ( ..)  => { 
149123                        return  Err ( MoveError :: cannot_move_out_of ( 
150124                            self . loc , 
151-                             InteriorOfSliceOrArray  {  ty :  place_ty,  is_index :  true  } , 
125+                             BorrowedContent  { 
126+                                 target_place :  place_ref. project_deeper ( & [ elem] ,  tcx) , 
127+                             } , 
128+                         ) ) ; 
129+                     } 
130+                     ty:: Adt ( adt,  _)  if  adt. has_dtor ( tcx)  && !adt. is_box ( )  => { 
131+                         return  Err ( MoveError :: cannot_move_out_of ( 
132+                             self . loc , 
133+                             InteriorOfTypeWithDestructor  {  container_ty :  place_ty } , 
134+                         ) ) ; 
135+                     } 
136+                     ty:: Adt ( adt,  _)  if  adt. is_union ( )  => { 
137+                         union_path. get_or_insert ( base) ; 
138+                     } 
139+                     ty:: Slice ( _)  => { 
140+                         return  Err ( MoveError :: cannot_move_out_of ( 
141+                             self . loc , 
142+                             InteriorOfSliceOrArray  { 
143+                                 ty :  place_ty, 
144+                                 is_index :  matches ! ( elem,  ProjectionElem :: Index ( ..) ) , 
145+                             } , 
152146                        ) ) ; 
153147                    } 
154-                 } 
155148
156-                 _ => { } 
157-             } ; 
149+                     ty:: Array ( ..)  => { 
150+                         if  let  ProjectionElem :: Index ( ..)  = elem { 
151+                             return  Err ( MoveError :: cannot_move_out_of ( 
152+                                 self . loc , 
153+                                 InteriorOfSliceOrArray  {  ty :  place_ty,  is_index :  true  } , 
154+                             ) ) ; 
155+                         } 
156+                     } 
157+ 
158+                     _ => { } 
159+                 } ; 
158160
159-             if  union_path. is_none ( )  { 
160-                 base = self . add_move_path ( base,  elem,  |tcx| place_ref. project_deeper ( & [ elem] ,  tcx) ) ; 
161+                 if  union_path. is_none ( )  { 
162+                     base = self 
163+                         . add_move_path ( base,  elem,  |tcx| place_ref. project_deeper ( & [ elem] ,  tcx) ) ; 
164+                 } 
161165            } 
162166        } 
163167
@@ -198,10 +202,8 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
198202    } 
199203} 
200204
201- pub  type  MoveDat < ' tcx >  = Result < 
202-     ( FxHashMap < Local ,  Place < ' tcx > > ,  MoveData < ' tcx > ) , 
203-     ( MoveData < ' tcx > ,  Vec < ( Place < ' tcx > ,  MoveError < ' tcx > ) > ) , 
204- > ; 
205+ pub  type  MoveDat < ' tcx >  =
206+     Result < MoveData < ' tcx > ,  ( MoveData < ' tcx > ,  Vec < ( Place < ' tcx > ,  MoveError < ' tcx > ) > ) > ; 
205207
206208impl < ' a ,  ' tcx >  MoveDataBuilder < ' a ,  ' tcx >  { 
207209    fn  finalize ( self )  -> MoveDat < ' tcx >  { 
@@ -217,11 +219,7 @@ impl<'a, 'tcx> MoveDataBuilder<'a, 'tcx> {
217219            "done dumping moves" 
218220        } ) ; 
219221
220-         if  self . errors . is_empty ( )  { 
221-             Ok ( ( self . un_derefer . derefer_sidetable ,  self . data ) ) 
222-         }  else  { 
223-             Err ( ( self . data ,  self . errors ) ) 
224-         } 
222+         if  self . errors . is_empty ( )  {  Ok ( self . data )  }  else  {  Err ( ( self . data ,  self . errors ) )  } 
225223    } 
226224} 
227225
@@ -250,7 +248,7 @@ pub(super) fn gather_moves<'tcx>(
250248impl < ' a ,  ' tcx >  MoveDataBuilder < ' a ,  ' tcx >  { 
251249    fn  gather_args ( & mut  self )  { 
252250        for  arg in  self . body . args_iter ( )  { 
253-             let  path = self . data . rev_lookup . locals [ arg] ; 
251+             let  path = self . data . rev_lookup . find_local ( arg) ; 
254252
255253            let  init = self . data . inits . push ( Init  { 
256254                path, 
@@ -286,7 +284,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
286284            StatementKind :: Assign ( box ( place,  Rvalue :: CopyForDeref ( reffed) ) )  => { 
287285                assert ! ( place. projection. is_empty( ) ) ; 
288286                if  self . builder . body . local_decls [ place. local ] . is_deref_temp ( )  { 
289-                     self . builder . un_derefer . derefer_sidetable . insert ( place. local ,  * reffed) ; 
287+                     self . builder . data . rev_lookup . derefer_sidetable . insert ( place. local ,  * reffed) ; 
290288                } 
291289            } 
292290            StatementKind :: Assign ( box ( place,  rval) )  => { 
@@ -308,7 +306,7 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
308306            StatementKind :: StorageLive ( _)  => { } 
309307            StatementKind :: StorageDead ( local)  => { 
310308                // DerefTemp locals (results of CopyForDeref) don't actually move anything. 
311-                 if  !self . builder . un_derefer . derefer_sidetable . contains_key ( & local)  { 
309+                 if  !self . builder . data . rev_lookup . derefer_sidetable . contains_key ( & local)  { 
312310                    self . gather_move ( Place :: from ( * local) ) ; 
313311                } 
314312            } 
@@ -450,12 +448,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
450448
451449    fn  gather_move ( & mut  self ,  place :  Place < ' tcx > )  { 
452450        debug ! ( "gather_move({:?}, {:?})" ,  self . loc,  place) ; 
453-         if  let  Some ( new_place)  = self . builder . un_derefer . derefer ( place. as_ref ( ) ,  self . builder . body ) 
454-         { 
455-             self . gather_move ( new_place) ; 
456-             return ; 
457-         } 
458- 
459451        if  let  [ ref  base @ ..,  ProjectionElem :: Subslice  {  from,  to,  from_end :  false  } ]  =
460452            * * place. projection 
461453        { 
@@ -512,11 +504,6 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
512504    fn  gather_init ( & mut  self ,  place :  PlaceRef < ' tcx > ,  kind :  InitKind )  { 
513505        debug ! ( "gather_init({:?}, {:?})" ,  self . loc,  place) ; 
514506
515-         if  let  Some ( new_place)  = self . builder . un_derefer . derefer ( place,  self . builder . body )  { 
516-             self . gather_init ( new_place. as_ref ( ) ,  kind) ; 
517-             return ; 
518-         } 
519- 
520507        let  mut  place = place; 
521508
522509        // Check if we are assigning into a field of a union, if so, lookup the place 
0 commit comments