//! 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(pub F) where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result; impl fmt::Display for Fmt where F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result, { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { (self.0)(f) } } impl Debug for TraitId { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_trait_id(*self, fmt).unwrap_or_else(|| write!(fmt, "TraitId({:?})", self.0)) } } impl Debug for AdtId { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_adt_id(*self, fmt).unwrap_or_else(|| write!(fmt, "AdtId({:?})", self.0)) } } impl Debug for AssocTypeId { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_assoc_type_id(*self, fmt) .unwrap_or_else(|| write!(fmt, "AssocTypeId({:?})", self.0)) } } impl Debug for FnDefId { 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 Debug for ClosureId { fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result { I::debug_closure_id(*self, fmt).unwrap_or_else(|| write!(fmt, "ClosureId({:?})", self.0)) } } impl Debug for GeneratorId { fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result { I::debug_generator_id(*self, fmt) .unwrap_or_else(|| write!(fmt, "GeneratorId({:?})", self.0)) } } impl Debug for ForeignDefId { 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 Debug for Ty { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_ty(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for Lifetime { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_lifetime(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for Const { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_const(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for ConcreteConst { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "{:?}", self.interned) } } impl Debug for GenericArg { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_generic_arg(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for Goal { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_goal(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for Goals { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_goals(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for ProgramClauseImplication { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_program_clause_implication(self, fmt) .unwrap_or_else(|| write!(fmt, "ProgramClauseImplication(?)")) } } impl Debug for ProgramClause { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_program_clause(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for ProgramClauses { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_program_clauses(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for Constraints { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_constraints(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl 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 Debug for AliasTy { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_alias(self, fmt).unwrap_or_else(|| write!(fmt, "AliasTy(?)")) } } impl Debug for QuantifiedWhereClauses { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_quantified_where_clauses(self, fmt) .unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for ProjectionTy { 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 Debug for OpaqueTy { 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 Display for Substitution { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_substitution(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Debug for OpaqueTyId { 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 Debug for TyData { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { self.kind.fmt(fmt) } } impl Debug for TyKind { 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::Generator(generator, substitution) => { write!(fmt, "{:?}<{:?}>", generator, substitution) } TyKind::GeneratorWitness(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 Debug for DynTy { 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 Debug for FnSubst { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "{:?}", self.0) } } impl Debug for FnPointer { 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 Debug for LifetimeData { 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::Empty(UniverseIndex::ROOT) => write!(fmt, "'"), LifetimeData::Empty(universe) => write!(fmt, "'", universe), LifetimeData::Erased => write!(fmt, "'"), LifetimeData::Phantom(..) => unreachable!(), } } } impl VariableKinds { 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); 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, 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 ``. This is because variable kind lists // are always associated with binders like `forall { // ... }`. 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 Debug for ConstData { 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 Debug for GoalData { 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, 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 Goals { /// 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); 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 GenericArgData { /// 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, 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 ProgramClauseImplication { /// 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, 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::Generator(generator, substitution) => write!( fmt, "{:?}{:?}", generator, substitution.with_angle(interner) ), TyKind::GeneratorWitness(witness, substitution) => { write!(fmt, "{:?}{:?}", witness, substitution.with_angle(interner)) } TyKind::Foreign(foreign_ty) => write!(fmt, "{:?}", foreign_ty,), TyKind::Error => write!(fmt, "{{error}}"), } } } impl TyKind { /// 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, 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 Substitution { /// 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 TraitRef { /// Returns a "Debuggable" type that prints like `P0 as Trait`. pub fn with_as(&self) -> impl std::fmt::Debug + '_ { SeparatorTraitRef { trait_ref: self, separator: " as ", } } /// Returns a "Debuggable" type that prints like `P0: Trait`. pub fn with_colon(&self) -> impl std::fmt::Debug + '_ { SeparatorTraitRef { trait_ref: self, separator: ": ", } } } impl Debug for TraitRef { 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, /// 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(¶meters[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 Debug for LifetimeOutlives { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "{:?}: {:?}", self.a, self.b) } } impl Debug for TypeOutlives { 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, 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 ProjectionTy { /// 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, 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 OpaqueTy { /// 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 Debug for Normalize { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "Normalize({:?} -> {:?})", self.alias, self.ty) } } impl Debug for AliasEq { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "AliasEq({:?} = {:?})", self.alias, self.ty) } } impl Debug for WhereClause { 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 Debug for FromEnv { 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 Debug for WellFormed { 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 Debug for DomainGoal { 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 Debug for EqGoal { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "({:?} = {:?})", self.a, self.b) } } impl Debug for SubtypeGoal { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "({:?} <: {:?})", self.a, self.b) } } impl Debug for Binders { 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 Debug for ProgramClauseData { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "{:?}", self.0) } } impl Debug for Environment { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { write!(fmt, "Env({:?})", self.clauses) } } impl Debug for CanonicalVarKinds { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_canonical_var_kinds(self, fmt) .unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } } impl Canonical { /// 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, 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 Debug for GenericArgData { 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 Debug for VariableKind { 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 Debug for WithKind { 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 Debug for Constraint { 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 Display for ConstrainedSubst { #[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 Substitution { /// 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> { Angle(self.as_slice(interner)) } } impl Debug for Substitution { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { Display::fmt(self, fmt) } } impl Debug for Variances { fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> { I::debug_variances(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned)) } }