//! HTML formatting module
//!
//! This module contains a large number of `Display` implementations for
//! various types in `rustdoc::clean`.
//!
//! These implementations all emit HTML. As an internal implementation detail,
//! some of them support an alternate format that emits text, but that should
//! not be used external to this module.

use std::cmp::Ordering;
use std::fmt::{self, Display, Write};
use std::iter::{self, once};
use std::slice;

use itertools::{Either, Itertools};
use rustc_abi::ExternAbi;
use rustc_ast::join_path_syms;
use rustc_data_structures::fx::FxHashSet;
use rustc_hir as hir;
use rustc_hir::def::{DefKind, MacroKinds};
use rustc_hir::def_id::{DefId, LOCAL_CRATE};
use rustc_hir::{ConstStability, StabilityLevel, StableSince};
use rustc_metadata::creader::CStore;
use rustc_middle::ty::{self, TyCtxt, TypingMode};
use rustc_span::symbol::kw;
use rustc_span::{Symbol, sym};
use tracing::{debug, trace};

use super::url_parts_builder::UrlPartsBuilder;
use crate::clean::types::ExternalLocation;
use crate::clean::utils::find_nearest_parent_module;
use crate::clean::{self, ExternalCrate, PrimitiveType};
use crate::display::{Joined as _, MaybeDisplay as _, WithOpts, Wrapped};
use crate::formats::cache::Cache;
use crate::formats::item_type::ItemType;
use crate::html::escape::{Escape, EscapeBodyText};
use crate::html::render::Context;
use crate::passes::collect_intra_doc_links::UrlFragment;

pub(crate) fn print_generic_bounds(
    bounds: &[clean::GenericBound],
    cx: &Context<'_>,
) -> impl Display {
    fmt::from_fn(move |f| {
        let mut bounds_dup = FxHashSet::default();

        bounds
            .iter()
            .filter(move |b| bounds_dup.insert(*b))
            .map(|bound| print_generic_bound(bound, cx))
            .joined(" + ", f)
    })
}

pub(crate) fn print_generic_param_def(
    generic_param: &clean::GenericParamDef,
    cx: &Context<'_>,
) -> impl Display {
    fmt::from_fn(move |f| match &generic_param.kind {
        clean::GenericParamDefKind::Lifetime { outlives } => {
            write!(f, "{}", generic_param.name)?;

            if !outlives.is_empty() {
                f.write_str(": ")?;
                outlives.iter().map(|lt| print_lifetime(lt)).joined(" + ", f)?;
            }

            Ok(())
        }
        clean::GenericParamDefKind::Type { bounds, default, .. } => {
            f.write_str(generic_param.name.as_str())?;

            if !bounds.is_empty() {
                f.write_str(": ")?;
                print_generic_bounds(bounds, cx).fmt(f)?;
            }

            if let Some(ty) = default {
                f.write_str(" = ")?;
                print_type(ty, cx).fmt(f)?;
            }

            Ok(())
        }
        clean::GenericParamDefKind::Const { ty, default, .. } => {
            write!(f, "const {}: ", generic_param.name)?;
            print_type(ty, cx).fmt(f)?;

            if let Some(default) = default {
                f.write_str(" = ")?;
                if f.alternate() {
                    write!(f, "{default}")?;
                } else {
                    write!(f, "{}", Escape(default))?;
                }
            }

            Ok(())
        }
    })
}

pub(crate) fn print_generics(generics: &clean::Generics, cx: &Context<'_>) -> impl Display {
    let mut real_params = generics.params.iter().filter(|p| !p.is_synthetic_param()).peekable();
    if real_params.peek().is_none() {
        None
    } else {
        Some(Wrapped::with_angle_brackets().wrap_fn(move |f| {
            real_params.clone().map(|g| print_generic_param_def(g, cx)).joined(", ", f)
        }))
    }
    .maybe_display()
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub(crate) enum Ending {
    Newline,
    NoNewline,
}

fn print_where_predicate(predicate: &clean::WherePredicate, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        match predicate {
            clean::WherePredicate::BoundPredicate { ty, bounds, bound_params } => {
                print_higher_ranked_params_with_space(bound_params, cx, "for").fmt(f)?;
                print_type(ty, cx).fmt(f)?;
                f.write_str(":")?;
                if !bounds.is_empty() {
                    f.write_str(" ")?;
                    print_generic_bounds(bounds, cx).fmt(f)?;
                }
                Ok(())
            }
            clean::WherePredicate::RegionPredicate { lifetime, bounds } => {
                // We don't need to check `alternate` since we can be certain that neither
                // the lifetime nor the bounds contain any characters which need escaping.
                write!(f, "{}:", print_lifetime(lifetime))?;
                if !bounds.is_empty() {
                    write!(f, " {}", print_generic_bounds(bounds, cx))?;
                }
                Ok(())
            }
            clean::WherePredicate::EqPredicate { lhs, rhs } => {
                let opts = WithOpts::from(f);
                write!(
                    f,
                    "{} == {}",
                    opts.display(print_qpath_data(lhs, cx)),
                    opts.display(print_term(rhs, cx)),
                )
            }
        }
    })
}

/// * The Generics from which to emit a where-clause.
/// * The number of spaces to indent each line with.
/// * Whether the where-clause needs to add a comma and newline after the last bound.
pub(crate) fn print_where_clause(
    gens: &clean::Generics,
    cx: &Context<'_>,
    indent: usize,
    ending: Ending,
) -> Option<impl Display> {
    if gens.where_predicates.is_empty() {
        return None;
    }

    Some(fmt::from_fn(move |f| {
        let where_preds = fmt::from_fn(|f| {
            gens.where_predicates
                .iter()
                .map(|predicate| {
                    fmt::from_fn(|f| {
                        if f.alternate() {
                            f.write_str(" ")?;
                        } else {
                            f.write_str("\n")?;
                        }
                        print_where_predicate(predicate, cx).fmt(f)
                    })
                })
                .joined(",", f)
        });

        let clause = if f.alternate() {
            if ending == Ending::Newline {
                format!(" where{where_preds},")
            } else {
                format!(" where{where_preds}")
            }
        } else {
            let mut br_with_padding = String::with_capacity(6 * indent + 28);
            br_with_padding.push('\n');

            let where_indent = 3;
            let padding_amount = if ending == Ending::Newline {
                indent + 4
            } else if indent == 0 {
                4
            } else {
                indent + where_indent + "where ".len()
            };

            for _ in 0..padding_amount {
                br_with_padding.push(' ');
            }
            let where_preds = where_preds.to_string().replace('\n', &br_with_padding);

            if ending == Ending::Newline {
                let mut clause = " ".repeat(indent.saturating_sub(1));
                write!(clause, "<div class=\"where\">where{where_preds},</div>")?;
                clause
            } else {
                // insert a newline after a single space but before multiple spaces at the start
                if indent == 0 {
                    format!("\n<span class=\"where\">where{where_preds}</span>")
                } else {
                    // put the first one on the same line as the 'where' keyword
                    let where_preds = where_preds.replacen(&br_with_padding, " ", 1);

                    let mut clause = br_with_padding;
                    // +1 is for `\n`.
                    clause.truncate(indent + 1 + where_indent);

                    write!(clause, "<span class=\"where\">where{where_preds}</span>")?;
                    clause
                }
            }
        };
        write!(f, "{clause}")
    }))
}

