//! The `HirDisplay` trait, which serves two purposes: Turning various bits from
//! HIR back into source code, and just displaying them for debugging/testing
//! purposes.

use std::{
    fmt::{self, Debug},
    mem,
};

use base_db::Crate;
use chalk_ir::{BoundVar, Safety, TyKind};
use either::Either;
use hir_def::{
    FindPathConfig, GeneralConstId, GenericDefId, HasModule, LocalFieldId, Lookup, ModuleDefId,
    ModuleId, TraitId,
    db::DefDatabase,
    expr_store::{ExpressionStore, path::Path},
    find_path::{self, PrefixKind},
    hir::generics::{TypeOrConstParamData, TypeParamProvenance, WherePredicate},
    item_scope::ItemInNs,
    item_tree::FieldsShape,
    lang_item::LangItem,
    nameres::DefMap,
    signatures::VariantFields,
    type_ref::{
        ConstRef, LifetimeRef, LifetimeRefId, TraitBoundModifier, TypeBound, TypeRef, TypeRefId,
        UseArgRef,
    },
    visibility::Visibility,
};
use hir_expand::{mod_path::PathKind, name::Name};
use intern::{Internable, Interned, sym};
use itertools::Itertools;
use la_arena::ArenaMap;
use rustc_apfloat::{
    Float,
    ieee::{Half as f16, Quad as f128},
};
use rustc_hash::FxHashSet;
use rustc_type_ir::{
    AliasTyKind, CoroutineArgsParts, RegionKind,
    inherent::{AdtDef, GenericArgs as _, IntoKind, SliceLike},
};
use smallvec::SmallVec;
use span::Edition;
use stdx::never;
use triomphe::Arc;

use crate::next_solver::infer::DbInternerInferExt;
use crate::next_solver::infer::traits::ObligationCause;
use crate::{
    AliasEq, AliasTy, Binders, CallableDefId, CallableSig, ConcreteConst, Const, ConstScalar,
    ConstValue, DomainGoal, FnAbi, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData,
    LifetimeOutlives, MemoryMap, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause,
    TraitEnvironment, TraitRef, TraitRefExt, Ty, TyExt, WhereClause, consteval_nextsolver,
    db::{HirDatabase, InternedClosure},
    from_assoc_type_id, from_placeholder_idx,
    generics::generics,
    infer::normalize,
    layout::Layout,
    lt_from_placeholder_idx,
    mir::pad16,
    next_solver::{
        BoundExistentialPredicate, DbInterner, GenericArgs, SolverDefId,
        mapping::{
            ChalkToNextSolver, convert_args_for_result, convert_const_for_result,
            convert_region_for_result, convert_ty_for_result,
        },
    },
    primitive, to_assoc_type_id,
    utils::{self, ClosureSubst, detect_variant_from_bytes},
};

pub trait HirWrite: fmt::Write {
    fn start_location_link(&mut self, _location: ModuleDefId) {}
    fn end_location_link(&mut self) {}
}

// String will ignore link metadata
impl HirWrite for String {}

// `core::Formatter` will ignore metadata
impl HirWrite for fmt::Formatter<'_> {}

pub struct HirFormatter<'a> {
    /// The database handle
    pub db: &'a dyn HirDatabase,
    /// The sink to write into
    fmt: &'a mut dyn HirWrite,
    /// A buffer to intercept writes with, this allows us to track the overall size of the formatted output.
    buf: String,
    /// The current size of the formatted output.
    curr_size: usize,
    /// Size from which we should truncate the output.
    max_size: Option<usize>,
    /// When rendering something that has a concept of "children" (like fields in a struct), this limits
    /// how many should be rendered.
    pub entity_limit: Option<usize>,
    /// When rendering functions, whether to show the constraint from the container
    show_container_bounds: bool,
    omit_verbose_types: bool,
    closure_style: ClosureStyle,
    display_lifetimes: DisplayLifetime,
    display_kind: DisplayKind,
    display_target: DisplayTarget,
    bounds_formatting_ctx: BoundsFormattingCtx,
}

// FIXME: To consider, ref and dyn trait lifetimes can be omitted if they are `'_`, path args should
// not be when in signatures
// So this enum does not encode this well enough
// Also 'static can be omitted for ref and dyn trait lifetimes in static/const item types
// FIXME: Also named lifetimes may be rendered in places where their name is not in scope?
#[derive(Copy, Clone)]
pub enum DisplayLifetime {
    Always,
    OnlyStatic,
    OnlyNamed,
    OnlyNamedOrStatic,
    Never,
}

#[derive(Default)]
enum BoundsFormattingCtx {
    Entered {
        /// We can have recursive bounds like the following case:
        /// ```ignore
        /// where
        ///     T: Foo,
        ///     T::FooAssoc: Baz<<T::FooAssoc as Bar>::BarAssoc> + Bar
        /// ```
        /// So, record the projection types met while formatting bounds and
        //. prevent recursing into their bounds to avoid infinite loops.
        projection_tys_met: FxHashSet<ProjectionTy>,
    },
    #[default]
    Exited,
}

impl BoundsFormattingCtx {
    fn contains(&mut self, proj: &ProjectionTy) -> bool {
        match self {
            BoundsFormattingCtx::Entered { projection_tys_met } => {
                projection_tys_met.contains(proj)
            }
            BoundsFormattingCtx::Exited => false,
        }
    }
}

impl HirFormatter<'_> {
    fn start_location_link(&mut self, location: ModuleDefId) {
        self.fmt.start_location_link(location);
    }

    fn end_location_link(&mut self) {
        self.fmt.end_location_link();
    }

    fn format_bounds_with<T, F: FnOnce(&mut Self) -> T>(
        &mut self,
        target: ProjectionTy,
        format_bounds: F,
    ) -> T {
        match self.bounds_formatting_ctx {
            BoundsFormattingCtx::Entered { ref mut projection_tys_met } => {
                projection_tys_met.insert(target);
                format_bounds(self)
            }
            BoundsFormattingCtx::Exited => {
                let mut projection_tys_met = FxHashSet::default();
                projection_tys_met.insert(target);
                self.bounds_formatting_ctx = BoundsFormattingCtx::Entered { projection_tys_met };
                let res = format_bounds(self);
                // Since we want to prevent only the infinite recursions in bounds formatting
                // and do not want to skip formatting of other separate bounds, clear context
                // when exiting the formatting of outermost bounds
                self.bounds_formatting_ctx = BoundsFormattingCtx::Exited;
                res
            }
        }
    }

    fn render_lifetime(&self, lifetime: &Lifetime) -> bool {
        match self.display_lifetimes {
            DisplayLifetime::Always => true,
            DisplayLifetime::OnlyStatic => matches!(***lifetime.interned(), LifetimeData::Static),
            DisplayLifetime::OnlyNamed => {
                matches!(***lifetime.interned(), LifetimeData::Placeholder(_))
            }
            DisplayLifetime::OnlyNamedOrStatic => matches!(
                ***lifetime.interned(),
                LifetimeData::Static | LifetimeData::Placeholder(_)
            ),
            DisplayLifetime::Never => false,
        }
    }

    fn render_region(&self, lifetime: crate::next_solver::Region<'_>) -> bool {
        match self.display_lifetimes {
            DisplayLifetime::Always => true,
            DisplayLifetime::OnlyStatic => {
                matches!(lifetime.kind(), rustc_type_ir::RegionKind::ReStatic)
            }
            DisplayLifetime::OnlyNamed => {
                matches!(
                    lifetime.kind(),
                    rustc_type_ir::RegionKind::RePlaceholder(_)
                        | rustc_type_ir::RegionKind::ReEarlyParam(_)
                )
            }
            DisplayLifetime::OnlyNamedOrStatic => matches!(
                lifetime.kind(),
                rustc_type_ir::RegionKind::ReStatic
                    | rustc_type_ir::RegionKind::RePlaceholder(_)
                    | rustc_type_ir::RegionKind::ReEarlyParam(_)
            ),
            DisplayLifetime::Never => false,
        }
    }
}

pub trait HirDisplay {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError>;

    /// Returns a `Display`able type that is human-readable.
    fn into_displayable<'a>(
        &'a self,
        db: &'a dyn HirDatabase,
        max_size: Option<usize>,
        limited_size: Option<usize>,
        omit_verbose_types: bool,
        display_target: DisplayTarget,
        display_kind: DisplayKind,
        closure_style: ClosureStyle,
        show_container_bounds: bool,
    ) -> HirDisplayWrapper<'a, Self>
    where
        Self: Sized,
    {
        assert!(
            !matches!(display_kind, DisplayKind::SourceCode { .. }),
            "HirDisplayWrapper cannot fail with DisplaySourceCodeError, use HirDisplay::hir_fmt directly instead"
        );
        HirDisplayWrapper {
            db,
            t: self,
            max_size,
            limited_size,
            omit_verbose_types,
            display_target,
            display_kind,
            closure_style,
            show_container_bounds,
            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
        }
    }

    /// Returns a `Display`able type that is human-readable.
    /// Use this for showing types to the user (e.g. diagnostics)
    fn display<'a>(
        &'a self,
        db: &'a dyn HirDatabase,
        display_target: DisplayTarget,
    ) -> HirDisplayWrapper<'a, Self>
    where
        Self: Sized,
    {
        HirDisplayWrapper {
            db,
            t: self,
            max_size: None,
            limited_size: None,
            omit_verbose_types: false,
            closure_style: ClosureStyle::ImplFn,
            display_target,
            display_kind: DisplayKind::Diagnostics,
            show_container_bounds: false,
            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
        }
    }

    /// Returns a `Display`able type that is human-readable and tries to be succinct.
    /// Use this for showing types to the user where space is constrained (e.g. doc popups)
    fn display_truncated<'a>(
        &'a self,
        db: &'a dyn HirDatabase,
        max_size: Option<usize>,
        display_target: DisplayTarget,
    ) -> HirDisplayWrapper<'a, Self>
    where
        Self: Sized,
    {
        HirDisplayWrapper {
            db,
            t: self,
            max_size,
            limited_size: None,
            omit_verbose_types: true,
            closure_style: ClosureStyle::ImplFn,
            display_target,
            display_kind: DisplayKind::Diagnostics,
            show_container_bounds: false,
            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
        }
    }

    /// Returns a `Display`able type that is human-readable and tries to limit the number of items inside.
    /// Use this for showing definitions which may contain too many items, like `trait`, `struct`, `enum`
    fn display_limited<'a>(
        &'a self,
        db: &'a dyn HirDatabase,
        limited_size: Option<usize>,
        display_target: DisplayTarget,
    ) -> HirDisplayWrapper<'a, Self>
    where
        Self: Sized,
    {
        HirDisplayWrapper {
            db,
            t: self,
            max_size: None,
            limited_size,
            omit_verbose_types: true,
            closure_style: ClosureStyle::ImplFn,
            display_target,
            display_kind: DisplayKind::Diagnostics,
            show_container_bounds: false,
            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
        }
    }

    /// Returns a String representation of `self` that can be inserted into the given module.
    /// Use this when generating code (e.g. assists)
    fn display_source_code<'a>(
        &'a self,
        db: &'a dyn HirDatabase,
        module_id: ModuleId,
        allow_opaque: bool,
    ) -> Result<String, DisplaySourceCodeError> {
        let mut result = String::new();
        match self.hir_fmt(&mut HirFormatter {
            db,
            fmt: &mut result,
            buf: String::with_capacity(20),
            curr_size: 0,
            max_size: None,
            entity_limit: None,
            omit_verbose_types: false,
            closure_style: ClosureStyle::ImplFn,
            display_target: DisplayTarget::from_crate(db, module_id.krate()),
            display_kind: DisplayKind::SourceCode { target_module_id: module_id, allow_opaque },
            show_container_bounds: false,
            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
            bounds_formatting_ctx: Default::default(),
        }) {
            Ok(()) => {}
            Err(HirDisplayError::FmtError) => panic!("Writing to String can't fail!"),
            Err(HirDisplayError::DisplaySourceCodeError(e)) => return Err(e),
        };
        Ok(result)
    }

    /// Returns a String representation of `self` for test purposes
    fn display_test<'a>(
        &'a self,
        db: &'a dyn HirDatabase,
        display_target: DisplayTarget,
    ) -> HirDisplayWrapper<'a, Self>
    where
        Self: Sized,
    {
        HirDisplayWrapper {
            db,
            t: self,
            max_size: None,
            limited_size: None,
            omit_verbose_types: false,
            closure_style: ClosureStyle::ImplFn,
            display_target,
            display_kind: DisplayKind::Test,
            show_container_bounds: false,
            display_lifetimes: DisplayLifetime::Always,
        }
    }

    /// Returns a String representation of `self` that shows the constraint from
    /// the container for functions
    fn display_with_container_bounds<'a>(
        &'a self,
        db: &'a dyn HirDatabase,
        show_container_bounds: bool,
        display_target: DisplayTarget,
    ) -> HirDisplayWrapper<'a, Self>
    where
        Self: Sized,
    {
        HirDisplayWrapper {
            db,
            t: self,
            max_size: None,
            limited_size: None,
            omit_verbose_types: false,
            closure_style: ClosureStyle::ImplFn,
            display_target,
            display_kind: DisplayKind::Diagnostics,
            show_container_bounds,
            display_lifetimes: DisplayLifetime::OnlyNamedOrStatic,
        }
    }
}

