@@ -115,44 +115,125 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
115115 let body = self . builder . body ;
116116 let tcx = self . builder . tcx ;
117117 let place_ty = place_ref. ty ( body, tcx) . ty ;
118- match place_ty. kind ( ) {
119- ty:: Ref ( ..) | ty:: RawPtr ( ..) => {
120- return Err ( MoveError :: cannot_move_out_of (
121- self . loc ,
122- BorrowedContent { target_place : place_ref. project_deeper ( & [ elem] , tcx) } ,
123- ) ) ;
124- }
125- ty:: Adt ( adt, _) if adt. has_dtor ( tcx) && !adt. is_box ( ) => {
126- return Err ( MoveError :: cannot_move_out_of (
127- self . loc ,
128- InteriorOfTypeWithDestructor { container_ty : place_ty } ,
129- ) ) ;
130- }
131- ty:: Adt ( adt, _) if adt. is_union ( ) => {
132- union_path. get_or_insert ( base) ;
133- }
134- ty:: Slice ( _) => {
135- return Err ( MoveError :: cannot_move_out_of (
136- self . loc ,
137- InteriorOfSliceOrArray {
138- ty : place_ty,
139- is_index : matches ! ( elem, ProjectionElem :: Index ( ..) ) ,
140- } ,
141- ) ) ;
118+ match elem {
119+ ProjectionElem :: Deref => match place_ty. kind ( ) {
120+ ty:: Ref ( ..) | ty:: RawPtr ( ..) => {
121+ return Err ( MoveError :: cannot_move_out_of (
122+ self . loc ,
123+ BorrowedContent {
124+ target_place : place_ref. project_deeper ( & [ elem] , tcx) ,
125+ } ,
126+ ) ) ;
127+ }
128+ ty:: Adt ( adt, _) => {
129+ if !adt. is_box ( ) {
130+ bug ! ( "Adt should be a box type when Place is deref" ) ;
131+ }
132+ }
133+ ty:: Bool
134+ | ty:: Char
135+ | ty:: Int ( _)
136+ | ty:: Uint ( _)
137+ | ty:: Float ( _)
138+ | ty:: Foreign ( _)
139+ | ty:: Str
140+ | ty:: Array ( _, _)
141+ | ty:: Slice ( _)
142+ | ty:: FnDef ( _, _)
143+ | ty:: FnPtr ( _)
144+ | ty:: Dynamic ( _, _, _)
145+ | ty:: Closure ( _, _)
146+ | ty:: Generator ( _, _, _)
147+ | ty:: GeneratorWitness ( _)
148+ | ty:: GeneratorWitnessMIR ( _, _)
149+ | ty:: Never
150+ | ty:: Tuple ( _)
151+ | ty:: Alias ( _, _)
152+ | ty:: Param ( _)
153+ | ty:: Bound ( _, _)
154+ | ty:: Infer ( _)
155+ | ty:: Error ( _)
156+ | ty:: Placeholder ( _) => {
157+ bug ! ( "When Place is Deref it's type shouldn't be {place_ty:#?}" )
158+ }
159+ } ,
160+ ProjectionElem :: Field ( _, _) => match place_ty. kind ( ) {
161+ ty:: Adt ( adt, _) => {
162+ if adt. has_dtor ( tcx) {
163+ return Err ( MoveError :: cannot_move_out_of (
164+ self . loc ,
165+ InteriorOfTypeWithDestructor { container_ty : place_ty } ,
166+ ) ) ;
167+ }
168+ if adt. is_union ( ) {
169+ union_path. get_or_insert ( base) ;
170+ }
171+ }
172+ ty:: Closure ( _, _) | ty:: Generator ( _, _, _) | ty:: Tuple ( _) => ( ) ,
173+ ty:: Bool
174+ | ty:: Char
175+ | ty:: Int ( _)
176+ | ty:: Uint ( _)
177+ | ty:: Float ( _)
178+ | ty:: Foreign ( _)
179+ | ty:: Str
180+ | ty:: Array ( _, _)
181+ | ty:: Slice ( _)
182+ | ty:: RawPtr ( _)
183+ | ty:: Ref ( _, _, _)
184+ | ty:: FnDef ( _, _)
185+ | ty:: FnPtr ( _)
186+ | ty:: Dynamic ( _, _, _)
187+ | ty:: GeneratorWitness ( _)
188+ | ty:: GeneratorWitnessMIR ( _, _)
189+ | ty:: Never
190+ | ty:: Alias ( _, _)
191+ | ty:: Param ( _)
192+ | ty:: Bound ( _, _)
193+ | ty:: Infer ( _)
194+ | ty:: Error ( _)
195+ | ty:: Placeholder ( _) => bug ! (
196+ "When Place contains ProjectionElem::Field it's type shouldn't be {place_ty:#?}"
197+ ) ,
198+ } ,
199+ ProjectionElem :: ConstantIndex { .. } | ProjectionElem :: Subslice { .. } => {
200+ match place_ty. kind ( ) {
201+ ty:: Slice ( _) => {
202+ return Err ( MoveError :: cannot_move_out_of (
203+ self . loc ,
204+ InteriorOfSliceOrArray {
205+ ty : place_ty,
206+ is_index : matches ! ( elem, ProjectionElem :: Index ( ..) ) ,
207+ } ,
208+ ) ) ;
209+ }
210+ ty:: Array ( _, _) => ( ) ,
211+ _ => bug ! ( "Unexpected type {:#?}" , place_ty. is_array( ) ) ,
212+ }
142213 }
143-
144- ty:: Array ( ..) => {
145- if let ProjectionElem :: Index ( ..) = elem {
214+ ProjectionElem :: Index ( _) => match place_ty. kind ( ) {
215+ ty:: Array ( ..) => {
146216 return Err ( MoveError :: cannot_move_out_of (
147217 self . loc ,
148218 InteriorOfSliceOrArray { ty : place_ty, is_index : true } ,
149219 ) ) ;
150220 }
151- }
152-
153- _ => { }
154- } ;
155-
221+ ty:: Slice ( _) => {
222+ return Err ( MoveError :: cannot_move_out_of (
223+ self . loc ,
224+ InteriorOfSliceOrArray {
225+ ty : place_ty,
226+ is_index : matches ! ( elem, ProjectionElem :: Index ( ..) ) ,
227+ } ,
228+ ) ) ;
229+ }
230+ _ => bug ! ( "Unexpected type {place_ty:#?}" ) ,
231+ } ,
232+ // `OpaqueCast` only transmutes the type, so no moves there and
233+ // `Downcast` only changes information about a `Place` without moving
234+ // So it's safe to skip these.
235+ ProjectionElem :: OpaqueCast ( _) | ProjectionElem :: Downcast ( _, _) => ( ) ,
236+ }
156237 if union_path. is_none ( ) {
157238 // inlined from add_move_path because of a borrowck conflict with the iterator
158239 base =
0 commit comments