Skip to content

Commit 0d5c5fa

Browse files
Rollup merge of rust-lang#106354 - aDotInTheVoid:rdj-always-discr, r=GuillaumeGomez
Rustdoc-Json: Report discriminant on all kinds of enum variant. Closes rust-lang#106299 Probably easier to review one commit at a time. r? `@GuillaumeGomez`
2 parents 0670a61 + cca5d21 commit 0d5c5fa

22 files changed

+257
-201
lines changed

src/librustdoc/clean/mod.rs

+27-15
Original file line numberDiff line numberDiff line change
@@ -1949,40 +1949,52 @@ pub(crate) fn clean_field_with_def_id(
19491949
}
19501950

19511951
pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item {
1952+
let discriminant = match variant.discr {
1953+
ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }),
1954+
ty::VariantDiscr::Relative(_) => None,
1955+
};
1956+
19521957
let kind = match variant.ctor_kind() {
1953-
Some(CtorKind::Const) => Variant::CLike(match variant.discr {
1954-
ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }),
1955-
ty::VariantDiscr::Relative(_) => None,
1956-
}),
1957-
Some(CtorKind::Fn) => Variant::Tuple(
1958+
Some(CtorKind::Const) => VariantKind::CLike,
1959+
Some(CtorKind::Fn) => VariantKind::Tuple(
19581960
variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
19591961
),
1960-
None => Variant::Struct(VariantStruct {
1962+
None => VariantKind::Struct(VariantStruct {
19611963
ctor_kind: None,
19621964
fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(),
19631965
}),
19641966
};
1965-
Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx)
1967+
1968+
Item::from_def_id_and_parts(
1969+
variant.def_id,
1970+
Some(variant.name),
1971+
VariantItem(Variant { kind, discriminant }),
1972+
cx,
1973+
)
19661974
}
19671975

19681976
fn clean_variant_data<'tcx>(
19691977
variant: &hir::VariantData<'tcx>,
19701978
disr_expr: &Option<hir::AnonConst>,
19711979
cx: &mut DocContext<'tcx>,
19721980
) -> Variant {
1973-
match variant {
1974-
hir::VariantData::Struct(..) => Variant::Struct(VariantStruct {
1981+
let discriminant = disr_expr.map(|disr| Discriminant {
1982+
expr: Some(disr.body),
1983+
value: cx.tcx.hir().local_def_id(disr.hir_id).to_def_id(),
1984+
});
1985+
1986+
let kind = match variant {
1987+
hir::VariantData::Struct(..) => VariantKind::Struct(VariantStruct {
19751988
ctor_kind: None,
19761989
fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(),
19771990
}),
19781991
hir::VariantData::Tuple(..) => {
1979-
Variant::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect())
1992+
VariantKind::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect())
19801993
}
1981-
hir::VariantData::Unit(..) => Variant::CLike(disr_expr.map(|disr| Discriminant {
1982-
expr: Some(disr.body),
1983-
value: cx.tcx.hir().local_def_id(disr.hir_id).to_def_id(),
1984-
})),
1985-
}
1994+
hir::VariantData::Unit(..) => VariantKind::CLike,
1995+
};
1996+
1997+
Variant { discriminant, kind }
19861998
}
19871999