impl HirFormatter<'_> {
    pub fn krate(&self) -> Crate {
        self.display_target.krate
    }

    pub fn edition(&self) -> Edition {
        self.display_target.edition
    }

    pub fn write_joined<T: HirDisplay>(
        &mut self,
        iter: impl IntoIterator<Item = T>,
        sep: &str,
    ) -> Result<(), HirDisplayError> {
        let mut first = true;
        for e in iter {
            if !first {
                write!(self, "{sep}")?;
            }
            first = false;

            // Abbreviate multiple omitted types with a single ellipsis.
            if self.should_truncate() {
                return write!(self, "{TYPE_HINT_TRUNCATION}");
            }

            e.hir_fmt(self)?;
        }
        Ok(())
    }

    /// This allows using the `write!` macro directly with a `HirFormatter`.
    pub fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> Result<(), HirDisplayError> {
        // We write to a buffer first to track output size
        self.buf.clear();
        fmt::write(&mut self.buf, args)?;
        self.curr_size += self.buf.len();

        // Then we write to the internal formatter from the buffer
        self.fmt.write_str(&self.buf).map_err(HirDisplayError::from)
    }

    pub fn write_str(&mut self, s: &str) -> Result<(), HirDisplayError> {
        self.fmt.write_str(s)?;
        Ok(())
    }

    pub fn write_char(&mut self, c: char) -> Result<(), HirDisplayError> {
        self.fmt.write_char(c)?;
        Ok(())
    }

    pub fn should_truncate(&self) -> bool {
        match self.max_size {
            Some(max_size) => self.curr_size >= max_size,
            None => false,
        }
    }

    pub fn omit_verbose_types(&self) -> bool {
        self.omit_verbose_types
    }

    pub fn show_container_bounds(&self) -> bool {
        self.show_container_bounds
    }
}

#[derive(Debug, Clone, Copy)]
pub struct DisplayTarget {
    krate: Crate,
    pub edition: Edition,
}

impl DisplayTarget {
    pub fn from_crate(db: &dyn HirDatabase, krate: Crate) -> Self {
        let edition = krate.data(db).edition;
        Self { krate, edition }
    }
}

#[derive(Clone, Copy)]
pub enum DisplayKind {
    /// Display types for inlays, doc popups, autocompletion, etc...
    /// Showing `{unknown}` or not qualifying paths is fine here.
    /// There's no reason for this to fail.
    Diagnostics,
    /// Display types for inserting them in source files.
    /// The generated code should compile, so paths need to be qualified.
    SourceCode { target_module_id: ModuleId, allow_opaque: bool },
    /// Only for test purpose to keep real types
    Test,
}

impl DisplayKind {
    fn is_source_code(self) -> bool {
        matches!(self, Self::SourceCode { .. })
    }

    fn allows_opaque(self) -> bool {
        match self {
            Self::SourceCode { allow_opaque, .. } => allow_opaque,
            _ => true,
        }
    }
}

#[derive(Debug)]
pub enum DisplaySourceCodeError {
    PathNotFound,
    Coroutine,
    OpaqueType,
}

pub enum HirDisplayError {
    /// Errors that can occur when generating source code
    DisplaySourceCodeError(DisplaySourceCodeError),
    /// `FmtError` is required to be compatible with std::fmt::Display
    FmtError,
}
impl From<fmt::Error> for HirDisplayError {
    fn from(_: fmt::Error) -> Self {
        Self::FmtError
    }
}

pub struct HirDisplayWrapper<'a, T> {
    db: &'a dyn HirDatabase,
    t: &'a T,
    max_size: Option<usize>,
    limited_size: Option<usize>,
    omit_verbose_types: bool,
    closure_style: ClosureStyle,
    display_kind: DisplayKind,
    display_target: DisplayTarget,
    show_container_bounds: bool,
    display_lifetimes: DisplayLifetime,
}

#[derive(Debug, PartialEq, Eq, Clone, Copy)]
pub enum ClosureStyle {
    /// `impl FnX(i32, i32) -> i32`, where `FnX` is the most special trait between `Fn`, `FnMut`, `FnOnce` that the
    /// closure implements. This is the default.
    ImplFn,
    /// `|i32, i32| -> i32`
    RANotation,
    /// `{closure#14825}`, useful for some diagnostics (like type mismatch) and internal usage.
    ClosureWithId,
    /// `{closure#14825}<i32, ()>`, useful for internal usage.
    ClosureWithSubst,
    /// `…`, which is the `TYPE_HINT_TRUNCATION`
    Hide,
}

impl<T: HirDisplay> HirDisplayWrapper<'_, T> {
    pub fn write_to<F: HirWrite>(&self, f: &mut F) -> Result<(), HirDisplayError> {
        self.t.hir_fmt(&mut HirFormatter {
            db: self.db,
            fmt: f,
            buf: String::with_capacity(self.max_size.unwrap_or(20)),
            curr_size: 0,
            max_size: self.max_size,
            entity_limit: self.limited_size,
            omit_verbose_types: self.omit_verbose_types,
            display_kind: self.display_kind,
            display_target: self.display_target,
            closure_style: self.closure_style,
            show_container_bounds: self.show_container_bounds,
            display_lifetimes: self.display_lifetimes,
            bounds_formatting_ctx: Default::default(),
        })
    }

    pub fn with_closure_style(mut self, c: ClosureStyle) -> Self {
        self.closure_style = c;
        self
    }

    pub fn with_lifetime_display(mut self, l: DisplayLifetime) -> Self {
        self.display_lifetimes = l;
        self
    }
}

impl<T> fmt::Display for HirDisplayWrapper<'_, T>
where
    T: HirDisplay,
{
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        match self.write_to(f) {
            Ok(()) => Ok(()),
            Err(HirDisplayError::FmtError) => Err(fmt::Error),
            Err(HirDisplayError::DisplaySourceCodeError(_)) => {
                // This should never happen
                panic!(
                    "HirDisplay::hir_fmt failed with DisplaySourceCodeError when calling Display::fmt!"
                )
            }
        }
    }
}

const TYPE_HINT_TRUNCATION: &str = "…";

impl<T: HirDisplay> HirDisplay for &T {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        HirDisplay::hir_fmt(*self, f)
    }
}

impl<T: HirDisplay + Internable> HirDisplay for Interned<T> {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        HirDisplay::hir_fmt(self.as_ref(), f)
    }
}

impl HirDisplay for ProjectionTy {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        if f.should_truncate() {
            return write!(f, "{TYPE_HINT_TRUNCATION}");
        }
        let trait_ref = self.trait_ref(f.db);
        let self_ty = trait_ref.self_type_parameter(Interner);

        // if we are projection on a type parameter, check if the projection target has bounds
        // itself, if so, we render them directly as `impl Bound` instead of the less useful
        // `<Param as Trait>::Assoc`
        if !f.display_kind.is_source_code()
            && let TyKind::Placeholder(idx) = self_ty.kind(Interner)
            && !f.bounds_formatting_ctx.contains(self)
        {
            let db = f.db;
            let id = from_placeholder_idx(db, *idx).0;
            let generics = generics(db, id.parent);

            let substs = generics.placeholder_subst(db);
            let bounds = db
                .generic_predicates(id.parent)
                .iter()
                .map(|pred| pred.clone().substitute(Interner, &substs))
                .filter(|wc| {
                    let ty = match wc.skip_binders() {
                        WhereClause::Implemented(tr) => tr.self_type_parameter(Interner),
                        WhereClause::TypeOutlives(t) => t.ty.clone(),
                        // We shouldn't be here if these exist
                        WhereClause::AliasEq(_) | WhereClause::LifetimeOutlives(_) => {
                            return false;
                        }
                    };
                    let TyKind::Alias(AliasTy::Projection(proj)) = ty.kind(Interner) else {
                        return false;
                    };
                    proj == self
                })
                .collect::<Vec<_>>();
            if !bounds.is_empty() {
                return f.format_bounds_with(self.clone(), |f| {
                    write_bounds_like_dyn_trait_with_prefix(
                        f,
                        "impl",
                        Either::Left(
                            &TyKind::Alias(AliasTy::Projection(self.clone())).intern(Interner),
                        ),
                        &bounds,
                        SizedByDefault::NotSized,
                    )
                });
            }
        }

        write!(f, "<")?;
        self_ty.hir_fmt(f)?;
        write!(f, " as ")?;
        trait_ref.hir_fmt(f)?;
        write!(
            f,
            ">::{}",
            f.db.type_alias_signature(from_assoc_type_id(self.associated_ty_id))
                .name
                .display(f.db, f.edition())
        )?;
        let proj_params =
            &self.substitution.as_slice(Interner)[trait_ref.substitution.len(Interner)..];
        hir_fmt_generics(f, proj_params, None, None)
    }
}

impl HirDisplay for OpaqueTy {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        if f.should_truncate() {
            return write!(f, "{TYPE_HINT_TRUNCATION}");
        }

        self.substitution.at(Interner, 0).hir_fmt(f)
    }
}

impl HirDisplay for GenericArg {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        match self.interned() {
            crate::GenericArgData::Ty(ty) => ty.hir_fmt(f),
            crate::GenericArgData::Lifetime(lt) => lt.hir_fmt(f),
            crate::GenericArgData::Const(c) => c.hir_fmt(f),
        }
    }
}

impl<'db> HirDisplay for crate::next_solver::GenericArg<'db> {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        match self.kind() {
            rustc_type_ir::GenericArgKind::Type(ty) => ty.hir_fmt(f),
            rustc_type_ir::GenericArgKind::Lifetime(lt) => lt.hir_fmt(f),
            rustc_type_ir::GenericArgKind::Const(c) => c.hir_fmt(f),
        }
    }
}

impl HirDisplay for Const {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        let c = self.to_nextsolver(DbInterner::new_with(f.db, None, None));
        c.hir_fmt(f)
    }
}