#[inline]
pub(crate) fn print_lifetime(lt: &clean::Lifetime) -> &str {
    lt.0.as_str()
}

pub(crate) fn print_constant_kind(
    constant_kind: &clean::ConstantKind,
    tcx: TyCtxt<'_>,
) -> impl Display {
    let expr = constant_kind.expr(tcx);
    fmt::from_fn(
        move |f| {
            if f.alternate() { f.write_str(&expr) } else { write!(f, "{}", Escape(&expr)) }
        },
    )
}

fn print_poly_trait(poly_trait: &clean::PolyTrait, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        print_higher_ranked_params_with_space(&poly_trait.generic_params, cx, "for").fmt(f)?;
        print_path(&poly_trait.trait_, cx).fmt(f)
    })
}

pub(crate) fn print_generic_bound(
    generic_bound: &clean::GenericBound,
    cx: &Context<'_>,
) -> impl Display {
    fmt::from_fn(move |f| match generic_bound {
        clean::GenericBound::Outlives(lt) => f.write_str(print_lifetime(lt)),
        clean::GenericBound::TraitBound(ty, modifiers) => {
            // `const` and `[const]` trait bounds are experimental; don't render them.
            let hir::TraitBoundModifiers { polarity, constness: _ } = modifiers;
            f.write_str(match polarity {
                hir::BoundPolarity::Positive => "",
                hir::BoundPolarity::Maybe(_) => "?",
                hir::BoundPolarity::Negative(_) => "!",
            })?;
            print_poly_trait(ty, cx).fmt(f)
        }
        clean::GenericBound::Use(args) => {
            f.write_str("use")?;
            Wrapped::with_angle_brackets()
                .wrap_fn(|f| args.iter().map(|arg| arg.name()).joined(", ", f))
                .fmt(f)
        }
    })
}

fn print_generic_args(generic_args: &clean::GenericArgs, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        match generic_args {
            clean::GenericArgs::AngleBracketed { args, constraints } => {
                if !args.is_empty() || !constraints.is_empty() {
                    Wrapped::with_angle_brackets()
                        .wrap_fn(|f| {
                            [Either::Left(args), Either::Right(constraints)]
                                .into_iter()
                                .flat_map(Either::factor_into_iter)
                                .map(|either| {
                                    either.map_either(
                                        |arg| print_generic_arg(arg, cx),
                                        |constraint| print_assoc_item_constraint(constraint, cx),
                                    )
                                })
                                .joined(", ", f)
                        })
                        .fmt(f)?;
                }
            }
            clean::GenericArgs::Parenthesized { inputs, output } => {
                Wrapped::with_parens()
                    .wrap_fn(|f| inputs.iter().map(|ty| print_type(ty, cx)).joined(", ", f))
                    .fmt(f)?;
                if let Some(ref ty) = *output {
                    f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
                    print_type(ty, cx).fmt(f)?;
                }
            }
            clean::GenericArgs::ReturnTypeNotation => {
                f.write_str("(..)")?;
            }
        }
        Ok(())
    })
}

// Possible errors when computing href link source for a `DefId`
#[derive(PartialEq, Eq)]
pub(crate) enum HrefError {
    /// This item is known to rustdoc, but from a crate that does not have documentation generated.
    ///
    /// This can only happen for non-local items.
    ///
    /// # Example
    ///
    /// Crate `a` defines a public trait and crate `b` – the target crate that depends on `a` –
    /// implements it for a local type.
    /// We document `b` but **not** `a` (we only _build_ the latter – with `rustc`):
    ///
    /// ```sh
    /// rustc a.rs --crate-type=lib
    /// rustdoc b.rs --crate-type=lib --extern=a=liba.rlib
    /// ```
    ///
    /// Now, the associated items in the trait impl want to link to the corresponding item in the
    /// trait declaration (see `html::render::assoc_href_attr`) but it's not available since their
    /// *documentation (was) not built*.
    DocumentationNotBuilt,
    /// This can only happen for non-local items when `--document-private-items` is not passed.
    Private,
    // Not in external cache, href link should be in same page
    NotInExternalCache,
    /// Refers to an unnamable item, such as one defined within a function or const block.
    UnnamableItem,
}

/// Type representing information of an `href` attribute.
pub(crate) struct HrefInfo {
    /// URL to the item page.
    pub(crate) url: String,
    /// Kind of the item (used to generate the `title` attribute).
    pub(crate) kind: ItemType,
    /// Rust path to the item (used to generate the `title` attribute).
    pub(crate) rust_path: Vec<Symbol>,
}

/// This function is to get the external macro path because they are not in the cache used in
/// `href_with_root_path`.
fn generate_macro_def_id_path(
    def_id: DefId,
    cx: &Context<'_>,
    root_path: Option<&str>,
) -> Result<HrefInfo, HrefError> {
    let tcx = cx.tcx();
    let crate_name = tcx.crate_name(def_id.krate);
    let cache = cx.cache();

    let cstore = CStore::from_tcx(tcx);
    // We need this to prevent a `panic` when this function is used from intra doc links...
    if !cstore.has_crate_data(def_id.krate) {
        debug!("No data for crate {crate_name}");
        return Err(HrefError::NotInExternalCache);
    }
    let DefKind::Macro(kinds) = tcx.def_kind(def_id) else {
        unreachable!();
    };
    let item_type = if kinds == MacroKinds::DERIVE {
        ItemType::ProcDerive
    } else if kinds == MacroKinds::ATTR {
        ItemType::ProcAttribute
    } else {
        ItemType::Macro
    };
    let mut path = clean::inline::get_item_path(tcx, def_id, item_type);
    if path.len() < 2 {
        // The minimum we can have is the crate name followed by the macro name. If shorter, then
        // it means that `relative` was empty, which is an error.
        debug!("macro path cannot be empty!");
        return Err(HrefError::NotInExternalCache);
    }

    // FIXME: Try to use `iter().chain().once()` instead.
    let mut prev = None;
    if let Some(last) = path.pop() {
        path.push(Symbol::intern(&format!("{}.{last}.html", item_type.as_str())));
        prev = Some(last);
    }

    let url = match cache.extern_locations[&def_id.krate] {
        ExternalLocation::Remote(ref s) => {
            // `ExternalLocation::Remote` always end with a `/`.
            format!("{s}{path}", path = fmt::from_fn(|f| path.iter().joined("/", f)))
        }
        ExternalLocation::Local => {
            // `root_path` always end with a `/`.
            format!(
                "{root_path}{path}",
                root_path = root_path.unwrap_or(""),
                path = fmt::from_fn(|f| path.iter().joined("/", f))
            )
        }
        ExternalLocation::Unknown => {
            debug!("crate {crate_name} not in cache when linkifying macros");
            return Err(HrefError::NotInExternalCache);
        }
    };
    if let Some(prev) = prev {
        path.pop();
        path.push(prev);
    }
    Ok(HrefInfo { url, kind: item_type, rust_path: path })
}

