@@ -1257,13 +1257,13 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
12571257 w,
12581258 cx,
12591259 Some ( & t. generics ) ,
1260- variants_iter ( ) ,
1260+ & variants ,
12611261 variants_count,
12621262 has_stripped_entries,
12631263 * is_non_exhaustive,
12641264 )
12651265 } ) ;
1266- item_variants ( w, cx, it, variants_iter ( ) ) ;
1266+ item_variants ( w, cx, it, & variants ) ;
12671267 }
12681268 clean:: TypeAliasInnerType :: Union { fields } => {
12691269 wrap_item ( w, |w| {
@@ -1416,11 +1416,12 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
14161416 it. name. unwrap( ) ,
14171417 e. generics. print( cx) ,
14181418 ) ;
1419+
14191420 render_enum_fields (
14201421 w,
14211422 cx,
14221423 Some ( & e. generics ) ,
1423- e. variants ( ) ,
1424+ & e. variants ,
14241425 count_variants,
14251426 e. has_stripped_entries ( ) ,
14261427 it. is_non_exhaustive ( ) ,
@@ -1430,22 +1431,80 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
14301431 write ! ( w, "{}" , document( cx, it, None , HeadingOffset :: H2 ) ) ;
14311432
14321433 if count_variants != 0 {
1433- item_variants ( w, cx, it, e. variants ( ) ) ;
1434+ item_variants ( w, cx, it, & e. variants ) ;
14341435 }
14351436 let def_id = it. item_id . expect_def_id ( ) ;
14361437 write ! ( w, "{}" , render_assoc_items( cx, it, def_id, AssocItemRender :: All ) ) ;
14371438 write ! ( w, "{}" , document_type_layout( cx, def_id) ) ;
14381439}
14391440
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 (
14411499 mut w : & mut Buffer ,
14421500 cx : & mut Context < ' _ > ,
14431501 g : Option < & clean:: Generics > ,
1444- variants : impl Iterator < Item = & ' a clean:: Item > ,
1502+ variants : & rustc_index :: IndexVec < rustc_target :: abi :: VariantIdx , clean:: Item > ,
14451503 count_variants : usize ,
14461504 has_stripped_entries : bool ,
14471505 is_non_exhaustive : bool ,
14481506) {
1507+ let is_c_like_enum = is_c_like_enum ( variants) ;
14491508 if !g. is_some_and ( |g| print_where_clause_and_check ( w, g, cx) ) {
14501509 // If there wasn't a `where` clause, we add a whitespace.
14511510 w. write_str ( " " ) ;
@@ -1461,21 +1520,18 @@ fn render_enum_fields<'a>(
14611520 toggle_open ( & mut w, format_args ! ( "{count_variants} variants" ) ) ;
14621521 }
14631522 const TAB : & str = " " ;
1464- for v in variants {
1523+ for ( index, v) in variants. iter_enumerated ( ) {
1524+ if v. is_stripped ( ) {
1525+ continue ;
1526+ }
14651527 w. write_str ( TAB ) ;
1466- let name = v. name . unwrap ( ) ;
14671528 match * v. kind {
1468- // FIXME(#101337): Show discriminant
14691529 clean:: VariantItem ( ref var) => match var. kind {
14701530 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)
14761532 }
14771533 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) ) ;
14791535 }
14801536 clean:: VariantKind :: Struct ( ref s) => {
14811537 render_struct ( w, v, None , None , & s. fields , TAB , false , cx) ;
@@ -1496,11 +1552,11 @@ fn render_enum_fields<'a>(
14961552 }
14971553}
14981554
1499- fn item_variants < ' a > (
1555+ fn item_variants (
15001556 w : & mut Buffer ,
15011557 cx : & mut Context < ' _ > ,
15021558 it : & clean:: Item ,
1503- variants : impl Iterator < Item = & ' a clean:: Item > ,
1559+ variants : & rustc_index :: IndexVec < rustc_target :: abi :: VariantIdx , clean:: Item > ,
15041560) {
15051561 let tcx = cx. tcx ( ) ;
15061562 write ! (
@@ -1513,7 +1569,11 @@ fn item_variants<'a>(
15131569 document_non_exhaustive_header( it) ,
15141570 document_non_exhaustive( it)
15151571 ) ;
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+ }
15171577 let id = cx. derive_id ( format ! ( "{}.{}" , ItemType :: Variant , variant. name. unwrap( ) ) ) ;
15181578 write ! (
15191579 w,
@@ -1528,12 +1588,20 @@ fn item_variants<'a>(
15281588 it. const_stable_since ( tcx) ,
15291589 " rightside" ,
15301590 ) ;
1531- write ! ( w , "<h3 class=\" code-header\" >{name}" , name = variant . name . unwrap ( ) ) ;
1591+ w . write_str ( "<h3 class=\" code-header\" >" ) ;
15321592 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
15351594 {
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 ( ) ) ;
15371605 }
15381606
15391607 let clean:: VariantItem ( variant_data) = & * variant. kind else { unreachable ! ( ) } ;
0 commit comments