From ec76b6eedddfd601a9684db945ff927e57f2aa03 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 25 Jul 2021 14:48:57 +0200 Subject: [PATCH 1/5] Add support for tuple structs' fields documentation --- src/librustdoc/html/render/mod.rs | 3 +++ src/librustdoc/html/render/print_item.rs | 18 +++++++++--------- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 68c59612ccc44..5298a560627cb 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -2007,6 +2007,9 @@ fn sidebar_struct(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, s: &clea } sidebar.push_str(""); + } else if let CtorKind::Fn = s.struct_type { + sidebar + .push_str("

Tuple Fields

"); } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 2dfbaff1cc995..8f7e84428956a 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1176,21 +1176,21 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St _ => None, }) .peekable(); - if let CtorKind::Fictive = s.struct_type { + if let CtorKind::Fictive | CtorKind::Fn = s.struct_type { if fields.peek().is_some() { write!( w, "

\ - Fields{}

", + {}{}\ + ", + if let CtorKind::Fictive = s.struct_type { "Fields" } else { "Tuple Fields" }, document_non_exhaustive_header(it) ); document_non_exhaustive(w, it); - for (field, ty) in fields { - let id = cx.derive_id(format!( - "{}.{}", - ItemType::StructField, - field.name.as_ref().unwrap() - )); + for (index, (field, ty)) in fields.enumerate() { + let field_name = + field.name.map_or_else(|| index.to_string(), |sym| (*sym.as_str()).to_string()); + let id = cx.derive_id(format!("{}.{}", ItemType::StructField, field_name)); write!( w, "\ @@ -1199,7 +1199,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St ", item_type = ItemType::StructField, id = id, - name = field.name.as_ref().unwrap(), + name = field_name, ty = ty.print(cx) ); document(w, cx, field, Some(it)); From 19f30b72b30c7745d3ed126ebeaf3fe3d253677f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 25 Jul 2021 14:57:45 +0200 Subject: [PATCH 2/5] Add test for tuple struct documentation fields --- src/test/rustdoc/tuple-struct-fields-doc.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/rustdoc/tuple-struct-fields-doc.rs diff --git a/src/test/rustdoc/tuple-struct-fields-doc.rs b/src/test/rustdoc/tuple-struct-fields-doc.rs new file mode 100644 index 0000000000000..ab3d4903b2b6e --- /dev/null +++ b/src/test/rustdoc/tuple-struct-fields-doc.rs @@ -0,0 +1,19 @@ +#![crate_name = "foo"] + +// @has foo/struct.Foo.html +// @has - '//h2[@id="fields"]' 'Tuple Fields' +// @has - '//h3[@class="sidebar-title"]/a[@href="#fields"]' 'Tuple Fields' +// @has - '//*[@id="structfield.0"]' '0: u32' +// @has - '//*[@id="main"]/div[@class="docblock"]' 'hello' +// @!has - '//*[@id="structfield.1"]' +// @has - '//*[@id="structfield.2"]' '2: char' +// @has - '//*[@id="structfield.3"]' '3: i8' +// @has - '//*[@id="main"]/div[@class="docblock"]' 'not hello' +pub struct Foo( + /// hello + pub u32, + char, + pub char, + /// not hello + pub i8, +); From 2b790944a010498dd25a3bb327f2560927442c69 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 25 Jul 2021 21:18:02 +0200 Subject: [PATCH 3/5] Add support for tuple struct fields documentation in enums as well --- src/librustdoc/clean/mod.rs | 4 +--- src/librustdoc/html/render/print_item.rs | 10 +++++++--- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a2852dc6c724..a5ad8dfeb6b96 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1730,9 +1730,7 @@ impl Clean for hir::VariantData<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> Variant { match self { hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)), - hir::VariantData::Tuple(..) => { - Variant::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect()) - } + hir::VariantData::Tuple(..) => Variant::Struct(self.clean(cx)), hir::VariantData::Unit(..) => Variant::CLike, } } diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 8f7e84428956a..ea1cc8eb2ad52 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -1037,8 +1037,9 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum write!(w, "
", id = variant_id); write!( w, - "

Fields of {name}

", - name = variant.name.as_ref().unwrap() + "

{extra}Fields of {name}

", + extra = if s.struct_type == CtorKind::Fn { "Tuple " } else { "" }, + name = variant.name.as_ref().unwrap(), ); for field in &s.fields { use crate::clean::StructFieldItem; @@ -1509,7 +1510,10 @@ fn render_struct( if let Some(g) = g { write!(w, "{}", print_where_clause(g, cx, 0, false),) } - w.write_str(";"); + // We only want a ";" when we are displaying a tuple struct, not a variant tuple struct. + if structhead { + w.write_str(";"); + } } CtorKind::Const => { // Needed for PhantomData. From fbf78e1f9cc80ba5a68078c3cf2cb4d03aa7b00c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 25 Jul 2021 21:18:11 +0200 Subject: [PATCH 4/5] Add test for enum item tuple fields documentation --- src/test/rustdoc-ui/coverage/enums.stdout | 4 ++-- src/test/rustdoc/toggle-item-contents.rs | 4 ++-- src/test/rustdoc/tuple-struct-fields-doc.rs | 17 +++++++++++++++++ 3 files changed, 21 insertions(+), 4 deletions(-) diff --git a/src/test/rustdoc-ui/coverage/enums.stdout b/src/test/rustdoc-ui/coverage/enums.stdout index 64c012c1f66e3..414d60c86d308 100644 --- a/src/test/rustdoc-ui/coverage/enums.stdout +++ b/src/test/rustdoc-ui/coverage/enums.stdout @@ -1,7 +1,7 @@ +-------------------------------------+------------+------------+------------+------------+ | File | Documented | Percentage | Examples | Percentage | +-------------------------------------+------------+------------+------------+------------+ -| ...est/rustdoc-ui/coverage/enums.rs | 6 | 75.0% | 0 | 0.0% | +| ...est/rustdoc-ui/coverage/enums.rs | 6 | 66.7% | 0 | 0.0% | +-------------------------------------+------------+------------+------------+------------+ -| Total | 6 | 75.0% | 0 | 0.0% | +| Total | 6 | 66.7% | 0 | 0.0% | +-------------------------------------+------------+------------+------------+------------+ diff --git a/src/test/rustdoc/toggle-item-contents.rs b/src/test/rustdoc/toggle-item-contents.rs index 8d2046591d08a..ae871e79d7f6b 100644 --- a/src/test/rustdoc/toggle-item-contents.rs +++ b/src/test/rustdoc/toggle-item-contents.rs @@ -81,8 +81,8 @@ pub enum EnumStructVariant { } // @has 'toggle_item_contents/enum.LargeEnum.html' -// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1 -// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants' +// @count - '//*[@class="rust enum"]//details[@class="rustdoc-toggle type-contents-toggle"]' 1 +// @has - '//*[@class="rust enum"]//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 variants' pub enum LargeEnum { A, B, C, D, E, F(u8), G, H, I, J, K, L, M } diff --git a/src/test/rustdoc/tuple-struct-fields-doc.rs b/src/test/rustdoc/tuple-struct-fields-doc.rs index ab3d4903b2b6e..f3d8e39ea2d26 100644 --- a/src/test/rustdoc/tuple-struct-fields-doc.rs +++ b/src/test/rustdoc/tuple-struct-fields-doc.rs @@ -17,3 +17,20 @@ pub struct Foo( /// not hello pub i8, ); + +// @has foo/enum.Bar.html +// @has - '//pre[@class="rust enum"]' 'BarVariant(String),' +// @matches - '//*[@id="variant.BarVariant.fields"]/h3' '^Tuple Fields of BarVariant$' +// @has - '//*[@id="variant.BarVariant.field.0"]' '0: String' +// @has - '//*[@id="variant.BarVariant.fields"]//*[@class="docblock"]' 'Hello docs' +// @matches - '//*[@id="variant.FooVariant.fields"]/h3' '^Fields of FooVariant$' +pub enum Bar { + BarVariant( + /// Hello docs + String + ), + FooVariant { + /// hello + x: u32, + }, +} From c4aa73525bbfef6895612599170a5b297e1625ba Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 27 Jul 2021 13:52:15 +0200 Subject: [PATCH 5/5] Add explanations for why we use Variant::Struct instead of Variant::Tuple for tuple structs in enums --- src/librustdoc/clean/mod.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a5ad8dfeb6b96..cf837024a8ed3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1730,6 +1730,12 @@ impl Clean for hir::VariantData<'_> { fn clean(&self, cx: &mut DocContext<'_>) -> Variant { match self { hir::VariantData::Struct(..) => Variant::Struct(self.clean(cx)), + // Important note here: `Variant::Tuple` is used on tuple structs which are not in an + // enum (so where converting from `ty::VariantDef`). In case we are in an enum, the kind + // is provided by the `Variant` wrapper directly, and since we need the fields' name + // (even for a tuple struct variant!), it's simpler to just store it as a + // `Variant::Struct` instead of a `Variant::Tuple` (otherwise it would force us to make + // a lot of changes when rendering them to generate the name as well). hir::VariantData::Tuple(..) => Variant::Struct(self.clean(cx)), hir::VariantData::Unit(..) => Variant::CLike, }