impl<'db> HirDisplay for crate::next_solver::Const<'db> {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        match self.kind() {
            rustc_type_ir::ConstKind::Placeholder(_) => write!(f, "<placeholder>"),
            rustc_type_ir::ConstKind::Bound(db, bound_const) => {
                write!(f, "?{}.{}", db.as_u32(), bound_const.var.as_u32())
            }
            rustc_type_ir::ConstKind::Infer(..) => write!(f, "#c#"),
            rustc_type_ir::ConstKind::Param(param) => {
                let generics = generics(f.db, param.id.parent());
                let param_data = &generics[param.id.local_id()];
                write!(f, "{}", param_data.name().unwrap().display(f.db, f.edition()))?;
                Ok(())
            }
            rustc_type_ir::ConstKind::Value(const_bytes) => render_const_scalar_ns(
                f,
                &const_bytes.value.inner().0,
                &const_bytes.value.inner().1,
                const_bytes.ty,
            ),
            rustc_type_ir::ConstKind::Unevaluated(unev) => {
                let c = match unev.def {
                    SolverDefId::ConstId(id) => GeneralConstId::ConstId(id),
                    SolverDefId::StaticId(id) => GeneralConstId::StaticId(id),
                    _ => unreachable!(),
                };
                write!(f, "{}", c.name(f.db))?;
                hir_fmt_generics_ns(f, unev.args.as_slice(), c.generic_def(f.db), None)?;
                Ok(())
            }
            rustc_type_ir::ConstKind::Error(..) => f.write_char('_'),
            rustc_type_ir::ConstKind::Expr(..) => write!(f, "<const-expr>"),
        }
    }
}

fn render_const_scalar(
    f: &mut HirFormatter<'_>,
    b: &[u8],
    memory_map: &MemoryMap<'_>,
    ty: &Ty,
) -> Result<(), HirDisplayError> {
    let trait_env = TraitEnvironment::empty(f.krate());
    let interner = DbInterner::new_with(f.db, Some(trait_env.krate), trait_env.block);
    let ty = normalize(f.db, trait_env.clone(), ty.clone());
    let ty = ty.to_nextsolver(interner);
    render_const_scalar_inner(f, b, memory_map, ty, trait_env)
}

fn render_const_scalar_ns(
    f: &mut HirFormatter<'_>,
    b: &[u8],
    memory_map: &MemoryMap<'_>,
    ty: crate::next_solver::Ty<'_>,
) -> Result<(), HirDisplayError> {
    let trait_env = TraitEnvironment::empty(f.krate());
    let interner = DbInterner::new_with(f.db, Some(trait_env.krate), trait_env.block);
    let infcx = interner.infer_ctxt().build(rustc_type_ir::TypingMode::PostAnalysis);
    let ty = infcx.at(&ObligationCause::new(), trait_env.env).deeply_normalize(ty).unwrap_or(ty);
    render_const_scalar_inner(f, b, memory_map, ty, trait_env)
}

fn render_const_scalar_inner<'db>(
    f: &mut HirFormatter<'_>,
    b: &[u8],
    memory_map: &MemoryMap<'_>,
    ty: crate::next_solver::Ty<'db>,
    trait_env: Arc<TraitEnvironment<'db>>,
) -> Result<(), HirDisplayError> {
    use rustc_type_ir::TyKind;
    match ty.kind() {
        TyKind::Bool => write!(f, "{}", b[0] != 0),
        TyKind::Char => {
            let it = u128::from_le_bytes(pad16(b, false)) as u32;
            let Ok(c) = char::try_from(it) else {
                return f.write_str("<unicode-error>");
            };
            write!(f, "{c:?}")
        }
        TyKind::Int(_) => {
            let it = i128::from_le_bytes(pad16(b, true));
            write!(f, "{it}")
        }
        TyKind::Uint(_) => {
            let it = u128::from_le_bytes(pad16(b, false));
            write!(f, "{it}")
        }
        TyKind::Float(fl) => match fl {
            rustc_type_ir::FloatTy::F16 => {
                // FIXME(#17451): Replace with builtins once they are stabilised.
                let it = f16::from_bits(u16::from_le_bytes(b.try_into().unwrap()).into());
                let s = it.to_string();
                if s.strip_prefix('-').unwrap_or(&s).chars().all(|c| c.is_ascii_digit()) {
                    // Match Rust debug formatting
                    write!(f, "{s}.0")
                } else {
                    write!(f, "{s}")
                }
            }
            rustc_type_ir::FloatTy::F32 => {
                let it = f32::from_le_bytes(b.try_into().unwrap());
                write!(f, "{it:?}")
            }
            rustc_type_ir::FloatTy::F64 => {
                let it = f64::from_le_bytes(b.try_into().unwrap());
                write!(f, "{it:?}")
            }
            rustc_type_ir::FloatTy::F128 => {
                // FIXME(#17451): Replace with builtins once they are stabilised.
                let it = f128::from_bits(u128::from_le_bytes(b.try_into().unwrap()));
                let s = it.to_string();
                if s.strip_prefix('-').unwrap_or(&s).chars().all(|c| c.is_ascii_digit()) {
                    // Match Rust debug formatting
                    write!(f, "{s}.0")
                } else {
                    write!(f, "{s}")
                }
            }
        },
        TyKind::Ref(_, t, _) => match t.kind() {
            TyKind::Str => {
                let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
                let size = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
                let Some(bytes) = memory_map.get(addr, size) else {
                    return f.write_str("<ref-data-not-available>");
                };
                let s = std::str::from_utf8(bytes).unwrap_or("<utf8-error>");
                write!(f, "{s:?}")
            }
            TyKind::Slice(ty) => {
                let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
                let count = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
                let Ok(layout) = f.db.layout_of_ty(ty, trait_env) else {
                    return f.write_str("<layout-error>");
                };
                let size_one = layout.size.bytes_usize();
                let Some(bytes) = memory_map.get(addr, size_one * count) else {
                    return f.write_str("<ref-data-not-available>");
                };
                let expected_len = count * size_one;
                if bytes.len() < expected_len {
                    never!(
                        "Memory map size is too small. Expected {expected_len}, got {}",
                        bytes.len(),
                    );
                    return f.write_str("<layout-error>");
                }
                f.write_str("&[")?;
                let mut first = true;
                for i in 0..count {
                    if first {
                        first = false;
                    } else {
                        f.write_str(", ")?;
                    }
                    let offset = size_one * i;
                    render_const_scalar_ns(f, &bytes[offset..offset + size_one], memory_map, ty)?;
                }
                f.write_str("]")
            }
            TyKind::Dynamic(_, _) => {
                let addr = usize::from_le_bytes(b[0..b.len() / 2].try_into().unwrap());
                let ty_id = usize::from_le_bytes(b[b.len() / 2..].try_into().unwrap());
                let Ok(t) = memory_map.vtable_ty(ty_id) else {
                    return f.write_str("<ty-missing-in-vtable-map>");
                };
                let Ok(layout) = f.db.layout_of_ty(t, trait_env) else {
                    return f.write_str("<layout-error>");
                };
                let size = layout.size.bytes_usize();
                let Some(bytes) = memory_map.get(addr, size) else {
                    return f.write_str("<ref-data-not-available>");
                };
                f.write_str("&")?;
                render_const_scalar_ns(f, bytes, memory_map, t)
            }
            TyKind::Adt(adt, _) if b.len() == 2 * size_of::<usize>() => match adt.def_id().0 {
                hir_def::AdtId::StructId(s) => {
                    let data = f.db.struct_signature(s);
                    write!(f, "&{}", data.name.display(f.db, f.edition()))?;
                    Ok(())
                }
                _ => f.write_str("<unsized-enum-or-union>"),
            },
            _ => {
                let addr = usize::from_le_bytes(match b.try_into() {
                    Ok(b) => b,
                    Err(_) => {
                        never!(
                            "tried rendering ty {:?} in const ref with incorrect byte count {}",
                            t,
                            b.len()
                        );
                        return f.write_str("<layout-error>");
                    }
                });
                let Ok(layout) = f.db.layout_of_ty(t, trait_env) else {
                    return f.write_str("<layout-error>");
                };
                let size = layout.size.bytes_usize();
                let Some(bytes) = memory_map.get(addr, size) else {
                    return f.write_str("<ref-data-not-available>");
                };
                f.write_str("&")?;
                render_const_scalar_ns(f, bytes, memory_map, t)
            }
        },
        TyKind::Tuple(tys) => {
            let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else {
                return f.write_str("<layout-error>");
            };
            f.write_str("(")?;
            let mut first = true;
            for (id, ty) in tys.iter().enumerate() {
                if first {
                    first = false;
                } else {
                    f.write_str(", ")?;
                }
                let offset = layout.fields.offset(id).bytes_usize();
                let Ok(layout) = f.db.layout_of_ty(ty, trait_env.clone()) else {
                    f.write_str("<layout-error>")?;
                    continue;
                };
                let size = layout.size.bytes_usize();
                render_const_scalar_ns(f, &b[offset..offset + size], memory_map, ty)?;
            }
            f.write_str(")")
        }
        TyKind::Adt(def, args) => {
            let def = def.def_id().0;
            let Ok(layout) = f.db.layout_of_adt(def, args, trait_env.clone()) else {
                return f.write_str("<layout-error>");
            };
            match def {
                hir_def::AdtId::StructId(s) => {
                    let data = f.db.struct_signature(s);
                    write!(f, "{}", data.name.display(f.db, f.edition()))?;
                    let field_types = f.db.field_types(s.into());
                    render_variant_after_name(
                        s.fields(f.db),
                        f,
                        &field_types,
                        f.db.trait_environment(def.into()),
                        &layout,
                        args,
                        b,
                        memory_map,
                    )
                }
                hir_def::AdtId::UnionId(u) => {
                    write!(f, "{}", f.db.union_signature(u).name.display(f.db, f.edition()))
                }
                hir_def::AdtId::EnumId(e) => {
                    let Ok(target_data_layout) = f.db.target_data_layout(trait_env.krate) else {
                        return f.write_str("<target-layout-not-available>");
                    };
                    let Some((var_id, var_layout)) =
                        detect_variant_from_bytes(&layout, f.db, &target_data_layout, b, e)
                    else {
                        return f.write_str("<failed-to-detect-variant>");
                    };
                    let loc = var_id.lookup(f.db);
                    write!(
                        f,
                        "{}",
                        loc.parent.enum_variants(f.db).variants[loc.index as usize]
                            .1
                            .display(f.db, f.edition())
                    )?;
                    let field_types = f.db.field_types(var_id.into());
                    render_variant_after_name(
                        var_id.fields(f.db),
                        f,
                        &field_types,
                        f.db.trait_environment(def.into()),
                        var_layout,
                        args,
                        b,
                        memory_map,
                    )
                }
            }
        }
        TyKind::FnDef(..) => ty.hir_fmt(f),
        TyKind::FnPtr(_, _) | TyKind::RawPtr(_, _) => {
            let it = u128::from_le_bytes(pad16(b, false));
            write!(f, "{it:#X} as ")?;
            ty.hir_fmt(f)
        }
        TyKind::Array(ty, len) => {
            let Some(len) = consteval_nextsolver::try_const_usize(f.db, len) else {
                return f.write_str("<unknown-array-len>");
            };
            let Ok(layout) = f.db.layout_of_ty(ty, trait_env) else {
                return f.write_str("<layout-error>");
            };
            let size_one = layout.size.bytes_usize();
            f.write_str("[")?;
            let mut first = true;
            for i in 0..len as usize {
                if first {
                    first = false;
                } else {
                    f.write_str(", ")?;
                }
                let offset = size_one * i;
                render_const_scalar_ns(f, &b[offset..offset + size_one], memory_map, ty)?;
            }
            f.write_str("]")
        }
        TyKind::Never => f.write_str("!"),
        TyKind::Closure(_, _) => f.write_str("<closure>"),
        TyKind::Coroutine(_, _) => f.write_str("<coroutine>"),
        TyKind::CoroutineWitness(_, _) => f.write_str("<coroutine-witness>"),
        TyKind::CoroutineClosure(_, _) => f.write_str("<coroutine-closure>"),
        TyKind::UnsafeBinder(_) => f.write_str("<unsafe-binder>"),
        // The below arms are unreachable, since const eval will bail out before here.
        TyKind::Foreign(_) => f.write_str("<extern-type>"),
        TyKind::Pat(_, _) => f.write_str("<pat>"),
        TyKind::Error(..)
        | TyKind::Placeholder(_)
        | TyKind::Alias(_, _)
        | TyKind::Param(_)
        | TyKind::Bound(_, _)
        | TyKind::Infer(_) => f.write_str("<placeholder-or-unknown-type>"),
        // The below arms are unreachable, since we handled them in ref case.
        TyKind::Slice(_) | TyKind::Str | TyKind::Dynamic(_, _) => f.write_str("<unsized-value>"),
    }
}

