@@ -919,7 +919,7 @@ fn variant_info_for_generator<'tcx>(
919
919
def_id : DefId ,
920
920
substs : ty:: SubstsRef < ' tcx > ,
921
921
) -> ( Vec < VariantInfo > , Option < Size > ) {
922
- let Variants :: Multiple { tag, ref tag_encoding, .. } = layout. variants else {
922
+ let Variants :: Multiple { tag, ref tag_encoding, tag_field , .. } = layout. variants else {
923
923
return ( vec ! [ ] , None ) ;
924
924
} ;
925
925
@@ -975,12 +975,28 @@ fn variant_info_for_generator<'tcx>(
975
975
if variant_size == Size :: ZERO {
976
976
variant_size = upvars_size;
977
977
}
978
- // We need to add the discriminant size back into min_size, since it is subtracted
979
- // later during printing.
980
- variant_size += match tag_encoding {
981
- TagEncoding :: Direct => tag. size ( cx) ,
982
- _ => Size :: ZERO ,
983
- } ;
978
+
979
+ // This `if` deserves some explanation.
980
+ //
981
+ // The layout code has a choice of where to place the discriminant of this generator.
982
+ // If the discriminant of the generator is placed early in the layout (before the
983
+ // variant's own fields), then it'll implicitly be counted towards the size of the
984
+ // variant, since we use the maximum offset to calculate size.
985
+ // (side-note: I know this is a bit problematic given upvars placement, etc).
986
+ //
987
+ // This is important, since the layout printing code always subtracts this discriminant
988
+ // size from the variant size if the struct is "enum"-like, so failing to account for it
989
+ // will either lead to numerical underflow, or an underreported variant size...
990
+ //
991
+ // However, if the discriminant is placed past the end of the variant, then we need
992
+ // to factor in the size of the discriminant manually. This really should be refactored
993
+ // better, but this "works" for now.
994
+ if layout. fields . offset ( tag_field) >= variant_size {
995
+ variant_size += match tag_encoding {
996
+ TagEncoding :: Direct => tag. size ( cx) ,
997
+ _ => Size :: ZERO ,
998
+ } ;
999
+ }
984
1000
985
1001
VariantInfo {
986
1002
name : Some ( Symbol :: intern ( & ty:: GeneratorSubsts :: variant_name ( variant_idx) ) ) ,
0 commit comments