diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index f7073a8751f..552958d5e40 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -1,6 +1,7 @@
use clean::AttributesExt;
use std::cmp::Ordering;
+use std::fmt;
use rustc_data_structures::fx::FxHashMap;
use rustc_hir as hir;
@@ -155,7 +156,7 @@ fn should_hide_fields(n_fields: usize) -> bool {
n_fields > 12
}
-fn toggle_open(w: &mut Buffer, text: &str) {
+fn toggle_open(w: &mut Buffer, text: impl fmt::Display) {
write!(
w,
"\
@@ -481,6 +482,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::>();
let required = t.items.iter().filter(|m| m.is_ty_method()).collect::>();
let provided = t.items.iter().filter(|m| m.is_method()).collect::>();
+ let count_types = types.len();
+ let count_consts = consts.len();
+ let count_methods = required.len() + provided.len();
// Output the trait definition
wrap_into_docblock(w, |w| {
@@ -511,9 +515,12 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
let mut toggle = false;
// If there are too many associated types, hide _everything_
- if should_hide_fields(types.len()) {
+ if should_hide_fields(count_types) {
toggle = true;
- toggle_open(w, "associated items");
+ toggle_open(
+ w,
+ format_args!("{} associated items", count_types + count_consts + count_methods),
+ );
}
for t in &types {
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
@@ -523,9 +530,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
// We also do this if the types + consts is large because otherwise we could
// render a bunch of types and _then_ a bunch of consts just because both were
// _just_ under the limit
- if !toggle && should_hide_fields(types.len() + consts.len()) {
+ if !toggle && should_hide_fields(count_types + count_consts) {
toggle = true;
- toggle_open(w, "associated constants and methods");
+ toggle_open(
+ w,
+ format_args!(
+ "{} associated constant{} and {} method{}",
+ count_consts,
+ pluralize(count_consts),
+ count_methods,
+ pluralize(count_methods),
+ ),
+ );
}
if !types.is_empty() && !consts.is_empty() {
w.write_str("\n");
@@ -534,9 +550,9 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra
render_assoc_item(w, t, AssocItemLink::Anchor(None), ItemType::Trait, cx);
w.write_str(";\n");
}
- if !toggle && should_hide_fields(required.len() + provided.len()) {
+ if !toggle && should_hide_fields(count_methods) {
toggle = true;
- toggle_open(w, "methods");
+ toggle_open(w, format_args!("{} methods", count_methods));
}
if !consts.is_empty() && !required.is_empty() {
w.write_str("\n");
@@ -933,9 +949,10 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
w.write_str(" {}");
} else {
w.write_str(" {\n");
- let toggle = should_hide_fields(e.variants.len());
+ let count_variants = e.variants.len();
+ let toggle = should_hide_fields(count_variants);
if toggle {
- toggle_open(w, "variants");
+ toggle_open(w, format_args!("{} variants", count_variants));
}
for v in &e.variants {
w.write_str(" ");
@@ -1012,7 +1029,8 @@ fn item_enum(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, e: &clean::Enum
use crate::clean::Variant;
if let clean::VariantItem(Variant::Struct(ref s)) = *variant.kind {
- toggle_open(w, "fields");
+ let count_fields = s.fields.len();
+ toggle_open(w, format_args!("{} field{}", count_fields, pluralize(count_fields)));
let variant_id = cx.derive_id(format!(
"{}.{}.fields",
ItemType::Variant,
@@ -1385,7 +1403,7 @@ fn render_union(
fields.iter().filter(|f| matches!(*f.kind, clean::StructFieldItem(..))).count();
let toggle = should_hide_fields(count_fields);
if toggle {
- toggle_open(w, "fields");
+ toggle_open(w, format_args!("{} fields", count_fields));
}
for field in fields {
@@ -1441,7 +1459,7 @@ fn render_struct(
let has_visible_fields = count_fields > 0;
let toggle = should_hide_fields(count_fields);
if toggle {
- toggle_open(w, "fields");
+ toggle_open(w, format_args!("{} fields", count_fields));
}
for field in fields {
if let clean::StructFieldItem(ref ty) = *field.kind {
@@ -1618,3 +1636,7 @@ fn document_type_layout(w: &mut Buffer, cx: &Context<'_>, ty_def_id: DefId) {
writeln!(w, "");
}
+
+fn pluralize(count: usize) -> &'static str {
+ if count > 1 { "s" } else { "" }
+}
diff --git a/src/test/rustdoc/toggle-item-contents.rs b/src/test/rustdoc/toggle-item-contents.rs
index 6e3c0b4c681..167858b6065 100644
--- a/src/test/rustdoc/toggle-item-contents.rs
+++ b/src/test/rustdoc/toggle-item-contents.rs
@@ -9,7 +9,7 @@ pub struct PubStruct {
// @has 'toggle_item_contents/struct.BigPubStruct.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
pub struct BigPubStruct {
pub a: usize,
pub b: usize,
@@ -28,7 +28,7 @@ pub struct BigPubStruct {
// @has 'toggle_item_contents/union.BigUnion.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 13 fields'
pub union BigUnion {
pub a: usize,
pub b: usize,
@@ -63,7 +63,7 @@ pub struct PrivStruct {
// @has 'toggle_item_contents/enum.Enum.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show fields'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 2 fields'
pub enum Enum {
A, B, C,
D {
@@ -72,9 +72,19 @@ pub enum Enum {
}
}
+// @has 'toggle_item_contents/enum.EnumStructVariant.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 field'
+pub enum EnumStructVariant {
+ A, B, C,
+ D {
+ a: u8,
+ }
+}
+
// @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 variants'
+// @has - '//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
}
@@ -90,7 +100,7 @@ pub trait Trait {
// @has 'toggle_item_contents/trait.GinormousTrait.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated items'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 16 associated items'
pub trait GinormousTrait {
type A;
type B;
@@ -113,7 +123,7 @@ pub trait GinormousTrait {
// @has 'toggle_item_contents/trait.HugeTrait.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show associated constants and methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 12 associated constants and 2 methods'
pub trait HugeTrait {
type A;
const M: usize = 1;
@@ -133,9 +143,30 @@ pub trait HugeTrait {
fn bar();
}
+// @has 'toggle_item_contents/trait.GiganticTrait.html'
+// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 1 associated constant and 1 method'
+pub trait GiganticTrait {
+ type A;
+ type B;
+ type C;
+ type D;
+ type E;
+ type F;
+ type G;
+ type H;
+ type I;
+ type J;
+ type K;
+ type L;
+ const M: usize = 1;
+ #[must_use]
+ fn foo();
+}
+
// @has 'toggle_item_contents/trait.BigTrait.html'
// @count - '//details[@class="rustdoc-toggle type-contents-toggle"]' 1
-// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show methods'
+// @has - '//details[@class="rustdoc-toggle type-contents-toggle"]' 'Show 14 methods'
pub trait BigTrait {
type A;
#[must_use]