@@ -101,7 +101,59 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
101101 Err ( MoveError :: cannot_move_out_of ( self . loc , Static ) )
102102 }
103103 Place :: Projection ( ref proj) => {
104- self . move_path_for_projection ( place, proj)
104+ let base = self . move_path_for ( & proj. base ) ?;
105+ let mir = self . builder . mir ;
106+ let tcx = self . builder . tcx ;
107+ let place_ty = proj. base . ty ( mir, tcx) . ty ;
108+ match place_ty. sty {
109+ ty:: Ref ( ..) | ty:: RawPtr ( ..) =>
110+ return Err ( MoveError :: cannot_move_out_of (
111+ self . loc ,
112+ BorrowedContent { target_place : place. clone ( ) } ) ) ,
113+ ty:: Adt ( adt, _) if adt. has_dtor ( tcx) && !adt. is_box ( ) =>
114+ return Err ( MoveError :: cannot_move_out_of ( self . loc ,
115+ InteriorOfTypeWithDestructor {
116+ container_ty : place_ty
117+ } ) ) ,
118+ // move out of union - always move the entire union
119+ ty:: Adt ( adt, _) if adt. is_union ( ) =>
120+ return Err ( MoveError :: UnionMove { path : base } ) ,
121+ ty:: Slice ( _) =>
122+ return Err ( MoveError :: cannot_move_out_of (
123+ self . loc ,
124+ InteriorOfSliceOrArray {
125+ ty : place_ty, is_index : match proj. elem {
126+ ProjectionElem :: Index ( ..) => true ,
127+ _ => false
128+ } ,
129+ } ) ) ,
130+ ty:: Array ( ..) => match proj. elem {
131+ ProjectionElem :: Index ( ..) =>
132+ return Err ( MoveError :: cannot_move_out_of (
133+ self . loc ,
134+ InteriorOfSliceOrArray {
135+ ty : place_ty, is_index : true
136+ } ) ) ,
137+ _ => {
138+ // FIXME: still badly broken
139+ }
140+ } ,
141+ _ => { }
142+ } ;
143+ match self . builder . data . rev_lookup . projections . entry ( ( base, proj. elem . lift ( ) ) ) {
144+ Entry :: Occupied ( ent) => Ok ( * ent. get ( ) ) ,
145+ Entry :: Vacant ( ent) => {
146+ let path = MoveDataBuilder :: new_move_path (
147+ & mut self . builder . data . move_paths ,
148+ & mut self . builder . data . path_map ,
149+ & mut self . builder . data . init_path_map ,
150+ Some ( base) ,
151+ place. clone ( )
152+ ) ;
153+ ent. insert ( path) ;
154+ Ok ( path)
155+ }
156+ }
105157 }
106158 }
107159 }
@@ -111,66 +163,6 @@ impl<'b, 'a, 'gcx, 'tcx> Gatherer<'b, 'a, 'gcx, 'tcx> {
111163 // drop), so this not being a valid move path is OK.
112164 let _ = self . move_path_for ( place) ;
113165 }
114-
115- fn move_path_for_projection ( & mut self ,
116- place : & Place < ' tcx > ,
117- proj : & Projection < ' tcx > )
118- -> Result < MovePathIndex , MoveError < ' tcx > >
119- {
120- let base = self . move_path_for ( & proj. base ) ?;
121- let mir = self . builder . mir ;
122- let tcx = self . builder . tcx ;
123- let place_ty = proj. base . ty ( mir, tcx) . ty ;
124- match place_ty. sty {
125- ty:: Ref ( ..) | ty:: RawPtr ( ..) =>
126- return Err ( MoveError :: cannot_move_out_of (
127- self . loc ,
128- BorrowedContent { target_place : place. clone ( ) } ) ) ,
129- ty:: Adt ( adt, _) if adt. has_dtor ( tcx) && !adt. is_box ( ) =>
130- return Err ( MoveError :: cannot_move_out_of ( self . loc ,
131- InteriorOfTypeWithDestructor {
132- container_ty : place_ty
133- } ) ) ,
134- // move out of union - always move the entire union
135- ty:: Adt ( adt, _) if adt. is_union ( ) =>
136- return Err ( MoveError :: UnionMove { path : base } ) ,
137- ty:: Slice ( _) =>
138- return Err ( MoveError :: cannot_move_out_of (
139- self . loc ,
140- InteriorOfSliceOrArray {
141- ty : place_ty, is_index : match proj. elem {
142- ProjectionElem :: Index ( ..) => true ,
143- _ => false
144- } ,
145- } ) ) ,
146- ty:: Array ( ..) => match proj. elem {
147- ProjectionElem :: Index ( ..) =>
148- return Err ( MoveError :: cannot_move_out_of (
149- self . loc ,
150- InteriorOfSliceOrArray {
151- ty : place_ty, is_index : true
152- } ) ) ,
153- _ => {
154- // FIXME: still badly broken
155- }
156- } ,
157- _ => { }
158- } ;
159- match self . builder . data . rev_lookup . projections . entry ( ( base, proj. elem . lift ( ) ) ) {
160- Entry :: Occupied ( ent) => Ok ( * ent. get ( ) ) ,
161- Entry :: Vacant ( ent) => {
162- let path = MoveDataBuilder :: new_move_path (
163- & mut self . builder . data . move_paths ,
164- & mut self . builder . data . path_map ,
165- & mut self . builder . data . init_path_map ,
166- Some ( base) ,
167- place. clone ( )
168- ) ;
169- ent. insert ( path) ;
170- Ok ( path)
171- }
172- }
173- }
174166}
175167
176168impl < ' a , ' gcx , ' tcx > MoveDataBuilder < ' a , ' gcx , ' tcx > {
0 commit comments