@@ -309,7 +309,8 @@ impl<'tcx> LayoutCalculator for LayoutCx<'tcx, TyCtxt<'tcx>> {
309309#[ derive( Copy , Clone , Debug ) ]
310310pub enum SizeSkeleton < ' tcx > {
311311 /// Any statically computable Layout.
312- Known ( Size ) ,
312+ /// Alignment can be `None` if unknown.
313+ Known ( Size , Option < Align > ) ,
313314
314315 /// This is a generic const expression (i.e. N * 2), which may contain some parameters.
315316 /// It must be of type usize, and represents the size of a type in bytes.
@@ -339,7 +340,12 @@ impl<'tcx> SizeSkeleton<'tcx> {
339340 // First try computing a static layout.
340341 let err = match tcx. layout_of ( param_env. and ( ty) ) {
341342 Ok ( layout) => {
342- return Ok ( SizeSkeleton :: Known ( layout. size ) ) ;
343+ if layout. abi . is_sized ( ) {
344+ return Ok ( SizeSkeleton :: Known ( layout. size , Some ( layout. align . abi ) ) ) ;
345+ } else {
346+ // Just to be safe, don't claim a known layout for unsized types.
347+ return Err ( tcx. arena . alloc ( LayoutError :: Unknown ( ty) ) ) ;
348+ }
343349 }
344350 Err ( err @ LayoutError :: Unknown ( _) ) => err,
345351 // We can't extract SizeSkeleton info from other layout errors
@@ -389,19 +395,20 @@ impl<'tcx> SizeSkeleton<'tcx> {
389395 ty:: Array ( inner, len) if tcx. features ( ) . transmute_generic_consts => {
390396 let len_eval = len. try_eval_target_usize ( tcx, param_env) ;
391397 if len_eval == Some ( 0 ) {
392- return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( 0 ) ) ) ;
398+ return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( 0 ) , None ) ) ;
393399 }
394400
395401 match SizeSkeleton :: compute ( inner, tcx, param_env) ? {
396402 // This may succeed because the multiplication of two types may overflow
397403 // but a single size of a nested array will not.
398- SizeSkeleton :: Known ( s) => {
404+ SizeSkeleton :: Known ( s, a ) => {
399405 if let Some ( c) = len_eval {
400406 let size = s
401407 . bytes ( )
402408 . checked_mul ( c)
403409 . ok_or_else ( || & * tcx. arena . alloc ( LayoutError :: SizeOverflow ( ty) ) ) ?;
404- return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( size) ) ) ;
410+ // Alignment is unchanged by arrays.
411+ return Ok ( SizeSkeleton :: Known ( Size :: from_bytes ( size) , a) ) ;
405412 }
406413 Err ( tcx. arena . alloc ( LayoutError :: Unknown ( ty) ) )
407414 }
@@ -427,8 +434,10 @@ impl<'tcx> SizeSkeleton<'tcx> {
427434 for field in fields {
428435 let field = field?;
429436 match field {
430- SizeSkeleton :: Known ( size) => {
431- if size. bytes ( ) > 0 {
437+ SizeSkeleton :: Known ( size, align) => {
438+ let is_1zst = size. bytes ( ) == 0
439+ && align. is_some_and ( |align| align. bytes ( ) == 1 ) ;
440+ if !is_1zst {
432441 return Err ( err) ;
433442 }
434443 }
@@ -492,7 +501,7 @@ impl<'tcx> SizeSkeleton<'tcx> {
492501
493502 pub fn same_size ( self , other : SizeSkeleton < ' tcx > ) -> bool {
494503 match ( self , other) {
495- ( SizeSkeleton :: Known ( a) , SizeSkeleton :: Known ( b) ) => a == b,
504+ ( SizeSkeleton :: Known ( a, _ ) , SizeSkeleton :: Known ( b, _ ) ) => a == b,
496505 ( SizeSkeleton :: Pointer { tail : a, .. } , SizeSkeleton :: Pointer { tail : b, .. } ) => {
497506 a == b
498507 }
0 commit comments