@@ -319,38 +319,34 @@ pub(crate) mod rustc {
319319 ) -> Result < Self , Err > {
320320 assert ! ( def. is_enum( ) ) ;
321321
322- // Computes the variant of a given index.
323- let layout_of_variant = |index, encoding : Option < TagEncoding < VariantIdx > > | {
324- let tag = cx. tcx ( ) . tag_for_variant ( ( cx. tcx ( ) . erase_regions ( ty) , index) ) ;
325- let variant_def = Def :: Variant ( def. variant ( index) ) ;
326- let variant_layout = ty_variant ( cx, ( ty, layout) , index) ;
327- Self :: from_variant (
328- variant_def,
329- tag. map ( |tag| ( tag, index, encoding. unwrap ( ) ) ) ,
330- ( ty, variant_layout) ,
331- layout. size ,
332- cx,
333- )
334- } ;
322+ // Computes the layout of a variant.
323+ let layout_of_variant =
324+ |index, encoding : Option < TagEncoding < VariantIdx > > | -> Result < Self , Err > {
325+ let variant_layout = ty_variant ( cx, ( ty, layout) , index) ;
326+ if variant_layout. is_uninhabited ( ) {
327+ return Ok ( Self :: uninhabited ( ) ) ;
328+ }
329+ let tag = cx. tcx ( ) . tag_for_variant ( ( cx. tcx ( ) . erase_regions ( ty) , index) ) ;
330+ let variant_def = Def :: Variant ( def. variant ( index) ) ;
331+ Self :: from_variant (
332+ variant_def,
333+ tag. map ( |tag| ( tag, index, encoding. unwrap ( ) ) ) ,
334+ ( ty, variant_layout) ,
335+ layout. size ,
336+ cx,
337+ )
338+ } ;
335339
336- // We consider three kinds of enums, each demanding a different
337- // treatment of their layout computation:
338- // 1. enums that are uninhabited ZSTs
339- // 2. enums that delegate their layout to a variant
340- // 3. enums with multiple variants
341340 match layout. variants ( ) {
342- Variants :: Single { .. } if layout. is_uninhabited ( ) && layout. size == Size :: ZERO => {
343- // The layout representation of uninhabited, ZST enums is
344- // defined to be like that of the `!` type, as opposed of a
345- // typical enum. Consequently, they cannot be descended into
346- // as if they typical enums. We therefore special-case this
347- // scenario and simply return an uninhabited `Tree`.
348- Ok ( Self :: uninhabited ( ) )
349- }
350341 Variants :: Single { index } => {
351- // `Variants::Single` on enums with variants denotes that
352- // the enum delegates its layout to the variant at `index`.
353- layout_of_variant ( * index, None )
342+ // Hilariously, `Single` is used even for 0-variant enums; `index` is just junk in that case.
343+ if matches ! ( ty. kind( ) , ty:: Adt ( def, ..) if def. variants( ) . is_empty( ) ) {
344+ Ok ( Self :: uninhabited ( ) )
345+ } else {
346+ // `Variants::Single` on enums with variants denotes that
347+ // the enum delegates its layout to the variant at `index`.
348+ layout_of_variant ( * index, None )
349+ }
354350 }
355351 Variants :: Multiple { tag, tag_encoding, tag_field, .. } => {
356352 // `Variants::Multiple` denotes an enum with multiple
@@ -369,7 +365,7 @@ pub(crate) mod rustc {
369365 } ,
370366 ) ?;
371367
372- return Ok ( Self :: def ( Def :: Adt ( def) ) . then ( variants) ) ;
368+ Ok ( Self :: def ( Def :: Adt ( def) ) . then ( variants) )
373369 }
374370 }
375371 }
0 commit comments