//! Rustdoc's HTML rendering module.
//!
//! This modules contains the bulk of the logic necessary for rendering a
//! rustdoc `clean::Crate` instance to a set of static HTML pages. This
//! rendering process is largely driven by the `format!` syntax extension to
//! perform all I/O into files and streams.
//!
//! The rendering process is largely driven by the `Context` and `Cache`
//! structures. The cache is pre-populated by crawling the crate in question,
//! and then it is shared among the various rendering threads. The cache is meant
//! to be a fairly large structure not implementing `Clone` (because it's shared
//! among threads). The context, however, should be a lightweight structure. This
//! 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
//! fact that the shared cache is stored in TLS (and must be accessed as such).
//!
//! In addition to rendering the crate itself, this module is also responsible
//! for creating the corresponding search index and source file renderings.
//! These threads are not parallelized (they haven't been a bottleneck yet), and
//! both occur before the crate is rendered.

pub(crate) mod search_index;

#[cfg(test)]
mod tests;

mod context;
mod ordered_json;
mod print_item;
pub(crate) mod sidebar;
mod sorted_template;
pub(crate) mod span_map;
mod type_layout;
mod write_shared;

use std::borrow::Cow;
use std::collections::VecDeque;
use std::fmt::{self, Display as _, Write};
use std::iter::Peekable;
use std::path::PathBuf;
use std::{fs, str};

use askama::Template;
use indexmap::IndexMap;
use itertools::Either;
use rustc_ast::join_path_syms;
use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
use rustc_hir as hir;
use rustc_hir::attrs::{AttributeKind, DeprecatedSince, Deprecation};
use rustc_hir::def::DefKind;
use rustc_hir::def_id::{DefId, DefIdSet};
use rustc_hir::{ConstStability, Mutability, RustcVersion, StabilityLevel, StableSince};
use rustc_middle::ty::print::PrintTraitRefExt;
use rustc_middle::ty::{self, TyCtxt};
use rustc_span::DUMMY_SP;
use rustc_span::symbol::{Symbol, sym};
use tracing::{debug, info};

pub(crate) use self::context::*;
pub(crate) use self::span_map::{LinkFromSrc, collect_spans_and_sources};
pub(crate) use self::write_shared::*;
use crate::clean::{self, Defaultness, Item, ItemId, RenderedLink};
use crate::display::{Joined as _, MaybeDisplay as _};
use crate::error::Error;
use crate::formats::Impl;
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::html::escape::Escape;
use crate::html::format::{
    Ending, HrefError, HrefInfo, PrintWithSpace, full_print_fn_decl, href, print_abi_with_space,
    print_constness_with_space, print_generic_bounds, print_generics, print_impl, print_path,
    print_type, print_where_clause, visibility_print_with_space,
};
use crate::html::markdown::{
    HeadingOffset, IdMap, Markdown, MarkdownItemInfo, MarkdownSummaryLine, short_markdown_summary,
};
use crate::html::render::search_index::get_function_type_for_search;
use crate::html::static_files::SCRAPE_EXAMPLES_HELP_MD;
use crate::html::{highlight, sources};
use crate::scrape_examples::{CallData, CallLocation};
use crate::{DOC_RUST_LANG_ORG_VERSION, try_none};

pub(crate) fn ensure_trailing_slash(v: &str) -> impl fmt::Display {
    fmt::from_fn(move |f| {
        if !v.ends_with('/') && !v.is_empty() { write!(f, "{v}/") } else { f.write_str(v) }
    })
}

/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
/// impl.
#[derive(Copy, Clone, Debug)]
enum AssocItemRender<'a> {
    All,
    DerefFor { trait_: &'a clean::Path, type_: &'a clean::Type, deref_mut_: bool },
}

impl AssocItemRender<'_> {
    fn render_mode(&self) -> RenderMode {
        match self {
            Self::All => RenderMode::Normal,
            &Self::DerefFor { deref_mut_, .. } => RenderMode::ForDeref { mut_: deref_mut_ },
        }
    }

    fn class(&self) -> Option<&'static str> {
        if let Self::DerefFor { .. } = self { Some("impl-items") } else { None }
    }
}

/// For different handling of associated items from the Deref target of a type rather than the type
/// itself.
#[derive(Copy, Clone, PartialEq)]
enum RenderMode {
    Normal,
    ForDeref { mut_: bool },
}

// Helper structs for rendering items/sidebars and carrying along contextual
// information

#[derive(Debug)]
pub(crate) struct IndexItemInfo {
    pub(crate) ty: ItemType,
    pub(crate) desc: String,
    pub(crate) search_type: Option<IndexItemFunctionType>,
    pub(crate) aliases: Box<[Symbol]>,
    pub(crate) deprecation: Option<Deprecation>,
    pub(crate) is_unstable: bool,
}

impl IndexItemInfo {
    pub(crate) fn new(
        tcx: TyCtxt<'_>,
        cache: &Cache,
        item: &Item,
        parent_did: Option<DefId>,
        impl_generics: Option<&(clean::Type, clean::Generics)>,
    ) -> Self {
        let ty = item.type_();
        let desc = short_markdown_summary(&item.doc_value(), &item.link_names(cache));
        let search_type = get_function_type_for_search(item, tcx, impl_generics, parent_did, cache);
        let aliases = item.attrs.get_doc_aliases();
        let deprecation = item.deprecation(tcx);
        let is_unstable = item.is_unstable();
        Self { ty, desc, search_type, aliases, deprecation, is_unstable }
    }
}

/// Struct representing one entry in the JS search index. These are all emitted
/// by hand to a large JS file at the end of cache-creation.
#[derive(Debug)]
pub(crate) struct IndexItem {
    pub(crate) defid: Option<DefId>,
    pub(crate) name: Symbol,
    pub(crate) module_path: Vec<Symbol>,
    pub(crate) parent: Option<DefId>,
    pub(crate) parent_idx: Option<usize>,
    pub(crate) trait_parent: Option<DefId>,
    pub(crate) trait_parent_idx: Option<usize>,
    pub(crate) exact_module_path: Option<Vec<Symbol>>,
    pub(crate) impl_id: Option<DefId>,
    pub(crate) info: IndexItemInfo,
}

/// A type used for the search index.
#[derive(Clone, Debug, Eq, PartialEq)]
struct RenderType {
    id: Option<RenderTypeId>,
    generics: Option<Vec<RenderType>>,
    bindings: Option<Vec<(RenderTypeId, Vec<RenderType>)>>,
}

impl RenderType {
    fn size(&self) -> usize {
        let mut size = 1;
        if let Some(generics) = &self.generics {
            size += generics.iter().map(RenderType::size).sum::<usize>();
        }
        if let Some(bindings) = &self.bindings {
            for (_, constraints) in bindings.iter() {
                size += 1;
                size += constraints.iter().map(RenderType::size).sum::<usize>();
            }
        }
        size
    }
    // Types are rendered as lists of lists, because that's pretty compact.
    // 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.
    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 {
                Some(id) => id.write_to_string(string),
                None => string.push('`'),
            }
        }
        // Either just the type id, or `{type, generics, bindings?}`
        // where generics is a list of types,
        // and bindings is a list of `{id, typelist}` pairs.
        if self.generics.is_some() || self.bindings.is_some() {
            string.push('{');
            write_optional_id(self.id, string);
            string.push('{');
            for generic in self.generics.as_deref().unwrap_or_default() {
                generic.write_to_string(string);
            }
            string.push('}');
            if self.bindings.is_some() {
                string.push('{');
                for binding in self.bindings.as_deref().unwrap_or_default() {
                    string.push('{');
                    binding.0.write_to_string(string);
                    string.push('{');
                    for constraint in &binding.1[..] {
                        constraint.write_to_string(string);
                    }
                    string.push_str("}}");
                }
                string.push('}');
            }
            string.push('}');
        } else {
            write_optional_id(self.id, string);
        }
    }
    fn read_from_bytes(string: &[u8]) -> (RenderType, usize) {
        let mut i = 0;
        if string[i] == b'{' {
            i += 1;
            let (id, offset) = RenderTypeId::read_from_bytes(&string[i..]);
            i += offset;
            let generics = if string[i] == b'{' {
                i += 1;
                let mut generics = Vec::new();
                while string[i] != b'}' {
                    let (ty, offset) = RenderType::read_from_bytes(&string[i..]);
                    i += offset;
                    generics.push(ty);
                }
                assert!(string[i] == b'}');
                i += 1;
                Some(generics)
            } else {
                None
            };
            let bindings = if string[i] == b'{' {
                i += 1;
                let mut bindings = Vec::new();
                while string[i] == b'{' {
                    i += 1;
                    let (binding, boffset) = RenderTypeId::read_from_bytes(&string[i..]);
                    i += boffset;
                    let mut bconstraints = Vec::new();
                    assert!(string[i] == b'{');
                    i += 1;
                    while string[i] != b'}' {
                        let (constraint, coffset) = RenderType::read_from_bytes(&string[i..]);
                        i += coffset;
                        bconstraints.push(constraint);
                    }
                    assert!(string[i] == b'}');
                    i += 1;
                    bindings.push((binding.unwrap(), bconstraints));
                    assert!(string[i] == b'}');
                    i += 1;
                }
                assert!(string[i] == b'}');
                i += 1;
                Some(bindings)
            } else {
                None
            };
            assert!(string[i] == b'}');
            i += 1;
            (RenderType { id, generics, bindings }, i)
        } else {
            let (id, offset) = RenderTypeId::read_from_bytes(string);
            i += offset;
            (RenderType { id, generics: None, bindings: None }, i)
        }
    }
}

#[derive(Clone, Copy, Debug, Eq, PartialEq)]
enum RenderTypeId {
    DefId(DefId),
    Primitive(clean::PrimitiveType),
    AssociatedType(Symbol),
    Index(isize),
    Mut,
}

impl RenderTypeId {
    fn write_to_string(&self, string: &mut String) {
        let id: i32 = match &self {
            // 0 is a sentinel, everything else is one-indexed
            // concrete type
            RenderTypeId::Index(idx) if *idx >= 0 => (idx + 1isize).try_into().unwrap(),
            // generic type parameter
            RenderTypeId::Index(idx) => (*idx).try_into().unwrap(),
            _ => panic!("must convert render types to indexes before serializing"),
        };
        search_index::encode::write_signed_vlqhex_to_string(id, string);
    }
    fn read_from_bytes(string: &[u8]) -> (Option<RenderTypeId>, usize) {
        let Some((value, offset)) = search_index::encode::read_signed_vlqhex_from_string(string)
        else {
            return (None, 0);
        };
        let value = isize::try_from(value).unwrap();
        let ty = match value {
            ..0 => Some(RenderTypeId::Index(value)),
            0 => None,
            1.. => Some(RenderTypeId::Index(value - 1)),
        };
        (ty, offset)
    }
}

/// Full type of functions/methods in the search index.
#[derive(Clone, Debug, Eq, PartialEq)]
pub(crate) struct IndexItemFunctionType {
    inputs: Vec<RenderType>,
    output: Vec<RenderType>,
    where_clause: Vec<Vec<RenderType>>,
    param_names: Vec<Option<Symbol>>,
}

