//! 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::symbol::{Symbol, sym};
use rustc_span::{BytePos, DUMMY_SP, FileName, RealFileName};
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, 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_default_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,
};
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

/// 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) ty: ItemType,
    pub(crate) defid: Option<DefId>,
    pub(crate) name: Symbol,
    pub(crate) module_path: Vec<Symbol>,
    pub(crate) desc: String,
    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) search_type: Option<IndexItemFunctionType>,
    pub(crate) aliases: Box<[Symbol]>,
    pub(crate) deprecation: Option<Deprecation>,
}

/// 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(box 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 html = MarkdownItemInfo(note, &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 {
            // FIXME: `.value()` uses `clean::utils::format_integer_with_underscore_sep` under the
            //        hood which adds noisy underscores and a type suffix to number literals.
            //        This hurts readability in this context especially when more complex expressions
            //        are involved and it doesn't add much of value.
            //        Find a way to print constants here without all that jazz.
            let repr = konst.value(tcx).unwrap_or_else(|| konst.expr(tcx));
            if match value {
                AssocConstValue::TraitDefault(_) => true, // always show
                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| {
        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 = print_default_space(meth.is_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());
        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(box 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;

            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) {
                            // 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 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}\" open><summary>")?;
            }
            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}\">\
                                {}",
                            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}\">\
                            {}",
                        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}\">\
                            {}",
                        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}\">\
                            {}",
                        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}\">\
                            {}",
                        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());
            if toggled {
                close_tags.push("</details>");
                write!(
                    w,
                    "<details class=\"toggle implementors-toggle\"{}>\
                        <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 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(box 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();

        let source_map = tcx.sess.source_map();
        let files = source_map.files();
        let local = tcx.sess.local_crate_source_file().unwrap();

        let get_file_start_pos = || {
            let crate_src = local.clone().into_local_path()?;
            let abs_crate_src = crate_src.canonicalize().ok()?;
            let crate_root = abs_crate_src.parent()?.parent()?;
            let rel_path = path.strip_prefix(crate_root).ok()?;
            files
                .iter()
                .find(|file| match &file.name {
                    FileName::Real(RealFileName::LocalPath(other_path)) => rel_path == other_path,
                    _ => false,
                })
                .map(|file| file.start_pos)
        };

        // Look for the example file in the source map if it exists, otherwise
        // return a span to the local crate's source file
        let Some(file_span) = get_file_start_pos()
            .or_else(|| {
                files
                    .iter()
                    .find(|file| match &file.name {
                        FileName::Real(file_name) => file_name == &local,
                        _ => false,
                    })
                    .map(|file| file.start_pos)
            })
            .map(|start_pos| {
                rustc_span::Span::with_root_ctxt(
                    start_pos + BytePos(byte_min),
                    start_pos + BytePos(byte_max),
                )
            })
        else {
            // if the fallback span can't be built, don't render the code for this example
            return false;
        };

        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 {
    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());
                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())
}
