@@ -308,7 +308,8 @@ impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
308
308
#[ derive( Copy , Clone , Debug ) ]
309
309
pub enum SizeSkeleton < ' tcx > {
310
310
/// Any statically computable Layout.
311
- Known ( Size ) ,
311
+ /// Alignment can be `None` if unknown.
312
+ Known ( Size , Option < Align > ) ,
312
313
313
314
/// This is a generic const expression (i.e. N * 2), which may contain some parameters.
314
315
/// It must be of type usize, and represents the size of a type in bytes.
@@ -338,7 +339,12 @@ impl<'tcx> SizeSkeleton<'tcx> {
338
339
// First try computing a static layout.
339
340
let err = match tcx. layout_of ( param_env. and ( ty) ) {
340
341
Ok ( layout) => {
341
- return Ok ( SizeSkeleton :: Known ( layout. size ) ) ;
342
+ if layout. abi . is_sized ( ) {
343
+ return Ok ( SizeSkeleton :: Known ( layout. size , Some ( layout. align . abi ) ) ) ;
344
+ } else {
345
+ // Just to be safe, don't claim a known layout for unsized types.
346
+ return Err ( tcx. arena . alloc ( LayoutError :: Unknown ( ty) ) ) ;
347
+ }
342
348
}
343
349
Err ( err @ LayoutError :: Unknown ( _) ) => err,
344
350
// We can't extract SizeSkeleton info from other layout errors
@@ -390,19 +396,20 @@ impl<'tcx> SizeSkeleton<'tcx> {
390
396
{
391
397
let len_eval = len. try_eval_target_usize ( tcx, param_env) ;
392
398
if len_eval == Some ( 0 ) {
393
- return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( 0 ) ) ) ;
399
+ return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( 0 ) , None ) ) ;
394
400
}
395
401
396
402
match SizeSkeleton :: compute ( inner, tcx, param_env) ? {
397
403
// This may succeed because the multiplication of two types may overflow
398
404
// but a single size of a nested array will not.
399
- SizeSkeleton :: Known ( s) => {
405
+ SizeSkeleton :: Known ( s, a ) => {
400
406
if let Some ( c) = len_eval {
401
407
let size = s
402
408
. bytes ( )
403
409
. checked_mul ( c)
404
410
. ok_or_else ( || & * tcx. arena . alloc ( LayoutError :: SizeOverflow ( ty) ) ) ?;
405
- return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( size) ) ) ;
411
+ // Alignment is unchanged by arrays.
412
+ return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( size) , a) ) ;
406
413
}
407
414
Err ( tcx. arena . alloc ( LayoutError :: Unknown ( ty) ) )
408
415
}
@@ -428,8 +435,10 @@ impl<'tcx> SizeSkeleton<'tcx> {
428
435
for field in fields {
429
436
let field = field?;
430
437
match field {
431
- SizeSkeleton :: Known ( size) => {
432
- if size. bytes ( ) > 0 {
438
+ SizeSkeleton :: Known ( size, align) => {
439
+ let is_1zst = size. bytes ( ) == 0
440
+ && align. is_some_and ( |align| align. bytes ( ) == 1 ) ;
441
+ if !is_1zst {
433
442
return Err ( err) ;
434
443
}
435
444
}
@@ -493,7 +502,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
493
502
494
503
pub fn same_size ( self , other : SizeSkeleton < ' tcx > ) -> bool {
495
504
match ( self , other) {
496
- ( SizeSkeleton :: Known ( a) , SizeSkeleton :: Known ( b) ) => a == b,
505
+ ( SizeSkeleton :: Known ( a, _ ) , SizeSkeleton :: Known ( b, _ ) ) => a == b,
497
506
( SizeSkeleton :: Pointer { tail : a, .. } , SizeSkeleton :: Pointer { tail : b, .. } ) => {
498
507
a == b
499
508
}
0 commit comments