@@ -24,7 +24,7 @@ use syntax::source_map::{self, Span};
24
24
use syntax:: ast:: Mutability ;
25
25
26
26
use super :: {
27
- Value , ValTy , Operand , MemPlace , MPlaceTy , Place , PlaceExtra ,
27
+ Value , Operand , MemPlace , MPlaceTy , Place , PlaceExtra ,
28
28
Memory , Machine
29
29
} ;
30
30
@@ -466,18 +466,19 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
466
466
self . layout_of ( local_ty)
467
467
}
468
468
469
- /// Return the size and alignment of the value at the given type.
469
+ /// Return the actual dynamic size and alignment of the place at the given type.
470
470
/// Note that the value does not matter if the type is sized. For unsized types,
471
471
/// the value has to be a fat pointer, and we only care about the "extra" data in it.
472
- pub fn size_and_align_of_val (
472
+ pub fn size_and_align_of_mplace (
473
473
& self ,
474
- val : ValTy < ' tcx > ,
474
+ mplace : MPlaceTy < ' tcx > ,
475
475
) -> EvalResult < ' tcx , ( Size , Align ) > {
476
- let pointee_ty = val. layout . ty . builtin_deref ( true ) . unwrap ( ) . ty ;
477
- let layout = self . layout_of ( pointee_ty) ?;
478
- if !layout. is_unsized ( ) {
479
- Ok ( layout. size_and_align ( ) )
476
+ if let PlaceExtra :: None = mplace. extra {
477
+ assert ! ( !mplace. layout. is_unsized( ) ) ;
478
+ Ok ( mplace. layout . size_and_align ( ) )
480
479
} else {
480
+ let layout = mplace. layout ;
481
+ assert ! ( layout. is_unsized( ) ) ;
481
482
match layout. ty . sty {
482
483
ty:: TyAdt ( ..) | ty:: TyTuple ( ..) => {
483
484
// First get the size of all statically known fields.
@@ -498,12 +499,8 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
498
499
499
500
// Recurse to get the size of the dynamically sized field (must be
500
501
// the last field).
501
- let field_layout = layout. field ( self , layout. fields . count ( ) - 1 ) ?;
502
- let ( unsized_size, unsized_align) =
503
- self . size_and_align_of_val ( ValTy {
504
- value : val. value ,
505
- layout : field_layout
506
- } ) ?;
502
+ let field = self . mplace_field ( mplace, layout. fields . count ( ) as u64 - 1 ) ?;
503
+ let ( unsized_size, unsized_align) = self . size_and_align_of_mplace ( field) ?;
507
504
508
505
// FIXME (#26403, #27023): We should be adding padding
509
506
// to `sized_size` (to accommodate the `unsized_align`
@@ -533,18 +530,24 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M
533
530
Ok ( ( size. abi_align ( align) , align) )
534
531
}
535
532
ty:: TyDynamic ( ..) => {
536
- let ( _, vtable) = val. to_scalar_dyn_trait ( ) ?;
533
+ let vtable = match mplace. extra {
534
+ PlaceExtra :: Vtable ( vtable) => vtable,
535
+ _ => bug ! ( "Expected vtable" ) ,
536
+ } ;
537
537
// the second entry in the vtable is the dynamic size of the object.
538
538
self . read_size_and_align_from_vtable ( vtable)
539
539
}
540
540
541
541
ty:: TySlice ( _) | ty:: TyStr => {
542
+ let len = match mplace. extra {
543
+ PlaceExtra :: Length ( len) => len,
544
+ _ => bug ! ( "Expected length" ) ,
545
+ } ;
542
546
let ( elem_size, align) = layout. field ( self , 0 ) ?. size_and_align ( ) ;
543
- let ( _, len) = val. to_scalar_slice ( self ) ?;
544
547
Ok ( ( elem_size * len, align) )
545
548
}
546
549
547
- _ => bug ! ( "size_of_val::<{:?}>" , layout. ty) ,
550
+ _ => bug ! ( "size_of_val::<{:?}> not supported " , layout. ty) ,
548
551
}
549
552
}
550
553
}
0 commit comments