diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8f4099653562e..b89b74a7f5fd3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1949,20 +1949,28 @@ pub(crate) fn clean_field_with_def_id( } pub(crate) fn clean_variant_def<'tcx>(variant: &ty::VariantDef, cx: &mut DocContext<'tcx>) -> Item { + let discriminant = match variant.discr { + ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }), + ty::VariantDiscr::Relative(_) => None, + }; + let kind = match variant.ctor_kind() { - Some(CtorKind::Const) => Variant::CLike(match variant.discr { - ty::VariantDiscr::Explicit(def_id) => Some(Discriminant { expr: None, value: def_id }), - ty::VariantDiscr::Relative(_) => None, - }), - Some(CtorKind::Fn) => Variant::Tuple( + Some(CtorKind::Const) => VariantKind::CLike, + Some(CtorKind::Fn) => VariantKind::Tuple( variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), ), - None => Variant::Struct(VariantStruct { + None => VariantKind::Struct(VariantStruct { ctor_kind: None, fields: variant.fields.iter().map(|field| clean_middle_field(field, cx)).collect(), }), }; - Item::from_def_id_and_parts(variant.def_id, Some(variant.name), VariantItem(kind), cx) + + Item::from_def_id_and_parts( + variant.def_id, + Some(variant.name), + VariantItem(Variant { kind, discriminant }), + cx, + ) } fn clean_variant_data<'tcx>( @@ -1970,19 +1978,23 @@ fn clean_variant_data<'tcx>( disr_expr: &Option, cx: &mut DocContext<'tcx>, ) -> Variant { - match variant { - hir::VariantData::Struct(..) => Variant::Struct(VariantStruct { + let discriminant = disr_expr.map(|disr| Discriminant { + expr: Some(disr.body), + value: cx.tcx.hir().local_def_id(disr.hir_id).to_def_id(), + }); + + let kind = match variant { + hir::VariantData::Struct(..) => VariantKind::Struct(VariantStruct { ctor_kind: None, fields: variant.fields().iter().map(|x| clean_field(x, cx)).collect(), }), hir::VariantData::Tuple(..) => { - Variant::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect()) + VariantKind::Tuple(variant.fields().iter().map(|x| clean_field(x, cx)).collect()) } - hir::VariantData::Unit(..) => Variant::CLike(disr_expr.map(|disr| Discriminant { - expr: Some(disr.body), - value: cx.tcx.hir().local_def_id(disr.hir_id).to_def_id(), - })), - } + hir::VariantData::Unit(..) => VariantKind::CLike, + }; + + Variant { discriminant, kind } } fn clean_path<'tcx>(path: &hir::Path<'tcx>, cx: &mut DocContext<'tcx>) -> Path { diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 62217df8de79c..77ec024262123 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -807,8 +807,11 @@ impl ItemKind { match self { StructItem(s) => s.fields.iter(), UnionItem(u) => u.fields.iter(), - VariantItem(Variant::Struct(v)) => v.fields.iter(), - VariantItem(Variant::Tuple(v)) => v.iter(), + VariantItem(v) => match &v.kind { + VariantKind::CLike => [].iter(), + VariantKind::Tuple(t) => t.iter(), + VariantKind::Struct(s) => s.fields.iter(), + }, EnumItem(e) => e.variants.iter(), TraitItem(t) => t.items.iter(), ImplItem(i) => i.items.iter(), @@ -824,7 +827,6 @@ impl ItemKind { | TyMethodItem(_) | MethodItem(_, _) | StructFieldItem(_) - | VariantItem(_) | ForeignFunctionItem(_) | ForeignStaticItem(_) | ForeignTypeItem @@ -2136,17 +2138,23 @@ impl Enum { } #[derive(Clone, Debug)] -pub(crate) enum Variant { - CLike(Option), +pub(crate) struct Variant { + pub kind: VariantKind, + pub discriminant: Option, +} + +#[derive(Clone, Debug)] +pub(crate) enum VariantKind { + CLike, Tuple(Vec), Struct(VariantStruct), } impl Variant { pub(crate) fn has_stripped_entries(&self) -> Option { - match *self { - Self::Struct(ref struct_) => Some(struct_.has_stripped_entries()), - Self::CLike(..) | Self::Tuple(_) => None, + match &self.kind { + VariantKind::Struct(struct_) => Some(struct_.has_stripped_entries()), + VariantKind::CLike | VariantKind::Tuple(_) => None, } } } diff --git a/src/librustdoc/fold.rs b/src/librustdoc/fold.rs index c6f1f9de51a49..656aeefb01a4a 100644 --- a/src/librustdoc/fold.rs +++ b/src/librustdoc/fold.rs @@ -37,17 +37,21 @@ pub(crate) trait DocFolder: Sized { i.items = i.items.into_iter().filter_map(|x| self.fold_item(x)).collect(); ImplItem(i) } - VariantItem(i) => match i { - Variant::Struct(mut j) => { - j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect(); - VariantItem(Variant::Struct(j)) - } - Variant::Tuple(fields) => { - let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect(); - VariantItem(Variant::Tuple(fields)) - } - Variant::CLike(disr) => VariantItem(Variant::CLike(disr)), - }, + VariantItem(Variant { kind, discriminant }) => { + let kind = match kind { + VariantKind::Struct(mut j) => { + j.fields = j.fields.into_iter().filter_map(|x| self.fold_item(x)).collect(); + VariantKind::Struct(j) + } + VariantKind::Tuple(fields) => { + let fields = fields.into_iter().filter_map(|x| self.fold_item(x)).collect(); + VariantKind::Tuple(fields) + } + VariantKind::CLike => VariantKind::CLike, + }; + + VariantItem(Variant { kind, discriminant }) + } ExternCrateItem { src: _ } | ImportItem(_) | FunctionItem(_) diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index a7b57c373e3be..40dfb06975067 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1220,15 +1220,15 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: w.write_str(" "); let name = v.name.unwrap(); match *v.kind { - clean::VariantItem(ref var) => match var { - // FIXME(#101337): Show discriminant - clean::Variant::CLike(..) => write!(w, "{}", name), - clean::Variant::Tuple(ref s) => { + // FIXME(#101337): Show discriminant + clean::VariantItem(ref var) => match var.kind { + clean::VariantKind::CLike => write!(w, "{}", name), + clean::VariantKind::Tuple(ref s) => { write!(w, "{}(", name); print_tuple_struct_fields(w, cx, s); w.write_str(")"); } - clean::Variant::Struct(ref s) => { + clean::VariantKind::Struct(ref s) => { render_struct( w, v, @@ -1286,25 +1286,28 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean:: " rightside", ); write!(w, "

{name}", name = variant.name.unwrap()); - if let clean::VariantItem(clean::Variant::Tuple(ref s)) = *variant.kind { + + let clean::VariantItem(variant_data) = &*variant.kind else { unreachable!() }; + + if let clean::VariantKind::Tuple(ref s) = variant_data.kind { w.write_str("("); print_tuple_struct_fields(w, cx, s); w.write_str(")"); } w.write_str("

"); - use crate::clean::Variant; - - let heading_and_fields = match &*variant.kind { - clean::VariantItem(Variant::Struct(s)) => Some(("Fields", &s.fields)), - // Documentation on tuple variant fields is rare, so to reduce noise we only emit - // the section if at least one field is documented. - clean::VariantItem(Variant::Tuple(fields)) - if fields.iter().any(|f| f.doc_value().is_some()) => - { - Some(("Tuple Fields", fields)) + let heading_and_fields = match &variant_data.kind { + clean::VariantKind::Struct(s) => Some(("Fields", &s.fields)), + clean::VariantKind::Tuple(fields) => { + // Documentation on tuple variant fields is rare, so to reduce noise we only emit + // the section if at least one field is documented. + if fields.iter().any(|f| f.doc_value().is_some()) { + Some(("Tuple Fields", fields)) + } else { + None + } } - _ => None, + clean::VariantKind::CLike => None, }; if let Some((heading, fields)) = heading_and_fields { diff --git a/src/librustdoc/json/conversions.rs b/src/librustdoc/json/conversions.rs index d7184053c87a4..84af194904d1b 100644 --- a/src/librustdoc/json/conversions.rs +++ b/src/librustdoc/json/conversions.rs @@ -646,15 +646,20 @@ impl FromWithTcx for Enum { impl FromWithTcx for Variant { fn from_tcx(variant: clean::Variant, tcx: TyCtxt<'_>) -> Self { - use clean::Variant::*; - match variant { - CLike(disr) => Variant::Plain(disr.map(|disr| disr.into_tcx(tcx))), - Tuple(fields) => Variant::Tuple(ids_keeping_stripped(fields, tcx)), - Struct(s) => Variant::Struct { + use clean::VariantKind::*; + + let discriminant = variant.discriminant.map(|d| d.into_tcx(tcx)); + + let kind = match variant.kind { + CLike => VariantKind::Plain, + Tuple(fields) => VariantKind::Tuple(ids_keeping_stripped(fields, tcx)), + Struct(s) => VariantKind::Struct { fields_stripped: s.has_stripped_entries(), fields: ids(s.fields, tcx), }, - } + }; + + Variant { kind, discriminant } } } diff --git a/src/librustdoc/passes/stripper.rs b/src/librustdoc/passes/stripper.rs index 995fb5dcc1c86..bf111133b9f7f 100644 --- a/src/librustdoc/passes/stripper.rs +++ b/src/librustdoc/passes/stripper.rs @@ -132,7 +132,10 @@ impl<'a, 'tcx> DocFolder for Stripper<'a, 'tcx> { // implementations of traits are always public. clean::ImplItem(ref imp) if imp.trait_.is_some() => true, // Variant fields have inherited visibility - clean::VariantItem(clean::Variant::Struct(..) | clean::Variant::Tuple(..)) => true, + clean::VariantItem(clean::Variant { + kind: clean::VariantKind::Struct(..) | clean::VariantKind::Tuple(..), + .. + }) => true, _ => false, }; diff --git a/src/librustdoc/visit.rs b/src/librustdoc/visit.rs index d29ceead4f3a5..390b943612195 100644 --- a/src/librustdoc/visit.rs +++ b/src/librustdoc/visit.rs @@ -17,10 +17,10 @@ pub(crate) trait DocVisitor: Sized { EnumItem(i) => i.variants.iter().for_each(|x| self.visit_item(x)), TraitItem(i) => i.items.iter().for_each(|x| self.visit_item(x)), ImplItem(i) => i.items.iter().for_each(|x| self.visit_item(x)), - VariantItem(i) => match i { - Variant::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)), - Variant::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)), - Variant::CLike(_) => {} + VariantItem(i) => match &i.kind { + VariantKind::Struct(j) => j.fields.iter().for_each(|x| self.visit_item(x)), + VariantKind::Tuple(fields) => fields.iter().for_each(|x| self.visit_item(x)), + VariantKind::CLike => {} }, ExternCrateItem { src: _ } | ImportItem(_) diff --git a/src/rustdoc-json-types/lib.rs b/src/rustdoc-json-types/lib.rs index 1ee96b8231cd1..387d5787dfcb2 100644 --- a/src/rustdoc-json-types/lib.rs +++ b/src/rustdoc-json-types/lib.rs @@ -9,7 +9,7 @@ use std::path::PathBuf; use serde::{Deserialize, Serialize}; /// rustdoc format-version. -pub const FORMAT_VERSION: u32 = 23; +pub const FORMAT_VERSION: u32 = 24; /// A `Crate` is the root of the emitted JSON blob. It contains all type/documentation information /// about the language items in the local crate, as well as info about external items to allow @@ -333,11 +333,18 @@ pub struct Enum { pub impls: Vec, } +#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] +pub struct Variant { + /// Whether the variant is plain, a tuple-like, or struct-like. Contains the fields. + pub kind: VariantKind, + /// The discriminant, if explicitly specified. + pub discriminant: Option, +} + #[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "snake_case")] -#[serde(tag = "variant_kind", content = "variant_inner")] -pub enum Variant { - /// A variant with no parentheses, and possible discriminant. +pub enum VariantKind { + /// A variant with no parentheses /// /// ```rust /// enum Demo { @@ -345,7 +352,7 @@ pub enum Variant { /// PlainWithDiscriminant = 1, /// } /// ``` - Plain(Option), + Plain, /// A variant with unnamed fields. /// /// Unlike most of json, `#[doc(hidden)]` fields will be given as `None` diff --git a/src/test/rustdoc-json/enums/discriminant/basic.rs b/src/test/rustdoc-json/enums/discriminant/basic.rs index 8c221615aa753..06906df3b2c64 100644 --- a/src/test/rustdoc-json/enums/discriminant/basic.rs +++ b/src/test/rustdoc-json/enums/discriminant/basic.rs @@ -1,12 +1,12 @@ #[repr(i8)] pub enum Ordering { - // @is "$.index[*][?(@.name=='Less')].inner.variant_inner.expr" '"-1"' - // @is "$.index[*][?(@.name=='Less')].inner.variant_inner.value" '"-1"' + // @is "$.index[*][?(@.name=='Less')].inner.discriminant.expr" '"-1"' + // @is "$.index[*][?(@.name=='Less')].inner.discriminant.value" '"-1"' Less = -1, - // @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.expr" '"0"' - // @is "$.index[*][?(@.name=='Equal')].inner.variant_inner.value" '"0"' + // @is "$.index[*][?(@.name=='Equal')].inner.discriminant.expr" '"0"' + // @is "$.index[*][?(@.name=='Equal')].inner.discriminant.value" '"0"' Equal = 0, - // @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.expr" '"1"' - // @is "$.index[*][?(@.name=='Greater')].inner.variant_inner.value" '"1"' + // @is "$.index[*][?(@.name=='Greater')].inner.discriminant.expr" '"1"' + // @is "$.index[*][?(@.name=='Greater')].inner.discriminant.value" '"1"' Greater = 1, } diff --git a/src/test/rustdoc-json/enums/discriminant/expr.rs b/src/test/rustdoc-json/enums/discriminant/expr.rs index 235b0b47381fc..e639965e79b42 100644 --- a/src/test/rustdoc-json/enums/discriminant/expr.rs +++ b/src/test/rustdoc-json/enums/discriminant/expr.rs @@ -1,30 +1,30 @@ pub enum Foo { - // @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.value" '"0"' - // @is "$.index[*][?(@.name=='Addition')].inner.variant_inner.expr" '"{ _ }"' + // @is "$.index[*][?(@.name=='Addition')].inner.discriminant.value" '"0"' + // @is "$.index[*][?(@.name=='Addition')].inner.discriminant.expr" '"{ _ }"' Addition = 0 + 0, - // @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.value" '"1"' - // @is "$.index[*][?(@.name=='Bin')].inner.variant_inner.expr" '"0b1"' + // @is "$.index[*][?(@.name=='Bin')].inner.discriminant.value" '"1"' + // @is "$.index[*][?(@.name=='Bin')].inner.discriminant.expr" '"0b1"' Bin = 0b1, - // @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.value" '"2"' - // @is "$.index[*][?(@.name=='Oct')].inner.variant_inner.expr" '"0o2"' + // @is "$.index[*][?(@.name=='Oct')].inner.discriminant.value" '"2"' + // @is "$.index[*][?(@.name=='Oct')].inner.discriminant.expr" '"0o2"' Oct = 0o2, - // @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.value" '"3"' - // @is "$.index[*][?(@.name=='PubConst')].inner.variant_inner.expr" '"THREE"' + // @is "$.index[*][?(@.name=='PubConst')].inner.discriminant.value" '"3"' + // @is "$.index[*][?(@.name=='PubConst')].inner.discriminant.expr" '"THREE"' PubConst = THREE, - // @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.value" '"4"' - // @is "$.index[*][?(@.name=='Hex')].inner.variant_inner.expr" '"0x4"' + // @is "$.index[*][?(@.name=='Hex')].inner.discriminant.value" '"4"' + // @is "$.index[*][?(@.name=='Hex')].inner.discriminant.expr" '"0x4"' Hex = 0x4, - // @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.value" '"5"' - // @is "$.index[*][?(@.name=='Cast')].inner.variant_inner.expr" '"{ _ }"' + // @is "$.index[*][?(@.name=='Cast')].inner.discriminant.value" '"5"' + // @is "$.index[*][?(@.name=='Cast')].inner.discriminant.expr" '"{ _ }"' Cast = 5 as isize, - // @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.value" '"6"' - // @is "$.index[*][?(@.name=='PubCall')].inner.variant_inner.expr" '"{ _ }"' + // @is "$.index[*][?(@.name=='PubCall')].inner.discriminant.value" '"6"' + // @is "$.index[*][?(@.name=='PubCall')].inner.discriminant.expr" '"{ _ }"' PubCall = six(), - // @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.value" '"7"' - // @is "$.index[*][?(@.name=='PrivCall')].inner.variant_inner.expr" '"{ _ }"' + // @is "$.index[*][?(@.name=='PrivCall')].inner.discriminant.value" '"7"' + // @is "$.index[*][?(@.name=='PrivCall')].inner.discriminant.expr" '"{ _ }"' PrivCall = seven(), - // @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.value" '"8"' - // @is "$.index[*][?(@.name=='PrivConst')].inner.variant_inner.expr" '"EIGHT"' + // @is "$.index[*][?(@.name=='PrivConst')].inner.discriminant.value" '"8"' + // @is "$.index[*][?(@.name=='PrivConst')].inner.discriminant.expr" '"EIGHT"' PrivConst = EIGHT, } diff --git a/src/test/rustdoc-json/enums/discriminant/limits.rs b/src/test/rustdoc-json/enums/discriminant/limits.rs index 8df73d78d237f..e56d5594f2fc9 100644 --- a/src/test/rustdoc-json/enums/discriminant/limits.rs +++ b/src/test/rustdoc-json/enums/discriminant/limits.rs @@ -4,40 +4,40 @@ #[repr(u64)] pub enum U64 { - // @is "$.index[*][?(@.name=='U64Min')].inner.variant_inner.value" '"0"' - // @is "$.index[*][?(@.name=='U64Min')].inner.variant_inner.expr" '"u64::MIN"' + // @is "$.index[*][?(@.name=='U64Min')].inner.discriminant.value" '"0"' + // @is "$.index[*][?(@.name=='U64Min')].inner.discriminant.expr" '"u64::MIN"' U64Min = u64::MIN, - // @is "$.index[*][?(@.name=='U64Max')].inner.variant_inner.value" '"18446744073709551615"' - // @is "$.index[*][?(@.name=='U64Max')].inner.variant_inner.expr" '"u64::MAX"' + // @is "$.index[*][?(@.name=='U64Max')].inner.discriminant.value" '"18446744073709551615"' + // @is "$.index[*][?(@.name=='U64Max')].inner.discriminant.expr" '"u64::MAX"' U64Max = u64::MAX, } #[repr(i64)] pub enum I64 { - // @is "$.index[*][?(@.name=='I64Min')].inner.variant_inner.value" '"-9223372036854775808"' - // @is "$.index[*][?(@.name=='I64Min')].inner.variant_inner.expr" '"i64::MIN"' + // @is "$.index[*][?(@.name=='I64Min')].inner.discriminant.value" '"-9223372036854775808"' + // @is "$.index[*][?(@.name=='I64Min')].inner.discriminant.expr" '"i64::MIN"' I64Min = i64::MIN, - // @is "$.index[*][?(@.name=='I64Max')].inner.variant_inner.value" '"9223372036854775807"' - // @is "$.index[*][?(@.name=='I64Max')].inner.variant_inner.expr" '"i64::MAX"' + // @is "$.index[*][?(@.name=='I64Max')].inner.discriminant.value" '"9223372036854775807"' + // @is "$.index[*][?(@.name=='I64Max')].inner.discriminant.expr" '"i64::MAX"' I64Max = i64::MAX, } #[repr(u128)] pub enum U128 { - // @is "$.index[*][?(@.name=='U128Min')].inner.variant_inner.value" '"0"' - // @is "$.index[*][?(@.name=='U128Min')].inner.variant_inner.expr" '"u128::MIN"' + // @is "$.index[*][?(@.name=='U128Min')].inner.discriminant.value" '"0"' + // @is "$.index[*][?(@.name=='U128Min')].inner.discriminant.expr" '"u128::MIN"' U128Min = u128::MIN, - // @is "$.index[*][?(@.name=='U128Max')].inner.variant_inner.value" '"340282366920938463463374607431768211455"' - // @is "$.index[*][?(@.name=='U128Max')].inner.variant_inner.expr" '"u128::MAX"' + // @is "$.index[*][?(@.name=='U128Max')].inner.discriminant.value" '"340282366920938463463374607431768211455"' + // @is "$.index[*][?(@.name=='U128Max')].inner.discriminant.expr" '"u128::MAX"' U128Max = u128::MAX, } #[repr(i128)] pub enum I128 { - // @is "$.index[*][?(@.name=='I128Min')].inner.variant_inner.value" '"-170141183460469231731687303715884105728"' - // @is "$.index[*][?(@.name=='I128Min')].inner.variant_inner.expr" '"i128::MIN"' + // @is "$.index[*][?(@.name=='I128Min')].inner.discriminant.value" '"-170141183460469231731687303715884105728"' + // @is "$.index[*][?(@.name=='I128Min')].inner.discriminant.expr" '"i128::MIN"' I128Min = i128::MIN, - // @is "$.index[*][?(@.name=='I128Max')].inner.variant_inner.value" '"170141183460469231731687303715884105727"' - // @is "$.index[*][?(@.name=='I128Max')].inner.variant_inner.expr" '"i128::MAX"' + // @is "$.index[*][?(@.name=='I128Max')].inner.discriminant.value" '"170141183460469231731687303715884105727"' + // @is "$.index[*][?(@.name=='I128Max')].inner.discriminant.expr" '"i128::MAX"' I128Max = i128::MAX, } diff --git a/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs b/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs index 3417baa0760e1..6889b305ffb41 100644 --- a/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs +++ b/src/test/rustdoc-json/enums/discriminant/num_underscore_and_suffix.rs @@ -1,15 +1,15 @@ #[repr(u32)] pub enum Foo { - // @is "$.index[*][?(@.name=='Basic')].inner.variant_inner.value" '"0"' - // @is "$.index[*][?(@.name=='Basic')].inner.variant_inner.expr" '"0"' + // @is "$.index[*][?(@.name=='Basic')].inner.discriminant.value" '"0"' + // @is "$.index[*][?(@.name=='Basic')].inner.discriminant.expr" '"0"' Basic = 0, - // @is "$.index[*][?(@.name=='Suffix')].inner.variant_inner.value" '"10"' - // @is "$.index[*][?(@.name=='Suffix')].inner.variant_inner.expr" '"10u32"' + // @is "$.index[*][?(@.name=='Suffix')].inner.discriminant.value" '"10"' + // @is "$.index[*][?(@.name=='Suffix')].inner.discriminant.expr" '"10u32"' Suffix = 10u32, - // @is "$.index[*][?(@.name=='Underscore')].inner.variant_inner.value" '"100"' - // @is "$.index[*][?(@.name=='Underscore')].inner.variant_inner.expr" '"1_0_0"' + // @is "$.index[*][?(@.name=='Underscore')].inner.discriminant.value" '"100"' + // @is "$.index[*][?(@.name=='Underscore')].inner.discriminant.expr" '"1_0_0"' Underscore = 1_0_0, - // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant_inner.value" '"1000"' - // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.variant_inner.expr" '"1_0_0_0u32"' + // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.discriminant.value" '"1000"' + // @is "$.index[*][?(@.name=='SuffixUnderscore')].inner.discriminant.expr" '"1_0_0_0u32"' SuffixUnderscore = 1_0_0_0u32, } diff --git a/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs b/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs index 6af944a2219ef..6a4f54de61745 100644 --- a/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs +++ b/src/test/rustdoc-json/enums/discriminant/only_some_have_discriminant.rs @@ -1,10 +1,10 @@ pub enum Foo { - // @is "$.index[*][?(@.name=='Has')].inner.variant_inner" '{"expr":"0", "value":"0"}' + // @is "$.index[*][?(@.name=='Has')].inner.discriminant" '{"expr":"0", "value":"0"}' Has = 0, - // @is "$.index[*][?(@.name=='Doesnt')].inner.variant_inner" null + // @is "$.index[*][?(@.name=='Doesnt')].inner.discriminant" null Doesnt, - // @is "$.index[*][?(@.name=='AlsoDoesnt')].inner.variant_inner" null + // @is "$.index[*][?(@.name=='AlsoDoesnt')].inner.discriminant" null AlsoDoesnt, - // @is "$.index[*][?(@.name=='AlsoHas')].inner.variant_inner" '{"expr":"44", "value":"44"}' + // @is "$.index[*][?(@.name=='AlsoHas')].inner.discriminant" '{"expr":"44", "value":"44"}' AlsoHas = 44, } diff --git a/src/test/rustdoc-json/enums/discriminant/struct.rs b/src/test/rustdoc-json/enums/discriminant/struct.rs new file mode 100644 index 0000000000000..e91a632a3b38e --- /dev/null +++ b/src/test/rustdoc-json/enums/discriminant/struct.rs @@ -0,0 +1,15 @@ +// ignore-tidy-linelength + +#[repr(i32)] +// @is "$.index[*][?(@.name=='Foo')].attrs" '["#[repr(i32)]"]' +pub enum Foo { + // @is "$.index[*][?(@.name=='Struct')].inner.discriminant" null + // @count "$.index[*][?(@.name=='Struct')].inner.kind.struct.fields[*]" 0 + Struct {}, + // @is "$.index[*][?(@.name=='StructWithDiscr')].inner.discriminant" '{"expr": "42", "value": "42"}' + // @count "$.index[*][?(@.name=='StructWithDiscr')].inner.kind.struct.fields[*]" 1 + StructWithDiscr { x: i32 } = 42, + // @is "$.index[*][?(@.name=='StructWithHexDiscr')].inner.discriminant" '{"expr": "0x42", "value": "66"}' + // @count "$.index[*][?(@.name=='StructWithHexDiscr')].inner.kind.struct.fields[*]" 2 + StructWithHexDiscr { x: i32, y: bool } = 0x42, +} diff --git a/src/test/rustdoc-json/enums/discriminant/tuple.rs b/src/test/rustdoc-json/enums/discriminant/tuple.rs new file mode 100644 index 0000000000000..b94d5739eabcb --- /dev/null +++ b/src/test/rustdoc-json/enums/discriminant/tuple.rs @@ -0,0 +1,15 @@ +// ignore-tidy-linelength + +#[repr(u32)] +// @is "$.index[*][?(@.name=='Foo')].attrs" '["#[repr(u32)]"]' +pub enum Foo { + // @is "$.index[*][?(@.name=='Tuple')].inner.discriminant" null + // @count "$.index[*][?(@.name=='Tuple')].inner.kind.tuple[*]" 0 + Tuple(), + // @is "$.index[*][?(@.name=='TupleWithDiscr')].inner.discriminant" '{"expr": "1", "value": "1"}' + // @count "$.index[*][?(@.name=='TupleWithDiscr')].inner.kind.tuple[*]" 1 + TupleWithDiscr(i32) = 1, + // @is "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.discriminant" '{"expr": "0b10", "value": "2"}' + // @count "$.index[*][?(@.name=='TupleWithBinDiscr')].inner.kind.tuple[*]" 2 + TupleWithBinDiscr(i32, i32) = 0b10, +} diff --git a/src/test/rustdoc-json/enums/field_hidden.rs b/src/test/rustdoc-json/enums/field_hidden.rs index e6310cc3b997c..78a05431472cb 100644 --- a/src/test/rustdoc-json/enums/field_hidden.rs +++ b/src/test/rustdoc-json/enums/field_hidden.rs @@ -5,8 +5,8 @@ // @has "$.index[*][?(@.name=='ParseError')]" // @has "$.index[*][?(@.name=='UnexpectedEndTag')]" -// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_kind" '"tuple"' -// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_inner" [null] +// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.kind.tuple" [null] +// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.discriminant" null pub enum ParseError { UnexpectedEndTag(#[doc(hidden)] u32), diff --git a/src/test/rustdoc-json/enums/kind.rs b/src/test/rustdoc-json/enums/kind.rs index e9ea3ae23c226..1787a859c8b37 100644 --- a/src/test/rustdoc-json/enums/kind.rs +++ b/src/test/rustdoc-json/enums/kind.rs @@ -5,27 +5,22 @@ pub enum Foo { // @set Unit = "$.index[*][?(@.name=='Unit')].id" - // @is "$.index[*][?(@.name=='Unit')].inner.variant_kind" '"plain"' - // @is "$.index[*][?(@.name=='Unit')].inner.variant_inner" null + // @is "$.index[*][?(@.name=='Unit')].inner.kind" '"plain"' Unit, // @set Named = "$.index[*][?(@.name=='Named')].id" - // @is "$.index[*][?(@.name=='Named')].inner.variant_kind" '"struct"' - // @is "$.index[*][?(@.name=='Named')].inner.variant_inner" '{"fields": [], "fields_stripped": false}' + // @is "$.index[*][?(@.name=='Named')].inner.kind.struct" '{"fields": [], "fields_stripped": false}' Named {}, // @set Tuple = "$.index[*][?(@.name=='Tuple')].id" - // @is "$.index[*][?(@.name=='Tuple')].inner.variant_kind" '"tuple"' - // @is "$.index[*][?(@.name=='Tuple')].inner.variant_inner" [] + // @is "$.index[*][?(@.name=='Tuple')].inner.kind.tuple" [] Tuple(), // @set NamedField = "$.index[*][?(@.name=='NamedField')].id" // @set x = "$.index[*][?(@.name=='x' && @.kind=='struct_field')].id" - // @is "$.index[*][?(@.name=='NamedField')].inner.variant_kind" '"struct"' - // @is "$.index[*][?(@.name=='NamedField')].inner.variant_inner.fields[*]" $x - // @is "$.index[*][?(@.name=='NamedField')].inner.variant_inner.fields_stripped" false + // @is "$.index[*][?(@.name=='NamedField')].inner.kind.struct.fields[*]" $x + // @is "$.index[*][?(@.name=='NamedField')].inner.kind.struct.fields_stripped" false NamedField { x: i32 }, // @set TupleField = "$.index[*][?(@.name=='TupleField')].id" - // @is "$.index[*][?(@.name=='TupleField')].inner.variant_kind" '"tuple"' // @set tup_field = "$.index[*][?(@.name=='0' && @.kind=='struct_field')].id" - // @is "$.index[*][?(@.name=='TupleField')].inner.variant_inner[*]" $tup_field + // @is "$.index[*][?(@.name=='TupleField')].inner.kind.tuple[*]" $tup_field TupleField(i32), } diff --git a/src/test/rustdoc-json/enums/struct_field_hidden.rs b/src/test/rustdoc-json/enums/struct_field_hidden.rs index f612a34a49277..de939cde2e7b3 100644 --- a/src/test/rustdoc-json/enums/struct_field_hidden.rs +++ b/src/test/rustdoc-json/enums/struct_field_hidden.rs @@ -9,9 +9,8 @@ pub enum Foo { // @set y = "$.index[*][?(@.name=='y')].id" y: i32, }, - // @is "$.index[*][?(@.name=='Variant')].inner.variant_kind" '"struct"' - // @is "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields_stripped" true - // @is "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields[0]" $b - // @is "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields[1]" $y - // @count "$.index[*][?(@.name=='Variant')].inner.variant_inner.fields[*]" 2 + // @is "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields_stripped" true + // @is "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields[0]" $b + // @is "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields[1]" $y + // @count "$.index[*][?(@.name=='Variant')].inner.kind.struct.fields[*]" 2 } diff --git a/src/test/rustdoc-json/enums/tuple_fields_hidden.rs b/src/test/rustdoc-json/enums/tuple_fields_hidden.rs index f546eaa0d172d..70bfbb81826be 100644 --- a/src/test/rustdoc-json/enums/tuple_fields_hidden.rs +++ b/src/test/rustdoc-json/enums/tuple_fields_hidden.rs @@ -14,61 +14,50 @@ // @set 3.3.1 = "$.index[*][?(@.docs=='3.3.1')].id" pub enum EnumWithStrippedTupleVariants { - // @is "$.index[*][?(@.name=='None')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='None')].inner.variant_inner[*]" 0 + // @count "$.index[*][?(@.name=='None')].inner.kind.tuple[*]" 0 None(), - // @is "$.index[*][?(@.name=='One')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='One')].inner.variant_inner[*]" 1 - // @is "$.index[*][?(@.name=='One')].inner.variant_inner[0]" $1.1.0 + // @count "$.index[*][?(@.name=='One')].inner.kind.tuple[*]" 1 + // @is "$.index[*][?(@.name=='One')].inner.kind.tuple[0]" $1.1.0 One(/** 1.1.0*/ bool), - // @is "$.index[*][?(@.name=='OneHidden')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='OneHidden')].inner.variant_inner[*]" 1 - // @is "$.index[*][?(@.name=='OneHidden')].inner.variant_inner[0]" null + // @count "$.index[*][?(@.name=='OneHidden')].inner.kind.tuple[*]" 1 + // @is "$.index[*][?(@.name=='OneHidden')].inner.kind.tuple[0]" null OneHidden(#[doc(hidden)] bool), - // @is "$.index[*][?(@.name=='Two')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='Two')].inner.variant_inner[*]" 2 - // @is "$.index[*][?(@.name=='Two')].inner.variant_inner[0]" $2.1.0 - // @is "$.index[*][?(@.name=='Two')].inner.variant_inner[1]" $2.1.1 + // @count "$.index[*][?(@.name=='Two')].inner.kind.tuple[*]" 2 + // @is "$.index[*][?(@.name=='Two')].inner.kind.tuple[0]" $2.1.0 + // @is "$.index[*][?(@.name=='Two')].inner.kind.tuple[1]" $2.1.1 Two(/** 2.1.0*/ bool, /** 2.1.1*/ bool), - // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_inner[*]" 2 - // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_inner[0]" null - // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.variant_inner[1]" $2.2.1 + // @count "$.index[*][?(@.name=='TwoLeftHidden')].inner.kind.tuple[*]" 2 + // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.kind.tuple[0]" null + // @is "$.index[*][?(@.name=='TwoLeftHidden')].inner.kind.tuple[1]" $2.2.1 TwoLeftHidden(#[doc(hidden)] bool, /** 2.2.1*/ bool), - // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_inner[*]" 2 - // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_inner[0]" $2.3.0 - // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.variant_inner[1]" null + // @count "$.index[*][?(@.name=='TwoRightHidden')].inner.kind.tuple[*]" 2 + // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.kind.tuple[0]" $2.3.0 + // @is "$.index[*][?(@.name=='TwoRightHidden')].inner.kind.tuple[1]" null TwoRightHidden(/** 2.3.0*/ bool, #[doc(hidden)] bool), - // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_inner[*]" 2 - // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_inner[0]" null - // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.variant_inner[1]" null + // @count "$.index[*][?(@.name=='TwoBothHidden')].inner.kind.tuple[*]" 2 + // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.kind.tuple[0]" null + // @is "$.index[*][?(@.name=='TwoBothHidden')].inner.kind.tuple[1]" null TwoBothHidden(#[doc(hidden)] bool, #[doc(hidden)] bool), - // @is "$.index[*][?(@.name=='Three1')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='Three1')].inner.variant_inner[*]" 3 - // @is "$.index[*][?(@.name=='Three1')].inner.variant_inner[0]" null - // @is "$.index[*][?(@.name=='Three1')].inner.variant_inner[1]" $3.1.1 - // @is "$.index[*][?(@.name=='Three1')].inner.variant_inner[2]" $3.1.2 + // @count "$.index[*][?(@.name=='Three1')].inner.kind.tuple[*]" 3 + // @is "$.index[*][?(@.name=='Three1')].inner.kind.tuple[0]" null + // @is "$.index[*][?(@.name=='Three1')].inner.kind.tuple[1]" $3.1.1 + // @is "$.index[*][?(@.name=='Three1')].inner.kind.tuple[2]" $3.1.2 Three1(#[doc(hidden)] bool, /** 3.1.1*/ bool, /** 3.1.2*/ bool), - // @is "$.index[*][?(@.name=='Three2')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='Three2')].inner.variant_inner[*]" 3 - // @is "$.index[*][?(@.name=='Three2')].inner.variant_inner[0]" $3.2.0 - // @is "$.index[*][?(@.name=='Three2')].inner.variant_inner[1]" null - // @is "$.index[*][?(@.name=='Three2')].inner.variant_inner[2]" $3.2.2 + // @count "$.index[*][?(@.name=='Three2')].inner.kind.tuple[*]" 3 + // @is "$.index[*][?(@.name=='Three2')].inner.kind.tuple[0]" $3.2.0 + // @is "$.index[*][?(@.name=='Three2')].inner.kind.tuple[1]" null + // @is "$.index[*][?(@.name=='Three2')].inner.kind.tuple[2]" $3.2.2 Three2(/** 3.2.0*/ bool, #[doc(hidden)] bool, /** 3.2.2*/ bool), - // @is "$.index[*][?(@.name=='Three3')].inner.variant_kind" '"tuple"' - // @count "$.index[*][?(@.name=='Three3')].inner.variant_inner[*]" 3 - // @is "$.index[*][?(@.name=='Three3')].inner.variant_inner[0]" $3.3.0 - // @is "$.index[*][?(@.name=='Three3')].inner.variant_inner[1]" $3.3.1 - // @is "$.index[*][?(@.name=='Three3')].inner.variant_inner[2]" null + // @count "$.index[*][?(@.name=='Three3')].inner.kind.tuple[*]" 3 + // @is "$.index[*][?(@.name=='Three3')].inner.kind.tuple[0]" $3.3.0 + // @is "$.index[*][?(@.name=='Three3')].inner.kind.tuple[1]" $3.3.1 + // @is "$.index[*][?(@.name=='Three3')].inner.kind.tuple[2]" null Three3(/** 3.3.0*/ bool, /** 3.3.1*/ bool, #[doc(hidden)] bool), } - // @is "$.index[*][?(@.docs=='1.1.0')].name" '"0"' // @is "$.index[*][?(@.docs=='2.1.0')].name" '"0"' // @is "$.index[*][?(@.docs=='2.1.1')].name" '"1"' diff --git a/src/test/rustdoc-json/enums/variant_struct.rs b/src/test/rustdoc-json/enums/variant_struct.rs index 23b854d8d1721..bc870c502a011 100644 --- a/src/test/rustdoc-json/enums/variant_struct.rs +++ b/src/test/rustdoc-json/enums/variant_struct.rs @@ -1,11 +1,10 @@ // @is "$.index[*][?(@.name=='EnumStruct')].visibility" \"public\" // @is "$.index[*][?(@.name=='EnumStruct')].kind" \"enum\" pub enum EnumStruct { - // @is "$.index[*][?(@.name=='VariantS')].inner.variant_kind" \"struct\" // @is "$.index[*][?(@.name=='x')].kind" \"struct_field\" + // @set x = "$.index[*][?(@.name=='x')].id" // @is "$.index[*][?(@.name=='y')].kind" \"struct_field\" - VariantS { - x: u32, - y: String, - }, + // @set y = "$.index[*][?(@.name=='y')].id" + // @ismany "$.index[*][?(@.name=='VariantS')].inner.kind.struct.fields[*]" $x $y + VariantS { x: u32, y: String }, } diff --git a/src/test/rustdoc-json/enums/variant_tuple_struct.rs b/src/test/rustdoc-json/enums/variant_tuple_struct.rs index b71ec47a804ad..d1207bbfb18da 100644 --- a/src/test/rustdoc-json/enums/variant_tuple_struct.rs +++ b/src/test/rustdoc-json/enums/variant_tuple_struct.rs @@ -1,8 +1,10 @@ // @is "$.index[*][?(@.name=='EnumTupleStruct')].visibility" \"public\" // @is "$.index[*][?(@.name=='EnumTupleStruct')].kind" \"enum\" pub enum EnumTupleStruct { - // @is "$.index[*][?(@.name=='VariantA')].inner.variant_kind" \"tuple\" // @is "$.index[*][?(@.name=='0')].kind" \"struct_field\" + // @set f0 = "$.index[*][?(@.name=='0')].id" // @is "$.index[*][?(@.name=='1')].kind" \"struct_field\" + // @set f1 = "$.index[*][?(@.name=='1')].id" + // @ismany "$.index[*][?(@.name=='VariantA')].inner.kind.tuple[*]" $f0 $f1 VariantA(u32, String), } diff --git a/src/tools/jsondoclint/src/validator.rs b/src/tools/jsondoclint/src/validator.rs index e15f5fe3ccc96..291d02d67bd62 100644 --- a/src/tools/jsondoclint/src/validator.rs +++ b/src/tools/jsondoclint/src/validator.rs @@ -5,7 +5,7 @@ use rustdoc_json_types::{ Constant, Crate, DynTrait, Enum, FnDecl, Function, FunctionPointer, GenericArg, GenericArgs, GenericBound, GenericParamDef, Generics, Id, Impl, Import, ItemEnum, Module, OpaqueTy, Path, Primitive, ProcMacro, Static, Struct, StructKind, Term, Trait, TraitAlias, Type, TypeBinding, - TypeBindingKind, Typedef, Union, Variant, WherePredicate, + TypeBindingKind, Typedef, Union, Variant, VariantKind, WherePredicate, }; use crate::{item_kind::Kind, Error, ErrorKind}; @@ -140,24 +140,24 @@ impl<'a> Validator<'a> { } fn check_variant(&mut self, x: &'a Variant, id: &'a Id) { - match x { - Variant::Plain(discr) => { - if let Some(discr) = discr { - if let (Err(_), Err(_)) = - (discr.value.parse::(), discr.value.parse::()) - { - self.fail( - id, - ErrorKind::Custom(format!( - "Failed to parse discriminant value `{}`", - discr.value - )), - ); - } - } + let Variant { kind, discriminant } = x; + + if let Some(discr) = discriminant { + if let (Err(_), Err(_)) = (discr.value.parse::(), discr.value.parse::()) { + self.fail( + id, + ErrorKind::Custom(format!( + "Failed to parse discriminant value `{}`", + discr.value + )), + ); } - Variant::Tuple(tys) => tys.iter().flatten().for_each(|t| self.add_field_id(t)), - Variant::Struct { fields, fields_stripped: _ } => { + } + + match kind { + VariantKind::Plain => {} + VariantKind::Tuple(tys) => tys.iter().flatten().for_each(|t| self.add_field_id(t)), + VariantKind::Struct { fields, fields_stripped: _ } => { fields.iter().for_each(|f| self.add_field_id(f)) } }