@@ -22,6 +22,7 @@ use rustc::hir::CodegenFnAttrFlags;
2222use rustc:: hir:: def:: CtorKind ;
2323use rustc:: hir:: def_id:: { DefId , CrateNum , LOCAL_CRATE } ;
2424use rustc:: ich:: NodeIdHashingMode ;
25+ use rustc:: mir:: Field ;
2526use rustc:: mir:: interpret:: truncate;
2627use rustc_data_structures:: fingerprint:: Fingerprint ;
2728use rustc:: ty:: Instance ;
@@ -1306,12 +1307,15 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
13061307 }
13071308 layout:: Variants :: Multiple {
13081309 discr_kind : layout:: DiscriminantKind :: Tag ,
1310+ discr_index,
13091311 ref variants,
13101312 ..
13111313 } => {
13121314 let discriminant_info = if fallback {
1313- RegularDiscriminant ( self . discriminant_type_metadata
1314- . expect ( "" ) )
1315+ RegularDiscriminant {
1316+ discr_field : Field :: from ( discr_index) ,
1317+ discr_type_metadata : self . discriminant_type_metadata . unwrap ( )
1318+ }
13151319 } else {
13161320 // This doesn't matter in this case.
13171321 NoDiscriminant
@@ -1358,6 +1362,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
13581362 } ,
13591363 ref discr,
13601364 ref variants,
1365+ discr_index,
13611366 } => {
13621367 if fallback {
13631368 let variant = self . layout . for_variant ( cx, dataful_variant) ;
@@ -1403,8 +1408,8 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> {
14031408 }
14041409 compute_field_path ( cx, & mut name,
14051410 self . layout ,
1406- self . layout . fields . offset ( 0 ) ,
1407- self . layout . field ( cx, 0 ) . size ) ;
1411+ self . layout . fields . offset ( discr_index ) ,
1412+ self . layout . field ( cx, discr_index ) . size ) ;
14081413 name. push_str ( & adt. variants [ * niche_variants. start ( ) ] . ident . as_str ( ) ) ;
14091414
14101415 // Create the (singleton) list of descriptions of union members.
@@ -1486,6 +1491,8 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> {
14861491 name : name. to_string ( ) ,
14871492 type_metadata : if use_enum_fallback ( cx) {
14881493 match self . discriminant_type_metadata {
1494+ // Discriminant is always the first field of our variant
1495+ // when using the enum fallback.
14891496 Some ( metadata) if i == 0 => metadata,
14901497 _ => type_metadata ( cx, ty, self . span )
14911498 }
@@ -1504,7 +1511,7 @@ impl VariantMemberDescriptionFactory<'ll, 'tcx> {
15041511
15051512#[ derive( Copy , Clone ) ]
15061513enum EnumDiscriminantInfo < ' ll > {
1507- RegularDiscriminant ( & ' ll DIType ) ,
1514+ RegularDiscriminant { discr_field : Field , discr_type_metadata : & ' ll DIType } ,
15081515 OptimizedDiscriminant ,
15091516 NoDiscriminant
15101517}
@@ -1547,11 +1554,14 @@ fn describe_enum_variant(
15471554 let ( offsets, args) = if use_enum_fallback ( cx) {
15481555 // If this is not a univariant enum, there is also the discriminant field.
15491556 let ( discr_offset, discr_arg) = match discriminant_info {
1550- RegularDiscriminant ( _ ) => {
1557+ RegularDiscriminant { discr_field , .. } => {
15511558 // We have the layout of an enum variant, we need the layout of the outer enum
15521559 let enum_layout = cx. layout_of ( layout. ty ) ;
1553- ( Some ( enum_layout. fields . offset ( 0 ) ) ,
1554- Some ( ( "RUST$ENUM$DISR" . to_owned ( ) , enum_layout. field ( cx, 0 ) . ty ) ) )
1560+ let offset = enum_layout. fields . offset ( discr_field. as_usize ( ) ) ;
1561+ let args = (
1562+ "RUST$ENUM$DISR" . to_owned ( ) ,
1563+ enum_layout. field ( cx, discr_field. as_usize ( ) ) . ty ) ;
1564+ ( Some ( offset) , Some ( args) )
15551565 }
15561566 _ => ( None , None ) ,
15571567 } ;
@@ -1579,8 +1589,8 @@ fn describe_enum_variant(
15791589 offsets,
15801590 args,
15811591 discriminant_type_metadata : match discriminant_info {
1582- RegularDiscriminant ( discriminant_type_metadata ) => {
1583- Some ( discriminant_type_metadata )
1592+ RegularDiscriminant { discr_type_metadata , .. } => {
1593+ Some ( discr_type_metadata )
15841594 }
15851595 _ => None
15861596 } ,
@@ -1730,6 +1740,7 @@ fn prepare_enum_metadata(
17301740 layout:: Variants :: Multiple {
17311741 discr_kind : layout:: DiscriminantKind :: Niche { .. } ,
17321742 ref discr,
1743+ discr_index,
17331744 ..
17341745 } => {
17351746 // Find the integer type of the correct size.
@@ -1753,7 +1764,7 @@ fn prepare_enum_metadata(
17531764 UNKNOWN_LINE_NUMBER ,
17541765 size. bits ( ) ,
17551766 align. abi . bits ( ) as u32 ,
1756- layout. fields . offset ( 0 ) . bits ( ) ,
1767+ layout. fields . offset ( discr_index ) . bits ( ) ,
17571768 DIFlags :: FlagArtificial ,
17581769 discr_metadata) )
17591770 }
@@ -1762,6 +1773,7 @@ fn prepare_enum_metadata(
17621773 layout:: Variants :: Multiple {
17631774 discr_kind : layout:: DiscriminantKind :: Tag ,
17641775 ref discr,
1776+ discr_index,
17651777 ..
17661778 } => {
17671779 let discr_type = discr. value . to_ty ( cx. tcx ) ;
@@ -1777,7 +1789,7 @@ fn prepare_enum_metadata(
17771789 UNKNOWN_LINE_NUMBER ,
17781790 size. bits ( ) ,
17791791 align. bits ( ) as u32 ,
1780- layout. fields . offset ( 0 ) . bits ( ) ,
1792+ layout. fields . offset ( discr_index ) . bits ( ) ,
17811793 DIFlags :: FlagArtificial ,
17821794 discr_metadata) )
17831795 }
0 commit comments