diff options
| author | León Orell Valerian Liehr <liehr.exchange@gmx.net> | 2022-03-29 19:30:54 +0200 |
|---|---|---|
| committer | León Orell Valerian Liehr <liehr.exchange@gmx.net> | 2022-04-12 15:38:39 +0200 |
| commit | 8de453a8c6a26e43876def2d757bec40ed9b2767 (patch) | |
| tree | 356dab604c87c625d1866a4e2fc8b594ed75caa5 /src/librustdoc/html | |
| parent | 2a83fbc42a9bb6bfdb8d3fb4ecce83fb410d7642 (diff) | |
| download | rust-8de453a8c6a26e43876def2d757bec40ed9b2767.tar.gz rust-8de453a8c6a26e43876def2d757bec40ed9b2767.zip | |
rustdoc: discr. required+provided assoc consts+tys
Diffstat (limited to 'src/librustdoc/html')
| -rw-r--r-- | src/librustdoc/html/format.rs | 15 | ||||
| -rw-r--r-- | src/librustdoc/html/markdown.rs | 6 | ||||
| -rw-r--r-- | src/librustdoc/html/render/mod.rs | 247 | ||||
| -rw-r--r-- | src/librustdoc/html/render/print_item.rs | 160 | ||||
| -rw-r--r-- | src/librustdoc/html/static/js/search.js | 2 |
5 files changed, 262 insertions, 168 deletions
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 5c59609d5b8..55b0028180f 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -527,6 +527,21 @@ crate enum HrefError { /// This item is known to rustdoc, but from a crate that does not have documentation generated. /// /// This can only happen for non-local items. + /// + /// # Example + /// + /// Crate `a` defines a public trait and crate `b` – the target crate that depends on `a` – + /// implements it for a local type. + /// We document `b` but **not** `a` (we only _build_ the latter – with `rustc`): + /// + /// ```sh + /// rustc a.rs --crate-type=lib + /// rustdoc b.rs --crate-type=lib --extern=a=liba.rlib + /// ``` + /// + /// Now, the associated items in the trait impl want to link to the corresponding item in the + /// trait declaration (see `html::render::assoc_href_attr`) but it's not available since their + /// *documentation (was) not built*. DocumentationNotBuilt, /// This can only happen for non-local items when `--document-private-items` is not passed. Private, diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs index 943c521485b..1ebb41b5933 100644 --- a/src/librustdoc/html/markdown.rs +++ b/src/librustdoc/html/markdown.rs @@ -1452,8 +1452,10 @@ fn init_id_map() -> FxHashMap<String, usize> { map.insert("trait-implementations".to_owned(), 1); map.insert("synthetic-implementations".to_owned(), 1); map.insert("blanket-implementations".to_owned(), 1); - map.insert("associated-types".to_owned(), 1); - map.insert("associated-const".to_owned(), 1); + map.insert("required-associated-types".to_owned(), 1); + map.insert("provided-associated-types".to_owned(), 1); + map.insert("provided-associated-consts".to_owned(), 1); + map.insert("required-associated-consts".to_owned(), 1); map.insert("required-methods".to_owned(), 1); map.insert("provided-methods".to_owned(), 1); map.insert("implementors".to_owned(), 1); diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 12da16527a0..9891c4b676f 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -521,7 +521,7 @@ fn document_short( let mut summary_html = MarkdownSummaryLine(&s, &item.links(cx)).into_string(); if s.contains('\n') { - let link = format!(r#" <a href="{}">Read more</a>"#, naive_assoc_href(item, link, cx)); + let link = format!(r#" <a{}>Read more</a>"#, assoc_href_attr(item, link, cx)); if let Some(idx) = summary_html.rfind("</p>") { summary_html.insert_str(idx, &link); @@ -737,42 +737,82 @@ fn render_impls( w.write_str(&rendered_impls.join("")); } -fn naive_assoc_href(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) -> String { - use crate::formats::item_type::ItemType::*; +/// Build a (possibly empty) `href` attribute (a key-value pair) for the given associated item. +fn assoc_href_attr(it: &clean::Item, link: AssocItemLink<'_>, cx: &Context<'_>) -> String { + let name = it.name.unwrap(); + let item_type = it.type_(); - let name = it.name.as_ref().unwrap(); - let ty = match it.type_() { - Typedef | AssocType => AssocType, - s => s, - }; + let href = match link { + AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{}", id)), + AssocItemLink::Anchor(None) => Some(format!("#{}.{}", item_type, name)), + AssocItemLink::GotoSource(did, provided_methods) => { + // We're creating a link from the implementation of an associated item to its + // declaration in the trait declaration. + let item_type = match item_type { + // For historical but not technical reasons, the item type of methods in + // trait declarations depends on whether the method is required (`TyMethod`) or + // provided (`Method`). + ItemType::Method | ItemType::TyMethod => { + if provided_methods.contains(&name) { + ItemType::Method + } else { + ItemType::TyMethod + } + } + // For associated types and constants, no such distinction exists. + item_type => item_type, + }; - let anchor = format!("#{}.{}", ty, name); - match link { - AssocItemLink::Anchor(Some(ref id)) => format!("#{}", id), - AssocItemLink::Anchor(None) => anchor, - AssocItemLink::GotoSource(did, _) => { - href(did.expect_def_id(), cx).map(|p| format!("{}{}", p.0, anchor)).unwrap_or(anchor) + match href(did.expect_def_id(), cx) { + Ok((url, ..)) => Some(format!("{}#{}.{}", url, item_type, name)), + // The link is broken since it points to an external crate that wasn't documented. + // Do not create any link in such case. This is better than falling back to a + // dummy anchor like `#{item_type}.{name}` representing the `id` of *this* impl item + // (that used to happen in older versions). Indeed, in most cases this dummy would + // coincide with the `id`. However, it would not always do so. + // In general, this dummy would be incorrect: + // If the type with the trait impl also had an inherent impl with an assoc. item of + // the *same* name as this impl item, the dummy would link to that one even though + // those two items are distinct! + // In this scenario, the actual `id` of this impl item would be + // `#{item_type}.{name}-{n}` for some number `n` (a disambiguator). + Err(HrefError::DocumentationNotBuilt) => None, + Err(_) => Some(format!("#{}.{}", item_type, name)), + } } - } + }; + + // If there is no `href` for the reason explained above, simply do not render it which is valid: + // https://html.spec.whatwg.org/multipage/links.html#links-created-by-a-and-area-elements + href.map(|href| format!(" href=\"{}\"", href)).unwrap_or_default() } fn assoc_const( w: &mut Buffer, it: &clean::Item, ty: &clean::Type, + default: Option<&clean::ConstantKind>, link: AssocItemLink<'_>, extra: &str, cx: &Context<'_>, ) { write!( w, - "{}{}const <a href=\"{}\" class=\"constant\">{}</a>: {}", - extra, - it.visibility.print_with_space(it.def_id, cx), - naive_assoc_href(it, link, cx), - it.name.as_ref().unwrap(), - ty.print(cx) + "{extra}{vis}const <a{href} class=\"constant\">{name}</a>: {ty}", + extra = extra, + vis = it.visibility.print_with_space(it.def_id, cx), + href = assoc_href_attr(it, link, cx), + name = it.name.as_ref().unwrap(), + ty = ty.print(cx), ); + if let Some(default) = default { + // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the + // hood which adds noisy underscores and a type suffix to number literals. + // This hurts readability in this context especially when more complex expressions + // are involved and it doesn't add much of value. + // Find a way to print constants here without all that jazz. + write!(w, " = {}", default.value(cx.tcx()).unwrap_or_else(|| default.expr(cx.tcx()))); + } } fn assoc_type( @@ -787,9 +827,9 @@ fn assoc_type( ) { write!( w, - "{indent}type <a href=\"{href}\" class=\"associatedtype\">{name}</a>{generics}", + "{indent}type <a{href} class=\"associatedtype\">{name}</a>{generics}", indent = " ".repeat(indent), - href = naive_assoc_href(it, link, cx), + href = assoc_href_attr(it, link, cx), name = it.name.as_ref().unwrap(), generics = generics.print(cx), ); @@ -814,22 +854,6 @@ fn assoc_method( ) { let header = meth.fn_header(cx.tcx()).expect("Trying to get header from a non-function item"); let name = meth.name.as_ref().unwrap(); - let href = match link { - AssocItemLink::Anchor(Some(ref id)) => Some(format!("#{}", id)), - AssocItemLink::Anchor(None) => Some(format!("#{}.{}", meth.type_(), name)), - AssocItemLink::GotoSource(did, provided_methods) => { - // We're creating a link from an impl-item to the corresponding - // trait-item and need to map the anchored type accordingly. - let ty = - if provided_methods.contains(name) { ItemType::Method } else { ItemType::TyMethod }; - - match (href(did.expect_def_id(), cx), ty) { - (Ok(p), ty) => Some(format!("{}#{}.{}", p.0, ty, name)), - (Err(HrefError::DocumentationNotBuilt), ItemType::TyMethod) => None, - (Err(_), ty) => Some(format!("#{}.{}", ty, name)), - } - } - }; let vis = meth.visibility.print_with_space(meth.def_id, cx).to_string(); // FIXME: Once https://github.com/rust-lang/rust/issues/67792 is implemented, we can remove // this condition. @@ -843,6 +867,7 @@ fn assoc_method( let unsafety = header.unsafety.print_with_space(); let defaultness = print_default_space(meth.is_default()); let abi = print_abi_with_space(header.abi).to_string(); + let href = assoc_href_attr(meth, link, cx); // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`. let generics_len = format!("{:#}", g.print(cx)).len(); @@ -868,7 +893,7 @@ fn assoc_method( w.reserve(header_len + "<a href=\"\" class=\"fnname\">{".len() + "</a>".len()); write!( w, - "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn <a {href} class=\"fnname\">{name}</a>\ + "{indent}{vis}{constness}{asyncness}{unsafety}{defaultness}{abi}fn <a{href} class=\"fnname\">{name}</a>\ {generics}{decl}{notable_traits}{where_clause}", indent = indent_str, vis = vis, @@ -877,8 +902,7 @@ fn assoc_method( unsafety = unsafety, defaultness = defaultness, abi = abi, - // links without a href are valid - https://www.w3schools.com/tags/att_a_href.asp - href = href.map(|href| format!("href=\"{}\"", href)).unwrap_or_else(|| "".to_string()), + href = href, name = name, generics = g.print(cx), decl = d.full_print(header_len, indent, header.asyncness, cx), @@ -968,23 +992,43 @@ fn render_assoc_item( cx: &Context<'_>, render_mode: RenderMode, ) { - match *item.kind { + match &*item.kind { clean::StrippedItem(..) => {} - clean::TyMethodItem(ref m) => { + clean::TyMethodItem(m) => { assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) } - clean::MethodItem(ref m, _) => { + clean::MethodItem(m, _) => { assoc_method(w, item, &m.generics, &m.decl, link, parent, cx, render_mode) } - clean::AssocConstItem(ref ty, _) => { - assoc_const(w, item, ty, link, if parent == ItemType::Trait { " " } else { "" }, cx) - } - clean::AssocTypeItem(ref generics, ref bounds, ref default) => assoc_type( + kind @ (clean::TyAssocConstItem(ty) | clean::AssocConstItem(ty, _)) => assoc_const( + w, + item, + ty, + match kind { + clean::TyAssocConstItem(_) => None, + clean::AssocConstItem(_, default) => Some(default), + _ => unreachable!(), + }, + link, + if parent == ItemType::Trait { " " } else { "" }, + cx, + ), + clean::TyAssocTypeItem(ref generics, ref bounds) => assoc_type( w, item, generics, bounds, - default.as_ref(), + None, + link, + if parent == ItemType::Trait { 4 } else { 0 }, + cx, + ), + clean::AssocTypeItem(ref ty, ref bounds) => assoc_type( + w, + item, + &ty.generics, + bounds, + Some(ty.item_type.as_ref().unwrap_or(&ty.type_)), link, if parent == ItemType::Trait { 4 } else { 0 }, cx, @@ -1205,7 +1249,7 @@ fn render_deref_methods( .items .iter() .find_map(|item| match *item.kind { - clean::TypedefItem(ref t, true) => Some(match *t { + clean::AssocTypeItem(ref t, _) => Some(match *t { clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), _ => (&t.type_, &t.type_), }), @@ -1291,7 +1335,7 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String { impl_.print(false, cx) ); for it in &impl_.items { - if let clean::TypedefItem(ref tydef, _) = *it.kind { + if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind { out.push_str("<span class=\"where fmt-newline\"> "); let empty_set = FxHashSet::default(); let src_link = @@ -1300,7 +1344,7 @@ fn notable_traits_decl(decl: &clean::FnDecl, cx: &Context<'_>) -> String { &mut out, it, &tydef.generics, - &[], + &[], // intentionally leaving out bounds Some(&tydef.type_), src_link, 0, @@ -1439,7 +1483,7 @@ fn render_impl( if item_type == ItemType::Method { " method-toggle" } else { "" }; write!(w, "<details class=\"rustdoc-toggle{}\" open><summary>", method_toggle_class); } - match *item.kind { + match &*item.kind { clean::MethodItem(..) | clean::TyMethodItem(_) => { // Only render when the method is not static or we allow static methods if render_method_item { @@ -1471,63 +1515,68 @@ fn render_impl( w.write_str("</section>"); } } - clean::TypedefItem(ref tydef, _) => { - let source_id = format!("{}.{}", ItemType::AssocType, name); + kind @ (clean::TyAssocConstItem(ty) | clean::AssocConstItem(ty, _)) => { + let source_id = format!("{}.{}", item_type, name); let id = cx.derive_id(source_id.clone()); write!( w, "<section id=\"{}\" class=\"{}{} has-srclink\">", id, item_type, in_trait_class ); + render_rightside(w, cx, item, containing_item, render_mode); write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id); w.write_str("<h4 class=\"code-header\">"); - assoc_type( + assoc_const( w, item, - &tydef.generics, - &[], - Some(&tydef.type_), + ty, + match kind { + clean::TyAssocConstItem(_) => None, + clean::AssocConstItem(_, default) => Some(default), + _ => unreachable!(), + }, link.anchor(if trait_.is_some() { &source_id } else { &id }), - 0, + "", cx, ); w.write_str("</h4>"); w.write_str("</section>"); } - clean::AssocConstItem(ref ty, _) => { + clean::TyAssocTypeItem(generics, bounds) => { let source_id = format!("{}.{}", item_type, name); let id = cx.derive_id(source_id.clone()); - write!( - w, - "<section id=\"{}\" class=\"{}{} has-srclink\">", - id, item_type, in_trait_class - ); - render_rightside(w, cx, item, containing_item, render_mode); + write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class); write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id); w.write_str("<h4 class=\"code-header\">"); - assoc_const( + assoc_type( w, item, - ty, + generics, + bounds, + None, link.anchor(if trait_.is_some() { &source_id } else { &id }), - "", + 0, cx, ); w.write_str("</h4>"); w.write_str("</section>"); } - clean::AssocTypeItem(ref generics, ref bounds, ref default) => { + clean::AssocTypeItem(tydef, _bounds) => { let source_id = format!("{}.{}", item_type, name); let id = cx.derive_id(source_id.clone()); - write!(w, "<section id=\"{}\" class=\"{}{}\">", id, item_type, in_trait_class,); + write!( + w, + "<section id=\"{}\" class=\"{}{} has-srclink\">", + id, item_type, in_trait_class + ); write!(w, "<a href=\"#{}\" class=\"anchor\"></a>", id); w.write_str("<h4 class=\"code-header\">"); assoc_type( w, item, - generics, - bounds, - default.as_ref(), + &tydef.generics, + &[], // intentionally leaving out bounds + Some(tydef.item_type.as_ref().unwrap_or(&tydef.type_)), link.anchor(if trait_.is_some() { &source_id } else { &id }), 0, cx, @@ -1748,13 +1797,13 @@ pub(crate) fn render_impl_summary( write!(w, "{}", i.inner_impl().print(use_absolute, cx)); if show_def_docs { for it in &i.inner_impl().items { - if let clean::TypedefItem(ref tydef, _) = *it.kind { + if let clean::AssocTypeItem(ref tydef, ref _bounds) = *it.kind { w.write_str("<span class=\"where fmt-newline\"> "); assoc_type( w, it, &tydef.generics, - &[], + &[], // intentionally leaving out bounds Some(&tydef.type_), AssocItemLink::Anchor(None), 0, @@ -1822,7 +1871,7 @@ fn print_sidebar(cx: &Context<'_>, it: &clean::Item, buffer: &mut Buffer) { clean::PrimitiveItem(_) => sidebar_primitive(cx, buffer, it), clean::UnionItem(ref u) => sidebar_union(cx, buffer, it, u), clean::EnumItem(ref e) => sidebar_enum(cx, buffer, it, e), - clean::TypedefItem(_, _) => sidebar_typedef(cx, buffer, it), + clean::TypedefItem(_) => sidebar_typedef(cx, buffer, it), clean::ModuleItem(ref m) => sidebar_module(buffer, &m.items), clean::ForeignTypeItem => sidebar_foreign_type(cx, buffer, it), _ => {} @@ -1917,7 +1966,7 @@ fn get_methods( if !for_deref || should_render_item(item, deref_mut, tcx) { Some(SidebarLink { name, - url: get_next_url(used_links, format!("method.{}", name)), + url: get_next_url(used_links, format!("{}.{}", ItemType::Method, name)), }) } else { None @@ -1937,7 +1986,7 @@ fn get_associated_constants( .filter_map(|item| match item.name { Some(name) if !name.is_empty() && item.is_associated_const() => Some(SidebarLink { name, - url: get_next_url(used_links, format!("associatedconstant.{}", name)), + url: get_next_url(used_links, format!("{}.{}", ItemType::AssocConst, name)), }), _ => None, }) @@ -2106,7 +2155,7 @@ fn sidebar_deref_methods( debug!("found Deref: {:?}", impl_); if let Some((target, real_target)) = impl_.inner_impl().items.iter().find_map(|item| match *item.kind { - clean::TypedefItem(ref t, true) => Some(match *t { + clean::AssocTypeItem(ref t, _) => Some(match *t { clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), _ => (&t.type_, &t.type_), }), @@ -2281,19 +2330,37 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean print_sidebar_section( buf, &t.items, - "associated-types", - "Associated Types", + "required-associated-types", + "Required Associated Types", + |m| m.is_ty_associated_type(), + |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::AssocType), + ); + + print_sidebar_section( + buf, + &t.items, + "provided-associated-types", + "Provided Associated Types", |m| m.is_associated_type(), - |sym| format!("<a href=\"#associatedtype.{0}\">{0}</a>", sym), + |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::AssocType), + ); + + print_sidebar_section( + buf, + &t.items, + "required-associated-consts", + "Required Associated Constants", + |m| m.is_ty_associated_const(), + |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::AssocConst), ); print_sidebar_section( buf, &t.items, - "associated-const", - "Associated Constants", + "provided-associated-consts", + "Provided Associated Constants", |m| m.is_associated_const(), - |sym| format!("<a href=\"#associatedconstant.{0}\">{0}</a>", sym), + |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::AssocConst), ); print_sidebar_section( @@ -2302,7 +2369,7 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean "required-methods", "Required Methods", |m| m.is_ty_method(), - |sym| format!("<a href=\"#tymethod.{0}\">{0}</a>", sym), + |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::TyMethod), ); print_sidebar_section( @@ -2311,7 +2378,7 @@ fn sidebar_trait(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, t: &clean "provided-methods", "Provided Methods", |m| m.is_method(), - |sym| format!("<a href=\"#method.{0}\">{0}</a>", sym), + |sym| format!("<a href=\"#{1}.{0}\">{0}</a>", sym, ItemType::Method), ); let cache = cx.cache(); diff --git a/src/librustdoc/html/render/print_item.rs b/src/librustdoc/html/render/print_item.rs index 99d7475da33..1ed5c662c41 100644 --- a/src/librustdoc/html/render/print_item.rs +++ b/src/librustdoc/html/render/print_item.rs @@ -141,7 +141,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, item_vars.render_into(buf).unwrap(); - match *item.kind { + match &*item.kind { clean::ModuleItem(ref m) => item_module(buf, cx, item, &m.items), clean::FunctionItem(ref f) | clean::ForeignFunctionItem(ref f) => { item_function(buf, cx, item, f) @@ -150,7 +150,7 @@ pub(super) fn print_item(cx: &Context<'_>, item: &clean::Item, buf: &mut Buffer, 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, is_associated) => item_typedef(buf, cx, item, t, is_associated), + clean::TypedefItem(ref t) => item_typedef(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), @@ -507,13 +507,15 @@ fn item_function(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, f: &clean:: fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Trait) { let bounds = bounds(&t.bounds, false, cx); - let types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>(); - let consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>(); - let required = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>(); - let provided = t.items.iter().filter(|m| m.is_method()).collect::<Vec<_>>(); - let count_types = types.len(); - let count_consts = consts.len(); - let count_methods = required.len() + provided.len(); + let required_types = t.items.iter().filter(|m| m.is_ty_associated_type()).collect::<Vec<_>>(); + let provided_types = t.items.iter().filter(|m| m.is_associated_type()).collect::<Vec<_>>(); + let required_consts = t.items.iter().filter(|m| m.is_ty_associated_const()).collect::<Vec<_>>(); + let provided_consts = t.items.iter().filter(|m| m.is_associated_const()).collect::<Vec<_>>(); + let required_methods = t.items.iter().filter(|m| m.is_ty_method()).collect::<Vec<_>>(); + let provided_methods = t.items.iter().filter(|m| m.is_method()).collect::<Vec<_>>(); + let count_types = required_types.len() + provided_types.len(); + let count_consts = required_consts.len() + provided_consts.len(); + let count_methods = required_methods.len() + provided_methods.len(); // Output the trait definition wrap_into_docblock(w, |w| { @@ -554,16 +556,18 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra ), ); } - for t in &types { - render_assoc_item( - w, - t, - AssocItemLink::Anchor(None), - ItemType::Trait, - cx, - RenderMode::Normal, - ); - w.write_str(";\n"); + for types in [&required_types, &provided_types] { + for t in types { + render_assoc_item( + w, + t, + AssocItemLink::Anchor(None), + ItemType::Trait, + cx, + RenderMode::Normal, + ); + w.write_str(";\n"); + } } // If there are too many associated constants, hide everything after them // We also do this if the types + consts is large because otherwise we could @@ -582,28 +586,30 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra ), ); } - if !types.is_empty() && !consts.is_empty() { + if count_types != 0 && (count_consts != 0 || count_methods != 0) { w.write_str("\n"); } - for t in &consts { - render_assoc_item( - w, - t, - AssocItemLink::Anchor(None), - ItemType::Trait, - cx, - RenderMode::Normal, - ); - w.write_str(";\n"); + for consts in [&required_consts, &provided_consts] { + for c in consts { + render_assoc_item( + w, + c, + AssocItemLink::Anchor(None), + ItemType::Trait, + cx, + RenderMode::Normal, + ); + w.write_str(";\n"); + } } if !toggle && should_hide_fields(count_methods) { toggle = true; toggle_open(w, format_args!("{} methods", count_methods)); } - if !consts.is_empty() && !required.is_empty() { + if count_consts != 0 && count_methods != 0 { w.write_str("\n"); } - for (pos, m) in required.iter().enumerate() { + for (pos, m) in required_methods.iter().enumerate() { render_assoc_item( w, m, @@ -614,14 +620,14 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra ); w.write_str(";\n"); - if pos < required.len() - 1 { + if pos < required_methods.len() - 1 { w.write_str("<span class=\"item-spacer\"></span>"); } } - if !required.is_empty() && !provided.is_empty() { + if !required_methods.is_empty() && !provided_methods.is_empty() { w.write_str("\n"); } - for (pos, m) in provided.iter().enumerate() { + for (pos, m) in provided_methods.iter().enumerate() { render_assoc_item( w, m, @@ -640,7 +646,8 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra w.write_str(" { ... }\n"); } } - if pos < provided.len() - 1 { + + if pos < provided_methods.len() - 1 { w.write_str("<span class=\"item-spacer\"></span>"); } } @@ -703,53 +710,77 @@ fn item_trait(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Tra } } - if !types.is_empty() { + if !required_types.is_empty() { write_small_section_header( w, - "associated-types", - "Associated Types", + "required-associated-types", + "Required Associated Types", "<div class=\"methods\">", ); - for t in types { + for t in required_types { + trait_item(w, cx, t, it); + } + w.write_str("</div>"); + } + if !provided_types.is_empty() { + write_small_section_header( + w, + "provided-associated-types", + "Provided Associated Types", + "<div class=\"methods\">", + ); + for t in provided_types { trait_item(w, cx, t, it); } w.write_str("</div>"); } - if !consts.is_empty() { + if !required_consts.is_empty() { + write_small_section_header( + w, + "required-associated-consts", + "Required Associated Constants", + "<div class=\"methods\">", + ); + for t in required_consts { + trait_item(w, cx, t, it); + } + w.write_str("</div>"); + } + if !provided_consts.is_empty() { write_small_section_header( w, - "associated-const", - "Associated Constants", + "provided-associated-consts", + "Provided Associated Constants", "<div class=\"methods\">", ); - for t in consts { + for t in provided_consts { trait_item(w, cx, t, it); } w.write_str("</div>"); } // Output the documentation for each function individually - if !required.is_empty() { + if !required_methods.is_empty() { write_small_section_header( w, "required-methods", - "Required methods", + "Required Methods", "<div class=\"methods\">", ); - for m in required { + for m in required_methods { trait_item(w, cx, m, it); } w.write_str("</div>"); } - if !provided.is_empty() { + if !provided_methods.is_empty() { write_small_section_header( w, "provided-methods", - "Provided methods", + "Provided Methods", "<div class=\"methods\">", ); - for m in provided { + for m in provided_methods { trait_item(w, cx, m, it); } w.write_str("</div>"); @@ -933,25 +964,11 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean: render_assoc_items(w, cx, it, it.def_id.expect_def_id(), AssocItemRender::All) } -fn item_typedef( - w: &mut Buffer, - cx: &Context<'_>, - it: &clean::Item, - t: &clean::Typedef, - is_associated: bool, -) { - fn write_content( - w: &mut Buffer, - cx: &Context<'_>, - it: &clean::Item, - t: &clean::Typedef, - is_associated: bool, - ) { +fn item_typedef(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { + fn write_content(w: &mut Buffer, cx: &Context<'_>, it: &clean::Item, t: &clean::Typedef) { wrap_item(w, "typedef", |w| { render_attributes_in_pre(w, it, ""); - if !is_associated { - write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); - } + write!(w, "{}", it.visibility.print_with_space(it.def_id, cx)); write!( w, "type {}{}{where_clause} = {type_};", @@ -963,14 +980,7 @@ fn item_typedef( }); } - // If this is an associated typedef, we don't want to wrap it into a docblock. - if is_associated { - write_content(w, cx, it, t, is_associated); - } else { - wrap_into_docblock(w, |w| { - write_content(w, cx, it, t, is_associated); - }); - } + wrap_into_docblock(w, |w| write_content(w, cx, it, t)); document(w, cx, it, None, HeadingOffset::H2); diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index b0ce63a4ec1..ab52304491a 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -3,7 +3,7 @@ (function() { // This mapping table should match the discriminants of -// `rustdoc::html::item_type::ItemType` type in Rust. +// `rustdoc::formats::item_type::ItemType` type in Rust. var itemTypes = [ "mod", "externcrate", |
