summaryrefslogtreecommitdiffstats
path: root/src/librustdoc/html/render/print_item.rs
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-05-30 18:31:44 +0000
commitc23a457e72abe608715ac76f076f47dc42af07a5 (patch)
tree2772049aaf84b5c9d0ed12ec8d86812f7a7904b6 /src/librustdoc/html/render/print_item.rs
parentReleasing progress-linux version 1.73.0+dfsg1-1~progress7.99u1. (diff)
downloadrustc-c23a457e72abe608715ac76f076f47dc42af07a5.tar.xz
rustc-c23a457e72abe608715ac76f076f47dc42af07a5.zip
Merging upstream version 1.74.1+dfsg1.
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/librustdoc/html/render/print_item.rs')
-rw-r--r--src/librustdoc/html/render/print_item.rs449
1 files changed, 299 insertions, 150 deletions
diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs
index 6cab34986..c6751c958 100644
--- a/src/librustdoc/html/render/print_item.rs
+++ b/src/librustdoc/html/render/print_item.rs
@@ -198,7 +198,7 @@ pub(super) fn print_item(
clean::StructItem(..) => "Struct ",
clean::UnionItem(..) => "Union ",
clean::EnumItem(..) => "Enum ",
- clean::TypedefItem(..) => "Type Definition ",
+ clean::TypeAliasItem(..) => "Type Alias ",
clean::MacroItem(..) => "Macro ",
clean::ProcMacroItem(ref mac) => match mac.kind {
MacroKind::Bang => "Macro ",
@@ -273,7 +273,7 @@ pub(super) fn print_item(
clean::StructItem(ref s) => item_struct(buf, cx, item, s),
clean::UnionItem(ref s) => item_union(buf, cx, item, s),
clean::EnumItem(ref e) => item_enum(buf, cx, item, e),
- clean::TypedefItem(ref t) => item_typedef(buf, cx, item, t),
+ clean::TypeAliasItem(ref t) => item_type_alias(buf, cx, item, t),
clean::MacroItem(ref m) => item_macro(buf, cx, item, m),
clean::ProcMacroItem(ref m) => item_proc_macro(buf, cx, item, m),
clean::PrimitiveItem(_) => item_primitive(buf, cx, item),
@@ -343,7 +343,7 @@ fn item_module(w: &mut Buffer, cx: &mut Context<'_>, item: &clean::Item, items:
ItemType::Static => 8,
ItemType::Trait => 9,
ItemType::Function => 10,
- ItemType::Typedef => 12,
+ ItemType::TypeAlias => 12,
ItemType::Union => 13,
_ => 14 + ty as u8,
}
@@ -1217,8 +1217,8 @@ fn item_opaque_ty(
.unwrap();
}
-fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Typedef) {
- fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) {
+fn item_type_alias(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
+ fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::TypeAlias) {
wrap_item(w, |w| {
write!(
w,
@@ -1237,6 +1237,75 @@ fn item_typedef(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clea
write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
+ if let Some(inner_type) = &t.inner_type {
+ write!(
+ w,
+ "<h2 id=\"aliased-type\" class=\"small-section-header\">\
+ Aliased Type<a href=\"#aliased-type\" class=\"anchor\">§</a></h2>"
+ );
+
+ match inner_type {
+ clean::TypeAliasInnerType::Enum { variants, is_non_exhaustive } => {
+ let variants_iter = || variants.iter().filter(|i| !i.is_stripped());
+ wrap_item(w, |w| {
+ let variants_len = variants.len();
+ let variants_count = variants_iter().count();
+ let has_stripped_entries = variants_len != variants_count;
+
+ write!(w, "enum {}{}", it.name.unwrap(), t.generics.print(cx));
+ render_enum_fields(
+ w,
+ cx,
+ Some(&t.generics),
+ variants_iter(),
+ variants_count,
+ has_stripped_entries,
+ *is_non_exhaustive,
+ )
+ });
+ item_variants(w, cx, it, variants_iter());
+ }
+ clean::TypeAliasInnerType::Union { fields } => {
+ wrap_item(w, |w| {
+ let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
+ let has_stripped_fields = fields.len() != fields_count;
+
+ write!(w, "union {}{}", it.name.unwrap(), t.generics.print(cx));
+ render_struct_fields(
+ w,
+ Some(&t.generics),
+ None,
+ fields,
+ "",
+ true,
+ has_stripped_fields,
+ cx,
+ );
+ });
+ item_fields(w, cx, it, fields, None);
+ }
+ clean::TypeAliasInnerType::Struct { ctor_kind, fields } => {
+ wrap_item(w, |w| {
+ let fields_count = fields.iter().filter(|i| !i.is_stripped()).count();
+ let has_stripped_fields = fields.len() != fields_count;
+
+ write!(w, "struct {}{}", it.name.unwrap(), t.generics.print(cx));
+ render_struct_fields(
+ w,
+ Some(&t.generics),
+ *ctor_kind,
+ fields,
+ "",
+ true,
+ has_stripped_fields,
+ cx,
+ );
+ });
+ item_fields(w, cx, it, fields, None);
+ }
+ }
+ }
+
let def_id = it.item_id.expect_def_id();
// Render any items associated directly to this alias, as otherwise they
// won't be visible anywhere in the docs. It would be nice to also show
@@ -1315,6 +1384,12 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>(
s: &'a [clean::Item],
) -> impl fmt::Display + 'a + Captures<'cx> {
display_fn(|f| {
+ if s.iter()
+ .all(|field| matches!(*field.kind, clean::StrippedItem(box clean::StructFieldItem(..))))
+ {
+ return f.write_str("/* private fields */");
+ }
+
for (i, ty) in s.iter().enumerate() {
if i > 0 {
f.write_str(", ")?;
@@ -1332,7 +1407,7 @@ fn print_tuple_struct_fields<'a, 'cx: 'a>(
fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::Enum) {
let tcx = cx.tcx();
let count_variants = e.variants().count();
- wrap_item(w, |mut w| {
+ wrap_item(w, |w| {
render_attributes_in_code(w, it, tcx);
write!(
w,
@@ -1341,148 +1416,179 @@ fn item_enum(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, e: &clean::
it.name.unwrap(),
e.generics.print(cx),
);
- if !print_where_clause_and_check(w, &e.generics, cx) {
- // If there wasn't a `where` clause, we add a whitespace.
- w.write_str(" ");
- }
+ render_enum_fields(
+ w,
+ cx,
+ Some(&e.generics),
+ e.variants(),
+ count_variants,
+ e.has_stripped_entries(),
+ it.is_non_exhaustive(),
+ );
+ });
- let variants_stripped = e.has_stripped_entries();
- if count_variants == 0 && !variants_stripped {
- w.write_str("{}");
- } else {
- w.write_str("{\n");
- let toggle = should_hide_fields(count_variants);
- if toggle {
- toggle_open(&mut w, format_args!("{count_variants} variants"));
- }
- for v in e.variants() {
- w.write_str(" ");
- let name = v.name.unwrap();
- match *v.kind {
- // FIXME(#101337): Show discriminant
- clean::VariantItem(ref var) => match var.kind {
- clean::VariantKind::CLike => w.write_str(name.as_str()),
- clean::VariantKind::Tuple(ref s) => {
- write!(w, "{name}({})", print_tuple_struct_fields(cx, s),);
- }
- clean::VariantKind::Struct(ref s) => {
- render_struct(w, v, None, None, &s.fields, " ", false, cx);
- }
- },
- _ => unreachable!(),
- }
- w.write_str(",\n");
- }
+ write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
- if variants_stripped && !it.is_non_exhaustive() {
- w.write_str(" // some variants omitted\n");
- }
- if toggle {
- toggle_close(&mut w);
+ if count_variants != 0 {
+ item_variants(w, cx, it, e.variants());
+ }
+ let def_id = it.item_id.expect_def_id();
+ write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
+ write!(w, "{}", document_type_layout(cx, def_id));
+}
+
+fn render_enum_fields<'a>(
+ mut w: &mut Buffer,
+ cx: &mut Context<'_>,
+ g: Option<&clean::Generics>,
+ variants: impl Iterator<Item = &'a clean::Item>,
+ count_variants: usize,
+ has_stripped_entries: bool,
+ is_non_exhaustive: bool,
+) {
+ if !g.is_some_and(|g| print_where_clause_and_check(w, g, cx)) {
+ // If there wasn't a `where` clause, we add a whitespace.
+ w.write_str(" ");
+ }
+
+ let variants_stripped = has_stripped_entries;
+ if count_variants == 0 && !variants_stripped {
+ w.write_str("{}");
+ } else {
+ w.write_str("{\n");
+ let toggle = should_hide_fields(count_variants);
+ if toggle {
+ toggle_open(&mut w, format_args!("{count_variants} variants"));
+ }
+ const TAB: &str = " ";
+ for v in variants {
+ w.write_str(TAB);
+ let name = v.name.unwrap();
+ match *v.kind {
+ // FIXME(#101337): Show discriminant
+ clean::VariantItem(ref var) => match var.kind {
+ clean::VariantKind::CLike => w.write_str(name.as_str()),
+ clean::VariantKind::Tuple(ref s) => {
+ write!(w, "{name}({})", print_tuple_struct_fields(cx, s),);
+ }
+ clean::VariantKind::Struct(ref s) => {
+ render_struct(w, v, None, None, &s.fields, TAB, false, cx);
+ }
+ },
+ _ => unreachable!(),
}
- w.write_str("}");
+ w.write_str(",\n");
}
- });
- write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
+ if variants_stripped && !is_non_exhaustive {
+ w.write_str(" // some variants omitted\n");
+ }
+ if toggle {
+ toggle_close(&mut w);
+ }
+ w.write_str("}");
+ }
+}
- if count_variants != 0 {
+fn item_variants<'a>(
+ w: &mut Buffer,
+ cx: &mut Context<'_>,
+ it: &clean::Item,
+ variants: impl Iterator<Item = &'a clean::Item>,
+) {
+ let tcx = cx.tcx();
+ write!(
+ w,
+ "<h2 id=\"variants\" class=\"variants small-section-header\">\
+ Variants{}<a href=\"#variants\" class=\"anchor\">§</a>\
+ </h2>\
+ {}\
+ <div class=\"variants\">",
+ document_non_exhaustive_header(it),
+ document_non_exhaustive(it)
+ );
+ for variant in variants {
+ let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap()));
write!(
w,
- "<h2 id=\"variants\" class=\"variants small-section-header\">\
- Variants{}<a href=\"#variants\" class=\"anchor\">§</a>\
- </h2>\
- {}\
- <div class=\"variants\">",
- document_non_exhaustive_header(it),
- document_non_exhaustive(it)
+ "<section id=\"{id}\" class=\"variant\">\
+ <a href=\"#{id}\" class=\"anchor\">§</a>",
);
- for variant in e.variants() {
- let id = cx.derive_id(format!("{}.{}", ItemType::Variant, variant.name.unwrap()));
- write!(
- w,
- "<section id=\"{id}\" class=\"variant\">\
- <a href=\"#{id}\" class=\"anchor\">§</a>",
- );
- render_stability_since_raw_with_extra(
- w,
- variant.stable_since(tcx),
- variant.const_stability(tcx),
- it.stable_since(tcx),
- it.const_stable_since(tcx),
- " rightside",
- );
- write!(w, "<h3 class=\"code-header\">{name}", name = variant.name.unwrap());
+ render_stability_since_raw_with_extra(
+ w,
+ variant.stable_since(tcx),
+ variant.const_stability(tcx),
+ it.stable_since(tcx),
+ it.const_stable_since(tcx),
+ " rightside",
+ );
+ write!(w, "<h3 class=\"code-header\">{name}", name = variant.name.unwrap());
- let clean::VariantItem(variant_data) = &*variant.kind else { unreachable!() };
+ let clean::VariantItem(variant_data) = &*variant.kind else { unreachable!() };
- if let clean::VariantKind::Tuple(ref s) = variant_data.kind {
- write!(w, "({})", print_tuple_struct_fields(cx, s));
- }
- w.write_str("</h3></section>");
-
- let heading_and_fields = match &variant_data.kind {
- clean::VariantKind::Struct(s) => Some(("Fields", &s.fields)),
- clean::VariantKind::Tuple(fields) => {
- // Documentation on tuple variant fields is rare, so to reduce noise we only emit
- // the section if at least one field is documented.
- if fields.iter().any(|f| !f.doc_value().is_empty()) {
- Some(("Tuple Fields", fields))
- } else {
- None
- }
+ if let clean::VariantKind::Tuple(ref s) = variant_data.kind {
+ write!(w, "({})", print_tuple_struct_fields(cx, s));
+ }
+ w.write_str("</h3></section>");
+
+ let heading_and_fields = match &variant_data.kind {
+ clean::VariantKind::Struct(s) => Some(("Fields", &s.fields)),
+ clean::VariantKind::Tuple(fields) => {
+ // Documentation on tuple variant fields is rare, so to reduce noise we only emit
+ // the section if at least one field is documented.
+ if fields.iter().any(|f| !f.doc_value().is_empty()) {
+ Some(("Tuple Fields", fields))
+ } else {
+ None
}
- clean::VariantKind::CLike => None,
- };
+ }
+ clean::VariantKind::CLike => None,
+ };
- if let Some((heading, fields)) = heading_and_fields {
- let variant_id =
- cx.derive_id(format!("{}.{}.fields", ItemType::Variant, variant.name.unwrap()));
- write!(
- w,
- "<div class=\"sub-variant\" id=\"{variant_id}\">\
- <h4>{heading}</h4>\
- {}",
- document_non_exhaustive(variant)
- );
- for field in fields {
- match *field.kind {
- clean::StrippedItem(box clean::StructFieldItem(_)) => {}
- clean::StructFieldItem(ref ty) => {
- let id = cx.derive_id(format!(
- "variant.{}.field.{}",
- variant.name.unwrap(),
- field.name.unwrap()
- ));
- write!(
- w,
- "<div class=\"sub-variant-field\">\
+ if let Some((heading, fields)) = heading_and_fields {
+ let variant_id =
+ cx.derive_id(format!("{}.{}.fields", ItemType::Variant, variant.name.unwrap()));
+ write!(
+ w,
+ "<div class=\"sub-variant\" id=\"{variant_id}\">\
+ <h4>{heading}</h4>\
+ {}",
+ document_non_exhaustive(variant)
+ );
+ for field in fields {
+ match *field.kind {
+ clean::StrippedItem(box clean::StructFieldItem(_)) => {}
+ clean::StructFieldItem(ref ty) => {
+ let id = cx.derive_id(format!(
+ "variant.{}.field.{}",
+ variant.name.unwrap(),
+ field.name.unwrap()
+ ));
+ write!(
+ w,
+ "<div class=\"sub-variant-field\">\
<span id=\"{id}\" class=\"small-section-header\">\
<a href=\"#{id}\" class=\"anchor field\">§</a>\
<code>{f}: {t}</code>\
</span>",
- f = field.name.unwrap(),
- t = ty.print(cx),
- );
- write!(
- w,
- "{}</div>",
- document(cx, field, Some(variant), HeadingOffset::H5)
- );
- }
- _ => unreachable!(),
+ f = field.name.unwrap(),
+ t = ty.print(cx),
+ );
+ write!(
+ w,
+ "{}</div>",
+ document(cx, field, Some(variant), HeadingOffset::H5)
+ );
}
+ _ => unreachable!(),
}
- w.write_str("</div>");
}
-
- write!(w, "{}", document(cx, variant, Some(it), HeadingOffset::H4));
+ w.write_str("</div>");
}
- write!(w, "</div>");
+
+ write!(w, "{}", document(cx, variant, Some(it), HeadingOffset::H4));
}
- let def_id = it.item_id.expect_def_id();
- write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
- write!(w, "{}", document_type_layout(cx, def_id));
+ write!(w, "</div>");
}
fn item_macro(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, t: &clean::Macro) {
@@ -1593,15 +1699,28 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
write!(w, "{}", document(cx, it, None, HeadingOffset::H2));
- let mut fields = s
- .fields
+ item_fields(w, cx, it, &s.fields, s.ctor_kind);
+
+ let def_id = it.item_id.expect_def_id();
+ write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
+ write!(w, "{}", document_type_layout(cx, def_id));
+}
+
+fn item_fields(
+ w: &mut Buffer,
+ cx: &mut Context<'_>,
+ it: &clean::Item,
+ fields: &Vec<clean::Item>,
+ ctor_kind: Option<CtorKind>,
+) {
+ let mut fields = fields
.iter()
.filter_map(|f| match *f.kind {
clean::StructFieldItem(ref ty) => Some((f, ty)),
_ => None,
})
.peekable();
- if let None | Some(CtorKind::Fn) = s.ctor_kind {
+ if let None | Some(CtorKind::Fn) = ctor_kind {
if fields.peek().is_some() {
write!(
w,
@@ -1609,7 +1728,7 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
{}{}<a href=\"#fields\" class=\"anchor\">§</a>\
</h2>\
{}",
- if s.ctor_kind.is_none() { "Fields" } else { "Tuple Fields" },
+ if ctor_kind.is_none() { "Fields" } else { "Tuple Fields" },
document_non_exhaustive_header(it),
document_non_exhaustive(it)
);
@@ -1630,9 +1749,6 @@ fn item_struct(w: &mut Buffer, cx: &mut Context<'_>, it: &clean::Item, s: &clean
}
}
}
- let def_id = it.item_id.expect_def_id();
- write!(w, "{}", render_assoc_items(cx, it, def_id, AssocItemRender::All));
- write!(w, "{}", document_type_layout(cx, def_id));
}
fn item_static(w: &mut impl fmt::Write, cx: &mut Context<'_>, it: &clean::Item, s: &clean::Static) {
@@ -1871,7 +1987,7 @@ fn render_union<'a, 'cx: 'a>(
}
fn render_struct(
- mut w: &mut Buffer,
+ w: &mut Buffer,
it: &clean::Item,
g: Option<&clean::Generics>,
ty: Option<CtorKind>,
@@ -1891,6 +2007,29 @@ fn render_struct(
if let Some(g) = g {
write!(w, "{}", g.print(cx))
}
+ render_struct_fields(
+ w,
+ g,
+ ty,
+ fields,
+ tab,
+ structhead,
+ it.has_stripped_entries().unwrap_or(false),
+ cx,
+ )
+}
+
+fn render_struct_fields(
+ mut w: &mut Buffer,
+ g: Option<&clean::Generics>,
+ ty: Option<CtorKind>,
+ fields: &[clean::Item],
+ tab: &str,
+ structhead: bool,
+ has_stripped_entries: bool,
+ cx: &Context<'_>,
+) {
+ let tcx = cx.tcx();
match ty {
None => {
let where_displayed =
@@ -1922,11 +2061,11 @@ fn render_struct(
}
if has_visible_fields {
- if it.has_stripped_entries().unwrap() {
+ if has_stripped_entries {
write!(w, "\n{tab} /* private fields */");
}
write!(w, "\n{tab}");
- } else if it.has_stripped_entries().unwrap() {
+ } else if has_stripped_entries {
write!(w, " /* private fields */ ");
}
if toggle {
@@ -1936,21 +2075,31 @@ fn render_struct(
}
Some(CtorKind::Fn) => {
w.write_str("(");
- for (i, field) in fields.iter().enumerate() {
- if i > 0 {
- w.write_str(", ");
- }
- match *field.kind {
- clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"),
- clean::StructFieldItem(ref ty) => {
- write!(
- w,
- "{}{}",
- visibility_print_with_space(field.visibility(tcx), field.item_id, cx),
- ty.print(cx),
- )
+ if fields.iter().all(|field| {
+ matches!(*field.kind, clean::StrippedItem(box clean::StructFieldItem(..)))
+ }) {
+ write!(w, "/* private fields */");
+ } else {
+ for (i, field) in fields.iter().enumerate() {
+ if i > 0 {
+ w.write_str(", ");
+ }
+ match *field.kind {
+ clean::StrippedItem(box clean::StructFieldItem(..)) => write!(w, "_"),
+ clean::StructFieldItem(ref ty) => {
+ write!(
+ w,
+ "{}{}",
+ visibility_print_with_space(
+ field.visibility(tcx),
+ field.item_id,
+ cx
+ ),
+ ty.print(cx),
+ )
+ }
+ _ => unreachable!(),
}
- _ => unreachable!(),
}
}
w.write_str(")");