diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs
index 2648641e53e7..2a612fa9b8cd 100644
--- a/src/librustdoc/formats/cache.rs
+++ b/src/librustdoc/formats/cache.rs
@@ -574,20 +574,20 @@ fn add_item_to_search_index(tcx: TyCtxt<'_>, cache: &mut Cache, item: &clean::It
     );
     let aliases = item.attrs.get_doc_aliases();
     let deprecation = item.deprecation(tcx);
-    let index_item = IndexItem {
-        ty: item.type_(),
-        defid: Some(defid),
+    let index_item = IndexItem::new(
+        item.type_(),
+        Some(defid),
         name,
         path,
         desc,
-        parent: parent_did,
-        parent_idx: None,
-        exact_path: None,
+        parent_did,
+        None,
+        None,
         impl_id,
         search_type,
         aliases,
         deprecation,
-    };
+    );
     cache.search_index.push(index_item);
 }
 
diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs
index 2237e0f987bc..b9a2e65b0907 100644
--- a/src/librustdoc/html/render/mod.rs
+++ b/src/librustdoc/html/render/mod.rs
@@ -13,6 +13,9 @@
 //! is cloned per-thread and contains information about what is currently being
 //! rendered.
 //!
+//! The main entry point to the rendering system is the implementation of
+//! `FormatRenderer` on `Context`.
+//!
 //! In order to speed up rendering (mostly because of markdown rendering), the
 //! rendering process has been parallelized. This parallelization is only
 //! exposed through the `crate` method on the context, and then also from the
@@ -90,7 +93,7 @@ pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display {
 /// Specifies whether rendering directly implemented trait items or ones from a certain Deref
 /// impl.
 #[derive(Copy, Clone, Debug)]
-pub(crate) enum AssocItemRender<'a> {
+enum AssocItemRender<'a> {
     All,
     DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
 }
@@ -98,7 +101,7 @@ pub(crate) enum AssocItemRender<'a> {
 /// For different handling of associated items from the Deref target of a type rather than the type
 /// itself.
 #[derive(Copy, Clone, PartialEq)]