fn generate_item_def_id_path(
    mut def_id: DefId,
    original_def_id: DefId,
    cx: &Context<'_>,
    root_path: Option<&str>,
) -> Result<HrefInfo, HrefError> {
    use rustc_middle::traits::ObligationCause;
    use rustc_trait_selection::infer::TyCtxtInferExt;
    use rustc_trait_selection::traits::query::normalize::QueryNormalizeExt;

    let tcx = cx.tcx();
    let crate_name = tcx.crate_name(def_id.krate);

    // No need to try to infer the actual parent item if it's not an associated item from the `impl`
    // block.
    if def_id != original_def_id && matches!(tcx.def_kind(def_id), DefKind::Impl { .. }) {
        let infcx = tcx.infer_ctxt().build(TypingMode::non_body_analysis());
        def_id = infcx
            .at(&ObligationCause::dummy(), tcx.param_env(def_id))
            .query_normalize(ty::Binder::dummy(tcx.type_of(def_id).instantiate_identity()))
            .map(|resolved| infcx.resolve_vars_if_possible(resolved.value))
            .ok()
            .and_then(|normalized| normalized.skip_binder().ty_adt_def())
            .map(|adt| adt.did())
            .unwrap_or(def_id);
    }

    let relative = clean::inline::item_relative_path(tcx, def_id);
    let fqp: Vec<Symbol> = once(crate_name).chain(relative).collect();

    let shortty = ItemType::from_def_id(def_id, tcx);
    let module_fqp = to_module_fqp(shortty, &fqp);
    let mut is_remote = false;

    let url_parts = url_parts(cx.cache(), def_id, module_fqp, &cx.current, &mut is_remote)?;
    let mut url_parts = make_href(root_path, shortty, url_parts, &fqp, is_remote);
    if def_id != original_def_id {
        let kind = ItemType::from_def_id(original_def_id, tcx);
        url_parts = format!("{url_parts}#{kind}.{}", tcx.item_name(original_def_id))
    };
    Ok(HrefInfo { url: url_parts, kind: shortty, rust_path: fqp })
}

/// Checks if the given defid refers to an item that is unnamable, such as one defined in a const block.
fn is_unnamable(tcx: TyCtxt<'_>, did: DefId) -> bool {
    let mut cur_did = did;
    while let Some(parent) = tcx.opt_parent(cur_did) {
        match tcx.def_kind(parent) {
            // items defined in these can be linked to, as long as they are visible
            DefKind::Mod | DefKind::ForeignMod => cur_did = parent,
            // items in impls can be linked to,
            // as long as we can link to the item the impl is on.
            // since associated traits are not a thing,
            // it should not be possible to refer to an impl item if
            // the base type is not namable.
            DefKind::Impl { .. } => return false,
            // everything else does not have docs generated for it
            _ => return true,
        }
    }
    return false;
}

fn to_module_fqp(shortty: ItemType, fqp: &[Symbol]) -> &[Symbol] {
    if shortty == ItemType::Module { fqp } else { &fqp[..fqp.len() - 1] }
}

fn url_parts(
    cache: &Cache,
    def_id: DefId,
    module_fqp: &[Symbol],
    relative_to: &[Symbol],
    is_remote: &mut bool,
) -> Result<UrlPartsBuilder, HrefError> {
    match cache.extern_locations[&def_id.krate] {
        ExternalLocation::Remote(ref s) => {
            *is_remote = true;
            let s = s.trim_end_matches('/');
            let mut builder = UrlPartsBuilder::singleton(s);
            builder.extend(module_fqp.iter().copied());
            Ok(builder)
        }
        ExternalLocation::Local => Ok(href_relative_parts(module_fqp, relative_to)),
        ExternalLocation::Unknown => Err(HrefError::DocumentationNotBuilt),
    }
}

fn make_href(
    root_path: Option<&str>,
    shortty: ItemType,
    mut url_parts: UrlPartsBuilder,
    fqp: &[Symbol],
    is_remote: bool,
) -> String {
    if !is_remote && let Some(root_path) = root_path {
        let root = root_path.trim_end_matches('/');
        url_parts.push_front(root);
    }
    debug!(?url_parts);
    match shortty {
        ItemType::Module => {
            url_parts.push("index.html");
        }
        _ => {
            let last = fqp.last().unwrap();
            url_parts.push_fmt(format_args!("{shortty}.{last}.html"));
        }
    }
    url_parts.finish()
}

pub(crate) fn href_with_root_path(
    original_did: DefId,
    cx: &Context<'_>,
    root_path: Option<&str>,
) -> Result<HrefInfo, HrefError> {
    let tcx = cx.tcx();
    let def_kind = tcx.def_kind(original_did);
    let did = match def_kind {
        DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
            // documented on their parent's page
            tcx.parent(original_did)
        }
        // If this a constructor, we get the parent (either a struct or a variant) and then
        // generate the link for this item.
        DefKind::Ctor(..) => return href_with_root_path(tcx.parent(original_did), cx, root_path),
        DefKind::ExternCrate => {
            // Link to the crate itself, not the `extern crate` item.
            if let Some(local_did) = original_did.as_local() {
                tcx.extern_mod_stmt_cnum(local_did).unwrap_or(LOCAL_CRATE).as_def_id()
            } else {
                original_did
            }
        }
        _ => original_did,
    };
    if is_unnamable(cx.tcx(), did) {
        return Err(HrefError::UnnamableItem);
    }
    let cache = cx.cache();
    let relative_to = &cx.current;

    if !original_did.is_local() {
        // If we are generating an href for the "jump to def" feature, then the only case we want
        // to ignore is if the item is `doc(hidden)` because we can't link to it.
        if root_path.is_some() {
            if tcx.is_doc_hidden(original_did) {
                return Err(HrefError::Private);
            }
        } else if !cache.effective_visibilities.is_directly_public(tcx, did)
            && !cache.document_private
            && !cache.primitive_locations.values().any(|&id| id == did)
        {
            return Err(HrefError::Private);
        }
    }

    let mut is_remote = false;
    let (fqp, shortty, url_parts) = match cache.paths.get(&did) {
        Some(&(ref fqp, shortty)) => (fqp, shortty, {
            let module_fqp = to_module_fqp(shortty, fqp.as_slice());
            debug!(?fqp, ?shortty, ?module_fqp);
            href_relative_parts(module_fqp, relative_to)
        }),
        None => {
            // Associated items are handled differently with "jump to def". The anchor is generated
            // directly here whereas for intra-doc links, we have some extra computation being
            // performed there.
            let def_id_to_get = if root_path.is_some() { original_did } else { did };
            if let Some(&(ref fqp, shortty)) = cache.external_paths.get(&def_id_to_get) {
                let module_fqp = to_module_fqp(shortty, fqp);
                (fqp, shortty, url_parts(cache, did, module_fqp, relative_to, &mut is_remote)?)
            } else if matches!(def_kind, DefKind::Macro(_)) {
                return generate_macro_def_id_path(did, cx, root_path);
            } else if did.is_local() {
                return Err(HrefError::Private);
            } else {
                return generate_item_def_id_path(did, original_did, cx, root_path);
            }
        }
    };
    Ok(HrefInfo {
        url: make_href(root_path, shortty, url_parts, fqp, is_remote),
        kind: shortty,
        rust_path: fqp.clone(),
    })
}

