Rustdoc-Json: Store Variant Fields as their own item.

Closes #100587
Closes #92945
This commit is contained in:
Nixon Enraght-Moony 2022-09-05 22:17:50 +01:00
parent 6e4a9ab650
commit 065e0b9c9c
7 changed files with 203 additions and 18 deletions

View File

@ -144,10 +144,10 @@ while work_list:
) - visited
elif item["kind"] == "variant":
if item["inner"]["variant_kind"] == "tuple":
for ty in item["inner"]["variant_inner"]:
check_type(ty)
for field_id in filter(None, item["inner"]["variant_inner"]):
work_list.add(field_id)
elif item["inner"]["variant_kind"] == "struct":
work_list |= set(item["inner"]["variant_inner"]) - visited
work_list |= set(item["inner"]["variant_inner"]["fields"]) - visited
elif item["kind"] in ("function", "method"):
check_generics(item["inner"]["generics"])
check_decl(item["inner"]["decl"])

View File

@ -663,17 +663,11 @@ 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(
fields
.into_iter()
.filter_map(|f| match *f.kind {
clean::StructFieldItem(ty) => Some(ty.into_tcx(tcx)),
clean::StrippedItem(_) => None,
_ => unreachable!(),
})
.collect(),
),
Struct(s) => Variant::Struct(ids(s.fields, tcx)),
Tuple(fields) => Variant::Tuple(ids_keeping_stripped(fields, tcx)),
Struct(s) => Variant::Struct {
fields_stripped: s.has_stripped_entries(),
fields: ids(s.fields, tcx),
},
}
}
}
@ -796,3 +790,19 @@ fn ids(items: impl IntoIterator<Item = clean::Item>, tcx: TyCtxt<'_>) -> Vec<Id>
.map(|i| from_item_id_with_name(i.item_id, tcx, i.name))
.collect()
}
fn ids_keeping_stripped(
items: impl IntoIterator<Item = clean::Item>,
tcx: TyCtxt<'_>,
) -> Vec<Option<Id>> {
items
.into_iter()
.map(|i| {
if !i.is_stripped() && !i.is_keyword() {
Some(from_item_id_with_name(i.item_id, tcx, i.name))
} else {
None
}
})
.collect()
}

View File

@ -9,7 +9,7 @@
use serde::{Deserialize, Serialize};
/// rustdoc format-version.
pub const FORMAT_VERSION: u32 = 19;
pub const FORMAT_VERSION: u32 = 20;
/// 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
@ -308,9 +308,36 @@ pub struct Enum {
#[serde(rename_all = "snake_case")]
#[serde(tag = "variant_kind", content = "variant_inner")]
pub enum Variant {
/// A variant with no parentheses, and possible discriminant.
///
/// ```rust
/// enum Demo {
/// PlainVariant,
/// PlainWithDiscriminant = 1,
/// }
/// ```
Plain(Option<Discriminant>),
Tuple(Vec<Type>),
Struct(Vec<Id>),
/// A variant with unnamed fields.
///
/// Unlike most of json, `#[doc(hidden)]` fields will be given as `None`
/// instead of being ommited, because order matters.
///
/// ```rust
/// enum Demo {
/// TupleVariant(i32),
/// EmptyTupleVariant(),
/// }
/// ```
Tuple(Vec<Option<Id>>),
/// A variant with named fields.
///
/// ```rust
/// enum Demo {
/// StructVariant { x: i32 },
/// EmptyStructVariant {},
/// }
/// ```
Struct { fields: Vec<Id>, fields_stripped: bool },
}
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]

View File

@ -6,7 +6,7 @@
// @has "$.index[*][?(@.name=='ParseError')]"
// @has "$.index[*][?(@.name=='UnexpectedEndTag')]"
// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_kind" '"tuple"'
// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_inner" []
// @is "$.index[*][?(@.name=='UnexpectedEndTag')].inner.variant_inner" [null]
pub enum ParseError {
UnexpectedEndTag(#[doc(hidden)] u32),

View File

@ -0,0 +1,37 @@
// ignore-tidy-linelength
#![feature(no_core)]
#![no_core]
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
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}'
Named {},
// @set Tuple = "$.index[*][?(@.name=='Tuple')].id"
// @is "$.index[*][?(@.name=='Tuple')].inner.variant_kind" '"tuple"'
// @is "$.index[*][?(@.name=='Tuple')].inner.variant_inner" []
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
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
TupleField(i32),
}
// @is "$.index[*][?(@.name=='Foo')].inner.variants[0]" $Unit
// @is "$.index[*][?(@.name=='Foo')].inner.variants[1]" $Named
// @is "$.index[*][?(@.name=='Foo')].inner.variants[2]" $Tuple
// @is "$.index[*][?(@.name=='Foo')].inner.variants[3]" $NamedField
// @is "$.index[*][?(@.name=='Foo')].inner.variants[4]" $TupleField
// @count "$.index[*][?(@.name=='Foo')].inner.variants[*]" 5

View File

@ -0,0 +1,17 @@
pub enum Foo {
Variant {
#[doc(hidden)]
a: i32,
// @set b = "$.index[*][?(@.name=='b')].id"
b: i32,
#[doc(hidden)]
x: i32,
// @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
}

View File

@ -0,0 +1,94 @@
#![feature(no_core)]
#![no_core]
// @set 1.1.0 = "$.index[*][?(@.docs=='1.1.0')].id"
// @set 2.1.0 = "$.index[*][?(@.docs=='2.1.0')].id"
// @set 2.1.1 = "$.index[*][?(@.docs=='2.1.1')].id"
// @set 2.2.1 = "$.index[*][?(@.docs=='2.2.1')].id"
// @set 2.3.0 = "$.index[*][?(@.docs=='2.3.0')].id"
// @set 3.1.1 = "$.index[*][?(@.docs=='3.1.1')].id"
// @set 3.1.2 = "$.index[*][?(@.docs=='3.1.2')].id"
// @set 3.2.0 = "$.index[*][?(@.docs=='3.2.0')].id"
// @set 3.2.2 = "$.index[*][?(@.docs=='3.2.2')].id"
// @set 3.3.0 = "$.index[*][?(@.docs=='3.3.0')].id"
// @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
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
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
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
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
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
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
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
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
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
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"'
// @is "$.index[*][?(@.docs=='2.2.1')].name" '"1"'
// @is "$.index[*][?(@.docs=='2.3.0')].name" '"0"'
// @is "$.index[*][?(@.docs=='3.1.1')].name" '"1"'
// @is "$.index[*][?(@.docs=='3.1.2')].name" '"2"'
// @is "$.index[*][?(@.docs=='3.2.0')].name" '"0"'
// @is "$.index[*][?(@.docs=='3.2.2')].name" '"2"'
// @is "$.index[*][?(@.docs=='3.3.0')].name" '"0"'
// @is "$.index[*][?(@.docs=='3.3.1')].name" '"1"'
// @is "$.index[*][?(@.docs=='1.1.0')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='2.1.0')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='2.1.1')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='2.2.1')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='2.3.0')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='3.1.1')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='3.1.2')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='3.2.0')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='3.2.2')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='3.3.0')].inner" '{"kind": "primitive", "inner": "bool"}'
// @is "$.index[*][?(@.docs=='3.3.1')].inner" '{"kind": "primitive", "inner": "bool"}'