impl IndexItemFunctionType {
    fn size(&self) -> usize {
        self.inputs.iter().map(RenderType::size).sum::<usize>()
            + self.output.iter().map(RenderType::size).sum::<usize>()
            + self
                .where_clause
                .iter()
                .map(|constraints| constraints.iter().map(RenderType::size).sum::<usize>())
                .sum::<usize>()
    }
    fn read_from_string_without_param_names(string: &[u8]) -> (IndexItemFunctionType, usize) {
        let mut i = 0;
        if string[i] == b'`' {
            return (
                IndexItemFunctionType {
                    inputs: Vec::new(),
                    output: Vec::new(),
                    where_clause: Vec::new(),
                    param_names: Vec::new(),
                },
                1,
            );
        }
        assert_eq!(b'{', string[i]);
        i += 1;
        fn read_args_from_string(string: &[u8]) -> (Vec<RenderType>, usize) {
            let mut i = 0;
            let mut params = Vec::new();
            if string[i] == b'{' {
                // multiple params
                i += 1;
                while string[i] != b'}' {
                    let (ty, offset) = RenderType::read_from_bytes(&string[i..]);
                    i += offset;
                    params.push(ty);
                }
                i += 1;
            } else if string[i] != b'}' {
                let (tyid, offset) = RenderTypeId::read_from_bytes(&string[i..]);
                params.push(RenderType { id: tyid, generics: None, bindings: None });
                i += offset;
            }
            (params, i)
        }
        let (inputs, offset) = read_args_from_string(&string[i..]);
        i += offset;
        let (output, offset) = read_args_from_string(&string[i..]);
        i += offset;
        let mut where_clause = Vec::new();
        while string[i] != b'}' {
            let (constraint, offset) = read_args_from_string(&string[i..]);
            i += offset;
            where_clause.push(constraint);
        }
        assert_eq!(b'}', string[i], "{} {}", String::from_utf8_lossy(&string), i);
        i += 1;
        (IndexItemFunctionType { inputs, output, where_clause, param_names: Vec::new() }, i)
    }
    fn write_to_string_without_param_names<'a>(&'a self, string: &mut String) {
        // If we couldn't figure out a type, just write 0,
        // which is encoded as `` ` `` (see RenderTypeId::write_to_string).
        let has_missing = self
            .inputs
            .iter()
            .chain(self.output.iter())
            .any(|i| i.id.is_none() && i.generics.is_none());
        if has_missing {
            string.push('`');
        } else {
            string.push('{');
            match &self.inputs[..] {
                [one] if one.generics.is_none() && one.bindings.is_none() => {
                    one.write_to_string(string);
                }
                _ => {
                    string.push('{');
                    for item in &self.inputs[..] {
                        item.write_to_string(string);
                    }
                    string.push('}');
                }
            }
            match &self.output[..] {
                [] if self.where_clause.is_empty() => {}
                [one] if one.generics.is_none() && one.bindings.is_none() => {
                    one.write_to_string(string);
                }
                _ => {
                    string.push('{');
                    for item in &self.output[..] {
                        item.write_to_string(string);
                    }
                    string.push('}');
                }
            }
            for constraint in &self.where_clause {
                if let [one] = &constraint[..]
                    && one.generics.is_none()
                    && one.bindings.is_none()
                {
                    one.write_to_string(string);
                } else {
                    string.push('{');
                    for item in &constraint[..] {
                        item.write_to_string(string);
                    }
                    string.push('}');
                }
            }
            string.push('}');
        }
    }
}

#[derive(Debug, Clone)]
pub(crate) struct StylePath {
    /// The path to the theme
    pub(crate) path: PathBuf,
}

impl StylePath {
    pub(crate) fn basename(&self) -> Result<String, Error> {
        Ok(try_none!(try_none!(self.path.file_stem(), &self.path).to_str(), &self.path).to_string())
    }
}

#[derive(Debug, Eq, PartialEq, Hash)]
struct ItemEntry {
    url: String,
    name: String,
}

impl ItemEntry {
    fn new(mut url: String, name: String) -> ItemEntry {
        while url.starts_with('/') {
            url.remove(0);
        }
        ItemEntry { url, name }
    }
}

impl ItemEntry {
    fn print(&self) -> impl fmt::Display {
        fmt::from_fn(move |f| write!(f, "<a href=\"{}\">{}</a>", self.url, Escape(&self.name)))
    }
}

impl PartialOrd for ItemEntry {
    fn partial_cmp(&self, other: &ItemEntry) -> Option<::std::cmp::Ordering> {
        Some(self.cmp(other))
    }
}

impl Ord for ItemEntry {
    fn cmp(&self, other: &ItemEntry) -> ::std::cmp::Ordering {
        self.name.cmp(&other.name)
    }
}

#[derive(Debug)]
struct AllTypes {
    structs: FxIndexSet<ItemEntry>,
    enums: FxIndexSet<ItemEntry>,
    unions: FxIndexSet<ItemEntry>,
    primitives: FxIndexSet<ItemEntry>,
    traits: FxIndexSet<ItemEntry>,
    macros: FxIndexSet<ItemEntry>,
    functions: FxIndexSet<ItemEntry>,
    type_aliases: FxIndexSet<ItemEntry>,
    statics: FxIndexSet<ItemEntry>,
    constants: FxIndexSet<ItemEntry>,
    attribute_macros: FxIndexSet<ItemEntry>,
    derive_macros: FxIndexSet<ItemEntry>,
    trait_aliases: FxIndexSet<ItemEntry>,
}

impl AllTypes {
    fn new() -> AllTypes {
        let new_set = |cap| FxIndexSet::with_capacity_and_hasher(cap, Default::default());
        AllTypes {
            structs: new_set(100),
            enums: new_set(100),
            unions: new_set(100),
            primitives: new_set(26),
            traits: new_set(100),
            macros: new_set(100),
            functions: new_set(100),
            type_aliases: new_set(100),
            statics: new_set(100),
            constants: new_set(100),
            attribute_macros: new_set(100),
            derive_macros: new_set(100),
            trait_aliases: new_set(100),
        }
    }

    fn append(&mut self, item_name: String, item_type: &ItemType) {
        let mut url: Vec<_> = item_name.split("::").skip(1).collect();
        if let Some(name) = url.pop() {
            let new_url = format!("{}/{item_type}.{name}.html", url.join("/"));
            url.push(name);
            let name = url.join("::");
            match *item_type {
                ItemType::Struct => self.structs.insert(ItemEntry::new(new_url, name)),
                ItemType::Enum => self.enums.insert(ItemEntry::new(new_url, name)),
                ItemType::Union => self.unions.insert(ItemEntry::new(new_url, name)),
                ItemType::Primitive => self.primitives.insert(ItemEntry::new(new_url, name)),
                ItemType::Trait => self.traits.insert(ItemEntry::new(new_url, name)),
                ItemType::Macro => self.macros.insert(ItemEntry::new(new_url, name)),
                ItemType::Function => self.functions.insert(ItemEntry::new(new_url, name)),
                ItemType::TypeAlias => self.type_aliases.insert(ItemEntry::new(new_url, name)),
                ItemType::Static => self.statics.insert(ItemEntry::new(new_url, name)),
                ItemType::Constant => self.constants.insert(ItemEntry::new(new_url, name)),
                ItemType::ProcAttribute => {
                    self.attribute_macros.insert(ItemEntry::new(new_url, name))
                }
                ItemType::ProcDerive => self.derive_macros.insert(ItemEntry::new(new_url, name)),
                ItemType::TraitAlias => self.trait_aliases.insert(ItemEntry::new(new_url, name)),
                _ => true,
            };
        }
    }

    fn item_sections(&self) -> FxHashSet<ItemSection> {
        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.type_aliases.is_empty() {
            sections.insert(ItemSection::TypeAliases);
        }
        if !self.statics.is_empty() {
            sections.insert(ItemSection::Statics);
        }
        if !self.constants.is_empty() {
            sections.insert(ItemSection::Constants);
        }
        if !self.attribute_macros.is_empty() {
            sections.insert(ItemSection::AttributeMacros);
        }
        if !self.derive_macros.is_empty() {
            sections.insert(ItemSection::DeriveMacros);
        }
        if !self.trait_aliases.is_empty() {
            sections.insert(ItemSection::TraitAliases);
        }

        sections
    }

    fn print(&self) -> impl fmt::Display {
        fn print_entries(e: &FxIndexSet<ItemEntry>, kind: ItemSection) -> impl fmt::Display {
            fmt::from_fn(move |f| {
                if e.is_empty() {
                    return Ok(());
                }

                let mut e: Vec<&ItemEntry> = e.iter().collect();
                e.sort();
                write!(
                    f,
                    "<h3 id=\"{id}\">{title}</h3><ul class=\"all-items\">",
                    id = kind.id(),
                    title = kind.name(),
                )?;

                for s in e.iter() {
                    write!(f, "<li>{}</li>", s.print())?;
                }

                f.write_str("</ul>")
            })
        }

        fmt::from_fn(|f| {
            f.write_str(
                "<div class=\"main-heading\">\
                    <h1>List of all items</h1>\
                    <rustdoc-toolbar></rustdoc-toolbar>\
                </div>",
            )?;
            // Note: print_entries does not escape the title, because we know the current set of titles
            // doesn't require escaping.
            print_entries(&self.structs, ItemSection::Structs).fmt(f)?;
            print_entries(&self.enums, ItemSection::Enums).fmt(f)?;
            print_entries(&self.unions, ItemSection::Unions).fmt(f)?;
            print_entries(&self.primitives, ItemSection::PrimitiveTypes).fmt(f)?;
            print_entries(&self.traits, ItemSection::Traits).fmt(f)?;
            print_entries(&self.macros, ItemSection::Macros).fmt(f)?;
            print_entries(&self.attribute_macros, ItemSection::AttributeMacros).fmt(f)?;
            print_entries(&self.derive_macros, ItemSection::DeriveMacros).fmt(f)?;
            print_entries(&self.functions, ItemSection::Functions).fmt(f)?;
            print_entries(&self.type_aliases, ItemSection::TypeAliases).fmt(f)?;
            print_entries(&self.trait_aliases, ItemSection::TraitAliases).fmt(f)?;
            print_entries(&self.statics, ItemSection::Statics).fmt(f)?;
            print_entries(&self.constants, ItemSection::Constants).fmt(f)?;
            Ok(())
        })
    }
}

fn scrape_examples_help(shared: &SharedContext<'_>) -> String {
    let mut content = SCRAPE_EXAMPLES_HELP_MD.to_owned();
    content.push_str(&format!(
        "## More information\n\n\
      If you want more information about this feature, please read the [corresponding chapter in \
      the Rustdoc book]({DOC_RUST_LANG_ORG_VERSION}/rustdoc/scraped-examples.html)."
    ));

    format!(
        "<div class=\"main-heading\">\
             <h1>About scraped examples</h1>\
         </div>\
         <div>{}</div>",
        fmt::from_fn(|f| Markdown {
            content: &content,
            links: &[],
            ids: &mut IdMap::default(),
            error_codes: shared.codes,
            edition: shared.edition(),
            playground: &shared.playground,
            heading_offset: HeadingOffset::H1,
        }
        .write_into(f))
    )
}

fn document(
    cx: &Context<'_>,
    item: &clean::Item,
    parent: Option<&clean::Item>,
    heading_offset: HeadingOffset,
) -> impl fmt::Display {
    if let Some(ref name) = item.name {
        info!("Documenting {name}");
    }

    fmt::from_fn(move |f| {
        document_item_info(cx, item, parent).render_into(f)?;
        if parent.is_none() {
            write!(f, "{}", document_full_collapsible(item, cx, heading_offset))
        } else {
            write!(f, "{}", document_full(item, cx, heading_offset))
        }
    })
}

/// Render md_text as markdown.
fn render_markdown(
    cx: &Context<'_>,
    md_text: &str,
    links: Vec<RenderedLink>,
    heading_offset: HeadingOffset,
) -> impl fmt::Display {
    fmt::from_fn(move |f| {
        f.write_str("<div class=\"docblock\">")?;
        Markdown {
            content: md_text,
            links: &links,
            ids: &mut cx.id_map.borrow_mut(),
            error_codes: cx.shared.codes,
            edition: cx.shared.edition(),
            playground: &cx.shared.playground,
            heading_offset,
        }
        .write_into(&mut *f)?;
        f.write_str("</div>")
    })
}

/// Writes a documentation block containing only the first paragraph of the documentation. If the
/// docs are longer, a "Read more" link is appended to the end.
fn document_short(
    item: &clean::Item,
    cx: &Context<'_>,
    link: AssocItemLink<'_>,
    parent: &clean::Item,
    show_def_docs: bool,
) -> impl fmt::Display {
    fmt::from_fn(move |f| {
        document_item_info(cx, item, Some(parent)).render_into(f)?;
        if !show_def_docs {
            return Ok(());
        }
        let s = item.doc_value();
        if !s.is_empty() {
            let (mut summary_html, has_more_content) =
                MarkdownSummaryLine(&s, &item.links(cx)).into_string_with_has_more_content();

            let link = if has_more_content {
                let link = fmt::from_fn(|f| {
                    write!(
                        f,
                        " <a{}>Read more</a>",
                        assoc_href_attr(item, link, cx).maybe_display()
                    )
                });

                if let Some(idx) = summary_html.rfind("</p>") {
                    summary_html.insert_str(idx, &link.to_string());
                    None
                } else {
                    Some(link)
                }
            } else {
                None
            }
            .maybe_display();

            write!(f, "<div class='docblock'>{summary_html}{link}</div>")?;
        }
        Ok(())
    })
}