pub(crate) fn href(did: DefId, cx: &Context<'_>) -> Result<HrefInfo, HrefError> {
    href_with_root_path(did, cx, None)
}

/// Both paths should only be modules.
/// This is because modules get their own directories; that is, `std::vec` and `std::vec::Vec` will
/// both need `../iter/trait.Iterator.html` to get at the iterator trait.
pub(crate) fn href_relative_parts(fqp: &[Symbol], relative_to_fqp: &[Symbol]) -> UrlPartsBuilder {
    for (i, (f, r)) in fqp.iter().zip(relative_to_fqp.iter()).enumerate() {
        // e.g. linking to std::iter from std::vec (`dissimilar_part_count` will be 1)
        if f != r {
            let dissimilar_part_count = relative_to_fqp.len() - i;
            let fqp_module = &fqp[i..];
            return iter::repeat_n(sym::dotdot, dissimilar_part_count)
                .chain(fqp_module.iter().copied())
                .collect();
        }
    }
    match relative_to_fqp.len().cmp(&fqp.len()) {
        Ordering::Less => {
            // e.g. linking to std::sync::atomic from std::sync
            fqp[relative_to_fqp.len()..fqp.len()].iter().copied().collect()
        }
        Ordering::Greater => {
            // e.g. linking to std::sync from std::sync::atomic
            let dissimilar_part_count = relative_to_fqp.len() - fqp.len();
            iter::repeat_n(sym::dotdot, dissimilar_part_count).collect()
        }
        Ordering::Equal => {
            // linking to the same module
            UrlPartsBuilder::new()
        }
    }
}

pub(crate) fn link_tooltip(
    did: DefId,
    fragment: &Option<UrlFragment>,
    cx: &Context<'_>,
) -> impl fmt::Display {
    fmt::from_fn(move |f| {
        let cache = cx.cache();
        let Some((fqp, shortty)) = cache.paths.get(&did).or_else(|| cache.external_paths.get(&did))
        else {
            return Ok(());
        };
        let fqp = if *shortty == ItemType::Primitive {
            // primitives are documented in a crate, but not actually part of it
            slice::from_ref(fqp.last().unwrap())
        } else {
            fqp
        };
        if let &Some(UrlFragment::Item(id)) = fragment {
            write!(f, "{} ", cx.tcx().def_descr(id))?;
            for component in fqp {
                write!(f, "{component}::")?;
            }
            write!(f, "{}", cx.tcx().item_name(id))?;
        } else if !fqp.is_empty() {
            write!(f, "{shortty} ")?;
            write!(f, "{}", join_path_syms(fqp))?;
        }
        Ok(())
    })
}

/// Used to render a [`clean::Path`].
fn resolved_path(
    w: &mut fmt::Formatter<'_>,
    did: DefId,
    path: &clean::Path,
    print_all: bool,
    use_absolute: bool,
    cx: &Context<'_>,
) -> fmt::Result {
    let last = path.segments.last().unwrap();

    if print_all {
        for seg in &path.segments[..path.segments.len() - 1] {
            write!(w, "{}::", if seg.name == kw::PathRoot { "" } else { seg.name.as_str() })?;
        }
    }
    if w.alternate() {
        write!(w, "{}{:#}", last.name, print_generic_args(&last.args, cx))?;
    } else {
        let path = fmt::from_fn(|f| {
            if use_absolute {
                if let Ok(HrefInfo { rust_path, .. }) = href(did, cx) {
                    write!(
                        f,
                        "{path}::{anchor}",
                        path = join_path_syms(&rust_path[..rust_path.len() - 1]),
                        anchor = print_anchor(did, *rust_path.last().unwrap(), cx)
                    )
                } else {
                    write!(f, "{}", last.name)
                }
            } else {
                write!(f, "{}", print_anchor(did, last.name, cx))
            }
        });
        write!(w, "{path}{args}", args = print_generic_args(&last.args, cx))?;
    }
    Ok(())
}

fn primitive_link(
    f: &mut fmt::Formatter<'_>,
    prim: clean::PrimitiveType,
    name: fmt::Arguments<'_>,
    cx: &Context<'_>,
) -> fmt::Result {
    primitive_link_fragment(f, prim, name, "", cx)
}

fn primitive_link_fragment(
    f: &mut fmt::Formatter<'_>,
    prim: clean::PrimitiveType,
    name: fmt::Arguments<'_>,
    fragment: &str,
    cx: &Context<'_>,
) -> fmt::Result {
    let m = &cx.cache();
    let mut needs_termination = false;
    if !f.alternate() {
        match m.primitive_locations.get(&prim) {
            Some(&def_id) if def_id.is_local() => {
                let len = cx.current.len();
                let path = fmt::from_fn(|f| {
                    if len == 0 {
                        let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
                        write!(f, "{cname_sym}/")?;
                    } else {
                        for _ in 0..(len - 1) {
                            f.write_str("../")?;
                        }
                    }
                    Ok(())
                });
                write!(
                    f,
                    "<a class=\"primitive\" href=\"{path}primitive.{}.html{fragment}\">",
                    prim.as_sym()
                )?;
                needs_termination = true;
            }
            Some(&def_id) => {
                let loc = match m.extern_locations[&def_id.krate] {
                    ExternalLocation::Remote(ref s) => {
                        let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
                        let builder: UrlPartsBuilder =
                            [s.as_str().trim_end_matches('/'), cname_sym.as_str()]
                                .into_iter()
                                .collect();
                        Some(builder)
                    }
                    ExternalLocation::Local => {
                        let cname_sym = ExternalCrate { crate_num: def_id.krate }.name(cx.tcx());
                        Some(if cx.current.first() == Some(&cname_sym) {
                            iter::repeat_n(sym::dotdot, cx.current.len() - 1).collect()
                        } else {
                            iter::repeat_n(sym::dotdot, cx.current.len())
                                .chain(iter::once(cname_sym))
                                .collect()
                        })
                    }
                    ExternalLocation::Unknown => None,
                };
                if let Some(mut loc) = loc {
                    loc.push_fmt(format_args!("primitive.{}.html", prim.as_sym()));
                    write!(f, "<a class=\"primitive\" href=\"{}{fragment}\">", loc.finish())?;
                    needs_termination = true;
                }
            }
            None => {}
        }
    }
    Display::fmt(&name, f)?;
    if needs_termination {
        write!(f, "</a>")?;
    }
    Ok(())
}