fn render_variant_after_name<'db>(
    data: &VariantFields,
    f: &mut HirFormatter<'_>,
    field_types: &ArenaMap<LocalFieldId, Binders<Ty>>,
    trait_env: Arc<TraitEnvironment<'db>>,
    layout: &Layout,
    args: GenericArgs<'_>,
    b: &[u8],
    memory_map: &MemoryMap<'_>,
) -> Result<(), HirDisplayError> {
    let interner = DbInterner::new_with(f.db, Some(trait_env.krate), trait_env.block);
    match data.shape {
        FieldsShape::Record | FieldsShape::Tuple => {
            let render_field = |f: &mut HirFormatter<'_>, id: LocalFieldId| {
                let offset = layout.fields.offset(u32::from(id.into_raw()) as usize).bytes_usize();
                let ty = field_types[id]
                    .clone()
                    .substitute(Interner, &convert_args_for_result(interner, args.as_slice()));
                let Ok(layout) = f.db.layout_of_ty(ty.to_nextsolver(interner), trait_env.clone())
                else {
                    return f.write_str("<layout-error>");
                };
                let size = layout.size.bytes_usize();
                render_const_scalar(f, &b[offset..offset + size], memory_map, &ty)
            };
            let mut it = data.fields().iter();
            if matches!(data.shape, FieldsShape::Record) {
                write!(f, " {{")?;
                if let Some((id, data)) = it.next() {
                    write!(f, " {}: ", data.name.display(f.db, f.edition()))?;
                    render_field(f, id)?;
                }
                for (id, data) in it {
                    write!(f, ", {}: ", data.name.display(f.db, f.edition()))?;
                    render_field(f, id)?;
                }
                write!(f, " }}")?;
            } else {
                let mut it = it.map(|it| it.0);
                write!(f, "(")?;
                if let Some(id) = it.next() {
                    render_field(f, id)?;
                }
                for id in it {
                    write!(f, ", ")?;
                    render_field(f, id)?;
                }
                write!(f, ")")?;
            }
            Ok(())
        }
        FieldsShape::Unit => Ok(()),
    }
}

impl HirDisplay for BoundVar {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        write!(f, "?{}.{}", self.debruijn.depth(), self.index)
    }
}

impl HirDisplay for Ty {
    fn hir_fmt(
        &self,
        f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_>,
    ) -> Result<(), HirDisplayError> {
        let ty = self.to_nextsolver(DbInterner::new_with(db, None, None));
        ty.hir_fmt(f)
    }
}

