@@ -400,6 +400,15 @@ fn represent_type_uncached<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
400
400
}
401
401
}
402
402
}
403
+
404
+ // If the alignment is smaller than the chosen discriminant size, don't use the
405
+ // alignment as the final size.
406
+ let min_ty = ll_inttype ( & cx, min_ity) ;
407
+ let min_size = machine:: llsize_of_real ( cx, min_ty) ;
408
+ if ( align as u64 ) < min_size {
409
+ use_align = false ;
410
+ }
411
+
403
412
let ity = if use_align {
404
413
// Use the overall alignment
405
414
match align {
@@ -817,11 +826,11 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
817
826
// FIXME #10604: this breaks when vector types are present.
818
827
let ( size, align) = union_size_and_align ( & sts[ ..] ) ;
819
828
let align_s = align as u64 ;
820
- assert_eq ! ( size % align_s, 0 ) ;
821
- let align_units = size / align_s - 1 ;
822
-
823
829
let discr_ty = ll_inttype ( cx, ity) ;
824
830
let discr_size = machine:: llsize_of_alloc ( cx, discr_ty) ;
831
+ let padded_discr_size = roundup ( discr_size, align) ;
832
+ assert_eq ! ( size % align_s, 0 ) ; // Ensure division in align_units comes out evenly
833
+ let align_units = ( size - padded_discr_size) / align_s;
825
834
let fill_ty = match align_s {
826
835
1 => Type :: array ( & Type :: i8 ( cx) , align_units) ,
827
836
2 => Type :: array ( & Type :: i16 ( cx) , align_units) ,
@@ -833,10 +842,10 @@ fn generic_type_of<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
833
842
_ => panic ! ( "unsupported enum alignment: {}" , align)
834
843
} ;
835
844
assert_eq ! ( machine:: llalign_of_min( cx, fill_ty) , align) ;
836
- assert_eq ! ( align_s % discr_size, 0 ) ;
845
+ assert_eq ! ( padded_discr_size % discr_size, 0 ) ; // Ensure discr_ty can fill pad evenly
837
846
let mut fields: Vec < Type > =
838
847
[ discr_ty,
839
- Type :: array ( & discr_ty, align_s / discr_size - 1 ) ,
848
+ Type :: array ( & discr_ty, ( padded_discr_size - discr_size ) /discr_size ) ,
840
849
fill_ty] . iter ( ) . cloned ( ) . collect ( ) ;
841
850
if delay_drop_flag && dtor_needed {
842
851
fields. pop ( ) ;
0 commit comments