@@ -319,38 +319,35 @@ pub(crate) mod rustc {
319
319
) -> Result < Self , Err > {
320
320
assert ! ( def. is_enum( ) ) ;
321
321
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
+ } ;
335
339
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
341
340
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
- }
350
341
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;
343
+ // `index` is just junk in that case.
344
+ if ty. ty_adt_def ( ) . unwrap ( ) . variants ( ) . is_empty ( ) {
345
+ Ok ( Self :: uninhabited ( ) )
346
+ } else {
347
+ // `Variants::Single` on enums with variants denotes that
348
+ // the enum delegates its layout to the variant at `index`.
349
+ layout_of_variant ( * index, None )
350
+ }
354
351
}
355
352
Variants :: Multiple { tag, tag_encoding, tag_field, .. } => {
356
353
// `Variants::Multiple` denotes an enum with multiple
@@ -369,7 +366,7 @@ pub(crate) mod rustc {
369
366
} ,
370
367
) ?;
371
368
372
- return Ok ( Self :: def ( Def :: Adt ( def) ) . then ( variants) ) ;
369
+ Ok ( Self :: def ( Def :: Adt ( def) ) . then ( variants) )
373
370
}
374
371
}
375
372
}
0 commit comments