diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs
index 62def4a94e8..22a6fcd316a 100644
--- a/src/librustdoc/html/render/context.rs
+++ b/src/librustdoc/html/render/context.rs
@@ -17,8 +17,8 @@
use super::search_index::build_index;
use super::write_shared::write_shared;
use super::{
- collect_spans_and_sources, print_sidebar, scrape_examples_help, AllTypes, LinkFromSrc, NameDoc,
- StylePath, BASIC_KEYWORDS,
+ collect_spans_and_sources, print_sidebar, scrape_examples_help, sidebar_module_like, AllTypes,
+ LinkFromSrc, NameDoc, StylePath, BASIC_KEYWORDS,
};
use crate::clean::{self, types::ExternalLocation, ExternalCrate};
@@ -597,16 +597,24 @@ fn after_krate(&mut self) -> Result<(), Error> {
keywords: BASIC_KEYWORDS,
resource_suffix: &shared.resource_suffix,
};
- let sidebar = if shared.cache.crate_version.is_some() {
- format!("
Crate {}
", crate_name)
- } else {
- String::new()
- };
let all = shared.all.replace(AllTypes::new());
+ let mut sidebar = Buffer::html();
+ if shared.cache.crate_version.is_some() {
+ write!(sidebar, "Crate {}
", crate_name)
+ };
+
+ let mut items = Buffer::html();
+ sidebar_module_like(&mut items, all.item_sections());
+ if !items.is_empty() {
+ sidebar.push_str("");
+ }
+
let v = layout::render(
&shared.layout,
&page,
- sidebar,
+ sidebar.into_inner(),
|buf: &mut Buffer| all.print(buf),
&shared.style_files,
);
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index ced0ebdbb86..7e5e4df43d2 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -290,19 +290,66 @@ fn append(&mut self, item_name: String, item_type: &ItemType) {
};
}
}
-}
-impl AllTypes {
+ fn item_sections(&self) -> FxHashSet {
+ let mut sections = FxHashSet::default();
+
+ if !self.structs.is_empty() {
+ sections.insert(ItemSection::Structs);
+ }
+ if !self.enums.is_empty() {
+ sections.insert(ItemSection::Enums);
+ }
+ if !self.unions.is_empty() {
+ sections.insert(ItemSection::Unions);
+ }
+ if !self.primitives.is_empty() {
+ sections.insert(ItemSection::PrimitiveTypes);
+ }
+ if !self.traits.is_empty() {
+ sections.insert(ItemSection::Traits);
+ }
+ if !self.macros.is_empty() {
+ sections.insert(ItemSection::Macros);
+ }
+ if !self.functions.is_empty() {
+ sections.insert(ItemSection::Functions);
+ }
+ if !self.typedefs.is_empty() {
+ sections.insert(ItemSection::TypeDefinitions);
+ }
+ if !self.opaque_tys.is_empty() {
+ sections.insert(ItemSection::OpaqueTypes);
+ }
+ if !self.statics.is_empty() {
+ sections.insert(ItemSection::Statics);
+ }
+ if !self.constants.is_empty() {
+ sections.insert(ItemSection::Constants);
+ }
+ if !self.attributes.is_empty() {
+ sections.insert(ItemSection::AttributeMacros);
+ }
+ if !self.derives.is_empty() {
+ sections.insert(ItemSection::DeriveMacros);
+ }
+ if !self.trait_aliases.is_empty() {
+ sections.insert(ItemSection::TraitAliases);
+ }
+
+ sections
+ }
+
fn print(self, f: &mut Buffer) {
- fn print_entries(f: &mut Buffer, e: &FxHashSet, title: &str) {
+ fn print_entries(f: &mut Buffer, e: &FxHashSet, kind: ItemSection) {
if !e.is_empty() {
let mut e: Vec<&ItemEntry> = e.iter().collect();
e.sort();
write!(
f,
- "{}
",
- title.replace(' ', "-"), // IDs cannot contain whitespaces.
- title
+ "{title}
",
+ id = kind.id(),
+ title = kind.name(),
);
for s in e.iter() {
@@ -320,20 +367,20 @@ fn print_entries(f: &mut Buffer, e: &FxHashSet, title: &str) {
);
// Note: print_entries does not escape the title, because we know the current set of titles
// doesn't require escaping.
- print_entries(f, &self.structs, "Structs");
- print_entries(f, &self.enums, "Enums");
- print_entries(f, &self.unions, "Unions");
- print_entries(f, &self.primitives, "Primitives");
- print_entries(f, &self.traits, "Traits");
- print_entries(f, &self.macros, "Macros");
- print_entries(f, &self.attributes, "Attribute Macros");
- print_entries(f, &self.derives, "Derive Macros");
- print_entries(f, &self.functions, "Functions");
- print_entries(f, &self.typedefs, "Typedefs");
- print_entries(f, &self.trait_aliases, "Trait Aliases");
- print_entries(f, &self.opaque_tys, "Opaque Types");
- print_entries(f, &self.statics, "Statics");
- print_entries(f, &self.constants, "Constants");
+ print_entries(f, &self.structs, ItemSection::Structs);
+ print_entries(f, &self.enums, ItemSection::Enums);
+ print_entries(f, &self.unions, ItemSection::Unions);
+ print_entries(f, &self.primitives, ItemSection::PrimitiveTypes);
+ print_entries(f, &self.traits, ItemSection::Traits);
+ print_entries(f, &self.macros, ItemSection::Macros);
+ print_entries(f, &self.attributes, ItemSection::AttributeMacros);
+ print_entries(f, &self.derives, ItemSection::DeriveMacros);
+ print_entries(f, &self.functions, ItemSection::Functions);
+ print_entries(f, &self.typedefs, ItemSection::TypeDefinitions);
+ print_entries(f, &self.trait_aliases, ItemSection::TraitAliases);
+ print_entries(f, &self.opaque_tys, ItemSection::OpaqueTypes);
+ print_entries(f, &self.statics, ItemSection::Statics);
+ print_entries(f, &self.constants, ItemSection::Constants);
}
}
@@ -2468,7 +2515,7 @@ fn sidebar_enum(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item, e: &clean:
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
-enum ItemSection {
+pub(crate) enum ItemSection {
Reexports,
PrimitiveTypes,
Modules,
@@ -2620,25 +2667,11 @@ fn item_ty_to_section(ty: ItemType) -> ItemSection {
}
}
-fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) {
+pub(crate) fn sidebar_module_like(buf: &mut Buffer, item_sections_in_use: FxHashSet) {
use std::fmt::Write as _;
let mut sidebar = String::new();
- let item_sections_in_use: FxHashSet<_> = items
- .iter()
- .filter(|it| {
- !it.is_stripped()
- && it
- .name
- .or_else(|| {
- if let clean::ImportItem(ref i) = *it.kind &&
- let clean::ImportKind::Simple(s) = i.kind { Some(s) } else { None }
- })
- .is_some()
- })
- .map(|it| item_ty_to_section(it.type_()))
- .collect();
for &sec in ItemSection::ALL.iter().filter(|sec| item_sections_in_use.contains(sec)) {
let _ = write!(sidebar, "- {}
", sec.id(), sec.name());
}
@@ -2656,6 +2689,25 @@ fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) {
}
}
+fn sidebar_module(buf: &mut Buffer, items: &[clean::Item]) {
+ let item_sections_in_use: FxHashSet<_> = items
+ .iter()
+ .filter(|it| {
+ !it.is_stripped()
+ && it
+ .name
+ .or_else(|| {
+ if let clean::ImportItem(ref i) = *it.kind &&
+ let clean::ImportKind::Simple(s) = i.kind { Some(s) } else { None }
+ })
+ .is_some()
+ })
+ .map(|it| item_ty_to_section(it.type_()))
+ .collect();
+
+ sidebar_module_like(buf, item_sections_in_use);
+}
+
fn sidebar_foreign_type(cx: &Context<'_>, buf: &mut Buffer, it: &clean::Item) {
let mut sidebar = Buffer::new();
sidebar_assoc_items(cx, &mut sidebar, it);
diff --git a/src/test/rustdoc/sidebar-all-page.rs b/src/test/rustdoc/sidebar-all-page.rs
new file mode 100644
index 00000000000..e74b981de64
--- /dev/null
+++ b/src/test/rustdoc/sidebar-all-page.rs
@@ -0,0 +1,35 @@
+#![crate_name = "foo"]
+
+#![feature(rustdoc_internals)]
+
+// @has 'foo/all.html'
+// @has - '//*[@class="sidebar-elems"]//li' 'Structs'
+// @has - '//*[@class="sidebar-elems"]//li' 'Enums'
+// @has - '//*[@class="sidebar-elems"]//li' 'Unions'
+// @has - '//*[@class="sidebar-elems"]//li' 'Functions'
+// @has - '//*[@class="sidebar-elems"]//li' 'Traits'
+// @has - '//*[@class="sidebar-elems"]//li' 'Macros'
+// @has - '//*[@class="sidebar-elems"]//li' 'Type Definitions'
+// @has - '//*[@class="sidebar-elems"]//li' 'Constants'
+// @has - '//*[@class="sidebar-elems"]//li' 'Statics'
+// @has - '//*[@class="sidebar-elems"]//li' 'Primitive Types'
+
+pub struct Foo;
+pub enum Enum {
+ A,
+}
+pub union Bar {
+ a: u8,
+ b: u16,
+}
+pub fn foo() {}
+pub trait Trait {}
+#[macro_export]
+macro_rules! foo {
+ () => {}
+}
+pub type Type = u8;
+pub const FOO: u8 = 0;
+pub static BAR: u8 = 0;
+#[doc(primitive = "u8")]
+mod u8 {}