fn print_tybounds(
    bounds: &[clean::PolyTrait],
    lt: &Option<clean::Lifetime>,
    cx: &Context<'_>,
) -> impl Display {
    fmt::from_fn(move |f| {
        bounds.iter().map(|bound| print_poly_trait(bound, cx)).joined(" + ", f)?;
        if let Some(lt) = lt {
            // We don't need to check `alternate` since we can be certain that
            // the lifetime doesn't contain any characters which need escaping.
            write!(f, " + {}", print_lifetime(lt))?;
        }
        Ok(())
    })
}

fn print_higher_ranked_params_with_space(
    params: &[clean::GenericParamDef],
    cx: &Context<'_>,
    keyword: &'static str,
) -> impl Display {
    fmt::from_fn(move |f| {
        if !params.is_empty() {
            f.write_str(keyword)?;
            Wrapped::with_angle_brackets()
                .wrap_fn(|f| {
                    params.iter().map(|lt| print_generic_param_def(lt, cx)).joined(", ", f)
                })
                .fmt(f)?;
            f.write_char(' ')?;
        }
        Ok(())
    })
}

pub(crate) fn fragment(did: DefId, tcx: TyCtxt<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        let def_kind = tcx.def_kind(did);
        match def_kind {
            DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant => {
                let item_type = ItemType::from_def_id(did, tcx);
                write!(f, "#{}.{}", item_type.as_str(), tcx.item_name(did))
            }
            DefKind::Field => {
                let parent_def_id = tcx.parent(did);
                f.write_char('#')?;
                if tcx.def_kind(parent_def_id) == DefKind::Variant {
                    write!(f, "variant.{}.field", tcx.item_name(parent_def_id).as_str())?;
                } else {
                    f.write_str("structfield")?;
                };
                write!(f, ".{}", tcx.item_name(did))
            }
            _ => Ok(()),
        }
    })
}

pub(crate) fn print_anchor(did: DefId, text: Symbol, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        if let Ok(HrefInfo { url, kind, rust_path }) = href(did, cx) {
            write!(
                f,
                r#"<a class="{kind}" href="{url}{anchor}" title="{kind} {path}">{text}</a>"#,
                anchor = fragment(did, cx.tcx()),
                path = join_path_syms(rust_path),
                text = EscapeBodyText(text.as_str()),
            )
        } else {
            f.write_str(text.as_str())
        }
    })
}

fn fmt_type(
    t: &clean::Type,
    f: &mut fmt::Formatter<'_>,
    use_absolute: bool,
    cx: &Context<'_>,
) -> fmt::Result {
    trace!("fmt_type(t = {t:?})");

    match t {
        clean::Generic(name) => f.write_str(name.as_str()),
        clean::SelfTy => f.write_str("Self"),
        clean::Type::Path { path } => {
            // Paths like `T::Output` and `Self::Output` should be rendered with all segments.
            let did = path.def_id();
            resolved_path(f, did, path, path.is_assoc_ty(), use_absolute, cx)
        }
        clean::DynTrait(bounds, lt) => {
            f.write_str("dyn ")?;
            print_tybounds(bounds, lt, cx).fmt(f)
        }
        clean::Infer => write!(f, "_"),
        clean::Primitive(clean::PrimitiveType::Never) => {
            primitive_link(f, PrimitiveType::Never, format_args!("!"), cx)
        }
        &clean::Primitive(prim) => primitive_link(f, prim, format_args!("{}", prim.as_sym()), cx),
        clean::BareFunction(decl) => {
            print_higher_ranked_params_with_space(&decl.generic_params, cx, "for").fmt(f)?;
            decl.safety.print_with_space().fmt(f)?;
            print_abi_with_space(decl.abi).fmt(f)?;
            if f.alternate() {
                f.write_str("fn")?;
            } else {
                primitive_link(f, PrimitiveType::Fn, format_args!("fn"), cx)?;
            }
            print_fn_decl(&decl.decl, cx).fmt(f)
        }
        clean::UnsafeBinder(binder) => {
            print_higher_ranked_params_with_space(&binder.generic_params, cx, "unsafe").fmt(f)?;
            print_type(&binder.ty, cx).fmt(f)
        }
        clean::Tuple(typs) => match &typs[..] {
            &[] => primitive_link(f, PrimitiveType::Unit, format_args!("()"), cx),
            [one] => {
                if let clean::Generic(name) = one {
                    primitive_link(f, PrimitiveType::Tuple, format_args!("({name},)"), cx)
                } else {
                    write!(f, "(")?;
                    print_type(one, cx).fmt(f)?;
                    write!(f, ",)")
                }
            }
            many => {
                let generic_names: Vec<Symbol> = many
                    .iter()
                    .filter_map(|t| match t {
                        clean::Generic(name) => Some(*name),
                        _ => None,
                    })
                    .collect();
                let is_generic = generic_names.len() == many.len();
                if is_generic {
                    primitive_link(
                        f,
                        PrimitiveType::Tuple,
                        format_args!(
                            "{}",
                            Wrapped::with_parens()
                                .wrap_fn(|f| generic_names.iter().joined(", ", f))
                        ),
                        cx,
                    )
                } else {
                    Wrapped::with_parens()
                        .wrap_fn(|f| many.iter().map(|item| print_type(item, cx)).joined(", ", f))
                        .fmt(f)
                }
            }
        },
        clean::Slice(box clean::Generic(name)) => {
            primitive_link(f, PrimitiveType::Slice, format_args!("[{name}]"), cx)
        }
        clean::Slice(t) => Wrapped::with_square_brackets().wrap(print_type(t, cx)).fmt(f),
        clean::Type::Pat(t, pat) => {
            fmt::Display::fmt(&print_type(t, cx), f)?;
            write!(f, " is {pat}")
        }
        clean::Array(box clean::Generic(name), n) if !f.alternate() => primitive_link(
            f,
            PrimitiveType::Array,
            format_args!("[{name}; {n}]", n = Escape(n)),
            cx,
        ),
        clean::Array(t, n) => Wrapped::with_square_brackets()
            .wrap(fmt::from_fn(|f| {
                print_type(t, cx).fmt(f)?;
                f.write_str("; ")?;
                if f.alternate() {
                    f.write_str(n)
                } else {
                    primitive_link(f, PrimitiveType::Array, format_args!("{n}", n = Escape(n)), cx)
                }
            }))
            .fmt(f),
        clean::RawPointer(m, t) => {
            let m = m.ptr_str();

            if matches!(**t, clean::Generic(_)) || t.is_assoc_ty() {
                primitive_link(
                    f,
                    clean::PrimitiveType::RawPointer,
                    format_args!("*{m} {ty}", ty = WithOpts::from(f).display(print_type(t, cx))),
                    cx,
                )
            } else {
                primitive_link(f, clean::PrimitiveType::RawPointer, format_args!("*{m} "), cx)?;
                print_type(t, cx).fmt(f)
            }
        }
        clean::BorrowedRef { lifetime: l, mutability, type_: ty } => {
            let lt = fmt::from_fn(|f| match l {
                Some(l) => write!(f, "{} ", print_lifetime(l)),
                _ => Ok(()),
            });
            let m = mutability.print_with_space();
            let amp = if f.alternate() { "&" } else { "&amp;" };

            if let clean::Generic(name) = **ty {
                return primitive_link(
                    f,
                    PrimitiveType::Reference,
                    format_args!("{amp}{lt}{m}{name}"),
                    cx,
                );
            }

            write!(f, "{amp}{lt}{m}")?;

            let needs_parens = match **ty {
                clean::DynTrait(ref bounds, ref trait_lt)
                    if bounds.len() > 1 || trait_lt.is_some() =>
                {
                    true
                }
                clean::ImplTrait(ref bounds) if bounds.len() > 1 => true,
                _ => false,
            };
            Wrapped::with_parens()
                .when(needs_parens)
                .wrap_fn(|f| fmt_type(ty, f, use_absolute, cx))
                .fmt(f)
        }
        clean::ImplTrait(bounds) => {
            f.write_str("impl ")?;
            print_generic_bounds(bounds, cx).fmt(f)
        }
        clean::QPath(qpath) => print_qpath_data(qpath, cx).fmt(f),
    }
}