fn document_full_collapsible(
    item: &clean::Item,
    cx: &Context<'_>,
    heading_offset: HeadingOffset,
) -> impl fmt::Display {
    document_full_inner(item, cx, true, heading_offset)
}

fn document_full(
    item: &clean::Item,
    cx: &Context<'_>,
    heading_offset: HeadingOffset,
) -> impl fmt::Display {
    document_full_inner(item, cx, false, heading_offset)
}

fn document_full_inner(
    item: &clean::Item,
    cx: &Context<'_>,
    is_collapsible: bool,
    heading_offset: HeadingOffset,
) -> impl fmt::Display {
    fmt::from_fn(move |f| {
        if let Some(s) = item.opt_doc_value() {
            debug!("Doc block: =====\n{s}\n=====");
            if is_collapsible {
                write!(
                    f,
                    "<details class=\"toggle top-doc\" open>\
                     <summary class=\"hideme\">\
                        <span>Expand description</span>\
                     </summary>{}</details>",
                    render_markdown(cx, &s, item.links(cx), heading_offset)
                )?;
            } else {
                write!(f, "{}", render_markdown(cx, &s, item.links(cx), heading_offset))?;
            }
        }

        let kind = match &item.kind {
            clean::ItemKind::StrippedItem(kind) => kind,
            kind => kind,
        };

        if let clean::ItemKind::FunctionItem(..) | clean::ItemKind::MethodItem(..) = kind {
            render_call_locations(f, cx, item)?;
        }
        Ok(())
    })
}

#[derive(Template)]
#[template(path = "item_info.html")]
struct ItemInfo {
    items: Vec<ShortItemInfo>,
}
/// Add extra information about an item such as:
///
/// * Stability
/// * Deprecated
/// * Required features (through the `doc_cfg` feature)
fn document_item_info(
    cx: &Context<'_>,
    item: &clean::Item,
    parent: Option<&clean::Item>,
) -> ItemInfo {
    let items = short_item_info(item, cx, parent);
    ItemInfo { items }
}

fn portability(item: &clean::Item, parent: Option<&clean::Item>) -> Option<String> {
    let cfg = match (&item.cfg, parent.and_then(|p| p.cfg.as_ref())) {
        (Some(cfg), Some(parent_cfg)) => cfg.simplify_with(parent_cfg),
        (cfg, _) => cfg.as_deref().cloned(),
    };

    debug!(
        "Portability {name:?} {item_cfg:?} (parent: {parent:?}) - {parent_cfg:?} = {cfg:?}",
        name = item.name,
        item_cfg = item.cfg,
        parent_cfg = parent.and_then(|p| p.cfg.as_ref()),
    );

    Some(cfg?.render_long_html())
}

#[derive(Template)]
#[template(path = "short_item_info.html")]
enum ShortItemInfo {
    /// A message describing the deprecation of this item
    Deprecation {
        message: String,
    },
    /// The feature corresponding to an unstable item, and optionally
    /// a tracking issue URL and number.
    Unstable {
        feature: String,
        tracking: Option<(String, u32)>,
    },
    Portability {
        message: String,
    },
}

/// Render the stability, deprecation and portability information that is displayed at the top of
/// the item's documentation.
fn short_item_info(
    item: &clean::Item,
    cx: &Context<'_>,
    parent: Option<&clean::Item>,
) -> Vec<ShortItemInfo> {
    let mut extra_info = vec![];

    if let Some(depr @ Deprecation { note, since, suggestion: _ }) = item.deprecation(cx.tcx()) {
        // We display deprecation messages for #[deprecated], but only display
        // the future-deprecation messages for rustc versions.
        let mut message = match since {
            DeprecatedSince::RustcVersion(version) => {
                if depr.is_in_effect() {
                    format!("Deprecated since {version}")
                } else {
                    format!("Deprecating in {version}")
                }
            }
            DeprecatedSince::Future => String::from("Deprecating in a future version"),
            DeprecatedSince::NonStandard(since) => {
                format!("Deprecated since {}", Escape(since.as_str()))
            }
            DeprecatedSince::Unspecified | DeprecatedSince::Err => String::from("Deprecated"),
        };

        if let Some(note) = note {
            let note = note.as_str();
            let mut id_map = cx.id_map.borrow_mut();
            let links = item.links(cx);
            let html = MarkdownItemInfo::new(note, &links, &mut id_map);
            message.push_str(": ");
            html.write_into(&mut message).unwrap();
        }
        extra_info.push(ShortItemInfo::Deprecation { message });
    }

    // Render unstable items. But don't render "rustc_private" crates (internal compiler crates).
    // Those crates are permanently unstable so it makes no sense to render "unstable" everywhere.
    if let Some((StabilityLevel::Unstable { reason: _, issue, .. }, feature)) = item
        .stability(cx.tcx())
        .as_ref()
        .filter(|stab| stab.feature != sym::rustc_private)
        .map(|stab| (stab.level, stab.feature))
    {
        let tracking = if let (Some(url), Some(issue)) = (&cx.shared.issue_tracker_base_url, issue)
        {
            Some((url.clone(), issue.get()))
        } else {
            None
        };
        extra_info.push(ShortItemInfo::Unstable { feature: feature.to_string(), tracking });
    }

    if let Some(message) = portability(item, parent) {
        extra_info.push(ShortItemInfo::Portability { message });
    }

    extra_info
}

// Render the list of items inside one of the sections "Trait Implementations",
// "Auto Trait Implementations," "Blanket Trait Implementations" (on struct/enum pages).
fn render_impls(
    cx: &Context<'_>,
    mut w: impl Write,
    impls: &[&Impl],
    containing_item: &clean::Item,
    toggle_open_by_default: bool,
) -> fmt::Result {
    let mut rendered_impls = impls
        .iter()
        .map(|i| {
            let did = i.trait_did().unwrap();
            let provided_trait_methods = i.inner_impl().provided_trait_methods(cx.tcx());
            let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_trait_methods);
            let imp = render_impl(
                cx,
                i,
                containing_item,
                assoc_link,
                RenderMode::Normal,
                None,
                &[],
                ImplRenderingParameters {
                    show_def_docs: true,
                    show_default_items: true,
                    show_non_assoc_items: true,
                    toggle_open_by_default,
                },
            );
            imp.to_string()
        })
        .collect::<Vec<_>>();
    rendered_impls.sort();
    w.write_str(&rendered_impls.join(""))
}

