@@ -115,44 +115,125 @@ impl<'b, 'a, 'tcx> Gatherer<'b, 'a, 'tcx> {
115
115
let body = self . builder . body ;
116
116
let tcx = self . builder . tcx ;
117
117
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
+ }
142
213
}
143
-
144
- ty:: Array ( ..) => {
145
- if let ProjectionElem :: Index ( ..) = elem {
214
+ ProjectionElem :: Index ( _) => match place_ty. kind ( ) {
215
+ ty:: Array ( ..) => {
146
216
return Err ( MoveError :: cannot_move_out_of (
147
217
self . loc ,
148
218
InteriorOfSliceOrArray { ty : place_ty, is_index : true } ,
149
219
) ) ;
150
220
}
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
+ }
156
237
if union_path. is_none ( ) {
157
238
// inlined from add_move_path because of a borrowck conflict with the iterator
158
239
base =
0 commit comments