@@ -463,38 +463,43 @@ fn layout_of_uncached<'tcx>(
463463 ) ) ;
464464 }
465465
466- tcx. mk_layout (
467- cx. layout_of_struct_or_enum (
468- & def. repr ( ) ,
469- & variants,
470- def. is_enum ( ) ,
471- def. is_unsafe_cell ( ) ,
472- tcx. layout_scalar_valid_range ( def. did ( ) ) ,
473- |min, max| Integer :: repr_discr ( tcx, ty, & def. repr ( ) , min, max) ,
474- def. is_enum ( )
475- . then ( || def. discriminants ( tcx) . map ( |( v, d) | ( v, d. val as i128 ) ) )
476- . into_iter ( )
477- . flatten ( ) ,
478- def. repr ( ) . inhibit_enum_layout_opt ( )
479- || def
480- . variants ( )
481- . iter_enumerated ( )
482- . any ( |( i, v) | v. discr != ty:: VariantDiscr :: Relative ( i. as_u32 ( ) ) ) ,
483- {
484- let param_env = tcx. param_env ( def. did ( ) ) ;
485- def. is_struct ( )
486- && match def. variants ( ) . iter ( ) . next ( ) . and_then ( |x| x. fields . raw . last ( ) )
487- {
488- Some ( last_field) => tcx
489- . type_of ( last_field. did )
490- . subst_identity ( )
491- . is_sized ( tcx, param_env) ,
492- None => false ,
493- }
494- } ,
495- )
496- . ok_or_else ( || error ( cx, LayoutError :: SizeOverflow ( ty) ) ) ?,
497- )
466+ let get_discriminant_type =
467+ |min, max| Integer :: repr_discr ( tcx, ty, & def. repr ( ) , min, max) ;
468+
469+ let discriminants_iter = || {
470+ def. is_enum ( )
471+ . then ( || def. discriminants ( tcx) . map ( |( v, d) | ( v, d. val as i128 ) ) )
472+ . into_iter ( )
473+ . flatten ( )
474+ } ;
475+
476+ let dont_niche_optimize_enum = def. repr ( ) . inhibit_enum_layout_opt ( )
477+ || def
478+ . variants ( )
479+ . iter_enumerated ( )
480+ . any ( |( i, v) | v. discr != ty:: VariantDiscr :: Relative ( i. as_u32 ( ) ) ) ;
481+
482+ let maybe_unsized = def. is_struct ( )
483+ && def. non_enum_variant ( ) . fields . raw . last ( ) . is_some_and ( |last_field| {
484+ let param_env = tcx. param_env ( def. did ( ) ) ;
485+ !tcx. type_of ( last_field. did ) . subst_identity ( ) . is_sized ( tcx, param_env)
486+ } ) ;
487+
488+ let Some ( layout) = cx. layout_of_struct_or_enum (
489+ & def. repr ( ) ,
490+ & variants,
491+ def. is_enum ( ) ,
492+ def. is_unsafe_cell ( ) ,
493+ tcx. layout_scalar_valid_range ( def. did ( ) ) ,
494+ get_discriminant_type,
495+ discriminants_iter ( ) ,
496+ dont_niche_optimize_enum,
497+ !maybe_unsized,
498+ ) else {
499+ return Err ( error ( cx, LayoutError :: SizeOverflow ( ty) ) ) ;
500+ } ;
501+
502+ tcx. mk_layout ( layout)
498503 }
499504
500505 // Types with no meaningful known layout.
0 commit comments