/// 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<'_>,
) -> Option<impl fmt::Display> {
    let name = it.name.unwrap();
    let item_type = it.type_();

    enum Href<'a> {
        AnchorId(&'a str),
        Anchor(ItemType),
        Url(String, ItemType),
    }

    let href = match link {
        AssocItemLink::Anchor(Some(id)) => Href::AnchorId(id),
        AssocItemLink::Anchor(None) => Href::Anchor(item_type),
        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,
            };

            match href(did.expect_def_id(), cx) {
                Ok(HrefInfo { url, .. }) => Href::Url(url, item_type),
                // 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) => return None,
                Err(_) => Href::Anchor(item_type),
            }
        }
    };

    let href = fmt::from_fn(move |f| match &href {
        Href::AnchorId(id) => write!(f, "#{id}"),
        Href::Url(url, item_type) => {
            write!(f, "{url}#{item_type}.{name}")
        }
        Href::Anchor(item_type) => {
            write!(f, "#{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
    Some(fmt::from_fn(move |f| write!(f, " href=\"{href}\"")))
}

#[derive(Debug)]
enum AssocConstValue<'a> {
    // In trait definitions, it is relevant for the public API whether an
    // associated constant comes with a default value, so even if we cannot
    // render its value, the presence of a value must be shown using `= _`.
    TraitDefault(&'a clean::ConstantKind),
    // In impls, there is no need to show `= _`.
    Impl(&'a clean::ConstantKind),
    None,
}

fn assoc_const(
    it: &clean::Item,
    generics: &clean::Generics,
    ty: &clean::Type,
    value: AssocConstValue<'_>,
    link: AssocItemLink<'_>,
    indent: usize,
    cx: &Context<'_>,
) -> impl fmt::Display {
    let tcx = cx.tcx();
    fmt::from_fn(move |w| {
        render_attributes_in_code(w, it, &" ".repeat(indent), cx)?;
        write!(
            w,
            "{indent}{vis}const <a{href} class=\"constant\">{name}</a>{generics}: {ty}",
            indent = " ".repeat(indent),
            vis = visibility_print_with_space(it, cx),
            href = assoc_href_attr(it, link, cx).maybe_display(),
            name = it.name.as_ref().unwrap(),
            generics = print_generics(generics, cx),
            ty = print_type(ty, cx),
        )?;
        if let AssocConstValue::TraitDefault(konst) | AssocConstValue::Impl(konst) = value {
            let repr = konst.expr(tcx);
            if match value {
                AssocConstValue::TraitDefault(_) => true, // always show
                // FIXME: Comparing against the special string "_" denoting overly complex const exprs
                //        is rather hacky; `ConstKind::expr` should have a richer return type.
                AssocConstValue::Impl(_) => repr != "_", // show if there is a meaningful value to show
                AssocConstValue::None => unreachable!(),
            } {
                write!(w, " = {}", Escape(&repr))?;
            }
        }
        write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline).maybe_display())
    })
}

fn assoc_type(
    it: &clean::Item,
    generics: &clean::Generics,
    bounds: &[clean::GenericBound],
    default: Option<&clean::Type>,
    link: AssocItemLink<'_>,
    indent: usize,
    cx: &Context<'_>,
) -> impl fmt::Display {
    fmt::from_fn(move |w| {
        render_attributes_in_code(w, it, &" ".repeat(indent), cx)?;
        write!(
            w,
            "{indent}{vis}type <a{href} class=\"associatedtype\">{name}</a>{generics}",
            indent = " ".repeat(indent),
            vis = visibility_print_with_space(it, cx),
            href = assoc_href_attr(it, link, cx).maybe_display(),
            name = it.name.as_ref().unwrap(),
            generics = print_generics(generics, cx),
        )?;
        if !bounds.is_empty() {
            write!(w, ": {}", print_generic_bounds(bounds, cx))?;
        }
        // Render the default before the where-clause which aligns with the new recommended style. See #89122.
        if let Some(default) = default {
            write!(w, " = {}", print_type(default, cx))?;
        }
        write!(w, "{}", print_where_clause(generics, cx, indent, Ending::NoNewline).maybe_display())
    })
}

fn assoc_method(
    meth: &clean::Item,
    g: &clean::Generics,
    d: &clean::FnDecl,
    link: AssocItemLink<'_>,
    parent: ItemType,
    cx: &Context<'_>,
    render_mode: RenderMode,
) -> impl fmt::Display {
    let tcx = cx.tcx();
    let header = meth.fn_header(tcx).expect("Trying to get header from a non-function item");
    let name = meth.name.as_ref().unwrap();
    let vis = visibility_print_with_space(meth, cx).to_string();
    let defaultness = match meth.defaultness().expect("Expected assoc method to have defaultness") {
        Defaultness::Implicit => "",
        Defaultness::Final => "final ",
        Defaultness::Default => "default ",
    };
    // FIXME: Once https://github.com/rust-lang/rust/issues/143874 is implemented, we can remove
    // this condition.
    let constness = match render_mode {
        RenderMode::Normal => print_constness_with_space(
            &header.constness,
            meth.stable_since(tcx),
            meth.const_stability(tcx),
        ),
        RenderMode::ForDeref { .. } => "",
    };

    fmt::from_fn(move |w| {
        let asyncness = header.asyncness.print_with_space();
        let safety = header.safety.print_with_space();
        let abi = print_abi_with_space(header.abi).to_string();
        let href = assoc_href_attr(meth, link, cx).maybe_display();

        // NOTE: `{:#}` does not print HTML formatting, `{}` does. So `g.print` can't be reused between the length calculation and `write!`.
        let generics_len = format!("{:#}", print_generics(g, cx)).len();
        let mut header_len = "fn ".len()
            + vis.len()
            + defaultness.len()
            + constness.len()
            + asyncness.len()
            + safety.len()
            + abi.len()
            + name.as_str().len()
            + generics_len;

        let notable_traits = notable_traits_button(&d.output, cx).maybe_display();

        let (indent, indent_str, end_newline) = if parent == ItemType::Trait {
            header_len += 4;
            let indent_str = "    ";
            render_attributes_in_code(w, meth, indent_str, cx)?;
            (4, indent_str, Ending::NoNewline)
        } else {
            render_attributes_in_code(w, meth, "", cx)?;
            (0, "", Ending::Newline)
        };
        write!(
            w,
            "{indent}{vis}{defaultness}{constness}{asyncness}{safety}{abi}fn \
            <a{href} class=\"fn\">{name}</a>{generics}{decl}{notable_traits}{where_clause}",
            indent = indent_str,
            generics = print_generics(g, cx),
            decl = full_print_fn_decl(d, header_len, indent, cx),
            where_clause = print_where_clause(g, cx, indent, end_newline).maybe_display(),
        )
    })
}

/// Writes a span containing the versions at which an item became stable and/or const-stable. For
/// example, if the item became stable at 1.0.0, and const-stable at 1.45.0, this function would
/// write a span containing "1.0.0 (const: 1.45.0)".
///
/// Returns `None` if there is no stability annotation to be rendered.
///
/// Stability and const-stability are considered separately. If the item is unstable, no version
/// will be written. If the item is const-unstable, "const: unstable" will be appended to the
/// span, with a link to the tracking issue if present. If an item's stability or const-stability
/// version matches the version of its enclosing item, that version will be omitted.
///
/// Note that it is possible for an unstable function to be const-stable. In that case, the span
/// will include the const-stable version, but no stable version will be emitted, as a natural
/// consequence of the above rules.
fn render_stability_since_raw_with_extra(
    stable_version: Option<StableSince>,
    const_stability: Option<ConstStability>,
    extra_class: &str,
) -> Option<impl fmt::Display> {
    let mut title = String::new();
    let mut stability = String::new();

    if let Some(version) = stable_version.and_then(|version| since_to_string(&version)) {
        stability.push_str(&version);
        title.push_str(&format!("Stable since Rust version {version}"));
    }

    let const_title_and_stability = match const_stability {
        Some(ConstStability { level: StabilityLevel::Stable { since, .. }, .. }) => {
            since_to_string(&since)
                .map(|since| (format!("const since {since}"), format!("const: {since}")))
        }
        Some(ConstStability { level: StabilityLevel::Unstable { issue, .. }, feature, .. }) => {
            if stable_version.is_none() {
                // don't display const unstable if entirely unstable
                None
            } else {
                let unstable = if let Some(n) = issue {
                    format!(
                        "<a \
                        href=\"https://github.com/rust-lang/rust/issues/{n}\" \
                        title=\"Tracking issue for {feature}\"\
                       >unstable</a>"
                    )
                } else {
                    String::from("unstable")
                };

                Some((String::from("const unstable"), format!("const: {unstable}")))
            }
        }
        _ => None,
    };

    if let Some((const_title, const_stability)) = const_title_and_stability {
        if !title.is_empty() {
            title.push_str(&format!(", {const_title}"));
        } else {
            title.push_str(&const_title);
        }

        if !stability.is_empty() {
            stability.push_str(&format!(" ({const_stability})"));
        } else {
            stability.push_str(&const_stability);
        }
    }

    (!stability.is_empty()).then_some(fmt::from_fn(move |w| {
        write!(w, r#"<span class="since{extra_class}" title="{title}">{stability}</span>"#)
    }))
}

fn since_to_string(since: &StableSince) -> Option<String> {
    match since {
        StableSince::Version(since) => Some(since.to_string()),
        StableSince::Current => Some(RustcVersion::CURRENT.to_string()),
        StableSince::Err(_) => None,
    }
}

#[inline]
fn render_stability_since_raw(
    ver: Option<StableSince>,
    const_stability: Option<ConstStability>,
) -> Option<impl fmt::Display> {
    render_stability_since_raw_with_extra(ver, const_stability, "")
}

fn render_assoc_item(
    item: &clean::Item,
    link: AssocItemLink<'_>,
    parent: ItemType,
    cx: &Context<'_>,
    render_mode: RenderMode,
) -> impl fmt::Display {
    fmt::from_fn(move |f| match &item.kind {
        clean::StrippedItem(..) => Ok(()),
        clean::RequiredMethodItem(m, _) | clean::MethodItem(m, _) => {
            assoc_method(item, &m.generics, &m.decl, link, parent, cx, render_mode).fmt(f)
        }
        clean::RequiredAssocConstItem(generics, ty) => assoc_const(
            item,
            generics,
            ty,
            AssocConstValue::None,
            link,
            if parent == ItemType::Trait { 4 } else { 0 },
            cx,
        )
        .fmt(f),
        clean::ProvidedAssocConstItem(ci) => assoc_const(
            item,
            &ci.generics,
            &ci.type_,
            AssocConstValue::TraitDefault(&ci.kind),
            link,
            if parent == ItemType::Trait { 4 } else { 0 },
            cx,
        )
        .fmt(f),
        clean::ImplAssocConstItem(ci) => assoc_const(
            item,
            &ci.generics,
            &ci.type_,
            AssocConstValue::Impl(&ci.kind),
            link,
            if parent == ItemType::Trait { 4 } else { 0 },
            cx,
        )
        .fmt(f),
        clean::RequiredAssocTypeItem(generics, bounds) => assoc_type(
            item,
            generics,
            bounds,
            None,
            link,
            if parent == ItemType::Trait { 4 } else { 0 },
            cx,
        )
        .fmt(f),
        clean::AssocTypeItem(ty, bounds) => assoc_type(
            item,
            &ty.generics,
            bounds,
            Some(ty.item_type.as_ref().unwrap_or(&ty.type_)),
            link,
            if parent == ItemType::Trait { 4 } else { 0 },
            cx,
        )
        .fmt(f),
        _ => panic!("render_assoc_item called on non-associated-item"),
    })
}

#[derive(Copy, Clone)]
enum AssocItemLink<'a> {
    Anchor(Option<&'a str>),
    GotoSource(ItemId, &'a FxIndexSet<Symbol>),
}

impl<'a> AssocItemLink<'a> {
    fn anchor(&self, id: &'a str) -> Self {
        match *self {
            AssocItemLink::Anchor(_) => AssocItemLink::Anchor(Some(id)),
            ref other => *other,
        }
    }
}

fn write_section_heading(
    title: impl fmt::Display,
    id: &str,
    extra_class: Option<&str>,
    extra: impl fmt::Display,
) -> impl fmt::Display {
    fmt::from_fn(move |w| {
        let (extra_class, whitespace) = match extra_class {
            Some(extra) => (extra, " "),
            None => ("", ""),
        };
        write!(
            w,
            "<h2 id=\"{id}\" class=\"{extra_class}{whitespace}section-header\">\
            {title}\
            <a href=\"#{id}\" class=\"anchor\">§</a>\
         </h2>{extra}",
        )
    })
}

fn write_impl_section_heading(title: impl fmt::Display, id: &str) -> impl fmt::Display {
    write_section_heading(title, id, None, "")
}

fn render_all_impls(
    mut w: impl Write,
    cx: &Context<'_>,
    containing_item: &clean::Item,
    concrete: &[&Impl],
    synthetic: &[&Impl],
    blanket_impl: &[&Impl],
) -> fmt::Result {
    let impls = {
        let mut buf = String::new();
        render_impls(cx, &mut buf, concrete, containing_item, true)?;
        buf
    };
    if !impls.is_empty() {
        write!(
            w,
            "{}<div id=\"trait-implementations-list\">{impls}</div>",
            write_impl_section_heading("Trait Implementations", "trait-implementations")
        )?;
    }

    if !synthetic.is_empty() {
        write!(
            w,
            "{}<div id=\"synthetic-implementations-list\">",
            write_impl_section_heading("Auto Trait Implementations", "synthetic-implementations",)
        )?;
        render_impls(cx, &mut w, synthetic, containing_item, false)?;
        w.write_str("</div>")?;
    }

    if !blanket_impl.is_empty() {
        write!(
            w,
            "{}<div id=\"blanket-implementations-list\">",
            write_impl_section_heading("Blanket Implementations", "blanket-implementations")
        )?;
        render_impls(cx, &mut w, blanket_impl, containing_item, false)?;
        w.write_str("</div>")?;
    }
    Ok(())
}

fn render_assoc_items(
    cx: &Context<'_>,
    containing_item: &clean::Item,
    it: DefId,
    what: AssocItemRender<'_>,
) -> impl fmt::Display {
    fmt::from_fn(move |f| {
        let mut derefs = DefIdSet::default();
        derefs.insert(it);
        render_assoc_items_inner(f, cx, containing_item, it, what, &mut derefs)
    })
}

fn render_assoc_items_inner(
    mut w: &mut dyn fmt::Write,
    cx: &Context<'_>,
    containing_item: &clean::Item,
    it: DefId,
    what: AssocItemRender<'_>,
    derefs: &mut DefIdSet,
) -> fmt::Result {
    info!("Documenting associated items of {:?}", containing_item.name);
    let cache = &cx.shared.cache;
    let Some(v) = cache.impls.get(&it) else { return Ok(()) };
    let (mut non_trait, traits): (Vec<_>, _) =
        v.iter().partition(|i| i.inner_impl().trait_.is_none());
    if !non_trait.is_empty() {
        let render_mode = what.render_mode();
        let class_html = what
            .class()
            .map(|class| fmt::from_fn(move |f| write!(f, r#" class="{class}""#)))
            .maybe_display();
        let (section_heading, id) = match what {
            AssocItemRender::All => (
                Either::Left(write_impl_section_heading("Implementations", "implementations")),
                Cow::Borrowed("implementations-list"),
            ),
            AssocItemRender::DerefFor { trait_, type_, .. } => {
                let id = cx.derive_id(small_url_encode(format!(
                    "deref-methods-{:#}",
                    print_type(type_, cx)
                )));
                // the `impls.get` above only looks at the outermost type,
                // and the Deref impl may only be implemented for certain
                // values of generic parameters.
                // for example, if an item impls `Deref<[u8]>`,
                // we should not show methods from `[MaybeUninit<u8>]`.
                // this `retain` filters out any instances where
                // the types do not line up perfectly.
                non_trait.retain(|impl_| {
                    type_.is_doc_subtype_of(&impl_.inner_impl().for_, &cx.shared.cache)
                });
                let derived_id = cx.derive_id(&id);
                if let Some(def_id) = type_.def_id(cx.cache()) {
                    cx.deref_id_map.borrow_mut().insert(def_id, id.clone());
                }
                (
                    Either::Right(fmt::from_fn(move |f| {
                        write!(
                            f,
                            "<details class=\"toggle big-toggle\" open><summary>{}</summary>",
                            write_impl_section_heading(
                                fmt::from_fn(|f| write!(
                                    f,
                                    "<span>Methods from {trait_}&lt;Target = {type_}&gt;</span>",
                                    trait_ = print_path(trait_, cx),
                                    type_ = print_type(type_, cx),
                                )),
                                &id,
                            )
                        )
                    })),
                    Cow::Owned(derived_id),
                )
            }
        };
        let impls_buf = fmt::from_fn(|f| {
            non_trait
                .iter()
                .map(|i| {
                    render_impl(
                        cx,
                        i,
                        containing_item,
                        AssocItemLink::Anchor(None),
                        render_mode,
                        None,
                        &[],
                        ImplRenderingParameters {
                            show_def_docs: true,
                            show_default_items: true,
                            show_non_assoc_items: true,
                            toggle_open_by_default: true,
                        },
                    )
                })
                .joined("", f)
        })
        .to_string();

        if !impls_buf.is_empty() {
            write!(
                w,
                "{section_heading}<div id=\"{id}\"{class_html}>{impls_buf}</div>{}",
                matches!(what, AssocItemRender::DerefFor { .. })
                    .then_some("</details>")
                    .maybe_display(),
            )?;
        }
    }

    if !traits.is_empty() {
        let deref_impl = traits.iter().find(|t| {
            t.trait_did() == cx.tcx().lang_items().deref_trait() && !t.is_negative_trait_impl()
        });
        if let Some(impl_) = deref_impl {
            let has_deref_mut =
                traits.iter().any(|t| t.trait_did() == cx.tcx().lang_items().deref_mut_trait());
            render_deref_methods(&mut w, cx, impl_, containing_item, has_deref_mut, derefs)?;
        }

        // If we were already one level into rendering deref methods, we don't want to render
        // anything after recursing into any further deref methods above.
        if let AssocItemRender::DerefFor { .. } = what {
            return Ok(());
        }

        let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
            traits.into_iter().partition(|t| t.inner_impl().kind.is_auto());
        let (blanket_impl, concrete): (Vec<&Impl>, _) =
            concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());

        render_all_impls(w, cx, containing_item, &concrete, &synthetic, &blanket_impl)?;
    }
    Ok(())
}

/// `derefs` is the set of all deref targets that have already been handled.
fn render_deref_methods(
    mut w: impl Write,
    cx: &Context<'_>,
    impl_: &Impl,
    container_item: &clean::Item,
    deref_mut: bool,
    derefs: &mut DefIdSet,
) -> fmt::Result {
    let cache = cx.cache();
    let deref_type = impl_.inner_impl().trait_.as_ref().unwrap();
    let (target, real_target) = impl_
        .inner_impl()
        .items
        .iter()
        .find_map(|item| match item.kind {
            clean::AssocTypeItem(ref t, _) => Some(match *t {
                clean::TypeAlias { item_type: Some(ref type_), .. } => (type_, &t.type_),
                _ => (&t.type_, &t.type_),
            }),
            _ => None,
        })
        .expect("Expected associated type binding");
    debug!(
        "Render deref methods for {for_:#?}, target {target:#?}",
        for_ = impl_.inner_impl().for_
    );
    let what =
        AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut };
    if let Some(did) = target.def_id(cache) {
        if let Some(type_did) = impl_.inner_impl().for_.def_id(cache) {
            // `impl Deref<Target = S> for S`
            if did == type_did || !derefs.insert(did) {
                // Avoid infinite cycles
                return Ok(());
            }
        }
        render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs)?;
    } else if let Some(prim) = target.primitive_type()
        && let Some(&did) = cache.primitive_locations.get(&prim)
    {
        render_assoc_items_inner(&mut w, cx, container_item, did, what, derefs)?;
    }
    Ok(())
}

fn should_render_item(item: &clean::Item, deref_mut_: bool, tcx: TyCtxt<'_>) -> bool {
    let self_type_opt = match item.kind {
        clean::MethodItem(ref method, _) => method.decl.receiver_type(),
        clean::RequiredMethodItem(ref method, _) => method.decl.receiver_type(),
        _ => None,
    };

    if let Some(self_ty) = self_type_opt {
        let (by_mut_ref, by_box, by_value) = match *self_ty {
            clean::Type::BorrowedRef { mutability, .. } => {
                (mutability == Mutability::Mut, false, false)
            }
            clean::Type::Path { ref path } => {
                (false, Some(path.def_id()) == tcx.lang_items().owned_box(), false)
            }
            clean::Type::SelfTy => (false, false, true),
            _ => (false, false, false),
        };

        (deref_mut_ || !by_mut_ref) && !by_box && !by_value
    } else {
        false
    }
}

fn notable_traits_button(ty: &clean::Type, cx: &Context<'_>) -> Option<impl fmt::Display> {
    if ty.is_unit() {
        // Very common fast path.
        return None;
    }

    let did = ty.def_id(cx.cache())?;

    // Box has pass-through impls for Read, Write, Iterator, and Future when the
    // boxed type implements one of those. We don't want to treat every Box return
    // as being notably an Iterator (etc), though, so we exempt it. Pin has the same
    // issue, with a pass-through impl for Future.
    if Some(did) == cx.tcx().lang_items().owned_box()
        || Some(did) == cx.tcx().lang_items().pin_type()
    {
        return None;
    }

    let impls = cx.cache().impls.get(&did)?;
    let has_notable_trait = impls
        .iter()
        .map(Impl::inner_impl)
        .filter(|impl_| {
            impl_.polarity == ty::ImplPolarity::Positive
                // Two different types might have the same did,
                // without actually being the same.
                && ty.is_doc_subtype_of(&impl_.for_, cx.cache())
        })
        .filter_map(|impl_| impl_.trait_.as_ref())
        .filter_map(|trait_| cx.cache().traits.get(&trait_.def_id()))
        .any(|t| t.is_notable_trait(cx.tcx()));

    has_notable_trait.then(|| {
        cx.types_with_notable_traits.borrow_mut().insert(ty.clone());
        fmt::from_fn(|f| {
            write!(
                f,
                " <a href=\"#\" class=\"tooltip\" data-notable-ty=\"{ty}\">ⓘ</a>",
                ty = Escape(&format!("{:#}", print_type(ty, cx))),
            )
        })
    })
}

fn notable_traits_decl(ty: &clean::Type, cx: &Context<'_>) -> (String, String) {
    let did = ty.def_id(cx.cache()).expect("notable_traits_button already checked this");

    let impls = cx.cache().impls.get(&did).expect("notable_traits_button already checked this");

    let out = fmt::from_fn(|f| {
        let mut notable_impls = impls
            .iter()
            .map(|impl_| impl_.inner_impl())
            .filter(|impl_| impl_.polarity == ty::ImplPolarity::Positive)
            .filter(|impl_| {
                // Two different types might have the same did, without actually being the same.
                ty.is_doc_subtype_of(&impl_.for_, cx.cache())
            })
            .filter_map(|impl_| {
                if let Some(trait_) = &impl_.trait_
                    && let trait_did = trait_.def_id()
                    && let Some(trait_) = cx.cache().traits.get(&trait_did)
                    && trait_.is_notable_trait(cx.tcx())
                {
                    Some((impl_, trait_did))
                } else {
                    None
                }
            })
            .peekable();

        let has_notable_impl = if let Some((impl_, _)) = notable_impls.peek() {
            write!(
                f,
                "<h3>Notable traits for <code>{}</code></h3>\
                <pre><code>",
                print_type(&impl_.for_, cx),
            )?;
            true
        } else {
            false
        };

        for (impl_, trait_did) in notable_impls {
            write!(f, "<div class=\"where\">{}</div>", print_impl(impl_, false, cx))?;
            for it in &impl_.items {
                let clean::AssocTypeItem(tydef, ..) = &it.kind else {
                    continue;
                };

                let empty_set = FxIndexSet::default();
                let src_link = AssocItemLink::GotoSource(trait_did.into(), &empty_set);

                write!(
                    f,
                    "<div class=\"where\">    {};</div>",
                    assoc_type(
                        it,
                        &tydef.generics,
                        &[], // intentionally leaving out bounds
                        Some(&tydef.type_),
                        src_link,
                        0,
                        cx,
                    )
                )?;
            }
        }

        if !has_notable_impl {
            f.write_str("</code></pre>")?;
        }

        Ok(())
    })
    .to_string();

    (format!("{:#}", print_type(ty, cx)), out)
}

fn notable_traits_json<'a>(tys: impl Iterator<Item = &'a clean::Type>, cx: &Context<'_>) -> String {
    let mut mp = tys.map(|ty| notable_traits_decl(ty, cx)).collect::<IndexMap<_, _>>();
    mp.sort_unstable_keys();
    serde_json::to_string(&mp).expect("serialize (string, string) -> json object cannot fail")
}

#[derive(Clone, Copy, Debug)]
struct ImplRenderingParameters {
    show_def_docs: bool,
    show_default_items: bool,
    /// Whether or not to show methods.
    show_non_assoc_items: bool,
    toggle_open_by_default: bool,
}

fn render_impl(
    cx: &Context<'_>,
    i: &Impl,
    parent: &clean::Item,
    link: AssocItemLink<'_>,
    render_mode: RenderMode,
    use_absolute: Option<bool>,
    aliases: &[String],
    rendering_params: ImplRenderingParameters,
) -> impl fmt::Display {
    fmt::from_fn(move |w| {
        let cache = &cx.shared.cache;
        let traits = &cache.traits;
        let trait_ = i.trait_did().map(|did| &traits[&did]);
        let mut close_tags = <Vec<&str>>::with_capacity(2);

        // For trait implementations, the `interesting` output contains all methods that have doc
        // comments, and the `boring` output contains all methods that do not. The distinction is
        // used to allow hiding the boring methods.
        // `containing_item` is used for rendering stability info. If the parent is a trait impl,
        // `containing_item` will the grandparent, since trait impls can't have stability attached.
        fn doc_impl_item(
            boring: impl fmt::Write,
            interesting: impl fmt::Write,
            cx: &Context<'_>,
            item: &clean::Item,
            parent: &clean::Item,
            link: AssocItemLink<'_>,
            render_mode: RenderMode,
            is_default_item: bool,
            trait_: Option<&clean::Trait>,
            rendering_params: ImplRenderingParameters,
        ) -> fmt::Result {
            let item_type = item.type_();
            let name = item.name.as_ref().unwrap();

            let render_method_item = rendering_params.show_non_assoc_items
                && match render_mode {
                    RenderMode::Normal => true,
                    RenderMode::ForDeref { mut_: deref_mut_ } => {
                        should_render_item(item, deref_mut_, cx.tcx())
                    }
                };

            let in_trait_class = if trait_.is_some() { " trait-impl" } else { "" };

            let mut doc_buffer = String::new();
            let mut info_buffer = String::new();
            let mut short_documented = true;

            let mut trait_item_deprecated = false;
            if render_method_item {
                if !is_default_item {
                    if let Some(t) = trait_ {
                        // The trait item may have been stripped so we might not
                        // find any documentation or stability for it.
                        if let Some(it) = t.items.iter().find(|i| i.name == item.name) {
                            trait_item_deprecated = it.is_deprecated(cx.tcx());
                            // We need the stability of the item from the trait
                            // because impls can't have a stability.
                            if !item.doc_value().is_empty() {
                                document_item_info(cx, it, Some(parent))
                                    .render_into(&mut info_buffer)?;
                                doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string();
                                short_documented = false;
                            } else {
                                // In case the item isn't documented,
                                // provide short documentation from the trait.
                                doc_buffer = document_short(
                                    it,
                                    cx,
                                    link,
                                    parent,
                                    rendering_params.show_def_docs,
                                )
                                .to_string();
                            }
                        }
                    } else {
                        document_item_info(cx, item, Some(parent)).render_into(&mut info_buffer)?;
                        if rendering_params.show_def_docs {
                            doc_buffer = document_full(item, cx, HeadingOffset::H5).to_string();
                            short_documented = false;
                        }
                    }
                } else {
                    doc_buffer =
                        document_short(item, cx, link, parent, rendering_params.show_def_docs)
                            .to_string();
                }
            }
            let mut w = if short_documented && trait_.is_some() {
                Either::Left(interesting)
            } else {
                Either::Right(boring)
            };

            let mut deprecation_class = if trait_item_deprecated || item.is_deprecated(cx.tcx()) {
                " deprecated"
            } else {
                ""
            };

            let toggled = !doc_buffer.is_empty();
            if toggled {
                let method_toggle_class = if item_type.is_method() { " method-toggle" } else { "" };
                write!(
                    w,
                    "<details class=\"toggle{method_toggle_class}{deprecation_class}\" open><summary>"
                )?;
                deprecation_class = "";
            }
            match &item.kind {
                clean::MethodItem(..) | clean::RequiredMethodItem(..) => {
                    // Only render when the method is not static or we allow static methods
                    if render_method_item {
                        let id = cx.derive_id(format!("{item_type}.{name}"));
                        let source_id = trait_
                            .and_then(|trait_| {
                                trait_
                                    .items
                                    .iter()
                                    .find(|item| item.name.map(|n| n == *name).unwrap_or(false))
                            })
                            .map(|item| format!("{}.{name}", item.type_()));
                        write!(
                            w,
                            "<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
                                {}",
                            render_rightside(cx, item, render_mode)
                        )?;
                        if trait_.is_some() {
                            // Anchors are only used on trait impls.
                            write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                        }
                        write!(
                            w,
                            "<h4 class=\"code-header\">{}</h4></section>",
                            render_assoc_item(
                                item,
                                link.anchor(source_id.as_ref().unwrap_or(&id)),
                                ItemType::Impl,
                                cx,
                                render_mode,
                            ),
                        )?;
                    }
                }
                clean::RequiredAssocConstItem(generics, ty) => {
                    let source_id = format!("{item_type}.{name}");
                    let id = cx.derive_id(&source_id);
                    write!(
                        w,
                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
                            {}",
                        render_rightside(cx, item, render_mode)
                    )?;
                    if trait_.is_some() {
                        // Anchors are only used on trait impls.
                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                    }
                    write!(
                        w,
                        "<h4 class=\"code-header\">{}</h4></section>",
                        assoc_const(
                            item,
                            generics,
                            ty,
                            AssocConstValue::None,
                            link.anchor(if trait_.is_some() { &source_id } else { &id }),
                            0,
                            cx,
                        ),
                    )?;
                }
                clean::ProvidedAssocConstItem(ci) | clean::ImplAssocConstItem(ci) => {
                    let source_id = format!("{item_type}.{name}");
                    let id = cx.derive_id(&source_id);
                    write!(
                        w,
                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
                            {}",
                        render_rightside(cx, item, render_mode),
                    )?;
                    if trait_.is_some() {
                        // Anchors are only used on trait impls.
                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                    }
                    write!(
                        w,
                        "<h4 class=\"code-header\">{}</h4></section>",
                        assoc_const(
                            item,
                            &ci.generics,
                            &ci.type_,
                            match item.kind {
                                clean::ProvidedAssocConstItem(_) =>
                                    AssocConstValue::TraitDefault(&ci.kind),
                                clean::ImplAssocConstItem(_) => AssocConstValue::Impl(&ci.kind),
                                _ => unreachable!(),
                            },
                            link.anchor(if trait_.is_some() { &source_id } else { &id }),
                            0,
                            cx,
                        ),
                    )?;
                }
                clean::RequiredAssocTypeItem(generics, bounds) => {
                    let source_id = format!("{item_type}.{name}");
                    let id = cx.derive_id(&source_id);
                    write!(
                        w,
                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
                            {}",
                        render_rightside(cx, item, render_mode),
                    )?;
                    if trait_.is_some() {
                        // Anchors are only used on trait impls.
                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                    }
                    write!(
                        w,
                        "<h4 class=\"code-header\">{}</h4></section>",
                        assoc_type(
                            item,
                            generics,
                            bounds,
                            None,
                            link.anchor(if trait_.is_some() { &source_id } else { &id }),
                            0,
                            cx,
                        ),
                    )?;
                }
                clean::AssocTypeItem(tydef, _bounds) => {
                    let source_id = format!("{item_type}.{name}");
                    let id = cx.derive_id(&source_id);
                    write!(
                        w,
                        "<section id=\"{id}\" class=\"{item_type}{in_trait_class}{deprecation_class}\">\
                            {}",
                        render_rightside(cx, item, render_mode),
                    )?;
                    if trait_.is_some() {
                        // Anchors are only used on trait impls.
                        write!(w, "<a href=\"#{id}\" class=\"anchor\">§</a>")?;
                    }
                    write!(
                        w,
                        "<h4 class=\"code-header\">{}</h4></section>",
                        assoc_type(
                            item,
                            &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,
                        ),
                    )?;
                }
                clean::StrippedItem(..) => return Ok(()),
                _ => panic!("can't make docs for trait item with name {:?}", item.name),
            }

            w.write_str(&info_buffer)?;
            if toggled {
                write!(w, "</summary>{doc_buffer}</details>")?;
            }
            Ok(())
        }

        let mut impl_items = String::new();
        let mut default_impl_items = String::new();
        let impl_ = i.inner_impl();

        // Impl items are grouped by kinds:
        //
        // 1. Constants
        // 2. Types
        // 3. Functions
        //
        // This order is because you can have associated constants used in associated types (like array
        // length), and both in associated functions. So with this order, when reading from top to
        // bottom, you should see items definitions before they're actually used most of the time.
        let mut assoc_types = Vec::new();
        let mut methods = Vec::new();

        if !impl_.is_negative_trait_impl() {
            for impl_item in &impl_.items {
                match impl_item.kind {
                    clean::MethodItem(..) | clean::RequiredMethodItem(..) => {
                        methods.push(impl_item)
                    }
                    clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => {
                        assoc_types.push(impl_item)
                    }
                    clean::RequiredAssocConstItem(..)
                    | clean::ProvidedAssocConstItem(_)
                    | clean::ImplAssocConstItem(_) => {
                        // We render it directly since they're supposed to come first.
                        doc_impl_item(
                            &mut default_impl_items,
                            &mut impl_items,
                            cx,
                            impl_item,
                            if trait_.is_some() { &i.impl_item } else { parent },
                            link,
                            render_mode,
                            false,
                            trait_,
                            rendering_params,
                        )?;
                    }
                    _ => {}
                }
            }

            for assoc_type in assoc_types {
                doc_impl_item(
                    &mut default_impl_items,
                    &mut impl_items,
                    cx,
                    assoc_type,
                    if trait_.is_some() { &i.impl_item } else { parent },
                    link,
                    render_mode,
                    false,
                    trait_,
                    rendering_params,
                )?;
            }
            for method in methods {
                doc_impl_item(
                    &mut default_impl_items,
                    &mut impl_items,
                    cx,
                    method,
                    if trait_.is_some() { &i.impl_item } else { parent },
                    link,
                    render_mode,
                    false,
                    trait_,
                    rendering_params,
                )?;
            }
        }

        fn render_default_items(
            mut boring: impl fmt::Write,
            mut interesting: impl fmt::Write,
            cx: &Context<'_>,
            t: &clean::Trait,
            i: &clean::Impl,
            parent: &clean::Item,
            render_mode: RenderMode,
            rendering_params: ImplRenderingParameters,
        ) -> fmt::Result {
            for trait_item in &t.items {
                // Skip over any default trait items that are impossible to reference
                // (e.g. if it has a `Self: Sized` bound on an unsized type).
                if let Some(impl_def_id) = parent.item_id.as_def_id()
                    && let Some(trait_item_def_id) = trait_item.item_id.as_def_id()
                    && cx.tcx().is_impossible_associated_item((impl_def_id, trait_item_def_id))
                {
                    continue;
                }

                let n = trait_item.name;
                if i.items.iter().any(|m| m.name == n) {
                    continue;
                }
                let did = i.trait_.as_ref().unwrap().def_id();
                let provided_methods = i.provided_trait_methods(cx.tcx());
                let assoc_link = AssocItemLink::GotoSource(did.into(), &provided_methods);

                doc_impl_item(
                    &mut boring,
                    &mut interesting,
                    cx,
                    trait_item,
                    parent,
                    assoc_link,
                    render_mode,
                    true,
                    Some(t),
                    rendering_params,
                )?;
            }
            Ok(())
        }

        // If we've implemented a trait, then also emit documentation for all
        // default items which weren't overridden in the implementation block.
        // We don't emit documentation for default items if they appear in the
        // Implementations on Foreign Types or Implementors sections.
        if rendering_params.show_default_items
            && let Some(t) = trait_
            && !impl_.is_negative_trait_impl()
        {
            render_default_items(
                &mut default_impl_items,
                &mut impl_items,
                cx,
                t,
                impl_,
                &i.impl_item,
                render_mode,
                rendering_params,
            )?;
        }
        if render_mode == RenderMode::Normal {
            let toggled = !(impl_items.is_empty() && default_impl_items.is_empty());
            let deprecation_attr = if impl_.is_deprecated
                || trait_.is_some_and(|trait_| trait_.is_deprecated(cx.tcx()))
            {
                " deprecated"
            } else {
                ""
            };
            if toggled {
                close_tags.push("</details>");
                write!(
                    w,
                    "<details class=\"toggle implementors-toggle{deprecation_attr}\"{}>\
                        <summary>",
                    if rendering_params.toggle_open_by_default { " open" } else { "" }
                )?;
            }

            let (before_dox, after_dox) = i
                .impl_item
                .opt_doc_value()
                .map(|dox| {
                    Markdown {
                        content: &dox,
                        links: &i.impl_item.links(cx),
                        ids: &mut cx.id_map.borrow_mut(),
                        error_codes: cx.shared.codes,
                        edition: cx.shared.edition(),
                        playground: &cx.shared.playground,
                        heading_offset: HeadingOffset::H4,
                    }
                    .split_summary_and_content()
                })
                .unwrap_or((None, None));

            write!(
                w,
                "{}",
                render_impl_summary(
                    cx,
                    i,
                    parent,
                    rendering_params.show_def_docs,
                    use_absolute,
                    aliases,
                    before_dox.as_deref(),
                    trait_.is_none() && impl_.items.is_empty(),
                )
            )?;
            if toggled {
                w.write_str("</summary>")?;
            }

            if before_dox.is_some()
                && let Some(after_dox) = after_dox
            {
                write!(w, "<div class=\"docblock\">{after_dox}</div>")?;
            }

            if !default_impl_items.is_empty() || !impl_items.is_empty() {
                w.write_str("<div class=\"impl-items\">")?;
                close_tags.push("</div>");
            }
        }
        if !default_impl_items.is_empty() || !impl_items.is_empty() {
            w.write_str(&default_impl_items)?;
            w.write_str(&impl_items)?;
        }
        for tag in close_tags.into_iter().rev() {
            w.write_str(tag)?;
        }
        Ok(())
    })
}

// Render the items that appear on the right side of methods, impls, and
// associated types. For example "1.0.0 (const: 1.39.0) · source".
fn render_rightside(
    cx: &Context<'_>,
    item: &clean::Item,
    render_mode: RenderMode,
) -> impl fmt::Display {
    let tcx = cx.tcx();

    fmt::from_fn(move |w| {
        // FIXME: Once https://github.com/rust-lang/rust/issues/143874 is implemented, we can remove
        // this condition.
        let const_stability = match render_mode {
            RenderMode::Normal => item.const_stability(tcx),
            RenderMode::ForDeref { .. } => None,
        };
        let src_href = cx.src_href(item);
        let stability = render_stability_since_raw_with_extra(
            item.stable_since(tcx),
            const_stability,
            if src_href.is_some() { "" } else { " rightside" },
        );

        match (stability, src_href) {
            (Some(stability), Some(link)) => {
                write!(
                    w,
                    "<span class=\"rightside\">{stability} · <a class=\"src\" href=\"{link}\">Source</a></span>",
                )
            }
            (Some(stability), None) => {
                write!(w, "{stability}")
            }
            (None, Some(link)) => {
                write!(w, "<a class=\"src rightside\" href=\"{link}\">Source</a>")
            }
            (None, None) => Ok(()),
        }
    })
}

fn render_impl_summary(
    cx: &Context<'_>,
    i: &Impl,
    parent: &clean::Item,
    show_def_docs: bool,
    use_absolute: Option<bool>,
    // This argument is used to reference same type with different paths to avoid duplication
    // in documentation pages for trait with automatic implementations like "Send" and "Sync".
    aliases: &[String],
    doc: Option<&str>,
    impl_is_empty: bool,
) -> impl fmt::Display {
    fmt::from_fn(move |w| {
        let inner_impl = i.inner_impl();
        let id = cx.derive_id(get_id_for_impl(cx.tcx(), i.impl_item.item_id));
        let aliases = (!aliases.is_empty())
            .then_some(fmt::from_fn(|f| {
                write!(f, " data-aliases=\"{}\"", fmt::from_fn(|f| aliases.iter().joined(",", f)))
            }))
            .maybe_display();
        write!(
            w,
            "<section id=\"{id}\" class=\"impl\"{aliases}>\
                {}\
                <a href=\"#{id}\" class=\"anchor\">§</a>\
                <h3 class=\"code-header\">",
            render_rightside(cx, &i.impl_item, RenderMode::Normal)
        )?;

        if let Some(use_absolute) = use_absolute {
            write!(w, "{}", print_impl(inner_impl, use_absolute, cx))?;
            if show_def_docs {
                for it in &inner_impl.items {
                    if let clean::AssocTypeItem(ref tydef, ref _bounds) = it.kind {
                        write!(
                            w,
                            "<div class=\"where\">  {};</div>",
                            assoc_type(
                                it,
                                &tydef.generics,
                                &[], // intentionally leaving out bounds
                                Some(&tydef.type_),
                                AssocItemLink::Anchor(None),
                                0,
                                cx,
                            )
                        )?;
                    }
                }
            }
        } else {
            write!(w, "{}", print_impl(inner_impl, false, cx))?;
        }
        w.write_str("</h3>")?;

        let is_trait = inner_impl.trait_.is_some();
        if is_trait && let Some(portability) = portability(&i.impl_item, Some(parent)) {
            write!(
                w,
                "<span class=\"item-info\">\
                    <div class=\"stab portability\">{portability}</div>\
                </span>",
            )?;
        }

        if let Some(doc) = doc {
            if impl_is_empty {
                w.write_str(
                    "\
<div class=\"item-info\">\
    <div class=\"stab empty-impl\">This impl block contains no public items.</div>\
</div>",
                )?;
            }
            write!(w, "<div class=\"docblock\">{doc}</div>")?;
        }

        w.write_str("</section>")
    })
}

pub(crate) fn small_url_encode(s: String) -> String {
    // These characters don't need to be escaped in a URI.
    // See https://url.spec.whatwg.org/#query-percent-encode-set
    // and https://url.spec.whatwg.org/#urlencoded-parsing
    // and https://url.spec.whatwg.org/#url-code-points
    fn dont_escape(c: u8) -> bool {
        c.is_ascii_alphanumeric()
            || c == b'-'
            || c == b'_'
            || c == b'.'
            || c == b','
            || c == b'~'
            || c == b'!'
            || c == b'\''
            || c == b'('
            || c == b')'
            || c == b'*'
            || c == b'/'
            || c == b';'
            || c == b':'
            || c == b'?'
            // As described in urlencoded-parsing, the
            // first `=` is the one that separates key from
            // value. Following `=`s are part of the value.
            || c == b'='
    }
    let mut st = String::new();
    let mut last_match = 0;
    for (idx, b) in s.bytes().enumerate() {
        if dont_escape(b) {
            continue;
        }

        if last_match != idx {
            // Invariant: `idx` must be the first byte in a character at this point.
            st += &s[last_match..idx];
        }
        if b == b' ' {
            // URL queries are decoded with + replaced with SP.
            // While the same is not true for hashes, rustdoc only needs to be
            // consistent with itself when encoding them.
            st += "+";
        } else {
            write!(st, "%{b:02X}").unwrap();
        }
        // Invariant: if the current byte is not at the start of a multi-byte character,
        // we need to get down here so that when the next turn of the loop comes around,
        // last_match winds up equalling idx.
        //
        // In other words, dont_escape must always return `false` in multi-byte character.
        last_match = idx + 1;
    }

    if last_match != 0 {
        st += &s[last_match..];
        st
    } else {
        s
    }
}

fn get_id_for_impl(tcx: TyCtxt<'_>, impl_id: ItemId) -> String {
    use rustc_middle::ty::print::with_forced_trimmed_paths;
    let (type_, trait_) = match impl_id {
        ItemId::Auto { trait_, for_ } => {
            let ty = tcx.type_of(for_).skip_binder();
            (ty, Some(ty::TraitRef::new(tcx, trait_, [ty])))
        }
        ItemId::Blanket { impl_id, .. } | ItemId::DefId(impl_id) => {
            if let Some(trait_ref) = tcx.impl_opt_trait_ref(impl_id) {
                let trait_ref = trait_ref.skip_binder();
                (trait_ref.self_ty(), Some(trait_ref))
            } else {
                (tcx.type_of(impl_id).skip_binder(), None)
            }
        }
    };
    with_forced_trimmed_paths!(small_url_encode(if let Some(trait_) = trait_ {
        format!("impl-{trait_}-for-{type_}", trait_ = trait_.print_only_trait_path())
    } else {
        format!("impl-{type_}")
    }))
}

fn extract_for_impl_name(item: &clean::Item, cx: &Context<'_>) -> Option<(String, String)> {
    match item.kind {
        clean::ItemKind::ImplItem(ref i) if i.trait_.is_some() => {
            // Alternative format produces no URLs,
            // so this parameter does nothing.
            Some((
                format!("{:#}", print_type(&i.for_, cx)),
                get_id_for_impl(cx.tcx(), item.item_id),
            ))
        }
        _ => None,
    }
}

/// Returns the list of implementations for the primitive reference type, filtering out any
/// implementations that are on concrete or partially generic types, only keeping implementations
/// of the form `impl<T> Trait for &T`.
pub(crate) fn get_filtered_impls_for_reference<'a>(
    shared: &'a SharedContext<'_>,
    it: &clean::Item,
) -> (Vec<&'a Impl>, Vec<&'a Impl>, Vec<&'a Impl>) {
    let def_id = it.item_id.expect_def_id();
    // If the reference primitive is somehow not defined, exit early.
    let Some(v) = shared.cache.impls.get(&def_id) else {
        return (Vec::new(), Vec::new(), Vec::new());
    };
    // Since there is no "direct implementation" on the reference primitive type, we filter out
    // every implementation which isn't a trait implementation.
    let traits = v.iter().filter(|i| i.inner_impl().trait_.is_some());
    let (synthetic, concrete): (Vec<&Impl>, Vec<&Impl>) =
        traits.partition(|t| t.inner_impl().kind.is_auto());

    let (blanket_impl, concrete): (Vec<&Impl>, _) =
        concrete.into_iter().partition(|t| t.inner_impl().kind.is_blanket());
    // Now we keep only references over full generic types.
    let concrete: Vec<_> = concrete
        .into_iter()
        .filter(|t| match t.inner_impl().for_ {
            clean::Type::BorrowedRef { ref type_, .. } => type_.is_full_generic(),
            _ => false,
        })
        .collect();

    (concrete, synthetic, blanket_impl)
}

#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash)]
pub(crate) enum ItemSection {
    Reexports,
    PrimitiveTypes,
    Modules,
    Macros,
    Structs,
    Enums,
    Constants,
    Statics,
    Traits,
    Functions,
    TypeAliases,
    Unions,
    Implementations,
    TypeMethods,
    Methods,
    StructFields,
    Variants,
    AssociatedTypes,
    AssociatedConstants,
    ForeignTypes,
    Keywords,
    Attributes,
    AttributeMacros,
    DeriveMacros,
    TraitAliases,
}

impl ItemSection {
    const ALL: &'static [Self] = {
        use ItemSection::*;
        // NOTE: The order here affects the order in the UI.
        // Keep this synchronized with addSidebarItems in main.js
        &[
            Reexports,
            PrimitiveTypes,
            Modules,
            Macros,
            Structs,
            Enums,
            Constants,
            Statics,
            Traits,
            Functions,
            TypeAliases,
            Unions,
            Implementations,
            TypeMethods,
            Methods,
            StructFields,
            Variants,
            AssociatedTypes,
            AssociatedConstants,
            ForeignTypes,
            Keywords,
            Attributes,
            AttributeMacros,
            DeriveMacros,
            TraitAliases,
        ]
    };

    fn id(self) -> &'static str {
        match self {
            Self::Reexports => "reexports",
            Self::Modules => "modules",
            Self::Structs => "structs",
            Self::Unions => "unions",
            Self::Enums => "enums",
            Self::Functions => "functions",
            Self::TypeAliases => "types",
            Self::Statics => "statics",
            Self::Constants => "constants",
            Self::Traits => "traits",
            Self::Implementations => "impls",
            Self::TypeMethods => "tymethods",
            Self::Methods => "methods",
            Self::StructFields => "fields",
            Self::Variants => "variants",
            Self::Macros => "macros",
            Self::PrimitiveTypes => "primitives",
            Self::AssociatedTypes => "associated-types",
            Self::AssociatedConstants => "associated-consts",
            Self::ForeignTypes => "foreign-types",
            Self::Keywords => "keywords",
            Self::Attributes => "attributes",
            Self::AttributeMacros => "attributes",
            Self::DeriveMacros => "derives",
            Self::TraitAliases => "trait-aliases",
        }
    }

    fn name(self) -> &'static str {
        match self {
            Self::Reexports => "Re-exports",
            Self::Modules => "Modules",
            Self::Structs => "Structs",
            Self::Unions => "Unions",
            Self::Enums => "Enums",
            Self::Functions => "Functions",
            Self::TypeAliases => "Type Aliases",
            Self::Statics => "Statics",
            Self::Constants => "Constants",
            Self::Traits => "Traits",
            Self::Implementations => "Implementations",
            Self::TypeMethods => "Type Methods",
            Self::Methods => "Methods",
            Self::StructFields => "Struct Fields",
            Self::Variants => "Variants",
            Self::Macros => "Macros",
            Self::PrimitiveTypes => "Primitive Types",
            Self::AssociatedTypes => "Associated Types",
            Self::AssociatedConstants => "Associated Constants",
            Self::ForeignTypes => "Foreign Types",
            Self::Keywords => "Keywords",
            Self::Attributes => "Attributes",
            Self::AttributeMacros => "Attribute Macros",
            Self::DeriveMacros => "Derive Macros",
            Self::TraitAliases => "Trait Aliases",
        }
    }
}