pub(crate) fn print_type(type_: &clean::Type, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| fmt_type(type_, f, false, cx))
}

pub(crate) fn print_path(path: &clean::Path, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| resolved_path(f, path.def_id(), path, false, false, cx))
}

fn print_qpath_data(qpath_data: &clean::QPathData, cx: &Context<'_>) -> impl Display {
    let clean::QPathData { ref assoc, ref self_type, should_fully_qualify, ref trait_ } =
        *qpath_data;

    fmt::from_fn(move |f| {
        // FIXME(inherent_associated_types): Once we support non-ADT self-types (#106719),
        // we need to surround them with angle brackets in some cases (e.g. `<dyn …>::P`).

        if let Some(trait_) = trait_
            && should_fully_qualify
        {
            let opts = WithOpts::from(f);
            Wrapped::with_angle_brackets()
                .wrap(format_args!(
                    "{} as {}",
                    opts.display(print_type(self_type, cx)),
                    opts.display(print_path(trait_, cx))
                ))
                .fmt(f)?
        } else {
            print_type(self_type, cx).fmt(f)?;
        }
        f.write_str("::")?;
        // It's pretty unsightly to look at `<A as B>::C` in output, and
        // we've got hyperlinking on our side, so try to avoid longer
        // notation as much as possible by making `C` a hyperlink to trait
        // `B` to disambiguate.
        //
        // FIXME: this is still a lossy conversion and there should probably
        //        be a better way of representing this in general? Most of
        //        the ugliness comes from inlining across crates where
        //        everything comes in as a fully resolved QPath (hard to
        //        look at).
        if !f.alternate() {
            // FIXME(inherent_associated_types): We always link to the very first associated
            // type (in respect to source order) that bears the given name (`assoc.name`) and that is
            // affiliated with the computed `DefId`. This is obviously incorrect when we have
            // multiple impl blocks. Ideally, we would thread the `DefId` of the assoc ty itself
            // through here and map it to the corresponding HTML ID that was generated by
            // `render::Context::derive_id` when the impl blocks were rendered.
            // There is no such mapping unfortunately.
            // As a hack, we could badly imitate `derive_id` here by keeping *count* when looking
            // for the assoc ty `DefId` in `tcx.associated_items(self_ty_did).in_definition_order()`
            // considering privacy, `doc(hidden)`, etc.
            // I don't feel like that right now :cold_sweat:.

            let parent_href = match trait_ {
                Some(trait_) => href(trait_.def_id(), cx).ok(),
                None => self_type.def_id(cx.cache()).and_then(|did| href(did, cx).ok()),
            };

            if let Some(HrefInfo { url, rust_path, .. }) = parent_href {
                write!(
                    f,
                    "<a class=\"associatedtype\" href=\"{url}#{shortty}.{name}\" \
                                title=\"type {path}::{name}\">{name}</a>",
                    shortty = ItemType::AssocType,
                    name = assoc.name,
                    path = join_path_syms(rust_path),
                )
            } else {
                write!(f, "{}", assoc.name)
            }
        } else {
            write!(f, "{}", assoc.name)
        }?;

        print_generic_args(&assoc.args, cx).fmt(f)
    })
}

pub(crate) fn print_impl(
    impl_: &clean::Impl,
    use_absolute: bool,
    cx: &Context<'_>,
) -> impl Display {
    fmt::from_fn(move |f| {
        f.write_str("impl")?;
        print_generics(&impl_.generics, cx).fmt(f)?;
        f.write_str(" ")?;

        if let Some(ref ty) = impl_.trait_ {
            if impl_.is_negative_trait_impl() {
                f.write_char('!')?;
            }
            if impl_.kind.is_fake_variadic()
                && let Some(generics) = ty.generics()
                // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
                && let Ok(inner_type) = Itertools::exactly_one(generics)
            {
                let last = ty.last();
                if f.alternate() {
                    write!(f, "{last}")?;
                } else {
                    write!(f, "{}", print_anchor(ty.def_id(), last, cx))?;
                };
                Wrapped::with_angle_brackets()
                    .wrap_fn(|f| impl_.print_type(inner_type, f, use_absolute, cx))
                    .fmt(f)?;
            } else {
                print_path(ty, cx).fmt(f)?;
            }
            f.write_str(" for ")?;
        }

        if let Some(ty) = impl_.kind.as_blanket_ty() {
            fmt_type(ty, f, use_absolute, cx)?;
        } else {
            impl_.print_type(&impl_.for_, f, use_absolute, cx)?;
        }

        print_where_clause(&impl_.generics, cx, 0, Ending::Newline).maybe_display().fmt(f)
    })
}