impl<'db> HirDisplay for crate::next_solver::Ty<'db> {
    fn hir_fmt(
        &self,
        f @ &mut HirFormatter { db, .. }: &mut HirFormatter<'_>,
    ) -> Result<(), HirDisplayError> {
        let interner = DbInterner::new_with(db, None, None);
        if f.should_truncate() {
            return write!(f, "{TYPE_HINT_TRUNCATION}");
        }

        use rustc_type_ir::TyKind;
        match self.kind() {
            TyKind::Never => write!(f, "!")?,
            TyKind::Str => write!(f, "str")?,
            TyKind::Bool => write!(f, "bool")?,
            TyKind::Char => write!(f, "char")?,
            TyKind::Float(t) => write!(f, "{}", primitive::float_ty_to_string_ns(t))?,
            TyKind::Int(t) => write!(f, "{}", primitive::int_ty_to_string_ns(t))?,
            TyKind::Uint(t) => write!(f, "{}", primitive::uint_ty_to_string_ns(t))?,
            TyKind::Slice(t) => {
                write!(f, "[")?;
                t.hir_fmt(f)?;
                write!(f, "]")?;
            }
            TyKind::Array(t, c) => {
                write!(f, "[")?;
                t.hir_fmt(f)?;
                write!(f, "; ")?;
                convert_const_for_result(interner, c).hir_fmt(f)?;
                write!(f, "]")?;
            }
            kind @ (TyKind::RawPtr(t, m) | TyKind::Ref(_, t, m)) => {
                if let TyKind::Ref(l, _, _) = kind {
                    f.write_char('&')?;
                    if f.render_region(l) {
                        convert_region_for_result(interner, l).hir_fmt(f)?;
                        f.write_char(' ')?;
                    }
                    match m {
                        rustc_ast_ir::Mutability::Not => (),
                        rustc_ast_ir::Mutability::Mut => f.write_str("mut ")?,
                    }
                } else {
                    write!(
                        f,
                        "*{}",
                        match m {
                            rustc_ast_ir::Mutability::Not => "const ",
                            rustc_ast_ir::Mutability::Mut => "mut ",
                        }
                    )?;
                }

                // FIXME: all this just to decide whether to use parentheses...
                let contains_impl_fn = |bounds: &[QuantifiedWhereClause]| {
                    bounds.iter().any(|bound| {
                        if let WhereClause::Implemented(trait_ref) = bound.skip_binders() {
                            let trait_ = trait_ref.hir_trait_id();
                            fn_traits(db, trait_).any(|it| it == trait_)
                        } else {
                            false
                        }
                    })
                };
                let contains_impl_fn_ns = |bounds: &[BoundExistentialPredicate<'_>]| {
                    bounds.iter().any(|bound| match bound.skip_binder() {
                        rustc_type_ir::ExistentialPredicate::Trait(trait_ref) => {
                            let trait_ = trait_ref.def_id.0;
                            fn_traits(db, trait_).any(|it| it == trait_)
                        }
                        _ => false,
                    })
                };
                let (preds_to_print, has_impl_fn_pred) = match t.kind() {
                    TyKind::Dynamic(bounds, region) => {
                        let render_lifetime = f.render_region(region);
                        (
                            bounds.len() + render_lifetime as usize,
                            contains_impl_fn_ns(bounds.as_slice()),
                        )
                    }
                    TyKind::Alias(AliasTyKind::Opaque, ty) => {
                        let opaque_ty_id = match ty.def_id {
                            SolverDefId::InternedOpaqueTyId(id) => id,
                            _ => unreachable!(),
                        };
                        let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty_id);
                        if let ImplTraitId::ReturnTypeImplTrait(func, idx) = impl_trait_id {
                            let datas = db
                                .return_type_impl_traits(func)
                                .expect("impl trait id without data");
                            let data =
                                (*datas).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone());
                            let bounds = data.substitute(
                                Interner,
                                &convert_args_for_result(interner, ty.args.as_slice()),
                            );
                            let mut len = bounds.skip_binders().len();

                            // Don't count Sized but count when it absent
                            // (i.e. when explicit ?Sized bound is set).
                            let default_sized = SizedByDefault::Sized { anchor: func.krate(db) };
                            let sized_bounds = bounds
                                .skip_binders()
                                .iter()
                                .filter(|b| {
                                    matches!(
                                        b.skip_binders(),
                                        WhereClause::Implemented(trait_ref)
                                            if default_sized.is_sized_trait(
                                                trait_ref.hir_trait_id(),
                                                db,
                                            ),
                                    )
                                })
                                .count();
                            match sized_bounds {
                                0 => len += 1,
                                _ => {
                                    len = len.saturating_sub(sized_bounds);
                                }
                            }

                            (len, contains_impl_fn(bounds.skip_binders()))
                        } else {
                            (0, false)
                        }
                    }
                    _ => (0, false),
                };

                if has_impl_fn_pred && preds_to_print <= 2 {
                    return t.hir_fmt(f);
                }

                if preds_to_print > 1 {
                    write!(f, "(")?;
                    t.hir_fmt(f)?;
                    write!(f, ")")?;
                } else {
                    t.hir_fmt(f)?;
                }
            }
            TyKind::Tuple(tys) => {
                if tys.len() == 1 {
                    write!(f, "(")?;
                    tys.as_slice()[0].hir_fmt(f)?;
                    write!(f, ",)")?;
                } else {
                    write!(f, "(")?;
                    f.write_joined(tys.as_slice(), ", ")?;
                    write!(f, ")")?;
                }
            }
            TyKind::FnPtr(sig, header) => {
                let sig = CallableSig::from_fn_sig_and_header(interner, sig, header);
                sig.hir_fmt(f)?;
            }
            TyKind::FnDef(def, args) => {
                let def = def.0;
                let sig = db
                    .callable_item_signature(def)
                    .substitute(Interner, &convert_args_for_result(interner, args.as_slice()));

                if f.display_kind.is_source_code() {
                    // `FnDef` is anonymous and there's no surface syntax for it. Show it as a
                    // function pointer type.
                    return sig.hir_fmt(f);
                }
                if let Safety::Unsafe = sig.safety {
                    write!(f, "unsafe ")?;
                }
                if !matches!(sig.abi, FnAbi::Rust | FnAbi::RustCall) {
                    f.write_str("extern \"")?;
                    f.write_str(sig.abi.as_str())?;
                    f.write_str("\" ")?;
                }

                write!(f, "fn ")?;
                f.start_location_link(def.into());
                match def {
                    CallableDefId::FunctionId(ff) => {
                        write!(f, "{}", db.function_signature(ff).name.display(f.db, f.edition()))?
                    }
                    CallableDefId::StructId(s) => {
                        write!(f, "{}", db.struct_signature(s).name.display(f.db, f.edition()))?
                    }
                    CallableDefId::EnumVariantId(e) => {
                        let loc = e.lookup(db);
                        write!(
                            f,
                            "{}",
                            loc.parent.enum_variants(db).variants[loc.index as usize]
                                .1
                                .display(db, f.edition())
                        )?
                    }
                };
                f.end_location_link();

                let parameters = convert_args_for_result(interner, args.as_slice());
                if parameters.len(Interner) > 0 {
                    let generic_def_id = GenericDefId::from_callable(db, def);
                    let generics = generics(db, generic_def_id);
                    let (parent_len, self_param, type_, const_, impl_, lifetime) =
                        generics.provenance_split();
                    let parameters = parameters.as_slice(Interner);
                    debug_assert_eq!(
                        parameters.len(),
                        parent_len + self_param as usize + type_ + const_ + impl_ + lifetime
                    );
                    // We print all params except implicit impl Trait params. Still a bit weird; should we leave out parent and self?
                    if parameters.len() - impl_ > 0 {
                        let params_len = parameters.len();
                        // `parameters` are in the order of fn's params (including impl traits), fn's lifetimes
                        let parameters =
                            generic_args_sans_defaults(f, Some(generic_def_id), parameters);
                        assert!(params_len >= parameters.len());
                        let defaults = params_len - parameters.len();

                        // Normally, functions cannot have default parameters, but they can,
                        // for function-like things such as struct names or enum variants.
                        // The former cannot have defaults but does have parents,
                        // but the latter cannot have parents but can have defaults.
                        //
                        // However, it's also true that *traits* can have defaults too.
                        // In this case, there can be no function params.
                        let parent_end = if parent_len > 0 {
                            // If `parent_len` > 0, then there cannot be defaults on the function
                            // and all defaults must come from the parent.
                            parent_len - defaults
                        } else {
                            parent_len
                        };
                        let fn_params_no_impl_or_defaults = parameters.len() - parent_end - impl_;
                        let (parent_params, fn_params) = parameters.split_at(parent_end);

                        write!(f, "<")?;
                        hir_fmt_generic_arguments(f, parent_params, None)?;
                        if !parent_params.is_empty() && !fn_params.is_empty() {
                            write!(f, ", ")?;
                        }
                        hir_fmt_generic_arguments(
                            f,
                            &fn_params[..fn_params_no_impl_or_defaults],
                            None,
                        )?;
                        write!(f, ">")?;
                    }
                }
                write!(f, "(")?;
                f.write_joined(sig.params(), ", ")?;
                write!(f, ")")?;
                let ret = sig.ret();
                if !ret.is_unit() {
                    write!(f, " -> ")?;
                    ret.hir_fmt(f)?;
                }
            }
            TyKind::Adt(def, parameters) => {
                let def_id = def.def_id().0;
                f.start_location_link(def_id.into());
                match f.display_kind {
                    DisplayKind::Diagnostics | DisplayKind::Test => {
                        let name = match def_id {
                            hir_def::AdtId::StructId(it) => db.struct_signature(it).name.clone(),
                            hir_def::AdtId::UnionId(it) => db.union_signature(it).name.clone(),
                            hir_def::AdtId::EnumId(it) => db.enum_signature(it).name.clone(),
                        };
                        write!(f, "{}", name.display(f.db, f.edition()))?;
                    }
                    DisplayKind::SourceCode { target_module_id: module_id, allow_opaque: _ } => {
                        if let Some(path) = find_path::find_path(
                            db,
                            ItemInNs::Types(def_id.into()),
                            module_id,
                            PrefixKind::Plain,
                            false,
                            // FIXME: no_std Cfg?
                            FindPathConfig {
                                prefer_no_std: false,
                                prefer_prelude: true,
                                prefer_absolute: false,
                                allow_unstable: true,
                            },
                        ) {
                            write!(f, "{}", path.display(f.db, f.edition()))?;
                        } else {
                            return Err(HirDisplayError::DisplaySourceCodeError(
                                DisplaySourceCodeError::PathNotFound,
                            ));
                        }
                    }
                }
                f.end_location_link();

                hir_fmt_generics(
                    f,
                    convert_args_for_result(interner, parameters.as_slice()).as_slice(Interner),
                    Some(def.def_id().0.into()),
                    None,
                )?;
            }
            TyKind::Alias(AliasTyKind::Projection, alias_ty) => {
                let type_alias = match alias_ty.def_id {
                    SolverDefId::TypeAliasId(id) => id,
                    _ => unreachable!(),
                };
                let parameters = convert_args_for_result(interner, alias_ty.args.as_slice());

                let projection_ty = ProjectionTy {
                    associated_ty_id: to_assoc_type_id(type_alias),
                    substitution: parameters.clone(),
                };

                projection_ty.hir_fmt(f)?;
            }
            TyKind::Foreign(alias) => {
                let type_alias = db.type_alias_signature(alias.0);
                f.start_location_link(alias.0.into());
                write!(f, "{}", type_alias.name.display(f.db, f.edition()))?;
                f.end_location_link();
            }
            TyKind::Alias(AliasTyKind::Opaque, alias_ty) => {
                let opaque_ty_id = match alias_ty.def_id {
                    SolverDefId::InternedOpaqueTyId(id) => id,
                    _ => unreachable!(),
                };
                let parameters = convert_args_for_result(interner, alias_ty.args.as_slice());
                if !f.display_kind.allows_opaque() {
                    return Err(HirDisplayError::DisplaySourceCodeError(
                        DisplaySourceCodeError::OpaqueType,
                    ));
                }
                let impl_trait_id = db.lookup_intern_impl_trait_id(opaque_ty_id);
                match impl_trait_id {
                    ImplTraitId::ReturnTypeImplTrait(func, idx) => {
                        let datas =
                            db.return_type_impl_traits(func).expect("impl trait id without data");
                        let data =
                            (*datas).as_ref().map(|rpit| rpit.impl_traits[idx].bounds.clone());
                        let bounds = data.substitute(Interner, &parameters);
                        let krate = func.krate(db);
                        write_bounds_like_dyn_trait_with_prefix(
                            f,
                            "impl",
                            Either::Left(&convert_ty_for_result(interner, *self)),
                            bounds.skip_binders(),
                            SizedByDefault::Sized { anchor: krate },
                        )?;
                        // FIXME: it would maybe be good to distinguish this from the alias type (when debug printing), and to show the substitution
                    }
                    ImplTraitId::TypeAliasImplTrait(alias, idx) => {
                        let datas =
                            db.type_alias_impl_traits(alias).expect("impl trait id without data");
                        let data = (*datas).as_ref().map(|it| it.impl_traits[idx].bounds.clone());
                        let bounds = data.substitute(Interner, &parameters);
                        let krate = alias.krate(db);
                        write_bounds_like_dyn_trait_with_prefix(
                            f,
                            "impl",
                            Either::Left(&convert_ty_for_result(interner, *self)),
                            bounds.skip_binders(),
                            SizedByDefault::Sized { anchor: krate },
                        )?;
                    }
                    ImplTraitId::AsyncBlockTypeImplTrait(body, ..) => {
                        let future_trait =
                            LangItem::Future.resolve_trait(db, body.module(db).krate());
                        let output = future_trait.and_then(|t| {
                            t.trait_items(db)
                                .associated_type_by_name(&Name::new_symbol_root(sym::Output))
                        });
                        write!(f, "impl ")?;
                        if let Some(t) = future_trait {
                            f.start_location_link(t.into());
                        }
                        write!(f, "Future")?;
                        if future_trait.is_some() {
                            f.end_location_link();
                        }
                        write!(f, "<")?;
                        if let Some(t) = output {
                            f.start_location_link(t.into());
                        }
                        write!(f, "Output")?;
                        if output.is_some() {
                            f.end_location_link();
                        }
                        write!(f, " = ")?;
                        parameters.at(Interner, 0).hir_fmt(f)?;
                        write!(f, ">")?;
                    }
                }
            }
            TyKind::Closure(id, substs) => {
                let id = id.0;
                let substs = convert_args_for_result(interner, substs.as_slice());
                if f.display_kind.is_source_code() {
                    if !f.display_kind.allows_opaque() {
                        return Err(HirDisplayError::DisplaySourceCodeError(
                            DisplaySourceCodeError::OpaqueType,
                        ));
                    } else if f.closure_style != ClosureStyle::ImplFn {
                        never!("Only `impl Fn` is valid for displaying closures in source code");
                    }
                }
                let chalk_id: chalk_ir::ClosureId<_> = id.into();
                match f.closure_style {
                    ClosureStyle::Hide => return write!(f, "{TYPE_HINT_TRUNCATION}"),
                    ClosureStyle::ClosureWithId => {
                        return write!(f, "{{closure#{:?}}}", chalk_id.0.index());
                    }
                    ClosureStyle::ClosureWithSubst => {
                        write!(f, "{{closure#{:?}}}", chalk_id.0.index())?;
                        return hir_fmt_generics(f, substs.as_slice(Interner), None, None);
                    }
                    _ => (),
                }
                let sig = ClosureSubst(&substs).sig_ty(db).callable_sig(db);
                if let Some(sig) = sig {
                    let InternedClosure(def, _) = db.lookup_intern_closure(id);
                    let infer = db.infer(def);
                    let (_, kind) = infer.closure_info(&chalk_id);
                    match f.closure_style {
                        ClosureStyle::ImplFn => write!(f, "impl {kind:?}(")?,
                        ClosureStyle::RANotation => write!(f, "|")?,
                        _ => unreachable!(),
                    }
                    if sig.params().is_empty() {
                    } else if f.should_truncate() {
                        write!(f, "{TYPE_HINT_TRUNCATION}")?;
                    } else {
                        f.write_joined(sig.params(), ", ")?;
                    };
                    match f.closure_style {
                        ClosureStyle::ImplFn => write!(f, ")")?,
                        ClosureStyle::RANotation => write!(f, "|")?,
                        _ => unreachable!(),
                    }
                    if f.closure_style == ClosureStyle::RANotation || !sig.ret().is_unit() {
                        write!(f, " -> ")?;
                        // FIXME: We display `AsyncFn` as `-> impl Future`, but this is hard to fix because
                        // we don't have a trait environment here, required to normalize `<Ret as Future>::Output`.
                        sig.ret().hir_fmt(f)?;
                    }
                } else {
                    write!(f, "{{closure}}")?;
                }
            }
            TyKind::Placeholder(_) => write!(f, "{{placeholder}}")?,
            TyKind::Param(param) => {
                let generics = generics(db, param.id.parent());
                let param_data = &generics[param.id.local_id()];
                match param_data {
                    TypeOrConstParamData::TypeParamData(p) => match p.provenance {
                        TypeParamProvenance::TypeParamList | TypeParamProvenance::TraitSelf => {
                            write!(
                                f,
                                "{}",
                                p.name
                                    .clone()
                                    .unwrap_or_else(Name::missing)
                                    .display(f.db, f.edition())
                            )?
                        }
                        TypeParamProvenance::ArgumentImplTrait => {
                            let substs = generics.placeholder_subst(db);
                            let bounds = db
                                .generic_predicates(param.id.parent())
                                .iter()
                                .map(|pred| pred.clone().substitute(Interner, &substs))
                                .filter(|wc| match wc.skip_binders() {
                                    WhereClause::Implemented(tr) => {
                                        tr.self_type_parameter(Interner)
                                            == convert_ty_for_result(interner, *self)
                                    }
                                    WhereClause::AliasEq(AliasEq {
                                        alias: AliasTy::Projection(proj),
                                        ty: _,
                                    }) => {
                                        proj.self_type_parameter(db)
                                            == convert_ty_for_result(interner, *self)
                                    }
                                    WhereClause::AliasEq(_) => false,
                                    WhereClause::TypeOutlives(to) => {
                                        to.ty == convert_ty_for_result(interner, *self)
                                    }
                                    WhereClause::LifetimeOutlives(_) => false,
                                })
                                .collect::<Vec<_>>();
                            let krate = param.id.parent().module(db).krate();
                            write_bounds_like_dyn_trait_with_prefix(
                                f,
                                "impl",
                                Either::Left(&convert_ty_for_result(interner, *self)),
                                &bounds,
                                SizedByDefault::Sized { anchor: krate },
                            )?;
                        }
                    },
                    TypeOrConstParamData::ConstParamData(p) => {
                        write!(f, "{}", p.name.display(f.db, f.edition()))?;
                    }
                }
            }
            TyKind::Bound(debruijn_index, ty) => {
                let idx = chalk_ir::BoundVar {
                    debruijn: chalk_ir::DebruijnIndex::new(debruijn_index.as_u32()),
                    index: ty.var.as_usize(),
                };
                idx.hir_fmt(f)?
            }
            TyKind::Dynamic(..) => {
                let ty = convert_ty_for_result(interner, *self);
                let chalk_ir::TyKind::Dyn(dyn_ty) = ty.kind(Interner) else { unreachable!() };
                // Reorder bounds to satisfy `write_bounds_like_dyn_trait()`'s expectation.
                // FIXME: `Iterator::partition_in_place()` or `Vec::extract_if()` may make it
                // more efficient when either of them hits stable.
                let mut bounds: SmallVec<[_; 4]> =
                    dyn_ty.bounds.skip_binders().iter(Interner).cloned().collect();
                let (auto_traits, others): (SmallVec<[_; 4]>, _) =
                    bounds.drain(1..).partition(|b| b.skip_binders().trait_id().is_some());
                bounds.extend(others);
                bounds.extend(auto_traits);

                if f.render_lifetime(&dyn_ty.lifetime) {
                    // we skip the binders in `write_bounds_like_dyn_trait_with_prefix`
                    bounds.push(Binders::empty(
                        Interner,
                        chalk_ir::WhereClause::TypeOutlives(chalk_ir::TypeOutlives {
                            ty: ty.clone(),
                            lifetime: dyn_ty.lifetime.clone(),
                        }),
                    ));
                }

                write_bounds_like_dyn_trait_with_prefix(
                    f,
                    "dyn",
                    Either::Left(&ty),
                    &bounds,
                    SizedByDefault::NotSized,
                )?;
            }
            TyKind::Error(_) => {
                if f.display_kind.is_source_code() {
                    f.write_char('_')?;
                } else {
                    write!(f, "{{unknown}}")?;
                }
            }
            TyKind::Infer(..) => write!(f, "_")?,
            TyKind::Coroutine(_, subst) => {
                if f.display_kind.is_source_code() {
                    return Err(HirDisplayError::DisplaySourceCodeError(
                        DisplaySourceCodeError::Coroutine,
                    ));
                }
                let CoroutineArgsParts { resume_ty, yield_ty, return_ty, .. } =
                    subst.split_coroutine_args();
                write!(f, "|")?;
                resume_ty.hir_fmt(f)?;
                write!(f, "|")?;

                write!(f, " yields ")?;
                yield_ty.hir_fmt(f)?;

                write!(f, " -> ")?;
                return_ty.hir_fmt(f)?;
            }
            TyKind::CoroutineWitness(..) => write!(f, "{{coroutine witness}}")?,
            TyKind::Pat(_, _) => write!(f, "{{pat}}")?,
            TyKind::UnsafeBinder(_) => write!(f, "{{unsafe binder}}")?,
            TyKind::CoroutineClosure(_, _) => write!(f, "{{coroutine closure}}")?,
            TyKind::Alias(_, _) => write!(f, "{{alias}}")?,
        }
        Ok(())
    }
}

