Rollup merge of #101521 - aDotInTheVoid:rdj-structkind, r=GuillaumeGomez
Rustdoc-Json: More accurate struct type. Closes #101489 r? `@GuillaumeGomez`
This commit is contained in:
commit
8d21e97d64
@ -132,9 +132,11 @@ while work_list:
|
||||
work_list |= set(item["inner"]["items"]) - visited
|
||||
elif item["kind"] == "struct":
|
||||
check_generics(item["inner"]["generics"])
|
||||
work_list |= (
|
||||
set(item["inner"]["fields"]) | set(item["inner"]["impls"])
|
||||
) - visited
|
||||
work_list |= set(item["inner"]["impls"]) - visited
|
||||
if "tuple" in item["inner"]["kind"]:
|
||||
work_list |= set(filter(None, item["inner"]["kind"]["tuple"])) - visited
|
||||
elif "plain" in item["inner"]["kind"]:
|
||||
work_list |= set(item["inner"]["kind"]["plain"]["fields"]) - visited
|
||||
elif item["kind"] == "struct_field":
|
||||
check_type(item["inner"])
|
||||
elif item["kind"] == "enum":
|
||||
|
@ -304,11 +304,19 @@ impl FromWithTcx<clean::Struct> for Struct {
|
||||
fn from_tcx(struct_: clean::Struct, tcx: TyCtxt<'_>) -> Self {
|
||||
let fields_stripped = struct_.has_stripped_entries();
|
||||
let clean::Struct { struct_type, generics, fields } = struct_;
|
||||
|
||||
let kind = match struct_type {
|
||||
CtorKind::Fn => StructKind::Tuple(ids_keeping_stripped(fields, tcx)),
|
||||
CtorKind::Const => {
|
||||
assert!(fields.is_empty());
|
||||
StructKind::Unit
|
||||
}
|
||||
CtorKind::Fictive => StructKind::Plain { fields: ids(fields, tcx), fields_stripped },
|
||||
};
|
||||
|
||||
Struct {
|
||||
struct_type: from_ctor_kind(struct_type),
|
||||
kind,
|
||||
generics: generics.into_tcx(tcx),
|
||||
fields_stripped,
|
||||
fields: ids(fields, tcx),
|
||||
impls: Vec::new(), // Added in JsonRenderer::item
|
||||
}
|
||||
}
|
||||
@ -327,14 +335,6 @@ impl FromWithTcx<clean::Union> for Union {
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_ctor_kind(struct_type: CtorKind) -> StructType {
|
||||
match struct_type {
|
||||
CtorKind::Fictive => StructType::Plain,
|
||||
CtorKind::Fn => StructType::Tuple,
|
||||
CtorKind::Const => StructType::Unit,
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) fn from_fn_header(header: &rustc_hir::FnHeader) -> Header {
|
||||
Header {
|
||||
async_: header.is_async(),
|
||||
@ -644,20 +644,6 @@ impl FromWithTcx<clean::Enum> for Enum {
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWithTcx<clean::VariantStruct> for Struct {
|
||||
fn from_tcx(struct_: clean::VariantStruct, tcx: TyCtxt<'_>) -> Self {
|
||||
let fields_stripped = struct_.has_stripped_entries();
|
||||
let clean::VariantStruct { struct_type, fields } = struct_;
|
||||
Struct {
|
||||
struct_type: from_ctor_kind(struct_type),
|
||||
generics: Generics { params: vec![], where_predicates: vec![] },
|
||||
fields_stripped,
|
||||
fields: ids(fields, tcx),
|
||||
impls: Vec::new(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl FromWithTcx<clean::Variant> for Variant {
|
||||
fn from_tcx(variant: clean::Variant, tcx: TyCtxt<'_>) -> Self {
|
||||
use clean::Variant::*;
|
||||
|
@ -9,7 +9,7 @@ use std::path::PathBuf;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
/// rustdoc format-version.
|
||||
pub const FORMAT_VERSION: u32 = 20;
|
||||
pub const FORMAT_VERSION: u32 = 21;
|
||||
|
||||
/// 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
|
||||
@ -289,13 +289,39 @@ pub struct Union {
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Struct {
|
||||
pub struct_type: StructType,
|
||||
pub kind: StructKind,
|
||||
pub generics: Generics,
|
||||
pub fields_stripped: bool,
|
||||
pub fields: Vec<Id>,
|
||||
pub impls: Vec<Id>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum StructKind {
|
||||
/// A struct with no fields and no parentheses.
|
||||
///
|
||||
/// ```rust
|
||||
/// pub struct Unit;
|
||||
/// ```
|
||||
Unit,
|
||||
/// A struct with unnamed fields.
|
||||
///
|
||||
/// ```rust
|
||||
/// pub struct TupleStruct(i32);
|
||||
/// pub struct EmptyTupleStruct();
|
||||
/// ```
|
||||
///
|
||||
/// All [`Id`]'s will point to [`ItemEnum::StructField`]. Private and
|
||||
/// `#[doc(hidden)]` fields will be given as `None`
|
||||
Tuple(Vec<Option<Id>>),
|
||||
/// A struct with nammed fields.
|
||||
///
|
||||
/// ```rust
|
||||
/// pub struct PlainStruct { x: i32 }
|
||||
/// pub struct EmptyPlainStruct {}
|
||||
/// ```
|
||||
Plain { fields: Vec<Id>, fields_stripped: bool },
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Enum {
|
||||
pub generics: Generics,
|
||||
@ -357,14 +383,6 @@ pub struct Discriminant {
|
||||
pub value: String,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
#[serde(rename_all = "snake_case")]
|
||||
pub enum StructType {
|
||||
Plain,
|
||||
Tuple,
|
||||
Unit,
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash, Serialize, Deserialize)]
|
||||
pub struct Header {
|
||||
#[serde(rename = "const")]
|
||||
|
@ -3,10 +3,8 @@ use super::*;
|
||||
#[test]
|
||||
fn test_struct_info_roundtrip() {
|
||||
let s = ItemEnum::Struct(Struct {
|
||||
struct_type: StructType::Plain,
|
||||
generics: Generics { params: vec![], where_predicates: vec![] },
|
||||
fields_stripped: false,
|
||||
fields: vec![],
|
||||
kind: StructKind::Plain { fields: vec![], fields_stripped: false },
|
||||
impls: vec![],
|
||||
});
|
||||
|
||||
|
@ -17,7 +17,7 @@ pub mod l1 {
|
||||
pub mod l3 {
|
||||
|
||||
// @is "$.index[*][?(@.name=='L4')].kind" \"struct\"
|
||||
// @is "$.index[*][?(@.name=='L4')].inner.struct_type" \"unit\"
|
||||
// @is "$.index[*][?(@.name=='L4')].inner.kind" \"unit\"
|
||||
// @set l4_id = "$.index[*][?(@.name=='L4')].id"
|
||||
// @ismany "$.index[*][?(@.name=='l3')].inner.items[*]" $l4_id
|
||||
pub struct L4;
|
||||
|
11
src/test/rustdoc-json/structs/plain_all_pub.rs
Normal file
11
src/test/rustdoc-json/structs/plain_all_pub.rs
Normal file
@ -0,0 +1,11 @@
|
||||
pub struct Demo {
|
||||
pub x: i32,
|
||||
pub y: i32,
|
||||
}
|
||||
|
||||
// @set x = "$.index[*][?(@.name=='x')].id"
|
||||
// @set y = "$.index[*][?(@.name=='y')].id"
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[1]" $y
|
||||
// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 2
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" false
|
11
src/test/rustdoc-json/structs/plain_doc_hidden.rs
Normal file
11
src/test/rustdoc-json/structs/plain_doc_hidden.rs
Normal file
@ -0,0 +1,11 @@
|
||||
pub struct Demo {
|
||||
pub x: i32,
|
||||
#[doc(hidden)]
|
||||
pub y: i32,
|
||||
}
|
||||
|
||||
// @set x = "$.index[*][?(@.name=='x')].id"
|
||||
// @!has "$.index[*][?(@.name=='y')].id"
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
|
||||
// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 1
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" true
|
@ -1,6 +1,5 @@
|
||||
// @has "$.index[*][?(@.name=='PlainEmpty')].visibility" \"public\"
|
||||
// @has "$.index[*][?(@.name=='PlainEmpty')].kind" \"struct\"
|
||||
// @has "$.index[*][?(@.name=='PlainEmpty')].inner.struct_type" \"plain\"
|
||||
// @has "$.index[*][?(@.name=='PlainEmpty')].inner.fields_stripped" false
|
||||
// @has "$.index[*][?(@.name=='PlainEmpty')].inner.fields" []
|
||||
// @is "$.index[*][?(@.name=='PlainEmpty')].visibility" \"public\"
|
||||
// @is "$.index[*][?(@.name=='PlainEmpty')].kind" \"struct\"
|
||||
// @is "$.index[*][?(@.name=='PlainEmpty')].inner.kind.plain.fields_stripped" false
|
||||
// @is "$.index[*][?(@.name=='PlainEmpty')].inner.kind.plain.fields" []
|
||||
pub struct PlainEmpty {}
|
||||
|
9
src/test/rustdoc-json/structs/plain_pub_priv.rs
Normal file
9
src/test/rustdoc-json/structs/plain_pub_priv.rs
Normal file
@ -0,0 +1,9 @@
|
||||
pub struct Demo {
|
||||
pub x: i32,
|
||||
y: i32,
|
||||
}
|
||||
|
||||
// @set x = "$.index[*][?(@.name=='x')].id"
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[0]" $x
|
||||
// @count "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields[*]" 1
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.plain.fields_stripped" true
|
@ -1,5 +1,4 @@
|
||||
// @has "$.index[*][?(@.name=='Tuple')].visibility" \"public\"
|
||||
// @has "$.index[*][?(@.name=='Tuple')].kind" \"struct\"
|
||||
// @has "$.index[*][?(@.name=='Tuple')].inner.struct_type" \"tuple\"
|
||||
// @has "$.index[*][?(@.name=='Tuple')].inner.fields_stripped" true
|
||||
// @is "$.index[*][?(@.name=='Tuple')].visibility" \"public\"
|
||||
// @is "$.index[*][?(@.name=='Tuple')].kind" \"struct\"
|
||||
// @is "$.index[*][?(@.name=='Tuple')].inner.kind.tuple" '[null, null]'
|
||||
pub struct Tuple(u32, String);
|
||||
|
2
src/test/rustdoc-json/structs/tuple_empty.rs
Normal file
2
src/test/rustdoc-json/structs/tuple_empty.rs
Normal file
@ -0,0 +1,2 @@
|
||||
// @is "$.index[*][?(@.name=='TupleUnit')].inner.kind.tuple" []
|
||||
pub struct TupleUnit();
|
13
src/test/rustdoc-json/structs/tuple_pub_priv.rs
Normal file
13
src/test/rustdoc-json/structs/tuple_pub_priv.rs
Normal file
@ -0,0 +1,13 @@
|
||||
pub struct Demo(
|
||||
i32,
|
||||
/// field
|
||||
pub i32,
|
||||
#[doc(hidden)] i32,
|
||||
);
|
||||
|
||||
// @set field = "$.index[*][?(@.docs=='field')].id"
|
||||
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.tuple[0]" null
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.tuple[1]" $field
|
||||
// @is "$.index[*][?(@.name=='Demo')].inner.kind.tuple[2]" null
|
||||
// @count "$.index[*][?(@.name=='Demo')].inner.kind.tuple[*]" 3
|
@ -1,5 +1,4 @@
|
||||
// @has "$.index[*][?(@.name=='Unit')].visibility" \"public\"
|
||||
// @has "$.index[*][?(@.name=='Unit')].kind" \"struct\"
|
||||
// @has "$.index[*][?(@.name=='Unit')].inner.struct_type" \"unit\"
|
||||
// @has "$.index[*][?(@.name=='Unit')].inner.fields" []
|
||||
// @is "$.index[*][?(@.name=='Unit')].visibility" \"public\"
|
||||
// @is "$.index[*][?(@.name=='Unit')].kind" \"struct\"
|
||||
// @is "$.index[*][?(@.name=='Unit')].inner.kind" \"unit\"
|
||||
pub struct Unit;
|
||||
|
@ -1,13 +1,13 @@
|
||||
use std::collections::HashMap;
|
||||
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].visibility" \"public\"
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].kind" \"struct\"
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].name" \"T\"
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].kind.type"
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].name" \"U\"
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].kind.type"
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].inner.struct_type" \"plain\"
|
||||
// @has "$.index[*][?(@.name=='WithGenerics')].inner.fields_stripped" true
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].visibility" \"public\"
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].kind" \"struct\"
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].name" \"T\"
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[0].kind.type.bounds" []
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].name" \"U\"
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].inner.generics.params[1].kind.type.bounds" []
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].inner.kind.plain.fields_stripped" true
|
||||
// @is "$.index[*][?(@.name=='WithGenerics')].inner.kind.plain.fields" []
|
||||
pub struct WithGenerics<T, U> {
|
||||
stuff: Vec<T>,
|
||||
things: HashMap<U, U>,
|
||||
|
@ -1,9 +1,9 @@
|
||||
// @has "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\"
|
||||
// @has "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\"
|
||||
// @has "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\"
|
||||
// @has "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" []
|
||||
// @has "$.index[*][?(@.name=='WithPrimitives')].inner.struct_type" \"plain\"
|
||||
// @has "$.index[*][?(@.name=='WithPrimitives')].inner.fields_stripped" true
|
||||
// @is "$.index[*][?(@.name=='WithPrimitives')].visibility" \"public\"
|
||||
// @is "$.index[*][?(@.name=='WithPrimitives')].kind" \"struct\"
|
||||
// @is "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].name" \"\'a\"
|
||||
// @is "$.index[*][?(@.name=='WithPrimitives')].inner.generics.params[0].kind.lifetime.outlives" []
|
||||
// @is "$.index[*][?(@.name=='WithPrimitives')].inner.kind.plain.fields_stripped" true
|
||||
// @is "$.index[*][?(@.name=='WithPrimitives')].inner.kind.plain.fields" []
|
||||
pub struct WithPrimitives<'a> {
|
||||
num: u32,
|
||||
s: &'a str,
|
||||
|
Loading…
x
Reference in New Issue
Block a user