@@ -5,10 +5,12 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
5
5
use rustc_hir as hir;
6
6
use rustc_hir:: def:: CtorKind ;
7
7
use rustc_hir:: def_id:: DefId ;
8
+ use rustc_index:: IndexVec ;
8
9
use rustc_middle:: middle:: stability;
9
10
use rustc_middle:: ty:: { self , TyCtxt } ;
10
11
use rustc_span:: hygiene:: MacroKind ;
11
12
use rustc_span:: symbol:: { kw, sym, Symbol } ;
13
+ use rustc_target:: abi:: VariantIdx ;
12
14
use std:: cell:: { RefCell , RefMut } ;
13
15
use std:: cmp:: Ordering ;
14
16
use std:: fmt;
@@ -1257,13 +1259,14 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
1257
1259
w,
1258
1260
cx,
1259
1261
Some ( & t. generics ) ,
1260
- variants_iter ( ) ,
1262
+ & variants ,
1261
1263
variants_count,
1262
1264
has_stripped_entries,
1263
1265
* is_non_exhaustive,
1266
+ it. def_id ( ) . unwrap ( ) ,
1264
1267
)
1265
1268
} ) ;
1266
- item_variants ( w, cx, it, variants_iter ( ) ) ;
1269
+ item_variants ( w, cx, it, & variants ) ;
1267
1270
}
1268
1271
clean:: TypeAliasInnerType :: Union { fields } => {
1269
1272
wrap_item ( w, |w| {
@@ -1416,36 +1419,81 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
1416
1419
it. name. unwrap( ) ,
1417
1420
e. generics. print( cx) ,
1418
1421
) ;
1422
+
1419
1423
render_enum_fields (
1420
1424
w,
1421
1425
cx,
1422
1426
Some ( & e. generics ) ,
1423
- e. variants ( ) ,
1427
+ & e. variants ,
1424
1428
count_variants,
1425
1429
e. has_stripped_entries ( ) ,
1426
1430
it. is_non_exhaustive ( ) ,
1431
+ it. def_id ( ) . unwrap ( ) ,
1427
1432
) ;
1428
1433
} ) ;
1429
1434
1430
1435
write ! ( w, "{}" , document( cx, it, None , HeadingOffset :: H2 ) ) ;
1431
1436
1432
1437
if count_variants != 0 {
1433
- item_variants ( w, cx, it, e. variants ( ) ) ;
1438
+ item_variants ( w, cx, it, & e. variants ) ;
1434
1439
}
1435
1440
let def_id = it. item_id . expect_def_id ( ) ;
1436
1441
write ! ( w, "{}" , render_assoc_items( cx, it, def_id, AssocItemRender :: All ) ) ;
1437
1442
write ! ( w, "{}" , document_type_layout( cx, def_id) ) ;
1438
1443
}
1439
1444
1440
- fn render_enum_fields < ' a > (
1445
+ /// It'll return true if all variants are C-like variants and if at least one of them has a value
1446
+ /// set.
1447
+ fn should_show_enum_discriminant ( variants : & IndexVec < VariantIdx , clean:: Item > ) -> bool {
1448
+ let mut has_variants_with_value = false ;
1449
+ for variant in variants {
1450
+ if let clean:: VariantItem ( ref var) = * variant. kind &&
1451
+ matches ! ( var. kind, clean:: VariantKind :: CLike )
1452
+ {
1453
+ has_variants_with_value |= var. discriminant . is_some ( ) ;
1454
+ } else {
1455
+ return false ;
1456
+ }
1457
+ }
1458
+ has_variants_with_value
1459
+ }
1460
+
1461
+ fn display_c_like_variant (
1462
+ w : & mut Buffer ,
1463
+ cx : & mut Context < ' _ > ,
1464
+ item : & clean:: Item ,
1465
+ variant : & clean:: Variant ,
1466
+ index : VariantIdx ,
1467
+ should_show_enum_discriminant : bool ,
1468
+ enum_def_id : DefId ,
1469
+ ) {
1470
+ let name = item. name . unwrap ( ) ;
1471
+ if let Some ( ref value) = variant. discriminant {
1472
+ write ! ( w, "{} = {}" , name. as_str( ) , value. value( cx. tcx( ) , true ) ) ;
1473
+ } else if should_show_enum_discriminant {
1474
+ let adt_def = cx. tcx ( ) . adt_def ( enum_def_id) ;
1475
+ let discr = adt_def. discriminant_for_variant ( cx. tcx ( ) , index) ;
1476
+ if discr. ty . is_signed ( ) {
1477
+ write ! ( w, "{} = {}" , name. as_str( ) , discr. val as i128 ) ;
1478
+ } else {
1479
+ write ! ( w, "{} = {}" , name. as_str( ) , discr. val) ;
1480
+ }
1481
+ } else {
1482
+ w. write_str ( name. as_str ( ) ) ;
1483
+ }
1484
+ }
1485
+
1486
+ fn render_enum_fields (
1441
1487
mut w : & mut Buffer ,
1442
1488
cx : & mut Context < ' _ > ,
1443
1489
g : Option < & clean:: Generics > ,
1444
- variants : impl Iterator < Item = & ' a clean:: Item > ,
1490
+ variants : & IndexVec < VariantIdx , clean:: Item > ,
1445
1491
count_variants : usize ,
1446
1492
has_stripped_entries : bool ,
1447
1493
is_non_exhaustive : bool ,
1494
+ enum_def_id : DefId ,
1448
1495
) {
1496
+ let should_show_enum_discriminant = should_show_enum_discriminant ( variants) ;
1449
1497
if !g. is_some_and ( |g| print_where_clause_and_check ( w, g, cx) ) {
1450
1498
// If there wasn't a `where` clause, we add a whitespace.
1451
1499
w. write_str ( " " ) ;
@@ -1461,15 +1509,24 @@ fn render_enum_fields<'a>(
1461
1509
toggle_open ( & mut w, format_args ! ( "{count_variants} variants" ) ) ;
1462
1510
}
1463
1511
const TAB : & str = " " ;
1464
- for v in variants {
1512
+ for ( index, v) in variants. iter_enumerated ( ) {
1513
+ if v. is_stripped ( ) {
1514
+ continue ;
1515
+ }
1465
1516
w. write_str ( TAB ) ;
1466
- let name = v. name . unwrap ( ) ;
1467
1517
match * v. kind {
1468
- // FIXME(#101337): Show discriminant
1469
1518
clean:: VariantItem ( ref var) => match var. kind {
1470
- clean:: VariantKind :: CLike => w. write_str ( name. as_str ( ) ) ,
1519
+ clean:: VariantKind :: CLike => display_c_like_variant (
1520
+ w,
1521
+ cx,
1522
+ v,
1523
+ var,
1524
+ index,
1525
+ should_show_enum_discriminant,
1526
+ enum_def_id,
1527
+ ) ,
1471
1528
clean:: VariantKind :: Tuple ( ref s) => {
1472
- write ! ( w, "{name }({})" , print_tuple_struct_fields( cx, s) , ) ;
1529
+ write ! ( w, "{}({})" , v . name . unwrap ( ) , print_tuple_struct_fields( cx, s) ) ;
1473
1530
}
1474
1531
clean:: VariantKind :: Struct ( ref s) => {
1475
1532
render_struct ( w, v, None , None , & s. fields , TAB , false , cx) ;
@@ -1490,11 +1547,11 @@ fn render_enum_fields<'a>(
1490
1547
}
1491
1548
}
1492
1549
1493
- fn item_variants < ' a > (
1550
+ fn item_variants (
1494
1551
w : & mut Buffer ,
1495
1552
cx : & mut Context < ' _ > ,
1496
1553
it : & clean:: Item ,
1497
- variants : impl Iterator < Item = & ' a clean:: Item > ,
1554
+ variants : & IndexVec < VariantIdx , clean:: Item > ,
1498
1555
) {
1499
1556
let tcx = cx. tcx ( ) ;
1500
1557
write ! (
@@ -1507,7 +1564,11 @@ fn item_variants<'a>(
1507
1564
document_non_exhaustive_header( it) ,
1508
1565
document_non_exhaustive( it)
1509
1566
) ;
1510
- for variant in variants {
1567
+ let should_show_enum_discriminant = should_show_enum_discriminant ( variants) ;
1568
+ for ( index, variant) in variants. iter_enumerated ( ) {
1569
+ if variant. is_stripped ( ) {
1570
+ continue ;
1571
+ }
1511
1572
let id = cx. derive_id ( format ! ( "{}.{}" , ItemType :: Variant , variant. name. unwrap( ) ) ) ;
1512
1573
write ! (
1513
1574
w,
@@ -1522,7 +1583,22 @@ fn item_variants<'a>(
1522
1583
it. const_stable_since ( tcx) ,
1523
1584
" rightside" ,
1524
1585
) ;
1525
- write ! ( w, "<h3 class=\" code-header\" >{name}" , name = variant. name. unwrap( ) ) ;
1586
+ w. write_str ( "<h3 class=\" code-header\" >" ) ;
1587
+ if let clean:: VariantItem ( ref var) = * variant. kind &&
1588
+ let clean:: VariantKind :: CLike = var. kind
1589
+ {
1590
+ display_c_like_variant (
1591
+ w,
1592
+ cx,
1593
+ variant,
1594
+ var,
1595
+ index,
1596
+ should_show_enum_discriminant,
1597
+ it. def_id ( ) . unwrap ( ) ,
1598
+ ) ;
1599
+ } else {
1600
+ w. write_str ( variant. name . unwrap ( ) . as_str ( ) ) ;
1601
+ }
1526
1602
1527
1603
let clean:: VariantItem ( variant_data) = & * variant. kind else { unreachable ! ( ) } ;
1528
1604
0 commit comments