fn hir_fmt_generics(
    f: &mut HirFormatter<'_>,
    parameters: &[GenericArg],
    generic_def: Option<hir_def::GenericDefId>,
    self_: Option<&Ty>,
) -> Result<(), HirDisplayError> {
    if parameters.is_empty() {
        return Ok(());
    }

    let parameters_to_write = generic_args_sans_defaults(f, generic_def, parameters);

    if !parameters_to_write.is_empty() {
        write!(f, "<")?;
        hir_fmt_generic_arguments(f, parameters_to_write, self_)?;
        write!(f, ">")?;
    }

    Ok(())
}

fn hir_fmt_generics_ns<'db>(
    f: &mut HirFormatter<'_>,
    parameters: &[crate::next_solver::GenericArg<'db>],
    generic_def: Option<hir_def::GenericDefId>,
    self_: Option<crate::next_solver::Ty<'db>>,
) -> Result<(), HirDisplayError> {
    if parameters.is_empty() {
        return Ok(());
    }

    let parameters_to_write = generic_args_sans_defaults_ns(f, generic_def, parameters);

    if !parameters_to_write.is_empty() {
        write!(f, "<")?;
        hir_fmt_generic_arguments_ns(f, parameters_to_write, self_)?;
        write!(f, ">")?;
    }

    Ok(())
}

fn generic_args_sans_defaults<'ga>(
    f: &mut HirFormatter<'_>,
    generic_def: Option<hir_def::GenericDefId>,
    parameters: &'ga [GenericArg],
) -> &'ga [GenericArg] {
    if f.display_kind.is_source_code() || f.omit_verbose_types() {
        match generic_def
            .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
            .filter(|it| !it.is_empty())
        {
            None => parameters,
            Some(default_parameters) => {
                let should_show = |arg: &GenericArg, i: usize| {
                    let is_err = |arg: &GenericArg| match arg.data(Interner) {
                        chalk_ir::GenericArgData::Lifetime(it) => {
                            *it.data(Interner) == LifetimeData::Error
                        }
                        chalk_ir::GenericArgData::Ty(it) => *it.kind(Interner) == TyKind::Error,
                        chalk_ir::GenericArgData::Const(it) => matches!(
                            it.data(Interner).value,
                            ConstValue::Concrete(ConcreteConst {
                                interned: ConstScalar::Unknown,
                                ..
                            })
                        ),
                    };
                    // if the arg is error like, render it to inform the user
                    if is_err(arg) {
                        return true;
                    }
                    // otherwise, if the arg is equal to the param default, hide it (unless the
                    // default is an error which can happen for the trait Self type)
                    match default_parameters.get(i) {
                        None => true,
                        Some(default_parameter) => {
                            // !is_err(default_parameter.skip_binders())
                            // &&
                            arg != &default_parameter.clone().substitute(Interner, &parameters[..i])
                        }
                    }
                };
                let mut default_from = 0;
                for (i, parameter) in parameters.iter().enumerate() {
                    if should_show(parameter, i) {
                        default_from = i + 1;
                    }
                }
                &parameters[0..default_from]
            }
        }
    } else {
        parameters
    }
}

fn hir_fmt_generic_args<'db>(
    f: &mut HirFormatter<'_>,
    parameters: &[crate::next_solver::GenericArg<'db>],
    generic_def: Option<hir_def::GenericDefId>,
    self_: Option<crate::next_solver::Ty<'db>>,
) -> Result<(), HirDisplayError> {
    if parameters.is_empty() {
        return Ok(());
    }

    let parameters_to_write = generic_args_sans_defaults_ns(f, generic_def, parameters);

    if !parameters_to_write.is_empty() {
        write!(f, "<")?;
        hir_fmt_generic_arguments_ns(f, parameters_to_write, self_)?;
        write!(f, ">")?;
    }

    Ok(())
}

fn generic_args_sans_defaults_ns<'ga, 'db>(
    f: &mut HirFormatter<'_>,
    generic_def: Option<hir_def::GenericDefId>,
    parameters: &'ga [crate::next_solver::GenericArg<'db>],
) -> &'ga [crate::next_solver::GenericArg<'db>] {
    let interner = DbInterner::new_with(f.db, Some(f.krate()), None);
    if f.display_kind.is_source_code() || f.omit_verbose_types() {
        match generic_def
            .map(|generic_def_id| f.db.generic_defaults(generic_def_id))
            .filter(|it| !it.is_empty())
        {
            None => parameters,
            Some(default_parameters) => {
                let should_show = |arg: &crate::next_solver::GenericArg<'db>, i: usize| {
                    let is_err = |arg: &crate::next_solver::GenericArg<'db>| match arg.kind() {
                        rustc_type_ir::GenericArgKind::Lifetime(it) => {
                            matches!(it.kind(), RegionKind::ReError(..))
                        }
                        rustc_type_ir::GenericArgKind::Type(it) => {
                            matches!(it.kind(), rustc_type_ir::TyKind::Error(..))
                        }
                        rustc_type_ir::GenericArgKind::Const(it) => {
                            matches!(it.kind(), rustc_type_ir::ConstKind::Error(..),)
                        }
                    };
                    // if the arg is error like, render it to inform the user
                    if is_err(arg) {
                        return true;
                    }
                    // otherwise, if the arg is equal to the param default, hide it (unless the
                    // default is an error which can happen for the trait Self type)
                    match default_parameters.get(i) {
                        None => true,
                        Some(default_parameter) => {
                            // !is_err(default_parameter.skip_binders())
                            // &&
                            arg != &default_parameter
                                .clone()
                                .substitute(
                                    Interner,
                                    &convert_args_for_result(interner, &parameters[..i]),
                                )
                                .to_nextsolver(interner)
                        }
                    }
                };
                let mut default_from = 0;
                for (i, parameter) in parameters.iter().enumerate() {
                    if should_show(parameter, i) {
                        default_from = i + 1;
                    }
                }
                &parameters[0..default_from]
            }
        }
    } else {
        parameters
    }
}

fn hir_fmt_generic_arguments(
    f: &mut HirFormatter<'_>,
    parameters: &[GenericArg],
    self_: Option<&Ty>,
) -> Result<(), HirDisplayError> {
    let mut first = true;
    let lifetime_offset = parameters.iter().position(|arg| arg.lifetime(Interner).is_some());

    let (ty_or_const, lifetimes) = match lifetime_offset {
        Some(offset) => parameters.split_at(offset),
        None => (parameters, &[][..]),
    };
    for generic_arg in lifetimes.iter().chain(ty_or_const) {
        if !mem::take(&mut first) {
            write!(f, ", ")?;
        }
        match self_ {
            self_ @ Some(_) if generic_arg.ty(Interner) == self_ => write!(f, "Self")?,
            _ => generic_arg.hir_fmt(f)?,
        }
    }
    Ok(())
}

fn hir_fmt_generic_arguments_ns<'db>(
    f: &mut HirFormatter<'_>,
    parameters: &[crate::next_solver::GenericArg<'db>],
    self_: Option<crate::next_solver::Ty<'db>>,
) -> Result<(), HirDisplayError> {
    let mut first = true;
    let lifetime_offset = parameters.iter().position(|arg| arg.region().is_some());

    let (ty_or_const, lifetimes) = match lifetime_offset {
        Some(offset) => parameters.split_at(offset),
        None => (parameters, &[][..]),
    };
    for generic_arg in lifetimes.iter().chain(ty_or_const) {
        if !mem::take(&mut first) {
            write!(f, ", ")?;
        }
        match self_ {
            self_ @ Some(_) if generic_arg.ty() == self_ => write!(f, "Self")?,
            _ => generic_arg.hir_fmt(f)?,
        }
    }
    Ok(())
}

impl HirDisplay for CallableSig {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        let CallableSig { params_and_return: _, is_varargs, safety, abi: _ } = *self;
        if let Safety::Unsafe = safety {
            write!(f, "unsafe ")?;
        }
        // FIXME: Enable this when the FIXME on FnAbi regarding PartialEq is fixed.
        // if !matches!(abi, FnAbi::Rust) {
        //     f.write_str("extern \"")?;
        //     f.write_str(abi.as_str())?;
        //     f.write_str("\" ")?;
        // }
        write!(f, "fn(")?;
        f.write_joined(self.params(), ", ")?;
        if is_varargs {
            if self.params().is_empty() {
                write!(f, "...")?;
            } else {
                write!(f, ", ...")?;
            }
        }
        write!(f, ")")?;
        let ret = self.ret();
        if !ret.is_unit() {
            write!(f, " -> ")?;
            ret.hir_fmt(f)?;
        }
        Ok(())
    }
}

fn fn_traits(db: &dyn DefDatabase, trait_: TraitId) -> impl Iterator<Item = TraitId> + '_ {
    let krate = trait_.lookup(db).container.krate();
    utils::fn_traits(db, krate)
}

#[derive(Clone, Copy, PartialEq, Eq)]
pub enum SizedByDefault {
    NotSized,
    Sized { anchor: Crate },
}

impl SizedByDefault {
    fn is_sized_trait(self, trait_: TraitId, db: &dyn DefDatabase) -> bool {
        match self {
            Self::NotSized => false,
            Self::Sized { anchor } => {
                let sized_trait = LangItem::Sized.resolve_trait(db, anchor);
                Some(trait_) == sized_trait
            }
        }
    }
}

pub fn write_bounds_like_dyn_trait_with_prefix(
    f: &mut HirFormatter<'_>,
    prefix: &str,
    this: Either<&Ty, &Lifetime>,
    predicates: &[QuantifiedWhereClause],
    default_sized: SizedByDefault,
) -> Result<(), HirDisplayError> {
    write!(f, "{prefix}")?;
    if !predicates.is_empty()
        || predicates.is_empty() && matches!(default_sized, SizedByDefault::Sized { .. })
    {
        write!(f, " ")?;
        write_bounds_like_dyn_trait(f, this, predicates, default_sized)
    } else {
        Ok(())
    }
}

