@@ -1257,13 +1257,13 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
1257
1257
w,
1258
1258
cx,
1259
1259
Some ( & t. generics ) ,
1260
- variants_iter ( ) ,
1260
+ & variants ,
1261
1261
variants_count,
1262
1262
has_stripped_entries,
1263
1263
* is_non_exhaustive,
1264
1264
)
1265
1265
} ) ;
1266
- item_variants ( w, cx, it, variants_iter ( ) ) ;
1266
+ item_variants ( w, cx, it, & variants ) ;
1267
1267
}
1268
1268
clean:: TypeAliasInnerType :: Union { fields } => {
1269
1269
wrap_item ( w, |w| {
@@ -1416,11 +1416,12 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
1416
1416
it. name. unwrap( ) ,
1417
1417
e. generics. print( cx) ,
1418
1418
) ;
1419
+
1419
1420
render_enum_fields (
1420
1421
w,
1421
1422
cx,
1422
1423
Some ( & e. generics ) ,
1423
- e. variants ( ) ,
1424
+ & e. variants ,
1424
1425
count_variants,
1425
1426
e. has_stripped_entries ( ) ,
1426
1427
it. is_non_exhaustive ( ) ,
@@ -1430,22 +1431,80 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
1430
1431
write ! ( w, "{}" , document( cx, it, None , HeadingOffset :: H2 ) ) ;
1431
1432
1432
1433
if count_variants != 0 {
1433
- item_variants ( w, cx, it, e. variants ( ) ) ;
1434
+ item_variants ( w, cx, it, & e. variants ) ;
1434
1435
}
1435
1436
let def_id = it. item_id . expect_def_id ( ) ;
1436
1437
write ! ( w, "{}" , render_assoc_items( cx, it, def_id, AssocItemRender :: All ) ) ;
1437
1438
write ! ( w, "{}" , document_type_layout( cx, def_id) ) ;
1438
1439
}
1439
1440
1440
- fn render_enum_fields < ' a > (
1441
+ fn get_parent_enum_def_id (
1442
+ cx : & mut Context < ' _ > ,
1443
+ variant_def_id : rustc_hir:: def_id:: LocalDefId ,
1444
+ ) -> DefId {
1445
+ use rustc_hir:: { ItemKind , Node } ;
1446
+ let variant_hir_id = cx. tcx ( ) . hir ( ) . local_def_id_to_hir_id ( variant_def_id) ;
1447
+
1448
+ for ( _, node) in cx. tcx ( ) . hir ( ) . parent_iter ( variant_hir_id) {
1449
+ if let Node :: Item ( item) = node && matches ! ( item. kind, ItemKind :: Enum ( ..) ) {
1450
+ return item. owner_id . to_def_id ( ) ;
1451
+ }
1452
+ }
1453
+ panic ! ( "No parent enum found for variant {variant_def_id:?}" ) ;
1454
+ }
1455
+
1456
+ fn is_c_like_enum (
1457
+ variants : & rustc_index:: IndexVec < rustc_target:: abi:: VariantIdx , clean:: Item > ,
1458
+ ) -> bool {
1459
+ !variants. iter ( ) . any ( |variant| {
1460
+ matches ! (
1461
+ * variant. kind,
1462
+ clean:: VariantItem ( clean:: Variant {
1463
+ kind: clean:: VariantKind :: Tuple ( _) | clean:: VariantKind :: Struct ( _) ,
1464
+ ..
1465
+ } )
1466
+ )
1467
+ } )
1468
+ }
1469
+
1470
+ fn display_c_like_variant (
1471
+ w : & mut Buffer ,
1472
+ cx : & mut Context < ' _ > ,
1473
+ item : & clean:: Item ,
1474
+ variant : & clean:: Variant ,
1475
+ index : rustc_target:: abi:: VariantIdx ,
1476
+ is_c_like_enum : bool ,
1477
+ ) {
1478
+ let name = item. name . unwrap ( ) ;
1479
+ if let Some ( ref value) = variant. discriminant {
1480
+ write ! ( w, "{} = {}" , name. as_str( ) , value. value( cx. tcx( ) , true ) ) ;
1481
+ } else if is_c_like_enum &&
1482
+ let Some ( variant_def_id) = item. item_id . as_def_id ( ) &&
1483
+ let Some ( variant_def_id) = variant_def_id. as_local ( )
1484
+ {
1485
+ let enum_def_id = get_parent_enum_def_id ( cx, variant_def_id) ;
1486
+ let adt_def = cx. tcx ( ) . adt_def ( enum_def_id) ;
1487
+ let discr = adt_def. discriminant_for_variant ( cx. tcx ( ) , index) ;
1488
+ if discr. ty . is_signed ( ) {
1489
+ write ! ( w, "{} = {}" , name. as_str( ) , discr. val as i128 ) ;
1490
+ } else {
1491
+ write ! ( w, "{} = {}" , name. as_str( ) , discr. val) ;
1492
+ }
1493
+ } else {
1494
+ w. write_str ( name. as_str ( ) ) ;
1495
+ }
1496
+ }
1497
+
1498
+ fn render_enum_fields (
1441
1499
mut w : & mut Buffer ,
1442
1500
cx : & mut Context < ' _ > ,
1443
1501
g : Option < & clean:: Generics > ,
1444
- variants : impl Iterator < Item = & ' a clean:: Item > ,
1502
+ variants : & rustc_index :: IndexVec < rustc_target :: abi :: VariantIdx , clean:: Item > ,
1445
1503
count_variants : usize ,
1446
1504
has_stripped_entries : bool ,
1447
1505
is_non_exhaustive : bool ,
1448
1506
) {
1507
+ let is_c_like_enum = is_c_like_enum ( variants) ;
1449
1508
if !g. is_some_and ( |g| print_where_clause_and_check ( w, g, cx) ) {
1450
1509
// If there wasn't a `where` clause, we add a whitespace.
1451
1510
w. write_str ( " " ) ;
@@ -1461,21 +1520,18 @@ fn render_enum_fields<'a>(
1461
1520
toggle_open ( & mut w, format_args ! ( "{count_variants} variants" ) ) ;
1462
1521
}
1463
1522
const TAB : & str = " " ;
1464
- for v in variants {
1523
+ for ( index, v) in variants. iter_enumerated ( ) {
1524
+ if v. is_stripped ( ) {
1525
+ continue ;
1526
+ }
1465
1527
w. write_str ( TAB ) ;
1466
- let name = v. name . unwrap ( ) ;
1467
1528
match * v. kind {
1468
- // FIXME(#101337): Show discriminant
1469
1529
clean:: VariantItem ( ref var) => match var. kind {
1470
1530
clean:: VariantKind :: CLike => {
1471
- if let Some ( ref value) = var. discriminant {
1472
- write ! ( w, "{} = {}" , name. as_str( ) , value. value( cx. tcx( ) , true ) ) ;
1473
- } else {
1474
- w. write_str ( name. as_str ( ) ) ;
1475
- }
1531
+ display_c_like_variant ( w, cx, v, var, index, is_c_like_enum)
1476
1532
}
1477
1533
clean:: VariantKind :: Tuple ( ref s) => {
1478
- write ! ( w, "{name }({})" , print_tuple_struct_fields( cx, s) ) ;
1534
+ write ! ( w, "{}({})" , v . name . unwrap ( ) , print_tuple_struct_fields( cx, s) ) ;
1479
1535
}
1480
1536
clean:: VariantKind :: Struct ( ref s) => {
1481
1537
render_struct ( w, v, None , None , & s. fields , TAB , false , cx) ;
@@ -1496,11 +1552,11 @@ fn render_enum_fields<'a>(
1496
1552
}
1497
1553
}
1498
1554
1499
- fn item_variants < ' a > (
1555
+ fn item_variants (
1500
1556
w : & mut Buffer ,
1501
1557
cx : & mut Context < ' _ > ,
1502
1558
it : & clean:: Item ,
1503
- variants : impl Iterator < Item = & ' a clean:: Item > ,
1559
+ variants : & rustc_index :: IndexVec < rustc_target :: abi :: VariantIdx , clean:: Item > ,
1504
1560
) {
1505
1561
let tcx = cx. tcx ( ) ;
1506
1562
write ! (
@@ -1513,7 +1569,11 @@ fn item_variants<'a>(
1513
1569
document_non_exhaustive_header( it) ,
1514
1570
document_non_exhaustive( it)
1515
1571
) ;
1516
- for variant in variants {
1572
+ let is_c_like_enum = is_c_like_enum ( variants) ;
1573
+ for ( index, variant) in variants. iter_enumerated ( ) {
1574
+ if variant. is_stripped ( ) {
1575
+ continue ;
1576
+ }
1517
1577
let id = cx. derive_id ( format ! ( "{}.{}" , ItemType :: Variant , variant. name. unwrap( ) ) ) ;
1518
1578
write ! (
1519
1579
w,
@@ -1528,12 +1588,20 @@ fn item_variants<'a>(
1528
1588
it. const_stable_since ( tcx) ,
1529
1589
" rightside" ,
1530
1590
) ;
1531
- write ! ( w , "<h3 class=\" code-header\" >{name}" , name = variant . name . unwrap ( ) ) ;
1591
+ w . write_str ( "<h3 class=\" code-header\" >" ) ;
1532
1592
if let clean:: VariantItem ( ref var) = * variant. kind &&
1533
- let clean:: VariantKind :: CLike = var. kind &&
1534
- let Some ( ref value) = var. discriminant
1593
+ let clean:: VariantKind :: CLike = var. kind
1535
1594
{
1536
- write ! ( w, " = {}" , value. value( cx. tcx( ) , true ) ) ;
1595
+ display_c_like_variant (
1596
+ w,
1597
+ cx,
1598
+ variant,
1599
+ var,
1600
+ index,
1601
+ is_c_like_enum,
1602
+ ) ;
1603
+ } else {
1604
+ w. write_str ( variant. name . unwrap ( ) . as_str ( ) ) ;
1537
1605
}
1538
1606
1539
1607
let clean:: VariantItem ( variant_data) = & * variant. kind else { unreachable ! ( ) } ;
0 commit comments