fn item_ty_to_section(ty: ItemType) -> ItemSection {
    match ty {
        ItemType::ExternCrate | ItemType::Import => ItemSection::Reexports,
        ItemType::Module => ItemSection::Modules,
        ItemType::Struct => ItemSection::Structs,
        ItemType::Union => ItemSection::Unions,
        ItemType::Enum => ItemSection::Enums,
        ItemType::Function => ItemSection::Functions,
        ItemType::TypeAlias => ItemSection::TypeAliases,
        ItemType::Static => ItemSection::Statics,
        ItemType::Constant => ItemSection::Constants,
        ItemType::Trait => ItemSection::Traits,
        ItemType::Impl => ItemSection::Implementations,
        ItemType::TyMethod => ItemSection::TypeMethods,
        ItemType::Method => ItemSection::Methods,
        ItemType::StructField => ItemSection::StructFields,
        ItemType::Variant => ItemSection::Variants,
        ItemType::Macro => ItemSection::Macros,
        ItemType::Primitive => ItemSection::PrimitiveTypes,
        ItemType::AssocType => ItemSection::AssociatedTypes,
        ItemType::AssocConst => ItemSection::AssociatedConstants,
        ItemType::ForeignType => ItemSection::ForeignTypes,
        ItemType::Keyword => ItemSection::Keywords,
        ItemType::Attribute => ItemSection::Attributes,
        ItemType::ProcAttribute => ItemSection::AttributeMacros,
        ItemType::ProcDerive => ItemSection::DeriveMacros,
        ItemType::TraitAlias => ItemSection::TraitAliases,
    }
}