fn write_bounds_like_dyn_trait(
    f: &mut HirFormatter<'_>,
    this: Either<&Ty, &Lifetime>,
    predicates: &[QuantifiedWhereClause],
    default_sized: SizedByDefault,
) -> Result<(), HirDisplayError> {
    // Note: This code is written to produce nice results (i.e.
    // corresponding to surface Rust) for types that can occur in
    // actual Rust. It will have weird results if the predicates
    // aren't as expected (i.e. self types = $0, projection
    // predicates for a certain trait come after the Implemented
    // predicate for that trait).
    let mut first = true;
    let mut angle_open = false;
    let mut is_fn_trait = false;
    let mut is_sized = false;
    for p in predicates.iter() {
        match p.skip_binders() {
            WhereClause::Implemented(trait_ref) => {
                let trait_ = trait_ref.hir_trait_id();
                if default_sized.is_sized_trait(trait_, f.db) {
                    is_sized = true;
                    if matches!(default_sized, SizedByDefault::Sized { .. }) {
                        // Don't print +Sized, but rather +?Sized if absent.
                        continue;
                    }
                }
                if !is_fn_trait {
                    is_fn_trait = fn_traits(f.db, trait_).any(|it| it == trait_);
                }
                if !is_fn_trait && angle_open {
                    write!(f, ">")?;
                    angle_open = false;
                }
                if !first {
                    write!(f, " + ")?;
                }
                // We assume that the self type is ^0.0 (i.e. the
                // existential) here, which is the only thing that's
                // possible in actual Rust, and hence don't print it
                f.start_location_link(trait_.into());
                write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
                f.end_location_link();
                if is_fn_trait {
                    if let [self_, params @ ..] = trait_ref.substitution.as_slice(Interner)
                        && let Some(args) =
                            params.first().and_then(|it| it.assert_ty_ref(Interner).as_tuple())
                    {
                        write!(f, "(")?;
                        hir_fmt_generic_arguments(f, args.as_slice(Interner), self_.ty(Interner))?;
                        write!(f, ")")?;
                    }
                } else {
                    let params = generic_args_sans_defaults(
                        f,
                        Some(trait_.into()),
                        trait_ref.substitution.as_slice(Interner),
                    );
                    if let [self_, params @ ..] = params
                        && !params.is_empty()
                    {
                        write!(f, "<")?;
                        hir_fmt_generic_arguments(f, params, self_.ty(Interner))?;
                        // there might be assoc type bindings, so we leave the angle brackets open
                        angle_open = true;
                    }
                }
            }
            WhereClause::TypeOutlives(to) if Either::Left(&to.ty) == this => {
                if !is_fn_trait && angle_open {
                    write!(f, ">")?;
                    angle_open = false;
                }
                if !first {
                    write!(f, " + ")?;
                }
                to.lifetime.hir_fmt(f)?;
            }
            WhereClause::TypeOutlives(_) => {}
            WhereClause::LifetimeOutlives(lo) if Either::Right(&lo.a) == this => {
                if !is_fn_trait && angle_open {
                    write!(f, ">")?;
                    angle_open = false;
                }
                if !first {
                    write!(f, " + ")?;
                }
                lo.b.hir_fmt(f)?;
            }
            WhereClause::LifetimeOutlives(_) => {}
            WhereClause::AliasEq(alias_eq) if is_fn_trait => {
                is_fn_trait = false;
                if !alias_eq.ty.is_unit() {
                    write!(f, " -> ")?;
                    alias_eq.ty.hir_fmt(f)?;
                }
            }
            WhereClause::AliasEq(AliasEq { ty, alias }) => {
                // in types in actual Rust, these will always come
                // after the corresponding Implemented predicate
                if angle_open {
                    write!(f, ", ")?;
                } else {
                    write!(f, "<")?;
                    angle_open = true;
                }
                if let AliasTy::Projection(proj) = alias {
                    let assoc_ty_id = from_assoc_type_id(proj.associated_ty_id);
                    let type_alias = f.db.type_alias_signature(assoc_ty_id);
                    f.start_location_link(assoc_ty_id.into());
                    write!(f, "{}", type_alias.name.display(f.db, f.edition()))?;
                    f.end_location_link();

                    let proj_arg_count = generics(f.db, assoc_ty_id.into()).len_self();
                    let parent_len = proj.substitution.len(Interner) - proj_arg_count;
                    if proj_arg_count > 0 {
                        write!(f, "<")?;
                        hir_fmt_generic_arguments(
                            f,
                            &proj.substitution.as_slice(Interner)[parent_len..],
                            None,
                        )?;
                        write!(f, ">")?;
                    }
                    write!(f, " = ")?;
                }
                ty.hir_fmt(f)?;
            }
        }
        first = false;
    }
    if angle_open {
        write!(f, ">")?;
    }
    if let SizedByDefault::Sized { anchor } = default_sized {
        let sized_trait = LangItem::Sized.resolve_trait(f.db, anchor);
        if !is_sized {
            if !first {
                write!(f, " + ")?;
            }
            if let Some(sized_trait) = sized_trait {
                f.start_location_link(sized_trait.into());
            }
            write!(f, "?Sized")?;
        } else if first {
            if let Some(sized_trait) = sized_trait {
                f.start_location_link(sized_trait.into());
            }
            write!(f, "Sized")?;
        }
        if sized_trait.is_some() {
            f.end_location_link();
        }
    }
    Ok(())
}

impl HirDisplay for TraitRef {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        let trait_ = self.hir_trait_id();
        f.start_location_link(trait_.into());
        write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
        f.end_location_link();
        let substs = self.substitution.as_slice(Interner);
        hir_fmt_generics(f, &substs[1..], None, substs[0].ty(Interner))
    }
}

impl<'db> HirDisplay for crate::next_solver::TraitRef<'db> {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        let trait_ = self.def_id.0;
        f.start_location_link(trait_.into());
        write!(f, "{}", f.db.trait_signature(trait_).name.display(f.db, f.edition()))?;
        f.end_location_link();
        let substs = self.args.as_slice();
        hir_fmt_generic_args(f, &substs[1..], None, substs[0].ty())
    }
}

impl HirDisplay for WhereClause {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        if f.should_truncate() {
            return write!(f, "{TYPE_HINT_TRUNCATION}");
        }

        match self {
            WhereClause::Implemented(trait_ref) => {
                trait_ref.self_type_parameter(Interner).hir_fmt(f)?;
                write!(f, ": ")?;
                trait_ref.hir_fmt(f)?;
            }
            WhereClause::AliasEq(AliasEq { alias: AliasTy::Projection(projection_ty), ty }) => {
                write!(f, "<")?;
                let trait_ref = &projection_ty.trait_ref(f.db);
                trait_ref.self_type_parameter(Interner).hir_fmt(f)?;
                write!(f, " as ")?;
                trait_ref.hir_fmt(f)?;
                write!(f, ">::",)?;
                let type_alias = from_assoc_type_id(projection_ty.associated_ty_id);
                f.start_location_link(type_alias.into());
                write!(
                    f,
                    "{}",
                    f.db.type_alias_signature(type_alias).name.display(f.db, f.edition()),
                )?;
                f.end_location_link();
                write!(f, " = ")?;
                ty.hir_fmt(f)?;
            }
            WhereClause::AliasEq(_) => write!(f, "{{error}}")?,

            // FIXME implement these
            WhereClause::TypeOutlives(..) => {}
            WhereClause::LifetimeOutlives(..) => {}
        }
        Ok(())
    }
}

impl HirDisplay for LifetimeOutlives {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        self.a.hir_fmt(f)?;
        write!(f, ": ")?;
        self.b.hir_fmt(f)
    }
}

impl HirDisplay for Lifetime {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        self.interned().hir_fmt(f)
    }
}

impl HirDisplay for LifetimeData {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        match self {
            LifetimeData::Placeholder(idx) => {
                let id = lt_from_placeholder_idx(f.db, *idx).0;
                let generics = generics(f.db, id.parent);
                let param_data = &generics[id.local_id];
                write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
                Ok(())
            }
            LifetimeData::BoundVar(idx) => idx.hir_fmt(f),
            LifetimeData::InferenceVar(_) => write!(f, "_"),
            LifetimeData::Static => write!(f, "'static"),
            LifetimeData::Error => {
                if cfg!(test) {
                    write!(f, "'?")
                } else {
                    write!(f, "'_")
                }
            }
            LifetimeData::Erased => write!(f, "'<erased>"),
            LifetimeData::Phantom(void, _) => match *void {},
        }
    }
}

impl<'db> HirDisplay for crate::next_solver::Region<'db> {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        match self.kind() {
            rustc_type_ir::RegionKind::ReEarlyParam(param) => {
                let generics = generics(f.db, param.id.parent);
                let param_data = &generics[param.id.local_id];
                write!(f, "{}", param_data.name.display(f.db, f.edition()))?;
                Ok(())
            }
            rustc_type_ir::RegionKind::ReBound(db, idx) => {
                write!(f, "?{}.{}", db.as_u32(), idx.var.as_u32())
            }
            rustc_type_ir::RegionKind::ReVar(_) => write!(f, "_"),
            rustc_type_ir::RegionKind::ReStatic => write!(f, "'static"),
            rustc_type_ir::RegionKind::ReError(..) => {
                if cfg!(test) {
                    write!(f, "'?")
                } else {
                    write!(f, "'_")
                }
            }
            rustc_type_ir::RegionKind::ReErased => write!(f, "'<erased>"),
            rustc_type_ir::RegionKind::RePlaceholder(_) => write!(f, "<placeholder>"),
            rustc_type_ir::RegionKind::ReLateParam(_) => write!(f, "<late-param>"),
        }
    }
}

impl HirDisplay for DomainGoal {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        match self {
            DomainGoal::Holds(wc) => {
                write!(f, "Holds(")?;
                wc.hir_fmt(f)?;
                write!(f, ")")?;
            }
            _ => write!(f, "_")?,
        }
        Ok(())
    }
}

pub fn write_visibility(
    module_id: ModuleId,
    vis: Visibility,
    f: &mut HirFormatter<'_>,
) -> Result<(), HirDisplayError> {
    match vis {
        Visibility::Public => write!(f, "pub "),
        Visibility::PubCrate(_) => write!(f, "pub(crate) "),
        Visibility::Module(vis_id, _) => {
            let def_map = module_id.def_map(f.db);
            let root_module_id = def_map.module_id(DefMap::ROOT);
            if vis_id == module_id {
                // pub(self) or omitted
                Ok(())
            } else if root_module_id == vis_id {
                write!(f, "pub(crate) ")
            } else if module_id.containing_module(f.db) == Some(vis_id) {
                write!(f, "pub(super) ")
            } else {
                write!(f, "pub(in ...) ")
            }
        }
    }
}

pub trait HirDisplayWithExpressionStore {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        store: &ExpressionStore,
    ) -> Result<(), HirDisplayError>;
}

impl<T: ?Sized + HirDisplayWithExpressionStore> HirDisplayWithExpressionStore for &'_ T {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        store: &ExpressionStore,
    ) -> Result<(), HirDisplayError> {
        T::hir_fmt(&**self, f, store)
    }
}

pub fn hir_display_with_store<'a, T: HirDisplayWithExpressionStore + 'a>(
    value: T,
    store: &'a ExpressionStore,
) -> impl HirDisplay + 'a {
    ExpressionStoreAdapter(value, store)
}

struct ExpressionStoreAdapter<'a, T>(T, &'a ExpressionStore);

impl<'a, T> ExpressionStoreAdapter<'a, T> {
    fn wrap(store: &'a ExpressionStore) -> impl Fn(T) -> ExpressionStoreAdapter<'a, T> {
        move |value| ExpressionStoreAdapter(value, store)
    }
}

impl<T: HirDisplayWithExpressionStore> HirDisplay for ExpressionStoreAdapter<'_, T> {
    fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
        T::hir_fmt(&self.0, f, self.1)
    }
}
impl HirDisplayWithExpressionStore for LifetimeRefId {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        store: &ExpressionStore,
    ) -> Result<(), HirDisplayError> {
        match &store[*self] {
            LifetimeRef::Named(name) => write!(f, "{}", name.display(f.db, f.edition())),
            LifetimeRef::Static => write!(f, "'static"),
            LifetimeRef::Placeholder => write!(f, "'_"),
            LifetimeRef::Error => write!(f, "'{{error}}"),
            &LifetimeRef::Param(lifetime_param_id) => {
                let generic_params = f.db.generic_params(lifetime_param_id.parent);
                write!(
                    f,
                    "{}",
                    generic_params[lifetime_param_id.local_id].name.display(f.db, f.edition())
                )
            }
        }
    }
}

