blob: aac1fa35741fc2099c46357ac1fd107c5bce344c [file] [log] [blame]
//! Debug impls for types.
use std::fmt::{self, Debug, Display, Error, Formatter};
use super::*;
/// Wrapper to allow forwarding to `Display::fmt`, `Debug::fmt`, etc.
pub struct Fmt<F>(pub F)
where
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result;
impl<F> fmt::Display for Fmt<F>
where
F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
{
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
(self.0)(f)
}
}
impl<I: Interner> Debug for TraitId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_trait_id(*self, fmt).unwrap_or_else(|| write!(fmt, "TraitId({:?})", self.0))
}
}
impl<I: Interner> Debug for AdtId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_adt_id(*self, fmt).unwrap_or_else(|| write!(fmt, "AdtId({:?})", self.0))
}
}
impl<I: Interner> Debug for AssocTypeId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_assoc_type_id(*self, fmt)
.unwrap_or_else(|| write!(fmt, "AssocTypeId({:?})", self.0))
}
}
impl<I: Interner> Debug for FnDefId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
I::debug_fn_def_id(*self, fmt).unwrap_or_else(|| write!(fmt, "FnDefId({:?})", self.0))
}
}
impl<I: Interner> Debug for ClosureId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
I::debug_closure_id(*self, fmt).unwrap_or_else(|| write!(fmt, "ClosureId({:?})", self.0))
}
}
impl<I: Interner> Debug for CoroutineId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
I::debug_coroutine_id(*self, fmt)
.unwrap_or_else(|| write!(fmt, "CoroutineId({:?})", self.0))
}
}
impl<I: Interner> Debug for ForeignDefId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
I::debug_foreign_def_id(*self, fmt)
.unwrap_or_else(|| write!(fmt, "ForeignDefId({:?})", self.0))
}
}
impl<I: Interner> Debug for Ty<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_ty(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for Lifetime<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_lifetime(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for Const<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_const(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for ConcreteConst<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "{:?}", self.interned)
}
}
impl<I: Interner> Debug for GenericArg<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_generic_arg(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for Goal<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_goal(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for Goals<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_goals(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for ProgramClauseImplication<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_program_clause_implication(self, fmt)
.unwrap_or_else(|| write!(fmt, "ProgramClauseImplication(?)"))
}
}
impl<I: Interner> Debug for ProgramClause<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_program_clause(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for ProgramClauses<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_program_clauses(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for Constraints<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_constraints(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for SeparatorTraitRef<'_, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_separator_trait_ref(self, fmt)
.unwrap_or_else(|| write!(fmt, "SeparatorTraitRef(?)"))
}
}
impl<I: Interner> Debug for AliasTy<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_alias(self, fmt).unwrap_or_else(|| write!(fmt, "AliasTy(?)"))
}
}
impl<I: Interner> Debug for QuantifiedWhereClauses<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_quantified_where_clauses(self, fmt)
.unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for ProjectionTy<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_projection_ty(self, fmt).unwrap_or_else(|| {
unimplemented!("cannot format ProjectionTy without setting Program in tls")
})
}
}
impl<I: Interner> Debug for OpaqueTy<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_opaque_ty(self, fmt).unwrap_or_else(|| {
unimplemented!("cannot format OpaqueTy without setting Program in tls")
})
}
}
impl<I: Interner> Display for Substitution<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_substitution(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<I: Interner> Debug for OpaqueTyId<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_opaque_ty_id(*self, fmt).unwrap_or_else(|| write!(fmt, "OpaqueTyId({:?})", self.0))
}
}
impl Display for UniverseIndex {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "U{}", self.counter)
}
}
impl Debug for UniverseIndex {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "U{}", self.counter)
}
}
impl<I: Interner> Debug for TyData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
self.kind.fmt(fmt)
}
}
impl<I: Interner> Debug for TyKind<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
TyKind::BoundVar(db) => write!(fmt, "{:?}", db),
TyKind::Dyn(clauses) => write!(fmt, "{:?}", clauses),
TyKind::InferenceVar(var, TyVariableKind::General) => write!(fmt, "{:?}", var),
TyKind::InferenceVar(var, TyVariableKind::Integer) => write!(fmt, "{:?}i", var),
TyKind::InferenceVar(var, TyVariableKind::Float) => write!(fmt, "{:?}f", var),
TyKind::Alias(alias) => write!(fmt, "{:?}", alias),
TyKind::Placeholder(index) => write!(fmt, "{:?}", index),
TyKind::Function(function) => write!(fmt, "{:?}", function),
TyKind::Adt(id, substitution) => write!(fmt, "{:?}<{:?}>", id, substitution),
TyKind::AssociatedType(assoc_ty, substitution) => {
write!(fmt, "{:?}<{:?}>", assoc_ty, substitution)
}
TyKind::Scalar(scalar) => write!(fmt, "{:?}", scalar),
TyKind::Str => write!(fmt, "Str"),
TyKind::Tuple(arity, substitution) => write!(fmt, "{:?}<{:?}>", arity, substitution),
TyKind::OpaqueType(opaque_ty, substitution) => {
write!(fmt, "!{:?}<{:?}>", opaque_ty, substitution)
}
TyKind::Slice(substitution) => write!(fmt, "{{slice}}<{:?}>", substitution),
TyKind::FnDef(fn_def, substitution) => write!(fmt, "{:?}<{:?}>", fn_def, substitution),
TyKind::Ref(mutability, lifetime, ty) => match mutability {
Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty),
Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty),
},
TyKind::Raw(mutability, ty) => match mutability {
Mutability::Mut => write!(fmt, "(*mut {:?})", ty),
Mutability::Not => write!(fmt, "(*const {:?})", ty),
},
TyKind::Never => write!(fmt, "Never"),
TyKind::Array(ty, const_) => write!(fmt, "[{:?}; {:?}]", ty, const_),
TyKind::Closure(id, substitution) => {
write!(fmt, "{{closure:{:?}}}<{:?}>", id, substitution)
}
TyKind::Coroutine(coroutine, substitution) => {
write!(fmt, "{:?}<{:?}>", coroutine, substitution)
}
TyKind::CoroutineWitness(witness, substitution) => {
write!(fmt, "{:?}<{:?}>", witness, substitution)
}
TyKind::Foreign(foreign_ty) => write!(fmt, "{:?}", foreign_ty),
TyKind::Error => write!(fmt, "{{error}}"),
}
}
}
impl Debug for BoundVar {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let BoundVar { debruijn, index } = self;
write!(fmt, "{:?}.{:?}", debruijn, index)
}
}
impl Debug for DebruijnIndex {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let DebruijnIndex { depth } = self;
write!(fmt, "^{}", depth)
}
}
impl<I: Interner> Debug for DynTy<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let DynTy { bounds, lifetime } = self;
write!(fmt, "dyn {:?} + {:?}", bounds, lifetime)
}
}
impl Debug for InferenceVar {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "?{}", self.index)
}
}
impl<I: Interner> Debug for FnSubst<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "{:?}", self.0)
}
}
impl<I: Interner> Debug for FnPointer<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
// FIXME -- we should introduce some names or something here
let FnPointer {
num_binders,
substitution,
sig,
} = self;
write!(
fmt,
"{}{:?} for<{}> {:?}",
match sig.safety {
Safety::Unsafe => "unsafe ",
Safety::Safe => "",
},
sig.abi,
num_binders,
substitution
)
}
}
impl<I: Interner> Debug for LifetimeData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
LifetimeData::BoundVar(db) => write!(fmt, "'{:?}", db),
LifetimeData::InferenceVar(var) => write!(fmt, "'{:?}", var),
LifetimeData::Placeholder(index) => write!(fmt, "'{:?}", index),
LifetimeData::Static => write!(fmt, "'static"),
LifetimeData::Erased => write!(fmt, "'<erased>"),
LifetimeData::Phantom(..) => unreachable!(),
}
}
}
impl<I: Interner> VariableKinds<I> {
fn debug(&self) -> VariableKindsDebug<'_, I> {
VariableKindsDebug(self)
}
/// Helper method for debugging variable kinds.
pub fn inner_debug(&self, interner: I) -> VariableKindsInnerDebug<'_, I> {
VariableKindsInnerDebug {
variable_kinds: self,
interner,
}
}
}
struct VariableKindsDebug<'a, I: Interner>(&'a VariableKinds<I>);
impl<'a, I: Interner> Debug for VariableKindsDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_variable_kinds_with_angles(self.0, fmt)
.unwrap_or_else(|| write!(fmt, "{:?}", self.0.interned))
}
}
/// Helper struct for showing debug output for `VariableKinds`.
pub struct VariableKindsInnerDebug<'a, I: Interner> {
variable_kinds: &'a VariableKinds<I>,
interner: I,
}
impl<'a, I: Interner> Debug for VariableKindsInnerDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
// NB: We print variable kinds as a list delimited by `<>`,
// like `<K1, K2, ..>`. This is because variable kind lists
// are always associated with binders like `forall<type> {
// ... }`.
write!(fmt, "<")?;
for (index, binder) in self.variable_kinds.iter(self.interner).enumerate() {
if index > 0 {
write!(fmt, ", ")?;
}
match binder {
VariableKind::Ty(TyVariableKind::General) => write!(fmt, "type")?,
VariableKind::Ty(TyVariableKind::Integer) => write!(fmt, "integer type")?,
VariableKind::Ty(TyVariableKind::Float) => write!(fmt, "float type")?,
VariableKind::Lifetime => write!(fmt, "lifetime")?,
VariableKind::Const(ty) => write!(fmt, "const: {:?}", ty)?,
}
}
write!(fmt, ">")
}
}
impl<I: Interner> Debug for ConstData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match &self.value {
ConstValue::BoundVar(db) => write!(fmt, "{:?}", db),
ConstValue::InferenceVar(var) => write!(fmt, "{:?}", var),
ConstValue::Placeholder(index) => write!(fmt, "{:?}", index),
ConstValue::Concrete(evaluated) => write!(fmt, "{:?}", evaluated),
}
}
}
impl<I: Interner> Debug for GoalData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
GoalData::Quantified(qkind, ref subgoal) => write!(
fmt,
"{:?}{:?} {{ {:?} }}",
qkind,
subgoal.binders.debug(),
subgoal.value
),
GoalData::Implies(ref wc, ref g) => write!(fmt, "if ({:?}) {{ {:?} }}", wc, g),
GoalData::All(ref goals) => write!(fmt, "all{:?}", goals),
GoalData::Not(ref g) => write!(fmt, "not {{ {:?} }}", g),
GoalData::EqGoal(ref wc) => write!(fmt, "{:?}", wc),
GoalData::SubtypeGoal(ref wc) => write!(fmt, "{:?}", wc),
GoalData::DomainGoal(ref wc) => write!(fmt, "{:?}", wc),
GoalData::CannotProve => write!(fmt, r"¯\_(ツ)_/¯"),
}
}
}
/// Helper struct for showing debug output for `Goals`.
pub struct GoalsDebug<'a, I: Interner> {
goals: &'a Goals<I>,
interner: I,
}
impl<'a, I: Interner> Debug for GoalsDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "(")?;
for (goal, index) in self.goals.iter(self.interner).zip(0..) {
if index > 0 {
write!(fmt, ", ")?;
}
write!(fmt, "{:?}", goal)?;
}
write!(fmt, ")")?;
Ok(())
}
}
impl<I: Interner> Goals<I> {
/// Show debug output for `Goals`.
pub fn debug(&self, interner: I) -> GoalsDebug<'_, I> {
GoalsDebug {
goals: self,
interner,
}
}
}
/// Helper struct for showing debug output for `GenericArgData`.
pub struct GenericArgDataInnerDebug<'a, I: Interner>(&'a GenericArgData<I>);
impl<'a, I: Interner> Debug for GenericArgDataInnerDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self.0 {
GenericArgData::Ty(n) => write!(fmt, "{:?}", n),
GenericArgData::Lifetime(n) => write!(fmt, "{:?}", n),
GenericArgData::Const(n) => write!(fmt, "{:?}", n),
}
}
}
impl<I: Interner> GenericArgData<I> {
/// Helper method for debugging `GenericArgData`.
pub fn inner_debug(&self) -> GenericArgDataInnerDebug<'_, I> {
GenericArgDataInnerDebug(self)
}
}
/// Helper struct for showing debug output for program clause implications.
pub struct ProgramClauseImplicationDebug<'a, I: Interner> {
pci: &'a ProgramClauseImplication<I>,
interner: I,
}
impl<'a, I: Interner> Debug for ProgramClauseImplicationDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let ProgramClauseImplicationDebug { pci, interner } = self;
write!(fmt, "{:?}", pci.consequence)?;
let conditions = pci.conditions.as_slice(*interner);
let conds = conditions.len();
if conds == 0 {
return Ok(());
}
write!(fmt, " :- ")?;
for cond in &conditions[..conds - 1] {
write!(fmt, "{:?}, ", cond)?;
}
write!(fmt, "{:?}", conditions[conds - 1])
}
}
impl<I: Interner> ProgramClauseImplication<I> {
/// Show debug output for the program clause implication.
pub fn debug(&self, interner: I) -> ProgramClauseImplicationDebug<'_, I> {
ProgramClauseImplicationDebug {
pci: self,
interner,
}
}
}
/// Helper struct for showing debug output for application types.
pub struct TyKindDebug<'a, I: Interner> {
ty: &'a TyKind<I>,
interner: I,
}
impl<'a, I: Interner> Debug for TyKindDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let interner = self.interner;
match self.ty {
TyKind::BoundVar(db) => write!(fmt, "{:?}", db),
TyKind::Dyn(clauses) => write!(fmt, "{:?}", clauses),
TyKind::InferenceVar(var, TyVariableKind::General) => write!(fmt, "{:?}", var),
TyKind::InferenceVar(var, TyVariableKind::Integer) => write!(fmt, "{:?}i", var),
TyKind::InferenceVar(var, TyVariableKind::Float) => write!(fmt, "{:?}f", var),
TyKind::Alias(alias) => write!(fmt, "{:?}", alias),
TyKind::Placeholder(index) => write!(fmt, "{:?}", index),
TyKind::Function(function) => write!(fmt, "{:?}", function),
TyKind::Adt(id, substitution) => {
write!(fmt, "{:?}{:?}", id, substitution.with_angle(interner))
}
TyKind::AssociatedType(assoc_ty, substitution) => {
write!(fmt, "{:?}{:?}", assoc_ty, substitution.with_angle(interner))
}
TyKind::Scalar(scalar) => write!(fmt, "{:?}", scalar),
TyKind::Str => write!(fmt, "Str"),
TyKind::Tuple(arity, substitution) => {
write!(fmt, "{:?}{:?}", arity, substitution.with_angle(interner))
}
TyKind::OpaqueType(opaque_ty, substitution) => write!(
fmt,
"!{:?}{:?}",
opaque_ty,
substitution.with_angle(interner)
),
TyKind::Slice(ty) => write!(fmt, "[{:?}]", ty),
TyKind::FnDef(fn_def, substitution) => {
write!(fmt, "{:?}{:?}", fn_def, substitution.with_angle(interner))
}
TyKind::Ref(mutability, lifetime, ty) => match mutability {
Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty),
Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty),
},
TyKind::Raw(mutability, ty) => match mutability {
Mutability::Mut => write!(fmt, "(*mut {:?})", ty),
Mutability::Not => write!(fmt, "(*const {:?})", ty),
},
TyKind::Never => write!(fmt, "Never"),
TyKind::Array(ty, const_) => write!(fmt, "[{:?}; {:?}]", ty, const_),
TyKind::Closure(id, substitution) => write!(
fmt,
"{{closure:{:?}}}{:?}",
id,
substitution.with_angle(interner)
),
TyKind::Coroutine(coroutine, substitution) => write!(
fmt,
"{:?}{:?}",
coroutine,
substitution.with_angle(interner)
),
TyKind::CoroutineWitness(witness, substitution) => {
write!(fmt, "{:?}{:?}", witness, substitution.with_angle(interner))
}
TyKind::Foreign(foreign_ty) => write!(fmt, "{:?}", foreign_ty,),
TyKind::Error => write!(fmt, "{{error}}"),
}
}
}
impl<I: Interner> TyKind<I> {
/// Show debug output for the application type.
pub fn debug(&self, interner: I) -> TyKindDebug<'_, I> {
TyKindDebug { ty: self, interner }
}
}
/// Helper struct for showing debug output for substitutions.
pub struct SubstitutionDebug<'a, I: Interner> {
substitution: &'a Substitution<I>,
interner: I,
}
impl<'a, I: Interner> Debug for SubstitutionDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let SubstitutionDebug {
substitution,
interner,
} = self;
let mut first = true;
write!(fmt, "[")?;
for (index, value) in substitution.iter(*interner).enumerate() {
if first {
first = false;
} else {
write!(fmt, ", ")?;
}
write!(fmt, "?{} := {:?}", index, value)?;
}
write!(fmt, "]")?;
Ok(())
}
}
impl<I: Interner> Substitution<I> {
/// Show debug output for the substitution.
pub fn debug(&self, interner: I) -> SubstitutionDebug<'_, I> {
SubstitutionDebug {
substitution: self,
interner,
}
}
}
impl Debug for PlaceholderIndex {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let PlaceholderIndex { ui, idx } = self;
write!(fmt, "!{}_{}", ui.counter, idx)
}
}
impl<I: Interner> TraitRef<I> {
/// Returns a "Debuggable" type that prints like `P0 as Trait<P1..>`.
pub fn with_as(&self) -> impl std::fmt::Debug + '_ {
SeparatorTraitRef {
trait_ref: self,
separator: " as ",
}
}
/// Returns a "Debuggable" type that prints like `P0: Trait<P1..>`.
pub fn with_colon(&self) -> impl std::fmt::Debug + '_ {
SeparatorTraitRef {
trait_ref: self,
separator: ": ",
}
}
}
impl<I: Interner> Debug for TraitRef<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
Debug::fmt(&self.with_as(), fmt)
}
}
/// Trait ref with associated separator used for debug output.
pub struct SeparatorTraitRef<'me, I: Interner> {
/// The `TraitRef` itself.
pub trait_ref: &'me TraitRef<I>,
/// The separator used for displaying the `TraitRef`.
pub separator: &'me str,
}
/// Helper struct for showing debug output for the `SeperatorTraitRef`.
pub struct SeparatorTraitRefDebug<'a, 'me, I: Interner> {
separator_trait_ref: &'a SeparatorTraitRef<'me, I>,
interner: I,
}
impl<'a, 'me, I: Interner> Debug for SeparatorTraitRefDebug<'a, 'me, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let SeparatorTraitRefDebug {
separator_trait_ref,
interner,
} = self;
let parameters = separator_trait_ref
.trait_ref
.substitution
.as_slice(*interner);
write!(
fmt,
"{:?}{}{:?}{:?}",
parameters[0],
separator_trait_ref.separator,
separator_trait_ref.trait_ref.trait_id,
Angle(&parameters[1..])
)
}
}
impl<'me, I: Interner> SeparatorTraitRef<'me, I> {
/// Show debug output for the `SeperatorTraitRef`.
pub fn debug<'a>(&'a self, interner: I) -> SeparatorTraitRefDebug<'a, 'me, I> {
SeparatorTraitRefDebug {
separator_trait_ref: self,
interner,
}
}
}
impl<I: Interner> Debug for LifetimeOutlives<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "{:?}: {:?}", self.a, self.b)
}
}
impl<I: Interner> Debug for TypeOutlives<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "{:?}: {:?}", self.ty, self.lifetime)
}
}
/// Helper struct for showing debug output for projection types.
pub struct ProjectionTyDebug<'a, I: Interner> {
projection_ty: &'a ProjectionTy<I>,
interner: I,
}
impl<'a, I: Interner> Debug for ProjectionTyDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let ProjectionTyDebug {
projection_ty,
interner,
} = self;
write!(
fmt,
"({:?}){:?}",
projection_ty.associated_ty_id,
projection_ty.substitution.with_angle(*interner)
)
}
}
impl<I: Interner> ProjectionTy<I> {
/// Show debug output for the projection type.
pub fn debug(&self, interner: I) -> ProjectionTyDebug<'_, I> {
ProjectionTyDebug {
projection_ty: self,
interner,
}
}
}
/// Helper struct for showing debug output for opaque types.
pub struct OpaqueTyDebug<'a, I: Interner> {
opaque_ty: &'a OpaqueTy<I>,
interner: I,
}
impl<'a, I: Interner> Debug for OpaqueTyDebug<'a, I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let OpaqueTyDebug {
opaque_ty,
interner,
} = self;
write!(
fmt,
"{:?}{:?}",
opaque_ty.opaque_ty_id,
opaque_ty.substitution.with_angle(*interner)
)
}
}
impl<I: Interner> OpaqueTy<I> {
/// Show debug output for the opaque type.
pub fn debug(&self, interner: I) -> OpaqueTyDebug<'_, I> {
OpaqueTyDebug {
opaque_ty: self,
interner,
}
}
}
/// Wraps debug output in angle brackets (`<>`).
pub struct Angle<'a, T>(pub &'a [T]);
impl<'a, T: Debug> Debug for Angle<'a, T> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
if !self.0.is_empty() {
write!(fmt, "<")?;
for (index, elem) in self.0.iter().enumerate() {
if index > 0 {
write!(fmt, ", {:?}", elem)?;
} else {
write!(fmt, "{:?}", elem)?;
}
}
write!(fmt, ">")?;
}
Ok(())
}
}
impl<I: Interner> Debug for Normalize<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "Normalize({:?} -> {:?})", self.alias, self.ty)
}
}
impl<I: Interner> Debug for AliasEq<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "AliasEq({:?} = {:?})", self.alias, self.ty)
}
}
impl<I: Interner> Debug for WhereClause<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
WhereClause::Implemented(tr) => write!(fmt, "Implemented({:?})", tr.with_colon()),
WhereClause::AliasEq(a) => write!(fmt, "{:?}", a),
WhereClause::LifetimeOutlives(l_o) => write!(fmt, "{:?}", l_o),
WhereClause::TypeOutlives(t_o) => write!(fmt, "{:?}", t_o),
}
}
}
impl<I: Interner> Debug for FromEnv<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
FromEnv::Trait(t) => write!(fmt, "FromEnv({:?})", t.with_colon()),
FromEnv::Ty(t) => write!(fmt, "FromEnv({:?})", t),
}
}
}
impl<I: Interner> Debug for WellFormed<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
WellFormed::Trait(t) => write!(fmt, "WellFormed({:?})", t.with_colon()),
WellFormed::Ty(t) => write!(fmt, "WellFormed({:?})", t),
}
}
}
impl<I: Interner> Debug for DomainGoal<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
DomainGoal::Holds(n) => write!(fmt, "{:?}", n),
DomainGoal::WellFormed(n) => write!(fmt, "{:?}", n),
DomainGoal::FromEnv(n) => write!(fmt, "{:?}", n),
DomainGoal::Normalize(n) => write!(fmt, "{:?}", n),
DomainGoal::IsLocal(n) => write!(fmt, "IsLocal({:?})", n),
DomainGoal::IsUpstream(n) => write!(fmt, "IsUpstream({:?})", n),
DomainGoal::IsFullyVisible(n) => write!(fmt, "IsFullyVisible({:?})", n),
DomainGoal::LocalImplAllowed(tr) => {
write!(fmt, "LocalImplAllowed({:?})", tr.with_colon(),)
}
DomainGoal::Compatible => write!(fmt, "Compatible"),
DomainGoal::DownstreamType(n) => write!(fmt, "DownstreamType({:?})", n),
DomainGoal::Reveal => write!(fmt, "Reveal"),
DomainGoal::ObjectSafe(n) => write!(fmt, "ObjectSafe({:?})", n),
}
}
}
impl<I: Interner> Debug for EqGoal<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "({:?} = {:?})", self.a, self.b)
}
}
impl<I: Interner> Debug for SubtypeGoal<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "({:?} <: {:?})", self.a, self.b)
}
}
impl<T: HasInterner + Debug> Debug for Binders<T> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let Binders {
ref binders,
ref value,
} = *self;
write!(fmt, "for{:?} ", binders.debug())?;
Debug::fmt(value, fmt)
}
}
impl<I: Interner> Debug for ProgramClauseData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "{:?}", self.0)
}
}
impl<I: Interner> Debug for Environment<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
write!(fmt, "Env({:?})", self.clauses)
}
}
impl<I: Interner> Debug for CanonicalVarKinds<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_canonical_var_kinds(self, fmt)
.unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}
impl<T: HasInterner + Display> Canonical<T> {
/// Display the canonicalized item.
pub fn display(&self, interner: T::Interner) -> CanonicalDisplay<'_, T> {
CanonicalDisplay {
canonical: self,
interner,
}
}
}
/// Helper struct for displaying canonicalized items.
pub struct CanonicalDisplay<'a, T: HasInterner> {
canonical: &'a Canonical<T>,
interner: T::Interner,
}
impl<'a, T: HasInterner + Display> Display for CanonicalDisplay<'a, T> {
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
let Canonical { binders, value } = self.canonical;
let interner = self.interner;
let binders = binders.as_slice(interner);
if binders.is_empty() {
// Ordinarily, we try to print all binder levels, if they
// are empty, but we can skip in this *particular* case
// because we know that `Canonical` terms are never
// supposed to contain free variables. In other words,
// all "bound variables" that appear inside the canonical
// value must reference values that appear in `binders`.
write!(f, "{}", value)?;
} else {
write!(f, "for<")?;
for (i, pk) in binders.iter().enumerate() {
if i > 0 {
write!(f, ",")?;
}
write!(f, "?{}", pk.skip_kind())?;
}
write!(f, "> {{ {} }}", value)?;
}
Ok(())
}
}
impl<I: Interner> Debug for GenericArgData<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
GenericArgData::Ty(t) => write!(fmt, "Ty({:?})", t),
GenericArgData::Lifetime(l) => write!(fmt, "Lifetime({:?})", l),
GenericArgData::Const(c) => write!(fmt, "Const({:?})", c),
}
}
}
impl<I: Interner> Debug for VariableKind<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
VariableKind::Ty(TyVariableKind::General) => write!(fmt, "type"),
VariableKind::Ty(TyVariableKind::Integer) => write!(fmt, "integer type"),
VariableKind::Ty(TyVariableKind::Float) => write!(fmt, "float type"),
VariableKind::Lifetime => write!(fmt, "lifetime"),
VariableKind::Const(ty) => write!(fmt, "const: {:?}", ty),
}
}
}
impl<I: Interner, T: Debug> Debug for WithKind<I, T> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
let value = self.skip_kind();
match &self.kind {
VariableKind::Ty(TyVariableKind::General) => write!(fmt, "{:?} with kind type", value),
VariableKind::Ty(TyVariableKind::Integer) => {
write!(fmt, "{:?} with kind integer type", value)
}
VariableKind::Ty(TyVariableKind::Float) => {
write!(fmt, "{:?} with kind float type", value)
}
VariableKind::Lifetime => write!(fmt, "{:?} with kind lifetime", value),
VariableKind::Const(ty) => write!(fmt, "{:?} with kind {:?}", value, ty),
}
}
}
impl<I: Interner> Debug for Constraint<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
match self {
Constraint::LifetimeOutlives(a, b) => write!(fmt, "{:?}: {:?}", a, b),
Constraint::TypeOutlives(ty, lifetime) => write!(fmt, "{:?}: {:?}", ty, lifetime),
}
}
}
impl<I: Interner> Display for ConstrainedSubst<I> {
#[rustfmt::skip]
fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
let ConstrainedSubst { subst, constraints } = self;
let mut first = true;
let subst = format!("{}", Fmt(|f| Display::fmt(subst, f)));
if subst != "[]" {
write!(f, "substitution {}", subst)?;
first = false;
}
let constraints = format!("{}", Fmt(|f| Debug::fmt(constraints, f)));
if constraints != "[]" {
if !first { write!(f, ", ")?; }
write!(f, "lifetime constraints {}", constraints)?;
first = false;
}
let _ = first;
Ok(())
}
}
impl<I: Interner> Substitution<I> {
/// Displays the substitution in the form `< P0, .. Pn >`, or (if
/// the substitution is empty) as an empty string.
pub fn with_angle(&self, interner: I) -> Angle<'_, GenericArg<I>> {
Angle(self.as_slice(interner))
}
}
impl<I: Interner> Debug for Substitution<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
Display::fmt(self, fmt)
}
}
impl<I: Interner> Debug for Variances<I> {
fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
I::debug_variances(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
}
}