Skip to content

Commit 3ff244b

Browse files
committed
Auto merge of rust-lang#116600 - GuillaumeGomez:repr-enums-discriminant, r=fmease
Show enum discriminant if a compatible repr is used Follow-up of rust-lang#116142. It was mentioned in the [team meeting](https://rust-lang.zulipchat.com/#narrow/stream/393423-t-rustdoc.2Fmeetings/topic/meeting.2002-10-2023/near/394504024) that an enum with a `repr` should also get its discriminants displayed. Forgot to implement it in rust-lang#116142... It also allowed to uncover a bug: i was not providing the correct `DefId` in case it was a type alias to `render_enum_fields`. It's also fixed in this PR. r? `@fmease`
2 parents 4f05e95 + 00c3de9 commit 3ff244b

File tree

3 files changed

+122
-10
lines changed

3 files changed

+122
-10
lines changed

src/librustdoc/html/render/print_item.rs

+24-10
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ use rustc_hir::def::CtorKind;
77
use rustc_hir::def_id::DefId;
88
use rustc_index::IndexVec;
99
use rustc_middle::middle::stability;
10+
use rustc_middle::query::Key;
1011
use rustc_middle::ty::{self, TyCtxt};
1112
use rustc_span::hygiene::MacroKind;
1213
use rustc_span::symbol::{kw, sym, Symbol};
@@ -1249,6 +1250,9 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
12491250
match inner_type {
12501251
clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => {
12511252
let variants_iter = || variants.iter().filter(|i| !i.is_stripped());
1253+
let ty = cx.tcx().type_of(it.def_id().unwrap()).instantiate_identity();
1254+
let enum_def_id = ty.ty_adt_id().unwrap();
1255+
12521256
wrap_item(w, |w| {
12531257
let variants_len = variants.len();
12541258
let variants_count = variants_iter().count();
@@ -1263,10 +1267,10 @@ fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &c
12631267
variants_count,
12641268
has_stripped_entries,
12651269
*is_non_exhaustive,
1266-
it.def_id().unwrap(),
1270+
enum_def_id,
12671271
)
12681272
});
1269-
item_variants(w, cx, it, &variants);
1273+
item_variants(w, cx, it, &variants, enum_def_id);
12701274
}
12711275
clean::TypeAliasInnerType::Union { fields } => {
12721276
wrap_item(w, |w| {
@@ -1435,16 +1439,21 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
14351439
write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
14361440

14371441
if count_variants != 0 {
1438-
item_variants(w, cx, it, &e.variants);
1442+
item_variants(w, cx, it, &e.variants, it.def_id().unwrap());
14391443
}
14401444
let def_id = it.item_id.expect_def_id();
14411445
write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
14421446
write!(w, "{}", document_type_layout(cx, def_id));
14431447
}
14441448

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 {
1449+
/// It'll return false if any variant is not a C-like variant. Otherwise it'll return true if at
1450+
/// least one of them has an explicit discriminant or if the enum has `#[repr(C)]` or an integer
1451+
/// `repr`.
1452+
fn should_show_enum_discriminant(
1453+
cx: &Context<'_>,
1454+
enum_def_id: DefId,
1455+
variants: &IndexVec<VariantIdx, clean::Item>,
1456+
) -> bool {
14481457
let mut has_variants_with_value = false;
14491458
for variant in variants {
14501459
if let clean::VariantItem(ref var) = *variant.kind &&
@@ -1455,7 +1464,11 @@ fn should_show_enum_discriminant(variants: &IndexVec<VariantIdx, clean::Item>) -
14551464
return false;
14561465
}
14571466
}
1458-
has_variants_with_value
1467+
if has_variants_with_value {
1468+
return true;
1469+
}
1470+
let repr = cx.tcx().adt_def(enum_def_id).repr();
1471+
repr.c() || repr.int.is_some()
14591472
}
14601473

14611474
fn display_c_like_variant(
@@ -1493,7 +1506,7 @@ fn render_enum_fields(
14931506
is_non_exhaustive: bool,
14941507
enum_def_id: DefId,
14951508
) {
1496-
let should_show_enum_discriminant = should_show_enum_discriminant(variants);
1509+
let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants);
14971510
if !g.is_some_and(|g| print_where_clause_and_check(w, g, cx)) {
14981511
// If there wasn't a `where` clause, we add a whitespace.
14991512
w.write_str(" ");
@@ -1552,6 +1565,7 @@ fn item_variants(
15521565
cx: &mut Context<'_>,
15531566
it: &clean::Item,
15541567
variants: &IndexVec<VariantIdx, clean::Item>,
1568+
enum_def_id: DefId,
15551569
) {
15561570
let tcx = cx.tcx();
15571571
write!(
@@ -1564,7 +1578,7 @@ fn item_variants(
15641578
document_non_exhaustive_header(it),
15651579
document_non_exhaustive(it)
15661580
);
1567-
let should_show_enum_discriminant = should_show_enum_discriminant(variants);
1581+
let should_show_enum_discriminant = should_show_enum_discriminant(cx, enum_def_id, variants);
15681582
for (index, variant) in variants.iter_enumerated() {
15691583
if variant.is_stripped() {
15701584
continue;
@@ -1594,7 +1608,7 @@ fn item_variants(
15941608
var,
15951609
index,
15961610
should_show_enum_discriminant,
1597-
it.def_id().unwrap(),
1611+
enum_def_id,
15981612
);
15991613
} else {
16001614
w.write_str(variant.name.unwrap().as_str());

tests/rustdoc/auxiliary/enum-variant.rs

+24
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,27 @@ pub enum H {
2222
A,
2323
C(u32),
2424
}
25+
26+
#[repr(C)]
27+
pub enum N {
28+
A,
29+
B,
30+
}
31+
32+
#[repr(C)]
33+
pub enum O {
34+
A(u32),
35+
B,
36+
}
37+
38+
#[repr(u32)]
39+
pub enum P {
40+
A,
41+
B,
42+
}
43+
44+
#[repr(u32)]
45+
pub enum Q {
46+
A(u32),
47+
B,
48+
}

tests/rustdoc/enum-variant-value.rs

+74
Original file line numberDiff line numberDiff line change
@@ -115,3 +115,77 @@ pub enum I {
115115
C = Self::B as isize + X + 3,
116116
D = -1,
117117
}
118+
119+
// Testing `repr`.
120+
121+
// @has 'foo/enum.J.html'
122+
// @has - '//*[@class="rust item-decl"]/code' 'A = 0,'
123+
// @has - '//*[@class="rust item-decl"]/code' 'B = 1,'
124+
// @matches - '//*[@id="variant.A"]/h3' '^A = 0$'
125+
// @matches - '//*[@id="variant.B"]/h3' '^B = 1$'
126+
#[repr(C)]
127+
pub enum J {
128+
A,
129+
B,
130+
}
131+
132+
// @has 'foo/enum.K.html'
133+
// @has - '//*[@class="rust item-decl"]/code' 'A(u32),'
134+
// @has - '//*[@class="rust item-decl"]/code' 'B,'
135+
// @has - '//*[@id="variant.A"]/h3' 'A(u32)'
136+
// @matches - '//*[@id="variant.B"]/h3' '^B$'
137+
#[repr(C)]
138+
pub enum K {
139+
A(u32),
140+
B,
141+
}
142+
143+
// @has 'foo/enum.L.html'
144+
// @has - '//*[@class="rust item-decl"]/code' 'A = 0,'
145+
// @has - '//*[@class="rust item-decl"]/code' 'B = 1,'
146+
// @matches - '//*[@id="variant.A"]/h3' '^A = 0$'
147+
// @matches - '//*[@id="variant.B"]/h3' '^B = 1$'
148+
#[repr(u32)]
149+
pub enum L {
150+
A,
151+
B,
152+
}
153+
154+
// @has 'foo/enum.M.html'
155+
// @has - '//*[@class="rust item-decl"]/code' 'A(u32),'
156+
// @has - '//*[@class="rust item-decl"]/code' 'B,'
157+
// @has - '//*[@id="variant.A"]/h3' 'A(u32)'
158+
// @matches - '//*[@id="variant.B"]/h3' '^B$'
159+
#[repr(u32)]
160+
pub enum M {
161+
A(u32),
162+
B,
163+
}
164+
165+
// @has 'foo/enum.N.html'
166+
// @has - '//*[@class="rust item-decl"]/code' 'A = 0,'
167+
// @has - '//*[@class="rust item-decl"]/code' 'B = 1,'
168+
// @matches - '//*[@id="variant.A"]/h3' '^A = 0$'
169+
// @matches - '//*[@id="variant.B"]/h3' '^B = 1$'
170+
pub use bar::N;
171+
172+
// @has 'foo/enum.O.html'
173+
// @has - '//*[@class="rust item-decl"]/code' 'A(u32),'
174+
// @has - '//*[@class="rust item-decl"]/code' 'B,'
175+
// @has - '//*[@id="variant.A"]/h3' 'A(u32)'
176+
// @matches - '//*[@id="variant.B"]/h3' '^B$'
177+
pub use bar::O;
178+
179+
// @has 'foo/enum.P.html'
180+
// @has - '//*[@class="rust item-decl"]/code' 'A = 0,'
181+
// @has - '//*[@class="rust item-decl"]/code' 'B = 1,'
182+
// @matches - '//*[@id="variant.A"]/h3' '^A = 0$'
183+
// @matches - '//*[@id="variant.B"]/h3' '^B = 1$'
184+
pub use bar::P;
185+
186+
// @has 'foo/enum.Q.html'
187+
// @has - '//*[@class="rust item-decl"]/code' 'A(u32),'
188+
// @has - '//*[@class="rust item-decl"]/code' 'B,'
189+
// @has - '//*[@id="variant.A"]/h3' 'A(u32)'
190+
// @matches - '//*[@id="variant.B"]/h3' '^B$'
191+
pub use bar::Q;

0 commit comments

Comments
 (0)