diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 1a2852dc6c724..cf837024a8ed3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1730,9 +1730,13 @@ 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()) - } + // 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 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..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; @@ -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, "

\ - 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 +1200,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)); @@ -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. 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 new file mode 100644 index 0000000000000..f3d8e39ea2d26 --- /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, + }, +}