summaryrefslogtreecommitdiffstats
path: root/vendor/chalk-ir/src/debug.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/chalk-ir/src/debug.rs')
-rw-r--r--vendor/chalk-ir/src/debug.rs1016
1 files changed, 1016 insertions, 0 deletions
diff --git a/vendor/chalk-ir/src/debug.rs b/vendor/chalk-ir/src/debug.rs
new file mode 100644
index 000000000..76d66edf5
--- /dev/null
+++ b/vendor/chalk-ir/src/debug.rs
@@ -0,0 +1,1016 @@
+//! 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 GeneratorId<I> {
+ fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
+ I::debug_generator_id(*self, fmt)
+ .unwrap_or_else(|| write!(fmt, "GeneratorId({:?})", 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::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<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::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<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))
+ }
+}