//! 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, PrintWithSpace, href, print_abi_with_space, print_constness_with_space,
    print_default_space, print_generic_bounds, 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,
) {
    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("")).unwrap();
}

/// 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((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 = generics.print(cx),
            ty = ty.print(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 = generics.print(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, " = {}", default.print(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!("{:#}", g.print(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 = g.print(cx),
            decl = d.full_print(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],
) {
    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")
        )
        .unwrap();
    }

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

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

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

fn render_assoc_items_inner(
    mut w: &mut dyn fmt::Write,
    cx: &Context<'_>,
    containing_item: &clean::Item,
    it: DefId,
    what: AssocItemRender<'_>,
    derefs: &mut DefIdSet,
) {
    info!("Documenting associated items of {:?}", containing_item.name);
    let cache = &cx.shared.cache;
    let Some(v) = cache.impls.get(&it) else { return };
    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-{:#}", type_.print(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_ = trait_.print(cx),
                                    type_ = type_.print(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(),
            )
            .unwrap();
        }
    }

    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;
        }

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

/// `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,
) {
    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;
            }
        }
        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);
    }
}

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!("{:#}", ty.print(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>",
                impl_.for_.print(cx)
            )?;
            true
        } else {
            false
        };

        for (impl_, trait_did) in notable_impls {
            write!(f, "<div class=\"where\">{}</div>", impl_.print(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!("{:#}", ty.print(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)
                                    .unwrap();
                                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)
                            .unwrap();
                        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 trait_item in &impl_.items {
                match trait_item.kind {
                    clean::MethodItem(..) | clean::RequiredMethodItem(_) => {
                        methods.push(trait_item)
                    }
                    clean::RequiredAssocTypeItem(..) | clean::AssocTypeItem(..) => {
                        assoc_types.push(trait_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,
                            trait_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, "{}", inner_impl.print(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, "{}", inner_impl.print(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!("{:#}", i.for_.print(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<'_>,
) {
    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);
    }
}

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

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

/// 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())
}