19882000
fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path {

src/librustdoc/clean/types.rs

+16-8
Original file line numberDiff line numberDiff line change
@@ -807,8 +807,11 @@ impl ItemKind {
807807
match self {
808808
StructItem(s) => s.fields.iter(),
809809
UnionItem(u) => u.fields.iter(),
810-
VariantItem(Variant::Struct(v)) => v.fields.iter(),
811-
VariantItem(Variant::Tuple(v)) => v.iter(),
810+
VariantItem(v) => match &v.kind {
811+
VariantKind::CLike => [].iter(),
812+
VariantKind::Tuple(t) => t.iter(),
813+
VariantKind::Struct(s) => s.fields.iter(),
814+
},
812815
EnumItem(e) => e.variants.iter(),
813816
TraitItem(t) => t.items.iter(),
814817
ImplItem(i) => i.items.iter(),
@@ -824,7 +827,6 @@ impl ItemKind {
824827
| TyMethodItem(_)
825828
| MethodItem(_, _)
826829
| StructFieldItem(_)
827-
| VariantItem(_)
828830
| ForeignFunctionItem(_)
829831
| ForeignStaticItem(_)
830832
| ForeignTypeItem
@@ -2136,17 +2138,23 @@ impl Enum {
21362138
}
21372139

21382140
#[derive(Clone, Debug)]
2139-
pub(crate) enum Variant {
2140-
CLike(Option<Discriminant>),
2141+
pub(crate) struct Variant {
2142+
pub kind: VariantKind,
2143+
pub discriminant: Option<Discriminant>,
2144+
}
2145+
2146+
#[derive(Clone, Debug)]
2147+
pub(crate) enum VariantKind {
2148+
CLike,
21412149
Tuple(Vec<Item>),
21422150
Struct(VariantStruct),
21432151
}
21442152

21452153
impl Variant {
21462154
pub(crate) fn has_stripped_entries(&self) -> Option<bool> {
2147-
match *self {
2148-
Self::Struct(ref struct_) => Some(struct_.has_stripped_entries()),
2149-
Self::CLike(..) | Self::Tuple(_) => None,
2155+
match &self.kind {
2156+
VariantKind::Struct(struct_) => Some(struct_.has_stripped_entries()),
2157+
VariantKind::CLike | VariantKind::Tuple(_) => None,
21502158
}
21512159
}
21522160
}

src/librustdoc/fold.rs

+15-11
Original file line numberDiff line numberDiff line change
@@ -37,17 +37,21 @@ pub(crate) trait DocFolder: Sized {
3737
i.items = i.items.into_iter().filter_map(|x| self.fold_item(x)).collect();
3838
ImplItem(i)
3939
}
40-
VariantItem(i) => match i {
41-
Variant::Struct(mut j) => {
42-
j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
43-
VariantItem(Variant::Struct(j))
44-
}
45-
Variant::Tuple(fields) => {
46-
let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
47-
VariantItem(Variant::Tuple(fields))
48-
}
49-
Variant::CLike(disr) => VariantItem(Variant::CLike(disr)),
50-
},
40+
VariantItem(Variant { kind, discriminant }) => {
41+
let kind = match kind {
42+
VariantKind::Struct(mut j) => {
43+
j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
44+
VariantKind::Struct(j)
45+
}
46+
VariantKind::Tuple(fields) => {
47+
let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect();
48+
VariantKind::Tuple(fields)
49+
}
50+
VariantKind::CLike => VariantKind::CLike,
51+
};
52+
53+
VariantItem(Variant { kind, discriminant })
54+
}
5155
ExternCrateItem { src: _ }
5256
| ImportItem(_)
5357
| FunctionItem(_)

src/librustdoc/html/render/print_item.rs

+20-17
Original file line numberDiff line numberDiff line change
@@ -1220,15 +1220,15 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
12201220
w.write_str(" ");
12211221
let name = v.name.unwrap();
12221222
match *v.kind {
1223-
clean::VariantItem(ref var) => match var {
1224-
// FIXME(#101337): Show discriminant
1225-
clean::Variant::CLike(..) => write!(w, "{}", name),
1226-
clean::Variant::Tuple(ref s) => {
1223+
// FIXME(#101337): Show discriminant
1224+
clean::VariantItem(ref var) => match var.kind {
1225+
clean::VariantKind::CLike => write!(w, "{}", name),
1226+
clean::VariantKind::Tuple(ref s) => {
12271227
write!(w, "{}(", name);
12281228
print_tuple_struct_fields(w, cx, s);
12291229
w.write_str(")");
12301230
}
1231-
clean::Variant::Struct(ref s) => {
1231+
clean::VariantKind::Struct(ref s) => {
12321232
render_struct(
12331233
w,
12341234
v,
@@ -1286,25 +1286,28 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
12861286
" rightside",
12871287
);
12881288
write!(w, "<h3 class=\"code-header\">{name}", name = variant.name.unwrap());
1289-
if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind {
1289+
1290+
let clean::VariantItem(variant_data) = &*variant.kind else { unreachable!() };
1291+
1292+
if let clean::VariantKind::Tuple(ref s) = variant_data.kind {
12901293
w.write_str("(");
12911294
print_tuple_struct_fields(w, cx, s);
12921295
w.write_str(")");
12931296
}
12941297
w.write_str("</h3></section>");
12951298

1296-
use crate::clean::Variant;
1297-
1298-
let heading_and_fields = match &*variant.kind {
1299-
clean::VariantItem(Variant::Struct(s)) => Some(("Fields", &s.fields)),
1300-
// Documentation on tuple variant fields is rare, so to reduce noise we only emit
1301-
// the section if at least one field is documented.
1302-
clean::VariantItem(Variant::Tuple(fields))
1303-
if fields.iter().any(|f| f.doc_value().is_some()) =>
1304-
{
1305-
Some(("Tuple Fields", fields))
1299+
let heading_and_fields = match &variant_data.kind {
1300+
clean::VariantKind::Struct(s) => Some(("Fields", &s.fields)),
1301+
clean::VariantKind::Tuple(fields) => {
1302+
// Documentation on tuple variant fields is rare, so to reduce noise we only emit
1303+
// the section if at least one field is documented.
1304+
if fields.iter().any(|f| f.doc_value().is_some()) {
1305+
Some(("Tuple Fields", fields))
1306+
} else {
1307+
None
1308+
}
13061309
}
1307-
_ => None,
1310+
clean::VariantKind::CLike => None,
13081311
};
13091312

13101313
if let Some((heading, fields)) = heading_and_fields {

src/librustdoc/json/conversions.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -646,15 +646,20 @@ impl FromWithTcx<clean::Enum> for Enum {
646646

647647
impl FromWithTcx<clean::Variant> for Variant {
648648
fn from_tcx(variant: clean::Variant, tcx: TyCtxt<'_>) -> Self {
649-
use clean::Variant::*;
650-
match variant {
651-
CLike(disr) => Variant::Plain(disr.map(|disr| disr.into_tcx(tcx))),
652-
Tuple(fields) => Variant::Tuple(ids_keeping_stripped(fields, tcx)),
653-
Struct(s) => Variant::Struct {
649+
use clean::VariantKind::*;
650+
651+
let discriminant = variant.discriminant.map(|d| d.into_tcx(tcx));
652+
653+
let kind = match variant.kind {
654+
CLike => VariantKind::Plain,
655+
Tuple(fields) => VariantKind::Tuple(ids_keeping_stripped(fields, tcx)),
656+
Struct(s) => VariantKind::Struct {
654657
fields_stripped: s.has_stripped_entries(),
655658
fields: ids(s.fields, tcx),
656659
},
657-
}
660+
};
661+
662+
Variant { kind, discriminant }
658663
}
659664
}
660665

src/librustdoc/passes/stripper.rs

+4-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,10 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> {
132132
// implementations of traits are always public.
133133
clean::ImplItem(ref imp) if imp.trait_.is_some() => true,
134134
// Variant fields have inherited visibility
135-
clean::VariantItem(clean::Variant::Struct(..) | clean::Variant::Tuple(..)) => true,
135+
clean::VariantItem(clean::Variant {
136+
kind: clean::VariantKind::Struct(..) | clean::VariantKind::Tuple(..),
137+
..
138+
}) => true,
136139
_ => false,
137140
};
138141

src/librustdoc/visit.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,10 @@ pub(crate) trait DocVisitor: Sized {
1717
EnumItem(i) => i.variants.iter().for_each(|x| self.visit_item(x)),
1818
TraitItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
1919
ImplItem(i) => i.items.iter().for_each(|x| self.visit_item(x)),
20-
VariantItem(i) => match i {
21-
Variant::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)),
22-
Variant::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)),
23-
Variant::CLike(_) => {}
20+
VariantItem(i) => match &i.kind {
21+
VariantKind::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)),
22+
VariantKind::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)),
23+
VariantKind::CLike => {}
2424
},
2525
ExternCrateItem { src: _ }
2626
| ImportItem(_)

src/rustdoc-json-types/lib.rs

+12-5
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use std::path::PathBuf;
99
use serde::{Deserialize, Serialize};
1010

1111
/// rustdoc format-version.
12-
pub const FORMAT_VERSION: u32 = 23;
12+
pub const FORMAT_VERSION: u32 = 24;
1313

1414
/// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information
1515
/// about the language items in the local crate, as well as info about external items to allow
@@ -333,19 +333,26 @@ pub struct Enum {
333333
pub impls: Vec<Id>,
334334
}
335335

336+
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
337+
pub struct Variant {
338+
/// Whether the variant is plain, a tuple-like, or struct-like. Contains the fields.
339+
pub kind: VariantKind,
340+
/// The discriminant, if explicitly specified.
341+
pub discriminant: Option<Discriminant>,
342+
}
343+
336344
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
337345
#[serde(rename_all = "snake_case")]
338-
#[serde(tag = "variant_kind", content = "variant_inner")]
339-
pub enum Variant {
340-
/// A variant with no parentheses, and possible discriminant.
346+
pub enum VariantKind {
347+
/// A variant with no parentheses
341348
///
342349
/// ```rust
343350
/// enum Demo {
344351
/// PlainVariant,
345352
/// PlainWithDiscriminant = 1,
346353
/// }
347354
/// ```
348-
Plain(Option<Discriminant>),
355+
Plain,
349356
/// A variant with unnamed fields.
350357
///
351358
/// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
#[repr(i8)]
22
pub enum Ordering {
3-
// @is "$.index[*][?(@.name=='Less')].inner.variant_inner.expr" '"-1"'
4-
// @is "$.index[*][?(@.name=='Less')].inner.variant_inner.value" '"-1"'
3+
// @is "$.index[*][?(@.name=='Less')].inner.discriminant.expr" '"-1"'
4+
// @is "$.index[*][?(@.name=='Less')].inner.discriminant.value" '"-1"'
55
Less = -1,
6-
// @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.expr" '"0"'
7-
// @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.value" '"0"'
6+
// @is "$.index[*][?(@.name=='Equal')].inner.discriminant.expr" '"0"'
7+
// @is "$.index[*][?(@.name=='Equal')].inner.discriminant.value" '"0"'
88
Equal = 0,
9-
// @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.expr" '"1"'
10-
// @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.value" '"1"'
9+
// @is "$.index[*][?(@.name=='Greater')].inner.discriminant.expr" '"1"'
10+
// @is "$.index[*][?(@.name=='Greater')].inner.discriminant.value" '"1"'
1111
Greater = 1,
1212
}

src/test/rustdoc-json/enums/discriminant/expr.rs

+18-18
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
11
pub enum Foo {
2-
// @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.value" '"0"'
3-
// @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.expr" '"{ _ }"'
2+
// @is "$.index[*][?(@.name=='Addition')].inner.discriminant.value" '"0"'
3+
// @is "$.index[*][?(@.name=='Addition')].inner.discriminant.expr" '"{ _ }"'
44
Addition = 0 + 0,
5-
// @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.value" '"1"'
6-
// @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.expr" '"0b1"'
5+
// @is "$.index[*][?(@.name=='Bin')].inner.discriminant.value" '"1"'
6+
// @is "$.index[*][?(@.name=='Bin')].inner.discriminant.expr" '"0b1"'
77
Bin = 0b1,
8-
// @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.value" '"2"'
9-
// @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.expr" '"0o2"'
8+
// @is "$.index[*][?(@.name=='Oct')].inner.discriminant.value" '"2"'
9+
// @is "$.index[*][?(@.name=='Oct')].inner.discriminant.expr" '"0o2"'
1010
Oct = 0o2,
11-
// @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.value" '"3"'
12-
// @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.expr" '"THREE"'
11+
// @is "$.index[*][?(@.name=='PubConst')].inner.discriminant.value" '"3"'
12+
// @is "$.index[*][?(@.name=='PubConst')].inner.discriminant.expr" '"THREE"'
1313
PubConst = THREE,
14-
// @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.value" '"4"'
15-
// @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.expr" '"0x4"'
14+
// @is "$.index[*][?(@.name=='Hex')].inner.discriminant.value" '"4"'
15+
// @is "$.index[*][?(@.name=='Hex')].inner.discriminant.expr" '"0x4"'
1616
Hex = 0x4,
17-
// @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.value" '"5"'
18-
// @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.expr" '"{ _ }"'
17+
// @is "$.index[*][?(@.name=='Cast')].inner.discriminant.value" '"5"'
18+
// @is "$.index[*][?(@.name=='Cast')].inner.discriminant.expr" '"{ _ }"'
1919
Cast = 5 as isize,
20-
// @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.value" '"6"'
21-
// @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.expr" '"{ _ }"'
20+
// @is "$.index[*][?(@.name=='PubCall')].inner.discriminant.value" '"6"'
21+
// @is "$.index[*][?(@.name=='PubCall')].inner.discriminant.expr" '"{ _ }"'
2222
PubCall = six(),
23-
// @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.value" '"7"'
24-
// @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.expr" '"{ _ }"'
23+
// @is "$.index[*][?(@.name=='PrivCall')].inner.discriminant.value" '"7"'
24+
// @is "$.index[*][?(@.name=='PrivCall')].inner.discriminant.expr" '"{ _ }"'
2525
PrivCall = seven(),
26-
// @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.value" '"8"'
27-
// @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.expr" '"EIGHT"'
26+
// @is "$.index[*][?(@.name=='PrivConst')].inner.discriminant.value" '"8"'
27+
// @is "$.index[*][?(@.name=='PrivConst')].inner.discriminant.expr" '"EIGHT"'
2828
PrivConst = EIGHT,
2929
}
3030

0 commit comments

Comments
 (0)