@@ -280,13 +280,13 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
280
280
pub fn size_and_align_of_dst (
281
281
& mut self ,
282
282
ty : ty:: Ty < ' tcx > ,
283
- value : Value ,
283
+ value : Value , // This has to be a fat ptr; we only care about the "extra" data in it.
284
284
) -> EvalResult < ' tcx , ( u64 , u64 ) > {
285
285
if let Some ( size) = self . type_size ( ty) ? {
286
286
Ok ( ( size as u64 , self . type_align ( ty) ? as u64 ) )
287
287
} else {
288
288
match ty. sty {
289
- ty:: TyAdt ( def , substs ) => {
289
+ ty:: TyAdt ( .. ) | ty :: TyTuple ( .. ) => {
290
290
// First get the size of all statically known fields.
291
291
// Don't use type_of::sizing_type_of because that expects t to be sized,
292
292
// and it also rounds up to alignment, which we want to avoid,
@@ -309,9 +309,19 @@ impl<'a, 'tcx, M: Machine<'tcx>> EvalContext<'a, 'tcx, M> {
309
309
310
310
// Recurse to get the size of the dynamically sized field (must be
311
311
// the last field).
312
- let last_field = def. struct_variant ( ) . fields . last ( ) . unwrap ( ) ;
313
- let field_ty = self . field_ty ( substs, last_field) ;
314
- let ( unsized_size, unsized_align) = self . size_and_align_of_dst ( field_ty, value) ?;
312
+ let ( unsized_size, unsized_align) = match ty. sty {
313
+ ty:: TyAdt ( def, substs) => {
314
+ let last_field = def. struct_variant ( ) . fields . last ( ) . unwrap ( ) ;
315
+ let field_ty = self . field_ty ( substs, last_field) ;
316
+ self . size_and_align_of_dst ( field_ty, value) ?
317
+ }
318
+ ty:: TyTuple ( ref types, _) => {
319
+ let field_ty = types. last ( ) . unwrap ( ) ;
320
+ let field_ty = self . tcx . normalize_associated_type ( field_ty) ;
321
+ self . size_and_align_of_dst ( field_ty, value) ?
322
+ }
323
+ _ => bug ! ( "We already checked that we know this type" ) ,
324
+ } ;
315
325
316
326
// FIXME (#26403, #27023): We should be adding padding
317
327
// to `sized_size` (to accommodate the `unsized_align`
0 commit comments