impl HirDisplayWithExpressionStore for TypeRefId {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        store: &ExpressionStore,
    ) -> Result<(), HirDisplayError> {
        match &store[*self] {
            TypeRef::Never => write!(f, "!")?,
            TypeRef::TypeParam(param) => {
                let generic_params = f.db.generic_params(param.parent());
                match generic_params[param.local_id()].name() {
                    Some(name) => write!(f, "{}", name.display(f.db, f.edition()))?,
                    None => {
                        write!(f, "impl ")?;
                        f.write_joined(
                            generic_params
                                .where_predicates()
                                .iter()
                                .filter_map(|it| match it {
                                    WherePredicate::TypeBound { target, bound }
                                    | WherePredicate::ForLifetime { lifetimes: _, target, bound }
                                        if matches!(
                                            store[*target],
                                            TypeRef::TypeParam(t) if t == *param
                                        ) =>
                                    {
                                        Some(bound)
                                    }
                                    _ => None,
                                })
                                .map(ExpressionStoreAdapter::wrap(store)),
                            " + ",
                        )?;
                    }
                }
            }
            TypeRef::Placeholder => write!(f, "_")?,
            TypeRef::Tuple(elems) => {
                write!(f, "(")?;
                f.write_joined(elems.iter().map(ExpressionStoreAdapter::wrap(store)), ", ")?;
                if elems.len() == 1 {
                    write!(f, ",")?;
                }
                write!(f, ")")?;
            }
            TypeRef::Path(path) => path.hir_fmt(f, store)?,
            TypeRef::RawPtr(inner, mutability) => {
                let mutability = match mutability {
                    hir_def::type_ref::Mutability::Shared => "*const ",
                    hir_def::type_ref::Mutability::Mut => "*mut ",
                };
                write!(f, "{mutability}")?;
                inner.hir_fmt(f, store)?;
            }
            TypeRef::Reference(ref_) => {
                let mutability = match ref_.mutability {
                    hir_def::type_ref::Mutability::Shared => "",
                    hir_def::type_ref::Mutability::Mut => "mut ",
                };
                write!(f, "&")?;
                if let Some(lifetime) = &ref_.lifetime {
                    lifetime.hir_fmt(f, store)?;
                    write!(f, " ")?;
                }
                write!(f, "{mutability}")?;
                ref_.ty.hir_fmt(f, store)?;
            }
            TypeRef::Array(array) => {
                write!(f, "[")?;
                array.ty.hir_fmt(f, store)?;
                write!(f, "; ")?;
                array.len.hir_fmt(f, store)?;
                write!(f, "]")?;
            }
            TypeRef::Slice(inner) => {
                write!(f, "[")?;
                inner.hir_fmt(f, store)?;
                write!(f, "]")?;
            }
            TypeRef::Fn(fn_) => {
                if fn_.is_unsafe {
                    write!(f, "unsafe ")?;
                }
                if let Some(abi) = &fn_.abi {
                    f.write_str("extern \"")?;
                    f.write_str(abi.as_str())?;
                    f.write_str("\" ")?;
                }
                write!(f, "fn(")?;
                if let Some(((_, return_type), function_parameters)) = fn_.params.split_last() {
                    for index in 0..function_parameters.len() {
                        let (param_name, param_type) = &function_parameters[index];
                        if let Some(name) = param_name {
                            write!(f, "{}: ", name.display(f.db, f.edition()))?;
                        }

                        param_type.hir_fmt(f, store)?;

                        if index != function_parameters.len() - 1 {
                            write!(f, ", ")?;
                        }
                    }
                    if fn_.is_varargs {
                        write!(f, "{}...", if fn_.params.len() == 1 { "" } else { ", " })?;
                    }
                    write!(f, ")")?;
                    match &store[*return_type] {
                        TypeRef::Tuple(tup) if tup.is_empty() => {}
                        _ => {
                            write!(f, " -> ")?;
                            return_type.hir_fmt(f, store)?;
                        }
                    }
                }
            }
            TypeRef::ImplTrait(bounds) => {
                write!(f, "impl ")?;
                f.write_joined(bounds.iter().map(ExpressionStoreAdapter::wrap(store)), " + ")?;
            }
            TypeRef::DynTrait(bounds) => {
                write!(f, "dyn ")?;
                f.write_joined(bounds.iter().map(ExpressionStoreAdapter::wrap(store)), " + ")?;
            }
            TypeRef::Error => write!(f, "{{error}}")?,
        }
        Ok(())
    }
}

impl HirDisplayWithExpressionStore for ConstRef {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        _store: &ExpressionStore,
    ) -> Result<(), HirDisplayError> {
        // FIXME
        write!(f, "{{const}}")?;

        Ok(())
    }
}

impl HirDisplayWithExpressionStore for TypeBound {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        store: &ExpressionStore,
    ) -> Result<(), HirDisplayError> {
        match self {
            &TypeBound::Path(path, modifier) => {
                match modifier {
                    TraitBoundModifier::None => (),
                    TraitBoundModifier::Maybe => write!(f, "?")?,
                }
                store[path].hir_fmt(f, store)
            }
            TypeBound::Lifetime(lifetime) => lifetime.hir_fmt(f, store),
            TypeBound::ForLifetime(lifetimes, path) => {
                let edition = f.edition();
                write!(
                    f,
                    "for<{}> ",
                    lifetimes.iter().map(|it| it.display(f.db, edition)).format(", ")
                )?;
                store[*path].hir_fmt(f, store)
            }
            TypeBound::Use(args) => {
                write!(f, "use<")?;
                let edition = f.edition();
                let last = args.len().saturating_sub(1);
                for (idx, arg) in args.iter().enumerate() {
                    match arg {
                        UseArgRef::Lifetime(lt) => lt.hir_fmt(f, store)?,
                        UseArgRef::Name(n) => write!(f, "{}", n.display(f.db, edition))?,
                    }
                    if idx != last {
                        write!(f, ", ")?;
                    }
                }
                write!(f, "> ")
            }
            TypeBound::Error => write!(f, "{{error}}"),
        }
    }
}

impl HirDisplayWithExpressionStore for Path {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        store: &ExpressionStore,
    ) -> Result<(), HirDisplayError> {
        match (self.type_anchor(), self.kind()) {
            (Some(anchor), _) => {
                write!(f, "<")?;
                anchor.hir_fmt(f, store)?;
                write!(f, ">")?;
            }
            (_, PathKind::Plain) => {}
            (_, PathKind::Abs) => {}
            (_, PathKind::Crate) => write!(f, "crate")?,
            (_, &PathKind::SELF) => write!(f, "self")?,
            (_, PathKind::Super(n)) => {
                for i in 0..*n {
                    if i > 0 {
                        write!(f, "::")?;
                    }
                    write!(f, "super")?;
                }
            }
            (_, PathKind::DollarCrate(id)) => {
                // Resolve `$crate` to the crate's display name.
                // FIXME: should use the dependency name instead if available, but that depends on
                // the crate invoking `HirDisplay`
                let crate_data = id.extra_data(f.db);
                let name = crate_data
                    .display_name
                    .as_ref()
                    .map(|name| (*name.canonical_name()).clone())
                    .unwrap_or(sym::dollar_crate);
                write!(f, "{name}")?
            }
        }

        // Convert trait's `Self` bound back to the surface syntax. Note there is no associated
        // trait, so there can only be one path segment that `has_self_type`. The `Self` type
        // itself can contain further qualified path through, which will be handled by recursive
        // `hir_fmt`s.
        //
        // `trait_mod::Trait<Self = type_mod::Type, Args>::Assoc`
        // =>
        // `<type_mod::Type as trait_mod::Trait<Args>>::Assoc`
        let trait_self_ty = self.segments().iter().find_map(|seg| {
            let generic_args = seg.args_and_bindings?;
            generic_args.has_self_type.then(|| &generic_args.args[0])
        });
        if let Some(ty) = trait_self_ty {
            write!(f, "<")?;
            ty.hir_fmt(f, store)?;
            write!(f, " as ")?;
            // Now format the path of the trait...
        }

        for (seg_idx, segment) in self.segments().iter().enumerate() {
            if !matches!(self.kind(), PathKind::Plain) || seg_idx > 0 {
                write!(f, "::")?;
            }
            write!(f, "{}", segment.name.display(f.db, f.edition()))?;
            if let Some(generic_args) = segment.args_and_bindings {
                // We should be in type context, so format as `Foo<Bar>` instead of `Foo::<Bar>`.
                // Do we actually format expressions?
                match generic_args.parenthesized {
                    hir_def::expr_store::path::GenericArgsParentheses::ReturnTypeNotation => {
                        write!(f, "(..)")?;
                    }
                    hir_def::expr_store::path::GenericArgsParentheses::ParenSugar => {
                        // First argument will be a tuple, which already includes the parentheses.
                        // If the tuple only contains 1 item, write it manually to avoid the trailing `,`.
                        let tuple = match generic_args.args[0] {
                            hir_def::expr_store::path::GenericArg::Type(ty) => match &store[ty] {
                                TypeRef::Tuple(it) => Some(it),
                                _ => None,
                            },
                            _ => None,
                        };
                        if let Some(v) = tuple {
                            if v.len() == 1 {
                                write!(f, "(")?;
                                v[0].hir_fmt(f, store)?;
                                write!(f, ")")?;
                            } else {
                                generic_args.args[0].hir_fmt(f, store)?;
                            }
                        }
                        if let Some(ret) = generic_args.bindings[0].type_ref
                            && !matches!(&store[ret], TypeRef::Tuple(v) if v.is_empty())
                        {
                            write!(f, " -> ")?;
                            ret.hir_fmt(f, store)?;
                        }
                    }
                    hir_def::expr_store::path::GenericArgsParentheses::No => {
                        let mut first = true;
                        // Skip the `Self` bound if exists. It's handled outside the loop.
                        for arg in &generic_args.args[generic_args.has_self_type as usize..] {
                            if first {
                                first = false;
                                write!(f, "<")?;
                            } else {
                                write!(f, ", ")?;
                            }
                            arg.hir_fmt(f, store)?;
                        }
                        for binding in generic_args.bindings.iter() {
                            if first {
                                first = false;
                                write!(f, "<")?;
                            } else {
                                write!(f, ", ")?;
                            }
                            write!(f, "{}", binding.name.display(f.db, f.edition()))?;
                            match &binding.type_ref {
                                Some(ty) => {
                                    write!(f, " = ")?;
                                    ty.hir_fmt(f, store)?
                                }
                                None => {
                                    write!(f, ": ")?;
                                    f.write_joined(
                                        binding
                                            .bounds
                                            .iter()
                                            .map(ExpressionStoreAdapter::wrap(store)),
                                        " + ",
                                    )?;
                                }
                            }
                        }

                        // There may be no generic arguments to print, in case of a trait having only a
                        // single `Self` bound which is converted to `<Ty as Trait>::Assoc`.
                        if !first {
                            write!(f, ">")?;
                        }

                        // Current position: `<Ty as Trait<Args>|`
                        if generic_args.has_self_type {
                            write!(f, ">")?;
                        }
                    }
                }
            }
        }

        Ok(())
    }
}

impl HirDisplayWithExpressionStore for hir_def::expr_store::path::GenericArg {
    fn hir_fmt(
        &self,
        f: &mut HirFormatter<'_>,
        store: &ExpressionStore,
    ) -> Result<(), HirDisplayError> {
        match self {
            hir_def::expr_store::path::GenericArg::Type(ty) => ty.hir_fmt(f, store),
            hir_def::expr_store::path::GenericArg::Const(_c) => {
                // write!(f, "{}", c.display(f.db, f.edition()))
                write!(f, "<expr>")
            }
            hir_def::expr_store::path::GenericArg::Lifetime(lifetime) => lifetime.hir_fmt(f, store),
        }
    }
}
