@@ -332,22 +332,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
332
332
}
333
333
334
334
/// Return the actual dynamic size and alignment of the place at the given type.
335
- /// Only the `meta` part of the place matters.
335
+ /// Only the "meta" (metadata) part of the place matters.
336
+ /// This can fail to provide an answer for extern types.
336
337
pub ( super ) fn size_and_align_of (
337
338
& self ,
338
339
metadata : Option < Scalar < M :: PointerTag > > ,
339
340
layout : TyLayout < ' tcx > ,
340
- ) -> EvalResult < ' tcx , ( Size , Align ) > {
341
- let metadata = match metadata {
342
- None => {
343
- assert ! ( !layout. is_unsized( ) ) ;
344
- return Ok ( layout. size_and_align ( ) )
345
- }
346
- Some ( metadata) => {
347
- assert ! ( layout. is_unsized( ) ) ;
348
- metadata
349
- }
350
- } ;
341
+ ) -> EvalResult < ' tcx , Option < ( Size , Align ) > > {
342
+ if !layout. is_unsized ( ) {
343
+ return Ok ( Some ( layout. size_and_align ( ) ) ) ;
344
+ }
351
345
match layout. ty . sty {
352
346
ty:: Adt ( ..) | ty:: Tuple ( ..) => {
353
347
// First get the size of all statically known fields.
@@ -367,9 +361,11 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
367
361
) ;
368
362
369
363
// Recurse to get the size of the dynamically sized field (must be
370
- // the last field).
364
+ // the last field). Can't have foreign types here, how would we
365
+ // adjust alignment and size for them?
371
366
let field = layout. field ( self , layout. fields . count ( ) - 1 ) ?;
372
- let ( unsized_size, unsized_align) = self . size_and_align_of ( Some ( metadata) , field) ?;
367
+ let ( unsized_size, unsized_align) = self . size_and_align_of ( metadata, field) ?
368
+ . expect ( "Fields cannot be extern types" ) ;
373
369
374
370
// FIXME (#26403, #27023): We should be adding padding
375
371
// to `sized_size` (to accommodate the `unsized_align`
@@ -396,18 +392,22 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
396
392
//
397
393
// `(size + (align-1)) & -align`
398
394
399
- Ok ( ( size. abi_align ( align) , align) )
395
+ Ok ( Some ( ( size. abi_align ( align) , align) ) )
400
396
}
401
397
ty:: Dynamic ( ..) => {
402
- let vtable = metadata. to_ptr ( ) ?;
398
+ let vtable = metadata. expect ( "dyn trait fat ptr must have vtable" ) . to_ptr ( ) ?;
403
399
// the second entry in the vtable is the dynamic size of the object.
404
- self . read_size_and_align_from_vtable ( vtable)
400
+ Ok ( Some ( self . read_size_and_align_from_vtable ( vtable) ? ) )
405
401
}
406
402
407
403
ty:: Slice ( _) | ty:: Str => {
408
- let len = metadata. to_usize ( self ) ?;
404
+ let len = metadata. expect ( "slice fat ptr must have vtable" ) . to_usize ( self ) ?;
409
405
let ( elem_size, align) = layout. field ( self , 0 ) ?. size_and_align ( ) ;
410
- Ok ( ( elem_size * len, align) )
406
+ Ok ( Some ( ( elem_size * len, align) ) )
407
+ }
408
+
409
+ ty:: Foreign ( _) => {
410
+ Ok ( None )
411
411
}
412
412
413
413
_ => bug ! ( "size_and_align_of::<{:?}> not supported" , layout. ty) ,
@@ -417,7 +417,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
417
417
pub fn size_and_align_of_mplace (
418
418
& self ,
419
419
mplace : MPlaceTy < ' tcx , M :: PointerTag >
420
- ) -> EvalResult < ' tcx , ( Size , Align ) > {
420
+ ) -> EvalResult < ' tcx , Option < ( Size , Align ) > > {
421
421
self . size_and_align_of ( mplace. meta , mplace. layout )
422
422
}
423
423
0 commit comments