@@ -194,55 +194,48 @@ fn create_pointee_place<'tcx>(
194
194
) -> MPlaceTy < ' tcx > {
195
195
let tcx = ecx. tcx . tcx ;
196
196
197
- match ty. kind ( ) {
198
- ty:: Slice ( _) | ty:: Str => {
199
- let slice_ty = match ty. kind ( ) {
200
- ty:: Slice ( slice_ty) => * slice_ty,
201
- ty:: Str => tcx. mk_ty ( ty:: Uint ( ty:: UintTy :: U8 ) ) ,
202
- _ => bug ! ( "expected ty::Slice | ty::Str" ) ,
203
- } ;
204
-
205
- // Create a place for the underlying array
206
- let len = valtree. unwrap_branch ( ) . len ( ) as u64 ;
207
- let arr_ty = tcx. mk_array ( slice_ty, len as u64 ) ;
208
- let place = create_mplace_from_layout ( ecx, arr_ty) ;
209
- debug ! ( ?place) ;
197
+ if !ty. is_sized ( ecx. tcx , ty:: ParamEnv :: empty ( ) ) {
198
+ // We need to create `Allocation`s for custom DSTs
199
+
200
+ let ( unsized_inner_ty, num_elems) = get_info_on_unsized_field ( ty, valtree, tcx) ;
201
+ let unsized_inner_ty = match unsized_inner_ty. kind ( ) {
202
+ ty:: Str => tcx. mk_ty ( ty:: Uint ( ty:: UintTy :: U8 ) ) ,
203
+ _ => unsized_inner_ty,
204
+ } ;
205
+ let unsized_inner_ty_size =
206
+ tcx. layout_of ( ty:: ParamEnv :: empty ( ) . and ( unsized_inner_ty) ) . unwrap ( ) . layout . size ( ) ;
207
+ debug ! ( ?unsized_inner_ty, ?unsized_inner_ty_size, ?num_elems) ;
208
+
209
+ // for custom DSTs only the last field/element is unsized, but we need to also allocate
210
+ // space for the other fields/elements
211
+ let layout = tcx. layout_of ( ty:: ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
212
+ let size_of_sized_part = layout. layout . size ( ) ;
213
+
214
+ // Get the size of the memory behind the DST
215
+ let dst_size = unsized_inner_ty_size. checked_mul ( num_elems as u64 , & tcx) . unwrap ( ) ;
216
+
217
+ let ptr = ecx
218
+ . allocate_ptr (
219
+ size_of_sized_part. checked_add ( dst_size, & tcx) . unwrap ( ) ,
220
+ Align :: from_bytes ( 1 ) . unwrap ( ) ,
221
+ MemoryKind :: Stack ,
222
+ )
223
+ . unwrap ( ) ;
224
+ debug ! ( ?ptr) ;
210
225
211
- place
212
- }
213
- ty:: Adt ( _, _) if !ty. is_sized ( ecx. tcx , ty:: ParamEnv :: empty ( ) ) => {
214
- // We need to create `Allocation`s for custom DSTs
215
-
216
- let layout = tcx. layout_of ( ty:: ParamEnv :: empty ( ) . and ( ty) ) . unwrap ( ) ;
217
- let sized_fields_size = layout. layout . size ( ) ;
218
- let ( unsized_inner_ty, num_elems) = get_info_on_unsized_field ( ty, valtree, tcx) ;
219
- let unsized_inner_ty_size =
220
- tcx. layout_of ( ty:: ParamEnv :: empty ( ) . and ( unsized_inner_ty) ) . unwrap ( ) . layout . size ( ) ;
221
- debug ! ( ?unsized_inner_ty, ?unsized_inner_ty_size, ?num_elems) ;
222
-
223
- // Get the size of the array behind the DST
224
- let dst_size = unsized_inner_ty_size. checked_mul ( num_elems as u64 , & tcx) . unwrap ( ) ;
225
-
226
- let ptr = ecx
227
- . allocate_ptr (
228
- sized_fields_size. checked_add ( dst_size, & tcx) . unwrap ( ) ,
229
- Align :: from_bytes ( 1 ) . unwrap ( ) ,
230
- MemoryKind :: Stack ,
231
- )
232
- . unwrap ( ) ;
233
- debug ! ( ?ptr) ;
234
-
235
- let place = MPlaceTy :: from_aligned_ptr ( ptr. into ( ) , layout) ;
236
- debug ! ( ?place) ;
226
+ let mut place = MPlaceTy :: from_aligned_ptr ( ptr. into ( ) , layout) ;
227
+ place. meta = MemPlaceMeta :: Meta ( Scalar :: from_u64 ( num_elems as u64 ) ) ;
228
+ debug ! ( ?place) ;
237
229
238
- place
239
- }
240
- _ => create_mplace_from_layout ( ecx, ty) ,
230
+ place
231
+ } else {
232
+ create_mplace_from_layout ( ecx, ty)
241
233
}
242
234
}
243
235
244
236
/// Converts a `ValTree` to a `ConstValue`, which is needed after mir
245
237
/// construction has finished.
238
+ // FIXME Merge `valtree_to_const_value` and `fill_place_recursively` into one function
246
239
#[ instrument( skip( tcx) , level = "debug" ) ]
247
240
pub fn valtree_to_const_value < ' tcx > (
248
241
tcx : TyCtxt < ' tcx > ,
@@ -374,12 +367,9 @@ fn fill_place_recursively<'tcx>(
374
367
375
368
ecx. write_immediate ( imm, & ( * place) . into ( ) ) . unwrap ( ) ;
376
369
}
377
- ty:: Adt ( _, _) | ty:: Tuple ( _) | ty:: Array ( _, _) | ty:: Str => {
370
+ ty:: Adt ( _, _) | ty:: Tuple ( _) | ty:: Array ( _, _) | ty:: Str | ty :: Slice ( _ ) => {
378
371
let branches = valtree. unwrap_branch ( ) ;
379
372
380
- // Need to collect the length of the unsized field for meta info
381
- let mut unsized_meta_info = None ;
382
-
383
373
// Need to downcast place for enums
384
374
let ( place_adjusted, branches, variant_idx) = match ty. kind ( ) {
385
375
ty:: Adt ( def, _) if def. is_enum ( ) => {
@@ -399,48 +389,52 @@ fn fill_place_recursively<'tcx>(
399
389
} ;
400
390
debug ! ( ?place_adjusted, ?branches) ;
401
391
402
- // Create the places for the fields and fill them recursively
392
+ // Create the places (by indexing into `place`) for the fields and fill
393
+ // them recursively
403
394
for ( i, inner_valtree) in branches. iter ( ) . enumerate ( ) {
404
395
debug ! ( ?i, ?inner_valtree) ;
405
396
406
- if !ty. is_sized ( ecx. tcx , ty:: ParamEnv :: empty ( ) ) && i == branches. len ( ) - 1 {
407
- // Note: For custom DSTs we need to manually process the last unsized field.
408
- // We created a `Pointer` for the `Allocation` of the complete sized version of
409
- // the Adt in `create_pointee_place` and now we fill that `Allocation` with the
410
- // values in the ValTree. For the unsized field we have to additionally add the meta
411
- // data.
412
-
413
- let offset = place. layout . fields . offset ( i) ;
414
- let ( unsized_inner_ty, num_elems) = get_info_on_unsized_field ( ty, valtree, tcx) ;
415
- unsized_meta_info = Some ( num_elems) ;
416
-
417
- // We create an array type to allow the recursive call to fill the place
418
- // corresponding to the array
419
- let arr_ty = tcx. mk_array ( unsized_inner_ty, num_elems as u64 ) ;
420
- debug ! ( ?arr_ty) ;
421
- let arr_layout = tcx. layout_of ( ty:: ParamEnv :: empty ( ) . and ( arr_ty) ) . unwrap ( ) ;
422
- let mut place_arr =
423
- place. offset ( offset, MemPlaceMeta :: None , arr_layout, & tcx) . unwrap ( ) ;
424
- debug ! ( ?place_arr) ;
425
-
426
- fill_place_recursively ( ecx, & mut place_arr, * inner_valtree) ;
427
- dump_place ( & ecx, place_arr. into ( ) ) ;
428
-
429
- // Add the meta information for the unsized type
430
- place_arr. meta = MemPlaceMeta :: Meta ( Scalar :: from_u64 ( num_elems as u64 ) ) ;
431
-
432
- break ;
433
- }
434
-
435
- let mut place_inner = match * ty. kind ( ) {
436
- ty:: Adt ( _, _) | ty:: Tuple ( _) => ecx. mplace_field ( & place_adjusted, i) . unwrap ( ) ,
437
- ty:: Array ( _, _) | ty:: Str => {
438
- ecx. mplace_index ( & place_adjusted, i as u64 ) . unwrap ( )
397
+ let mut place_inner = match ty. kind ( ) {
398
+ ty:: Str | ty:: Slice ( _) => ecx. mplace_index ( & place, i as u64 ) . unwrap ( ) ,
399
+ _ if !ty. is_sized ( ecx. tcx , ty:: ParamEnv :: empty ( ) )
400
+ && i == branches. len ( ) - 1 =>
401
+ {
402
+ // Note: For custom DSTs we need to manually process the last unsized field.
403
+ // We created a `Pointer` for the `Allocation` of the complete sized version of
404
+ // the Adt in `create_pointee_place` and now we fill that `Allocation` with the
405
+ // values in the ValTree. For the unsized field we have to additionally add the meta
406
+ // data.
407
+
408
+ let ( unsized_inner_ty, num_elems) =
409
+ get_info_on_unsized_field ( ty, valtree, tcx) ;
410
+ debug ! ( ?unsized_inner_ty) ;
411
+
412
+ let inner_ty = match ty. kind ( ) {
413
+ ty:: Adt ( def, substs) => {
414
+ def. variant ( VariantIdx :: from_u32 ( 0 ) ) . fields [ i] . ty ( tcx, substs)
415
+ }
416
+ ty:: Tuple ( inner_tys) => inner_tys[ i] ,
417
+ _ => bug ! ( "unexpected unsized type {:?}" , ty) ,
418
+ } ;
419
+
420
+ let inner_layout =
421
+ tcx. layout_of ( ty:: ParamEnv :: empty ( ) . and ( inner_ty) ) . unwrap ( ) ;
422
+ debug ! ( ?inner_layout) ;
423
+
424
+ let offset = place_adjusted. layout . fields . offset ( i) ;
425
+ place
426
+ . offset (
427
+ offset,
428
+ MemPlaceMeta :: Meta ( Scalar :: from_u64 ( num_elems as u64 ) ) ,
429
+ inner_layout,
430
+ & tcx,
431
+ )
432
+ . unwrap ( )
439
433
}
440
- _ => bug ! ( ) ,
434
+ _ => ecx . mplace_field ( & place_adjusted , i ) . unwrap ( ) ,
441
435
} ;
442
- debug ! ( ?place_inner) ;
443
436
437
+ debug ! ( ?place_inner) ;
444
438
fill_place_recursively ( ecx, & mut place_inner, * inner_valtree) ;
445
439
dump_place ( & ecx, place_inner. into ( ) ) ;
446
440
}
@@ -453,12 +447,7 @@ fn fill_place_recursively<'tcx>(
453
447
ecx. write_discriminant ( variant_idx, & ( * place) . into ( ) ) . unwrap ( ) ;
454
448
}
455
449
456
- // add meta information for unsized type
457
- if !ty. is_sized ( ecx. tcx , ty:: ParamEnv :: empty ( ) ) {
458
- place. meta =
459
- MemPlaceMeta :: Meta ( Scalar :: from_u64 ( unsized_meta_info. unwrap ( ) as u64 ) ) ;
460
- }
461
-
450
+ debug ! ( "dump of place after writing discriminant:" ) ;
462
451
dump_place ( ecx, ( * place) . into ( ) ) ;
463
452
}
464
453
_ => bug ! ( "shouldn't have created a ValTree for {:?}" , ty) ,
0 commit comments