impl clean::Impl {
    fn print_type(
        &self,
        type_: &clean::Type,
        f: &mut fmt::Formatter<'_>,
        use_absolute: bool,
        cx: &Context<'_>,
    ) -> Result<(), fmt::Error> {
        if let clean::Type::Tuple(types) = type_
            && let [clean::Type::Generic(name)] = &types[..]
            && (self.kind.is_fake_variadic() || self.kind.is_auto())
        {
            // Hardcoded anchor library/core/src/primitive_docs.rs
            // Link should match `# Trait implementations`
            primitive_link_fragment(
                f,
                PrimitiveType::Tuple,
                format_args!("({name}₁, {name}₂, …, {name}ₙ)"),
                "#trait-implementations-1",
                cx,
            )?;
        } else if let clean::Type::Array(ty, len) = type_
            && let clean::Type::Generic(name) = &**ty
            && &len[..] == "1"
            && (self.kind.is_fake_variadic() || self.kind.is_auto())
        {
            primitive_link(f, PrimitiveType::Array, format_args!("[{name}; N]"), cx)?;
        } else if let clean::BareFunction(bare_fn) = &type_
            && let [clean::Parameter { type_: clean::Type::Generic(name), .. }] =
                &bare_fn.decl.inputs[..]
            && (self.kind.is_fake_variadic() || self.kind.is_auto())
        {
            // Hardcoded anchor library/core/src/primitive_docs.rs
            // Link should match `# Trait implementations`

            print_higher_ranked_params_with_space(&bare_fn.generic_params, cx, "for").fmt(f)?;
            bare_fn.safety.print_with_space().fmt(f)?;
            print_abi_with_space(bare_fn.abi).fmt(f)?;
            let ellipsis = if bare_fn.decl.c_variadic { ", ..." } else { "" };
            primitive_link_fragment(
                f,
                PrimitiveType::Tuple,
                format_args!("fn({name}₁, {name}₂, …, {name}ₙ{ellipsis})"),
                "#trait-implementations-1",
                cx,
            )?;
            // Write output.
            if !bare_fn.decl.output.is_unit() {
                write!(f, " -> ")?;
                fmt_type(&bare_fn.decl.output, f, use_absolute, cx)?;
            }
        } else if let clean::Type::Path { path } = type_
            && let Some(generics) = path.generics()
            // FIXME: rewrite in terms of `#![feature(exact_length_collection)]`. See: #149266
            && let Ok(ty) = Itertools::exactly_one(generics)
            && self.kind.is_fake_variadic()
        {
            print_anchor(path.def_id(), path.last(), cx).fmt(f)?;
            Wrapped::with_angle_brackets()
                .wrap_fn(|f| self.print_type(ty, f, use_absolute, cx))
                .fmt(f)?;
        } else {
            fmt_type(type_, f, use_absolute, cx)?;
        }
        Ok(())
    }
}

pub(crate) fn print_params(params: &[clean::Parameter], cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        params
            .iter()
            .map(|param| {
                fmt::from_fn(|f| {
                    if let Some(name) = param.name {
                        write!(f, "{name}: ")?;
                    }
                    print_type(&param.type_, cx).fmt(f)
                })
            })
            .joined(", ", f)
    })
}

// Implements Write but only counts the bytes "written".
struct WriteCounter(usize);

impl std::fmt::Write for WriteCounter {
    fn write_str(&mut self, s: &str) -> fmt::Result {
        self.0 += s.len();
        Ok(())
    }
}

// Implements Display by emitting the given number of spaces.
#[derive(Clone, Copy)]
struct Indent(usize);

impl Display for Indent {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        for _ in 0..self.0 {
            f.write_char(' ')?;
        }
        Ok(())
    }
}

fn print_parameter(parameter: &clean::Parameter, cx: &Context<'_>) -> impl fmt::Display {
    fmt::from_fn(move |f| {
        if let Some(self_ty) = parameter.to_receiver() {
            match self_ty {
                clean::SelfTy => f.write_str("self"),
                clean::BorrowedRef { lifetime, mutability, type_: box clean::SelfTy } => {
                    f.write_str(if f.alternate() { "&" } else { "&amp;" })?;
                    if let Some(lt) = lifetime {
                        write!(f, "{lt} ", lt = print_lifetime(lt))?;
                    }
                    write!(f, "{mutability}self", mutability = mutability.print_with_space())
                }
                _ => {
                    f.write_str("self: ")?;
                    print_type(self_ty, cx).fmt(f)
                }
            }
        } else {
            if parameter.is_const {
                write!(f, "const ")?;
            }
            if let Some(name) = parameter.name {
                write!(f, "{name}: ")?;
            }
            print_type(&parameter.type_, cx).fmt(f)
        }
    })
}

fn print_fn_decl(fn_decl: &clean::FnDecl, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        let ellipsis = if fn_decl.c_variadic { ", ..." } else { "" };
        Wrapped::with_parens()
            .wrap_fn(|f| {
                print_params(&fn_decl.inputs, cx).fmt(f)?;
                f.write_str(ellipsis)
            })
            .fmt(f)?;
        fn_decl.print_output(cx).fmt(f)
    })
}

/// * `header_len`: The length of the function header and name. In other words, the number of
///   characters in the function declaration up to but not including the parentheses.
///   This is expected to go into a `<pre>`/`code-header` block, so indentation and newlines
///   are preserved.
/// * `indent`: The number of spaces to indent each successive line with, if line-wrapping is
///   necessary.
pub(crate) fn full_print_fn_decl(
    fn_decl: &clean::FnDecl,
    header_len: usize,
    indent: usize,
    cx: &Context<'_>,
) -> impl Display {
    fmt::from_fn(move |f| {
        // First, generate the text form of the declaration, with no line wrapping, and count the bytes.
        let mut counter = WriteCounter(0);
        write!(&mut counter, "{:#}", fmt::from_fn(|f| { fn_decl.inner_full_print(None, f, cx) }))?;
        // If the text form was over 80 characters wide, we will line-wrap our output.
        let line_wrapping_indent = if header_len + counter.0 > 80 { Some(indent) } else { None };
        // Generate the final output. This happens to accept `{:#}` formatting to get textual
        // output but in practice it is only formatted with `{}` to get HTML output.
        fn_decl.inner_full_print(line_wrapping_indent, f, cx)
    })
}

impl clean::FnDecl {
    fn inner_full_print(
        &self,
        // For None, the declaration will not be line-wrapped. For Some(n),
        // the declaration will be line-wrapped, with an indent of n spaces.
        line_wrapping_indent: Option<usize>,
        f: &mut fmt::Formatter<'_>,
        cx: &Context<'_>,
    ) -> fmt::Result {
        Wrapped::with_parens()
            .wrap_fn(|f| {
                if !self.inputs.is_empty() {
                    let line_wrapping_indent = line_wrapping_indent.map(|n| Indent(n + 4));

                    if let Some(indent) = line_wrapping_indent {
                        write!(f, "\n{indent}")?;
                    }

                    let sep = fmt::from_fn(|f| {
                        if let Some(indent) = line_wrapping_indent {
                            write!(f, ",\n{indent}")
                        } else {
                            f.write_str(", ")
                        }
                    });

                    self.inputs.iter().map(|param| print_parameter(param, cx)).joined(sep, f)?;

                    if line_wrapping_indent.is_some() {
                        writeln!(f, ",")?
                    }

                    if self.c_variadic {
                        match line_wrapping_indent {
                            None => write!(f, ", ...")?,
                            Some(indent) => writeln!(f, "{indent}...")?,
                        };
                    }
                }

                if let Some(n) = line_wrapping_indent {
                    write!(f, "{}", Indent(n))?
                }

                Ok(())
            })
            .fmt(f)?;

        self.print_output(cx).fmt(f)
    }