/// Returns a list of all paths used in the type.
/// This is used to help deduplicate imported impls
/// for reexported types. If any of the contained
/// types are re-exported, we don't use the corresponding
/// entry from the js file, as inlining will have already
/// picked up the impl
fn collect_paths_for_type(first_ty: &clean::Type, cache: &Cache) -> Vec<String> {
    let mut out = Vec::new();
    let mut visited = FxHashSet::default();
    let mut work = VecDeque::new();

    let mut process_path = |did: DefId| {
        let get_extern = || cache.external_paths.get(&did).map(|s| &s.0);
        let fqp = cache.exact_paths.get(&did).or_else(get_extern);

        if let Some(path) = fqp {
            out.push(join_path_syms(path));
        }
    };

    work.push_back(first_ty);

    while let Some(ty) = work.pop_front() {
        if !visited.insert(ty) {
            continue;
        }

        match ty {
            clean::Type::Path { path } => process_path(path.def_id()),
            clean::Type::Tuple(tys) => {
                work.extend(tys.iter());
            }
            clean::Type::Slice(ty) => {
                work.push_back(ty);
            }
            clean::Type::Array(ty, _) => {
                work.push_back(ty);
            }
            clean::Type::RawPointer(_, ty) => {
                work.push_back(ty);
            }
            clean::Type::BorrowedRef { type_, .. } => {
                work.push_back(type_);
            }
            clean::Type::QPath(clean::QPathData { self_type, trait_, .. }) => {
                work.push_back(self_type);
                if let Some(trait_) = trait_ {
                    process_path(trait_.def_id());
                }
            }
            _ => {}
        }
    }
    out
}

