@@ -308,7 +308,8 @@ impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
308308#[ derive( Copy , Clone , Debug ) ]
309309pub enum SizeSkeleton < ' tcx > {
310310 /// Any statically computable Layout.
311- Known ( Size ) ,
311+ /// Alignment can be `None` if unknown.
312+ Known ( Size , Option < Align > ) ,
312313
313314 /// This is a generic const expression (i.e. N * 2), which may contain some parameters.
314315 /// It must be of type usize, and represents the size of a type in bytes.
@@ -338,7 +339,12 @@ impl<'tcx> SizeSkeleton<'tcx> {
338339 // First try computing a static layout.
339340 let err = match tcx. layout_of ( param_env. and ( ty) ) {
340341 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+ }
342348 }
343349 Err ( err @ LayoutError :: Unknown ( _) ) => err,
344350 // We can't extract SizeSkeleton info from other layout errors
@@ -390,19 +396,20 @@ impl<'tcx> SizeSkeleton<'tcx> {
390396 {
391397 let len_eval = len. try_eval_target_usize ( tcx, param_env) ;
392398 if len_eval == Some ( 0 ) {
393- return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( 0 ) ) ) ;
399+ return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( 0 ) , None ) ) ;
394400 }
395401
396402 match SizeSkeleton :: compute ( inner, tcx, param_env) ? {
397403 // This may succeed because the multiplication of two types may overflow
398404 // but a single size of a nested array will not.
399- SizeSkeleton :: Known ( s) => {
405+ SizeSkeleton :: Known ( s, a ) => {
400406 if let Some ( c) = len_eval {
401407 let size = s
402408 . bytes ( )
403409 . checked_mul ( c)
404410 . 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) ) ;
406413 }
407414 Err ( tcx. arena . alloc ( LayoutError :: Unknown ( ty) ) )
408415 }
@@ -428,8 +435,10 @@ impl<'tcx> SizeSkeleton<'tcx> {
428435 for field in fields {
429436 let field = field?;
430437 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 {
433442 return Err ( err) ;
434443 }
435444 }
@@ -493,7 +502,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
493502
494503 pub fn same_size ( self , other : SizeSkeleton < ' tcx > ) -> bool {
495504 match ( self , other) {
496- ( SizeSkeleton :: Known ( a) , SizeSkeleton :: Known ( b) ) => a == b,
505+ ( SizeSkeleton :: Known ( a, _ ) , SizeSkeleton :: Known ( b, _ ) ) => a == b,
497506 ( SizeSkeleton :: Pointer { tail : a, .. } , SizeSkeleton :: Pointer { tail : b, .. } ) => {
498507 a == b
499508 }
0 commit comments