    fn print_output(&self, cx: &Context<'_>) -> impl Display {
        fmt::from_fn(move |f| {
            if self.output.is_unit() {
                return Ok(());
            }

            f.write_str(if f.alternate() { " -> " } else { " -&gt; " })?;
            print_type(&self.output, cx).fmt(f)
        })
    }
}

pub(crate) fn visibility_print_with_space(item: &clean::Item, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| {
        if item.is_doc_hidden() {
            f.write_str("#[doc(hidden)] ")?;
        }

        let Some(vis) = item.visibility(cx.tcx()) else {
            return Ok(());
        };

        match vis {
            ty::Visibility::Public => f.write_str("pub ")?,
            ty::Visibility::Restricted(vis_did) => {
                // FIXME(camelid): This may not work correctly if `item_did` is a module.
                //                 However, rustdoc currently never displays a module's
                //                 visibility, so it shouldn't matter.
                let parent_module =
                    find_nearest_parent_module(cx.tcx(), item.item_id.expect_def_id());

                if vis_did.is_crate_root() {
                    f.write_str("pub(crate) ")?;
                } else if parent_module == Some(vis_did) {
                    // `pub(in foo)` where `foo` is the parent module
                    // is the same as no visibility modifier; do nothing
                } else if parent_module
                    .and_then(|parent| find_nearest_parent_module(cx.tcx(), parent))
                    == Some(vis_did)
                {
                    f.write_str("pub(super) ")?;
                } else {
                    let path = cx.tcx().def_path(vis_did);
                    debug!("path={path:?}");
                    // modified from `resolved_path()` to work with `DefPathData`
                    let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
                    let anchor = print_anchor(vis_did, last_name, cx);

                    f.write_str("pub(in ")?;
                    for seg in &path.data[..path.data.len() - 1] {
                        write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
                    }
                    write!(f, "{anchor}) ")?;
                }
            }
        }
        Ok(())
    })
}

pub(crate) trait PrintWithSpace {
    fn print_with_space(&self) -> &str;
}

impl PrintWithSpace for hir::Safety {
    fn print_with_space(&self) -> &str {
        self.prefix_str()
    }
}

impl PrintWithSpace for hir::HeaderSafety {
    fn print_with_space(&self) -> &str {
        match self {
            hir::HeaderSafety::SafeTargetFeatures => "",
            hir::HeaderSafety::Normal(safety) => safety.print_with_space(),
        }
    }
}

impl PrintWithSpace for hir::IsAsync {
    fn print_with_space(&self) -> &str {
        match self {
            hir::IsAsync::Async(_) => "async ",
            hir::IsAsync::NotAsync => "",
        }
    }
}

impl PrintWithSpace for hir::Mutability {
    fn print_with_space(&self) -> &str {
        match self {
            hir::Mutability::Not => "",
            hir::Mutability::Mut => "mut ",
        }
    }
}

pub(crate) fn print_constness_with_space(
    c: &hir::Constness,
    overall_stab: Option<StableSince>,
    const_stab: Option<ConstStability>,
) -> &'static str {
    match c {
        hir::Constness::Const => match (overall_stab, const_stab) {
            // const stable...
            (_, Some(ConstStability { level: StabilityLevel::Stable { .. }, .. }))
            // ...or when feature(staged_api) is not set...
            | (_, None)
            // ...or when const unstable, but overall unstable too
            | (None, Some(ConstStability { level: StabilityLevel::Unstable { .. }, .. })) => {
                "const "
            }
            // const unstable (and overall stable)
            (Some(_), Some(ConstStability { level: StabilityLevel::Unstable { .. }, .. })) => "",
        },
        // not const
        hir::Constness::NotConst => "",
    }
}

pub(crate) fn print_import(import: &clean::Import, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| match import.kind {
        clean::ImportKind::Simple(name) => {
            if name == import.source.path.last() {
                write!(f, "use {};", print_import_source(&import.source, cx))
            } else {
                write!(
                    f,
                    "use {source} as {name};",
                    source = print_import_source(&import.source, cx)
                )
            }
        }
        clean::ImportKind::Glob => {
            if import.source.path.segments.is_empty() {
                write!(f, "use *;")
            } else {
                write!(f, "use {}::*;", print_import_source(&import.source, cx))
            }
        }
    })
}

fn print_import_source(import_source: &clean::ImportSource, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| match import_source.did {
        Some(did) => resolved_path(f, did, &import_source.path, true, false, cx),
        _ => {
            for seg in &import_source.path.segments[..import_source.path.segments.len() - 1] {
                write!(f, "{}::", seg.name)?;
            }
            let name = import_source.path.last();
            if let hir::def::Res::PrimTy(p) = import_source.path.res {
                primitive_link(f, PrimitiveType::from(p), format_args!("{name}"), cx)?;
            } else {
                f.write_str(name.as_str())?;
            }
            Ok(())
        }
    })
}

fn print_assoc_item_constraint(
    assoc_item_constraint: &clean::AssocItemConstraint,
    cx: &Context<'_>,
) -> impl Display {
    fmt::from_fn(move |f| {
        f.write_str(assoc_item_constraint.assoc.name.as_str())?;
        print_generic_args(&assoc_item_constraint.assoc.args, cx).fmt(f)?;
        match assoc_item_constraint.kind {
            clean::AssocItemConstraintKind::Equality { ref term } => {
                f.write_str(" = ")?;
                print_term(term, cx).fmt(f)?;
            }
            clean::AssocItemConstraintKind::Bound { ref bounds } => {
                if !bounds.is_empty() {
                    f.write_str(": ")?;
                    print_generic_bounds(bounds, cx).fmt(f)?;
                }
            }
        }
        Ok(())
    })
}

pub(crate) fn print_abi_with_space(abi: ExternAbi) -> impl Display {
    fmt::from_fn(move |f| {
        let quot = if f.alternate() { "\"" } else { "&quot;" };
        match abi {
            ExternAbi::Rust => Ok(()),
            abi => write!(f, "extern {0}{1}{0} ", quot, abi.name()),
        }
    })
}

pub(crate) fn print_default_space(v: bool) -> &'static str {
    if v { "default " } else { "" }
}

fn print_generic_arg(generic_arg: &clean::GenericArg, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| match generic_arg {
        clean::GenericArg::Lifetime(lt) => f.write_str(print_lifetime(lt)),
        clean::GenericArg::Type(ty) => print_type(ty, cx).fmt(f),
        clean::GenericArg::Const(ct) => print_constant_kind(ct, cx.tcx()).fmt(f),
        clean::GenericArg::Infer => f.write_char('_'),
    })
}

fn print_term(term: &clean::Term, cx: &Context<'_>) -> impl Display {
    fmt::from_fn(move |f| match term {
        clean::Term::Type(ty) => print_type(ty, cx).fmt(f),
        clean::Term::Constant(ct) => print_constant_kind(ct, cx.tcx()).fmt(f),
    })
}