const MAX_FULL_EXAMPLES: usize = 5;
const NUM_VISIBLE_LINES: usize = 10;

/// Generates the HTML for example call locations generated via the --scrape-examples flag.
fn render_call_locations<W: fmt::Write>(
    mut w: W,
    cx: &Context<'_>,
    item: &clean::Item,
) -> fmt::Result {
    let tcx = cx.tcx();
    let def_id = item.item_id.expect_def_id();
    let key = tcx.def_path_hash(def_id);
    let Some(call_locations) = cx.shared.call_locations.get(&key) else { return Ok(()) };

    // Generate a unique ID so users can link to this section for a given method
    let id = cx.derive_id("scraped-examples");
    write!(
        &mut w,
        "<div class=\"docblock scraped-example-list\">\
          <span></span>\
          <h5 id=\"{id}\">\
             <a href=\"#{id}\">Examples found in repository</a>\
             <a class=\"scrape-help\" href=\"{root_path}scrape-examples-help.html\">?</a>\
          </h5>",
        root_path = cx.root_path(),
        id = id
    )?;

    // Create a URL to a particular location in a reverse-dependency's source file
    let link_to_loc = |call_data: &CallData, loc: &CallLocation| -> (String, String) {
        let (line_lo, line_hi) = loc.call_expr.line_span;
        let (anchor, title) = if line_lo == line_hi {
            ((line_lo + 1).to_string(), format!("line {}", line_lo + 1))
        } else {
            (
                format!("{}-{}", line_lo + 1, line_hi + 1),
                format!("lines {}-{}", line_lo + 1, line_hi + 1),
            )
        };
        let url = format!("{}{}#{anchor}", cx.root_path(), call_data.url);
        (url, title)
    };

    // Generate the HTML for a single example, being the title and code block
    let write_example = |w: &mut W, (path, call_data): (&PathBuf, &CallData)| -> bool {
        let contents = match fs::read_to_string(path) {
            Ok(contents) => contents,
            Err(err) => {
                let span = item.span(tcx).map_or(DUMMY_SP, |span| span.inner());
                tcx.dcx().span_err(span, format!("failed to read file {}: {err}", path.display()));
                return false;
            }
        };

        // To reduce file sizes, we only want to embed the source code needed to understand the example, not
        // the entire file. So we find the smallest byte range that covers all items enclosing examples.
        assert!(!call_data.locations.is_empty());
        let min_loc =
            call_data.locations.iter().min_by_key(|loc| loc.enclosing_item.byte_span.0).unwrap();
        let byte_min = min_loc.enclosing_item.byte_span.0;
        let line_min = min_loc.enclosing_item.line_span.0;
        let max_loc =
            call_data.locations.iter().max_by_key(|loc| loc.enclosing_item.byte_span.1).unwrap();
        let byte_max = max_loc.enclosing_item.byte_span.1;
        let line_max = max_loc.enclosing_item.line_span.1;

        // The output code is limited to that byte range.
        let contents_subset = &contents[(byte_min as usize)..(byte_max as usize)];

        // The call locations need to be updated to reflect that the size of the program has changed.
        // Specifically, the ranges are all subtracted by `byte_min` since that's the new zero point.
        let (mut byte_ranges, line_ranges): (Vec<_>, Vec<_>) = call_data
            .locations
            .iter()
            .map(|loc| {
                let (byte_lo, byte_hi) = loc.call_ident.byte_span;
                let (line_lo, line_hi) = loc.call_expr.line_span;
                let byte_range = (byte_lo - byte_min, byte_hi - byte_min);

                let line_range = (line_lo - line_min, line_hi - line_min);
                let (line_url, line_title) = link_to_loc(call_data, loc);

                (byte_range, (line_range, line_url, line_title))
            })
            .unzip();

        let (_, init_url, init_title) = &line_ranges[0];
        let needs_expansion = line_max - line_min > NUM_VISIBLE_LINES;
        let locations_encoded = serde_json::to_string(&line_ranges).unwrap();

        // For scraped examples, we don't need a real span from the SourceMap.
        // The URL is already provided in ScrapedInfo, and sources::print_src
        // will use that directly. We use DUMMY_SP as a placeholder.
        // Note: DUMMY_SP is safe here because href_from_span won't be called
        // for scraped examples.
        let file_span = rustc_span::DUMMY_SP;

        let mut decoration_info = FxIndexMap::default();
        decoration_info.insert("highlight focus", vec![byte_ranges.remove(0)]);
        decoration_info.insert("highlight", byte_ranges);

        sources::print_src(
            w,
            contents_subset,
            file_span,
            cx,
            &cx.root_path(),
            &highlight::DecorationInfo(decoration_info),
            &sources::SourceContext::Embedded(sources::ScrapedInfo {
                needs_expansion,
                offset: line_min,
                name: &call_data.display_name,
                url: init_url,
                title: init_title,
                locations: locations_encoded,
            }),
        )
        .unwrap();

        true
    };

    // The call locations are output in sequence, so that sequence needs to be determined.
    // Ideally the most "relevant" examples would be shown first, but there's no general algorithm
    // for determining relevance. We instead proxy relevance with the following heuristics:
    //   1. Code written to be an example is better than code not written to be an example, e.g.
    //      a snippet from examples/foo.rs is better than src/lib.rs. We don't know the Cargo
    //      directory structure in Rustdoc, so we proxy this by prioritizing code that comes from
    //      a --crate-type bin.
    //   2. Smaller examples are better than large examples. So we prioritize snippets that have
    //      the smallest number of lines in their enclosing item.
    //   3. Finally we sort by the displayed file name, which is arbitrary but prevents the
    //      ordering of examples from randomly changing between Rustdoc invocations.
    let ordered_locations = {
        fn sort_criterion<'a>(
            (_, call_data): &(&PathBuf, &'a CallData),
        ) -> (bool, u32, &'a String) {
            // Use the first location because that's what the user will see initially
            let (lo, hi) = call_data.locations[0].enclosing_item.byte_span;
            (!call_data.is_bin, hi - lo, &call_data.display_name)
        }

        let mut locs = call_locations.iter().collect::<Vec<_>>();
        locs.sort_by_key(sort_criterion);
        locs
    };

    let mut it = ordered_locations.into_iter().peekable();

    // An example may fail to write if its source can't be read for some reason, so this method
    // continues iterating until a write succeeds
    let write_and_skip_failure = |w: &mut W, it: &mut Peekable<_>| {
        for example in it.by_ref() {
            if write_example(&mut *w, example) {
                break;
            }
        }
    };

    // Write just one example that's visible by default in the method's description.
    write_and_skip_failure(&mut w, &mut it);

    // Then add the remaining examples in a hidden section.
    if it.peek().is_some() {
        write!(
            w,
            "<details class=\"toggle more-examples-toggle\">\
                  <summary class=\"hideme\">\
                     <span>More examples</span>\
                  </summary>\
                  <div class=\"hide-more\">Hide additional examples</div>\
                  <div class=\"more-scraped-examples\">\
                    <div class=\"toggle-line\"><div class=\"toggle-line-inner\"></div></div>"
        )?;

        // Only generate inline code for MAX_FULL_EXAMPLES number of examples. Otherwise we could
        // make the page arbitrarily huge!
        for _ in 0..MAX_FULL_EXAMPLES {
            write_and_skip_failure(&mut w, &mut it);
        }

        // For the remaining examples, generate a <ul> containing links to the source files.
        if it.peek().is_some() {
            w.write_str(
                r#"<div class="example-links">Additional examples can be found in:<br><ul>"#,
            )?;
            it.try_for_each(|(_, call_data)| {
                let (url, _) = link_to_loc(call_data, &call_data.locations[0]);
                write!(
                    w,
                    r#"<li><a href="{url}">{name}</a></li>"#,
                    url = url,
                    name = call_data.display_name
                )
            })?;
            w.write_str("</ul></div>")?;
        }

        w.write_str("</div></details>")?;
    }

    w.write_str("</div>")
}

