//! 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>,
    original_def_kind: DefKind,
) -> 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 def_kind = tcx.def_kind(def_id);
    let shortty = def_kind.into();
    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_kind(original_def_kind, Some(def_kind));
        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, def_kind);
            }
        }
    };
    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 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) {
            let tcx = cx.tcx();
            let def_kind = tcx.def_kind(did);
            let anchor = if matches!(
                def_kind,
                DefKind::AssocTy | DefKind::AssocFn | DefKind::AssocConst | DefKind::Variant
            ) {
                let parent_def_id = tcx.parent(did);
                let item_type =
                    ItemType::from_def_kind(def_kind, Some(tcx.def_kind(parent_def_id)));
                format!("#{}.{}", item_type.as_str(), tcx.item_name(did))
            } else {
                String::new()
            };

            write!(
                f,
                r#"<a class="{kind}" href="{url}{anchor}" title="{kind} {path}">{text}</a>"#,
                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()
                && let Ok(inner_type) = generics.exactly_one()
            {
                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()
            && let Ok(ty) = generics.exactly_one()
            && 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 {
        (0..self.0).for_each(|_| {
            f.write_char(' ').unwrap();
        });
        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),
    })
}