-pub(crate) enum RenderMode {
+enum RenderMode {
     Normal,
     ForDeref { mut_: bool },
 }
@@ -110,23 +113,55 @@ pub(crate) enum RenderMode {
 /// by hand to a large JS file at the end of cache-creation.
 #[derive(Debug)]
 pub(crate) struct IndexItem {
-    pub(crate) ty: ItemType,
-    pub(crate) defid: Option<DefId>,
-    pub(crate) name: Symbol,
-    pub(crate) path: String,
-    pub(crate) desc: String,
-    pub(crate) parent: Option<DefId>,
-    pub(crate) parent_idx: Option<isize>,
-    pub(crate) exact_path: Option<String>,
-    pub(crate) impl_id: Option<DefId>,
-    pub(crate) search_type: Option<IndexItemFunctionType>,
-    pub(crate) aliases: Box<[Symbol]>,
-    pub(crate) deprecation: Option<Deprecation>,
+    ty: ItemType,
+    defid: Option<DefId>,
+    name: Symbol,
+    path: String,
+    desc: String,
+    parent: Option<DefId>,
+    parent_idx: Option<isize>,
+    exact_path: Option<String>,
+    impl_id: Option<DefId>,
+    search_type: Option<IndexItemFunctionType>,
+    aliases: Box<[Symbol]>,
+    deprecation: Option<Deprecation>,
+}
+
+impl IndexItem {
+    pub fn new(
+        ty: ItemType,
+        defid: Option<DefId>,
+        name: Symbol,
+        path: String,
+        desc: String,
+        parent: Option<DefId>,
+        parent_idx: Option<isize>,
+        exact_path: Option<String>,
+        impl_id: Option<DefId>,
+        search_type: Option<IndexItemFunctionType>,
+        aliases: Box<[Symbol]>,
+        deprecation: Option<Deprecation>,
+    ) -> Self {
+        Self {
+            ty,
+            defid,
+            name,
+            path,
+            desc,
+            parent,
+            parent_idx,
+            exact_path,
+            impl_id,
+            search_type,
+            aliases,
+            deprecation,
+        }
+    }
 }
 
 /// A type used for the search index.
 #[derive(Debug, Eq, PartialEq)]
-pub(crate) struct RenderType {
+struct RenderType {
     id: Option<RenderTypeId>,
     generics: Option<Vec<RenderType>>,
     bindings: Option<Vec<(RenderTypeId, Vec<RenderType>)>>,
@@ -137,7 +172,7 @@ impl RenderType {
     // The contents of the lists are always integers in self-terminating hex
     // form, handled by `RenderTypeId::write_to_string`, so no commas are
     // needed to separate the items.
-    pub fn write_to_string(&self, string: &mut String) {
+    fn write_to_string(&self, string: &mut String) {
         fn write_optional_id(id: Option<RenderTypeId>, string: &mut String) {
             // 0 is a sentinel, everything else is one-indexed
             match id {
@@ -177,7 +212,7 @@ impl RenderType {
 }
 
 #[derive(Clone, Copy, Debug, Eq, PartialEq)]
-pub(crate) enum RenderTypeId {
+enum RenderTypeId {
     DefId(DefId),
     Primitive(clean::PrimitiveType),
     AssociatedType(Symbol),
@@ -186,7 +221,7 @@ pub(crate) enum RenderTypeId {
 }
 
 impl RenderTypeId {
-    pub fn write_to_string(&self, string: &mut String) {
+    fn write_to_string(&self, string: &mut String) {
         let id: i32 = match &self {
             // 0 is a sentinel, everything else is one-indexed
             // concrete type
@@ -209,7 +244,7 @@ pub(crate) struct IndexItemFunctionType {
 }
 
 impl IndexItemFunctionType {
-    pub fn write_to_string<'a>(
+    fn write_to_string<'a>(
         &'a self,
         string: &mut String,
         backref_queue: &mut VecDeque<&'a IndexItemFunctionType>,
@@ -309,7 +344,7 @@ impl ItemEntry {
 }
 
 impl ItemEntry {
-    pub(crate) fn print(&self) -> impl fmt::Display {
+    fn print(&self) -> impl fmt::Display {
         fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
     }
 }
@@ -760,7 +795,7 @@ fn short_item_info(
 
 // Render the list of items inside one of the sections "Trait Implementations",
 // "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
-pub(crate) fn render_impls(
+fn render_impls(
     cx: &Context<'_>,
     mut w: impl Write,
     impls: &[&Impl],
@@ -1201,7 +1236,7 @@ impl<'a> AssocItemLink<'a> {
     }
 }
 
-pub fn write_section_heading(
+fn write_section_heading(
     title: &str,
     id: &str,
     extra_class: Option<&str>,
@@ -1226,7 +1261,7 @@ fn write_impl_section_heading(title: &str, id: &str) -> impl fmt::Display {
     write_section_heading(title, id, None, "")
 }
 
-pub(crate) fn render_all_impls(
+fn render_all_impls(
     mut w: impl Write,
     cx: &Context<'_>,
     containing_item: &clean::Item,
@@ -1473,10 +1508,7 @@ fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) ->
     }
 }
 
-pub(crate) fn notable_traits_button(
-    ty: &clean::Type,
-    cx: &Context<'_>,
-) -> Option<impl fmt::Display> {
+fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<impl fmt::Display> {
     if ty.is_unit() {
         // Very common fast path.
         return None;
@@ -1588,10 +1620,7 @@ fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
     (format!("{:#}", ty.print(cx)), out)
 }
 
-pub(crate) fn notable_traits_json<'a>(
-    tys: impl Iterator<Item = &'a clean::Type>,
-    cx: &Context<'_>,
-) -> String {
+fn notable_traits_json<'a>(tys: impl Iterator<Item = &'a clean::Type>, cx: &Context<'_>) -> String {
     let mut mp: Vec<(String, String)> = tys.map(|ty| notable_traits_decl(ty, cx)).collect();
     mp.sort_by(|(name1, _html1), (name2, _html2)| name1.cmp(name2));
     struct NotableTraitsMap(Vec<(String, String)>);
@@ -2171,7 +2200,7 @@ fn render_rightside(
     })
 }
 
-pub(crate) fn render_impl_summary(
+fn render_impl_summary(
     cx: &Context<'_>,
     i: &Impl,
     parent: &clean::Item,