fn render_attributes_in_code(
    w: &mut impl fmt::Write,
    item: &clean::Item,
    prefix: &str,
    cx: &Context<'_>,
) -> fmt::Result {
    render_attributes_in_code_with_options(w, item, prefix, cx, true, "")
}

pub(super) fn render_attributes_in_code_with_options(
    w: &mut impl fmt::Write,
    item: &clean::Item,
    prefix: &str,
    cx: &Context<'_>,
    render_doc_hidden: bool,
    open_tag: &str,
) -> fmt::Result {
    w.write_str(open_tag)?;
    if render_doc_hidden && item.is_doc_hidden() {
        render_code_attribute(prefix, "#[doc(hidden)]", w)?;
    }
    for attr in &item.attrs.other_attrs {
        let hir::Attribute::Parsed(kind) = attr else { continue };
        let attr = match kind {
            AttributeKind::LinkSection { name, .. } => {
                Cow::Owned(format!("#[unsafe(link_section = {})]", Escape(&format!("{name:?}"))))
            }
            AttributeKind::NoMangle(..) => Cow::Borrowed("#[unsafe(no_mangle)]"),
            AttributeKind::ExportName { name, .. } => {
                Cow::Owned(format!("#[unsafe(export_name = {})]", Escape(&format!("{name:?}"))))
            }
            AttributeKind::NonExhaustive(..) => Cow::Borrowed("#[non_exhaustive]"),
            _ => continue,
        };
        render_code_attribute(prefix, attr.as_ref(), w)?;
    }

    if let Some(def_id) = item.def_id()
        && let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id)
    {
        render_code_attribute(prefix, &repr, w)?;
    }
    Ok(())
}

fn render_repr_attribute_in_code(
    w: &mut impl fmt::Write,
    cx: &Context<'_>,
    def_id: DefId,
) -> fmt::Result {
    if let Some(repr) = repr_attribute(cx.tcx(), cx.cache(), def_id) {
        render_code_attribute("", &repr, w)?;
    }
    Ok(())
}

fn render_code_attribute(prefix: &str, attr: &str, w: &mut impl fmt::Write) -> fmt::Result {
    write!(w, "<div class=\"code-attribute\">{prefix}{attr}</div>")
}

/// Compute the *public* `#[repr]` of the item given by `DefId`.
///
/// Read more about it here:
/// <https://doc.rust-lang.org/nightly/rustdoc/advanced-features.html#repr-documenting-the-representation-of-a-type>.
fn repr_attribute<'tcx>(
    tcx: TyCtxt<'tcx>,
    cache: &Cache,
    def_id: DefId,
) -> Option<Cow<'static, str>> {
    let adt = match tcx.def_kind(def_id) {
        DefKind::Struct | DefKind::Enum | DefKind::Union => tcx.adt_def(def_id),
        _ => return None,
    };
    let repr = adt.repr();

    let is_visible = |def_id| cache.document_hidden || !tcx.is_doc_hidden(def_id);
    let is_public_field = |field: &ty::FieldDef| {
        (cache.document_private || field.vis.is_public()) && is_visible(field.did)
    };

    if repr.transparent() {
        // The transparent repr is public iff the non-1-ZST field is public and visible or
        // – in case all fields are 1-ZST fields — at least one field is public and visible.
        let is_public = 'is_public: {
            // `#[repr(transparent)]` can only be applied to structs and single-variant enums.
            let var = adt.variant(rustc_abi::FIRST_VARIANT); // the first and only variant

            if !is_visible(var.def_id) {
                break 'is_public false;
            }

            // Side note: There can only ever be one or zero non-1-ZST fields.
            let non_1zst_field = var.fields.iter().find(|field| {
                let ty = ty::TypingEnv::post_analysis(tcx, field.did)
                    .as_query_input(tcx.type_of(field.did).instantiate_identity().skip_norm_wip());
                tcx.layout_of(ty).is_ok_and(|layout| !layout.is_1zst())
            });

            match non_1zst_field {
                Some(field) => is_public_field(field),
                None => var.fields.is_empty() || var.fields.iter().any(is_public_field),
            }
        };

        // Since the transparent repr can't have any other reprs or
        // repr modifiers beside it, we can safely return early here.
        return is_public.then(|| "#[repr(transparent)]".into());
    }

    // Fast path which avoids looking through the variants and fields in
    // the common case of no `#[repr]` or in the case of `#[repr(Rust)]`.
    // FIXME: This check is not very robust / forward compatible!
    if !repr.c()
        && !repr.simd()
        && repr.int.is_none()
        && repr.pack.is_none()
        && repr.align.is_none()
    {
        return None;
    }

    // The repr is public iff all components are public and visible.
    let is_public = adt
        .variants()
        .iter()
        .all(|variant| is_visible(variant.def_id) && variant.fields.iter().all(is_public_field));
    if !is_public {
        return None;
    }

    let mut result = Vec::<Cow<'_, _>>::new();

    if repr.c() {
        result.push("C".into());
    }
    if repr.simd() {
        result.push("simd".into());
    }
    if let Some(int) = repr.int {
        let prefix = if int.is_signed() { 'i' } else { 'u' };
        let int = match int {
            rustc_abi::IntegerType::Pointer(_) => format!("{prefix}size"),
            rustc_abi::IntegerType::Fixed(int, _) => {
                format!("{prefix}{}", int.size().bytes() * 8)
            }
        };
        result.push(int.into());
    }

    // Render modifiers last.
    if let Some(pack) = repr.pack {
        result.push(format!("packed({})", pack.bytes()).into());
    }
    if let Some(align) = repr.align {
        result.push(format!("align({})", align.bytes()).into());
    }

    (!result.is_empty()).then(|| format!("#[repr({})]", result.join(", ")).into())
}
