about summary refs log tree commit diff
diff options
context:
space:
mode:
authorYuki Okushi <jtitor@2k36.org>2021-07-29 06:11:45 +0900
committerGitHub <noreply@github.com>2021-07-29 06:11:45 +0900
commit014e22c836b649229023451af79c60fff1185888 (patch)
tree7fc864cba45274448a949df2f9eb764a427f2053
parent92229846364b983e6ac424c39a6e711ccfa8056b (diff)
parentc4aa73525bbfef6895612599170a5b297e1625ba (diff)
downloadrust-014e22c836b649229023451af79c60fff1185888.tar.gz
rust-014e22c836b649229023451af79c60fff1185888.zip
Rollup merge of #87451 - GuillaumeGomez:tuple-struct-field-doc, r=jyn514
Add support for tuple struct field documentation

Fixes  #42615.
This is #80320 updated to new codebase and with added tests.
Part of https://github.com/rust-lang/rust/issues/83255.

cc ```@camelid``` (since you were involved on the original PR).
r? ```@jyn514```
-rw-r--r--src/librustdoc/clean/mod.rs10
-rw-r--r--src/librustdoc/html/render/mod.rs3
-rw-r--r--src/librustdoc/html/render/print_item.rs28
-rw-r--r--src/test/rustdoc-ui/coverage/enums.stdout4
-rw-r--r--src/test/rustdoc/toggle-item-contents.rs4
-rw-r--r--src/test/rustdoc/tuple-struct-fields-doc.rs36
6 files changed, 66 insertions, 19 deletions
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 27c2f6cc87e..fd79292477c 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1730,9 +1730,13 @@ impl Clean<Variant> 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())
-            }
+            // 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,
         }
     }
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 2b7f7aa3691..c05ea81ac1f 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("</div>");
+        } else if let CtorKind::Fn = s.struct_type {
+            sidebar
+                .push_str("<h3 class=\"sidebar-title\"><a href=\"#fields\">Tuple Fields</a></h3>");
         }
     }
 
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 83ad4f7097b..5c30d8bbd17 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, "<div class=\"sub-variant\" id=\"{id}\">", id = variant_id);
                 write!(
                     w,
-                    "<h3>Fields of <b>{name}</b></h3><div>",
-                    name = variant.name.as_ref().unwrap()
+                    "<h3>{extra}Fields of <b>{name}</b></h3><div>",
+                    extra = if s.struct_type == CtorKind::Fn { "Tuple " } else { "" },
+                    name = variant.name.as_ref().unwrap(),
                 );
                 for field in &s.fields {
                     use crate::clean::StructFieldItem;
@@ -1176,21 +1177,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,
                 "<h2 id=\"fields\" class=\"fields small-section-header\">\
-                       Fields{}<a href=\"#fields\" class=\"anchor\"></a></h2>",
+                     {}{}<a href=\"#fields\" class=\"anchor\"></a>\
+                 </h2>",
+                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,
                     "<span id=\"{id}\" class=\"{item_type} small-section-header\">\
@@ -1199,7 +1200,7 @@ fn item_struct(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, s: &clean::St
                      </span>",
                     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));
@@ -1507,7 +1508,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.
diff --git a/src/test/rustdoc-ui/coverage/enums.stdout b/src/test/rustdoc-ui/coverage/enums.stdout
index 64c012c1f66..414d60c86d3 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 8d2046591d0..ae871e79d7f 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
new file mode 100644
index 00000000000..f3d8e39ea2d
--- /dev/null
+++ b/src/test/rustdoc/tuple-struct-fields-doc.rs
@@ -0,0 +1,36 @@
+#![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,
+);
+
+// @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,
+    },
+}