chalk_ir/
debug.rs

1//! Debug impls for types.
2
3use std::fmt::{self, Debug, Display, Error, Formatter};
4
5use super::*;
6
7/// Wrapper to allow forwarding to `Display::fmt`, `Debug::fmt`, etc.
8pub struct Fmt<F>(pub F)
9where
10    F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result;
11
12impl<F> fmt::Display for Fmt<F>
13where
14    F: Fn(&mut fmt::Formatter<'_>) -> fmt::Result,
15{
16    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
17        (self.0)(f)
18    }
19}
20
21impl<I: Interner> Debug for TraitId<I> {
22    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
23        I::debug_trait_id(*self, fmt).unwrap_or_else(|| write!(fmt, "TraitId({:?})", self.0))
24    }
25}
26
27impl<I: Interner> Debug for AdtId<I> {
28    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
29        I::debug_adt_id(*self, fmt).unwrap_or_else(|| write!(fmt, "AdtId({:?})", self.0))
30    }
31}
32
33impl<I: Interner> Debug for AssocTypeId<I> {
34    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
35        I::debug_assoc_type_id(*self, fmt)
36            .unwrap_or_else(|| write!(fmt, "AssocTypeId({:?})", self.0))
37    }
38}
39
40impl<I: Interner> Debug for FnDefId<I> {
41    fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
42        I::debug_fn_def_id(*self, fmt).unwrap_or_else(|| write!(fmt, "FnDefId({:?})", self.0))
43    }
44}
45
46impl<I: Interner> Debug for ClosureId<I> {
47    fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
48        I::debug_closure_id(*self, fmt).unwrap_or_else(|| write!(fmt, "ClosureId({:?})", self.0))
49    }
50}
51
52impl<I: Interner> Debug for CoroutineId<I> {
53    fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
54        I::debug_coroutine_id(*self, fmt)
55            .unwrap_or_else(|| write!(fmt, "CoroutineId({:?})", self.0))
56    }
57}
58
59impl<I: Interner> Debug for ForeignDefId<I> {
60    fn fmt(&self, fmt: &mut Formatter<'_>) -> std::fmt::Result {
61        I::debug_foreign_def_id(*self, fmt)
62            .unwrap_or_else(|| write!(fmt, "ForeignDefId({:?})", self.0))
63    }
64}
65
66impl<I: Interner> Debug for Ty<I> {
67    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
68        I::debug_ty(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
69    }
70}
71
72impl<I: Interner> Debug for Lifetime<I> {
73    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
74        I::debug_lifetime(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
75    }
76}
77
78impl<I: Interner> Debug for Const<I> {
79    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
80        I::debug_const(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
81    }
82}
83
84impl<I: Interner> Debug for ConcreteConst<I> {
85    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
86        write!(fmt, "{:?}", self.interned)
87    }
88}
89
90impl<I: Interner> Debug for GenericArg<I> {
91    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
92        I::debug_generic_arg(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
93    }
94}
95
96impl<I: Interner> Debug for Goal<I> {
97    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
98        I::debug_goal(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
99    }
100}
101
102impl<I: Interner> Debug for Goals<I> {
103    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
104        I::debug_goals(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
105    }
106}
107
108impl<I: Interner> Debug for ProgramClauseImplication<I> {
109    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
110        I::debug_program_clause_implication(self, fmt)
111            .unwrap_or_else(|| write!(fmt, "ProgramClauseImplication(?)"))
112    }
113}
114
115impl<I: Interner> Debug for ProgramClause<I> {
116    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
117        I::debug_program_clause(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
118    }
119}
120
121impl<I: Interner> Debug for ProgramClauses<I> {
122    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
123        I::debug_program_clauses(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
124    }
125}
126
127impl<I: Interner> Debug for Constraints<I> {
128    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
129        I::debug_constraints(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
130    }
131}
132
133impl<I: Interner> Debug for SeparatorTraitRef<'_, I> {
134    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
135        I::debug_separator_trait_ref(self, fmt)
136            .unwrap_or_else(|| write!(fmt, "SeparatorTraitRef(?)"))
137    }
138}
139
140impl<I: Interner> Debug for AliasTy<I> {
141    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
142        I::debug_alias(self, fmt).unwrap_or_else(|| write!(fmt, "AliasTy(?)"))
143    }
144}
145
146impl<I: Interner> Debug for QuantifiedWhereClauses<I> {
147    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
148        I::debug_quantified_where_clauses(self, fmt)
149            .unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
150    }
151}
152
153impl<I: Interner> Debug for ProjectionTy<I> {
154    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
155        I::debug_projection_ty(self, fmt).unwrap_or_else(|| {
156            unimplemented!("cannot format ProjectionTy without setting Program in tls")
157        })
158    }
159}
160
161impl<I: Interner> Debug for OpaqueTy<I> {
162    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
163        I::debug_opaque_ty(self, fmt).unwrap_or_else(|| {
164            unimplemented!("cannot format OpaqueTy without setting Program in tls")
165        })
166    }
167}
168
169impl<I: Interner> Display for Substitution<I> {
170    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
171        I::debug_substitution(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
172    }
173}
174
175impl<I: Interner> Debug for OpaqueTyId<I> {
176    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
177        I::debug_opaque_ty_id(*self, fmt).unwrap_or_else(|| write!(fmt, "OpaqueTyId({:?})", self.0))
178    }
179}
180
181impl Display for UniverseIndex {
182    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
183        write!(fmt, "U{}", self.counter)
184    }
185}
186
187impl Debug for UniverseIndex {
188    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
189        write!(fmt, "U{}", self.counter)
190    }
191}
192
193impl<I: Interner> Debug for TyData<I> {
194    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
195        self.kind.fmt(fmt)
196    }
197}
198
199impl<I: Interner> Debug for TyKind<I> {
200    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
201        match self {
202            TyKind::BoundVar(db) => write!(fmt, "{:?}", db),
203            TyKind::Dyn(clauses) => write!(fmt, "{:?}", clauses),
204            TyKind::InferenceVar(var, TyVariableKind::General) => write!(fmt, "{:?}", var),
205            TyKind::InferenceVar(var, TyVariableKind::Integer) => write!(fmt, "{:?}i", var),
206            TyKind::InferenceVar(var, TyVariableKind::Float) => write!(fmt, "{:?}f", var),
207            TyKind::Alias(alias) => write!(fmt, "{:?}", alias),
208            TyKind::Placeholder(index) => write!(fmt, "{:?}", index),
209            TyKind::Function(function) => write!(fmt, "{:?}", function),
210            TyKind::Adt(id, substitution) => write!(fmt, "{:?}<{:?}>", id, substitution),
211            TyKind::AssociatedType(assoc_ty, substitution) => {
212                write!(fmt, "{:?}<{:?}>", assoc_ty, substitution)
213            }
214            TyKind::Scalar(scalar) => write!(fmt, "{:?}", scalar),
215            TyKind::Str => write!(fmt, "Str"),
216            TyKind::Tuple(arity, substitution) => write!(fmt, "{:?}<{:?}>", arity, substitution),
217            TyKind::OpaqueType(opaque_ty, substitution) => {
218                write!(fmt, "!{:?}<{:?}>", opaque_ty, substitution)
219            }
220            TyKind::Slice(substitution) => write!(fmt, "{{slice}}<{:?}>", substitution),
221            TyKind::FnDef(fn_def, substitution) => write!(fmt, "{:?}<{:?}>", fn_def, substitution),
222            TyKind::Ref(mutability, lifetime, ty) => match mutability {
223                Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty),
224                Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty),
225            },
226            TyKind::Raw(mutability, ty) => match mutability {
227                Mutability::Mut => write!(fmt, "(*mut {:?})", ty),
228                Mutability::Not => write!(fmt, "(*const {:?})", ty),
229            },
230            TyKind::Never => write!(fmt, "Never"),
231            TyKind::Array(ty, const_) => write!(fmt, "[{:?}; {:?}]", ty, const_),
232            TyKind::Closure(id, substitution) => {
233                write!(fmt, "{{closure:{:?}}}<{:?}>", id, substitution)
234            }
235            TyKind::Coroutine(coroutine, substitution) => {
236                write!(fmt, "{:?}<{:?}>", coroutine, substitution)
237            }
238            TyKind::CoroutineWitness(witness, substitution) => {
239                write!(fmt, "{:?}<{:?}>", witness, substitution)
240            }
241            TyKind::Foreign(foreign_ty) => write!(fmt, "{:?}", foreign_ty),
242            TyKind::Error => write!(fmt, "{{error}}"),
243        }
244    }
245}
246
247impl Debug for BoundVar {
248    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
249        let BoundVar { debruijn, index } = self;
250        write!(fmt, "{:?}.{:?}", debruijn, index)
251    }
252}
253
254impl Debug for DebruijnIndex {
255    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
256        let DebruijnIndex { depth } = self;
257        write!(fmt, "^{}", depth)
258    }
259}
260
261impl<I: Interner> Debug for DynTy<I> {
262    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
263        let DynTy { bounds, lifetime } = self;
264        write!(fmt, "dyn {:?} + {:?}", bounds, lifetime)
265    }
266}
267
268impl Debug for InferenceVar {
269    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
270        write!(fmt, "?{}", self.index)
271    }
272}
273
274impl<I: Interner> Debug for FnSubst<I> {
275    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
276        write!(fmt, "{:?}", self.0)
277    }
278}
279
280impl<I: Interner> Debug for FnPointer<I> {
281    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
282        // FIXME -- we should introduce some names or something here
283        let FnPointer {
284            num_binders,
285            substitution,
286            sig,
287        } = self;
288        write!(
289            fmt,
290            "{}{:?} for<{}> {:?}",
291            match sig.safety {
292                Safety::Unsafe => "unsafe ",
293                Safety::Safe => "",
294            },
295            sig.abi,
296            num_binders,
297            substitution
298        )
299    }
300}
301
302impl<I: Interner> Debug for LifetimeData<I> {
303    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
304        match self {
305            LifetimeData::BoundVar(db) => write!(fmt, "'{:?}", db),
306            LifetimeData::InferenceVar(var) => write!(fmt, "'{:?}", var),
307            LifetimeData::Placeholder(index) => write!(fmt, "'{:?}", index),
308            LifetimeData::Static => write!(fmt, "'static"),
309            LifetimeData::Erased => write!(fmt, "'<erased>"),
310            LifetimeData::Error => write!(fmt, "'{{error}}"),
311            LifetimeData::Phantom(..) => unreachable!(),
312        }
313    }
314}
315
316impl<I: Interner> VariableKinds<I> {
317    fn debug(&self) -> VariableKindsDebug<'_, I> {
318        VariableKindsDebug(self)
319    }
320
321    /// Helper method for debugging variable kinds.
322    pub fn inner_debug(&self, interner: I) -> VariableKindsInnerDebug<'_, I> {
323        VariableKindsInnerDebug {
324            variable_kinds: self,
325            interner,
326        }
327    }
328}
329
330struct VariableKindsDebug<'a, I: Interner>(&'a VariableKinds<I>);
331
332impl<'a, I: Interner> Debug for VariableKindsDebug<'a, I> {
333    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
334        I::debug_variable_kinds_with_angles(self.0, fmt)
335            .unwrap_or_else(|| write!(fmt, "{:?}", self.0.interned))
336    }
337}
338
339/// Helper struct for showing debug output for `VariableKinds`.
340pub struct VariableKindsInnerDebug<'a, I: Interner> {
341    variable_kinds: &'a VariableKinds<I>,
342    interner: I,
343}
344
345impl<'a, I: Interner> Debug for VariableKindsInnerDebug<'a, I> {
346    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
347        // NB: We print variable kinds as a list delimited by `<>`,
348        // like `<K1, K2, ..>`. This is because variable kind lists
349        // are always associated with binders like `forall<type> {
350        // ... }`.
351        write!(fmt, "<")?;
352        for (index, binder) in self.variable_kinds.iter(self.interner).enumerate() {
353            if index > 0 {
354                write!(fmt, ", ")?;
355            }
356            match binder {
357                VariableKind::Ty(TyVariableKind::General) => write!(fmt, "type")?,
358                VariableKind::Ty(TyVariableKind::Integer) => write!(fmt, "integer type")?,
359                VariableKind::Ty(TyVariableKind::Float) => write!(fmt, "float type")?,
360                VariableKind::Lifetime => write!(fmt, "lifetime")?,
361                VariableKind::Const(ty) => write!(fmt, "const: {:?}", ty)?,
362            }
363        }
364        write!(fmt, ">")
365    }
366}
367
368impl<I: Interner> Debug for ConstData<I> {
369    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
370        match &self.value {
371            ConstValue::BoundVar(db) => write!(fmt, "{:?}", db),
372            ConstValue::InferenceVar(var) => write!(fmt, "{:?}", var),
373            ConstValue::Placeholder(index) => write!(fmt, "{:?}", index),
374            ConstValue::Concrete(evaluated) => write!(fmt, "{:?}", evaluated),
375        }
376    }
377}
378
379impl<I: Interner> Debug for GoalData<I> {
380    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
381        match self {
382            GoalData::Quantified(qkind, ref subgoal) => write!(
383                fmt,
384                "{:?}{:?} {{ {:?} }}",
385                qkind,
386                subgoal.binders.debug(),
387                subgoal.value
388            ),
389            GoalData::Implies(ref wc, ref g) => write!(fmt, "if ({:?}) {{ {:?} }}", wc, g),
390            GoalData::All(ref goals) => write!(fmt, "all{:?}", goals),
391            GoalData::Not(ref g) => write!(fmt, "not {{ {:?} }}", g),
392            GoalData::EqGoal(ref wc) => write!(fmt, "{:?}", wc),
393            GoalData::SubtypeGoal(ref wc) => write!(fmt, "{:?}", wc),
394            GoalData::DomainGoal(ref wc) => write!(fmt, "{:?}", wc),
395            GoalData::CannotProve => write!(fmt, r"¯\_(ツ)_/¯"),
396        }
397    }
398}
399
400/// Helper struct for showing debug output for `Goals`.
401pub struct GoalsDebug<'a, I: Interner> {
402    goals: &'a Goals<I>,
403    interner: I,
404}
405
406impl<'a, I: Interner> Debug for GoalsDebug<'a, I> {
407    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
408        write!(fmt, "(")?;
409        for (goal, index) in self.goals.iter(self.interner).zip(0..) {
410            if index > 0 {
411                write!(fmt, ", ")?;
412            }
413            write!(fmt, "{:?}", goal)?;
414        }
415        write!(fmt, ")")?;
416        Ok(())
417    }
418}
419
420impl<I: Interner> Goals<I> {
421    /// Show debug output for `Goals`.
422    pub fn debug(&self, interner: I) -> GoalsDebug<'_, I> {
423        GoalsDebug {
424            goals: self,
425            interner,
426        }
427    }
428}
429
430/// Helper struct for showing debug output for `GenericArgData`.
431pub struct GenericArgDataInnerDebug<'a, I: Interner>(&'a GenericArgData<I>);
432
433impl<'a, I: Interner> Debug for GenericArgDataInnerDebug<'a, I> {
434    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
435        match self.0 {
436            GenericArgData::Ty(n) => write!(fmt, "{:?}", n),
437            GenericArgData::Lifetime(n) => write!(fmt, "{:?}", n),
438            GenericArgData::Const(n) => write!(fmt, "{:?}", n),
439        }
440    }
441}
442
443impl<I: Interner> GenericArgData<I> {
444    /// Helper method for debugging `GenericArgData`.
445    pub fn inner_debug(&self) -> GenericArgDataInnerDebug<'_, I> {
446        GenericArgDataInnerDebug(self)
447    }
448}
449
450/// Helper struct for showing debug output for program clause implications.
451pub struct ProgramClauseImplicationDebug<'a, I: Interner> {
452    pci: &'a ProgramClauseImplication<I>,
453    interner: I,
454}
455
456impl<'a, I: Interner> Debug for ProgramClauseImplicationDebug<'a, I> {
457    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
458        let ProgramClauseImplicationDebug { pci, interner } = self;
459        write!(fmt, "{:?}", pci.consequence)?;
460
461        let conditions = pci.conditions.as_slice(*interner);
462
463        let conds = conditions.len();
464        if conds == 0 {
465            return Ok(());
466        }
467
468        write!(fmt, " :- ")?;
469        for cond in &conditions[..conds - 1] {
470            write!(fmt, "{:?}, ", cond)?;
471        }
472        write!(fmt, "{:?}", conditions[conds - 1])
473    }
474}
475
476impl<I: Interner> ProgramClauseImplication<I> {
477    /// Show debug output for the program clause implication.
478    pub fn debug(&self, interner: I) -> ProgramClauseImplicationDebug<'_, I> {
479        ProgramClauseImplicationDebug {
480            pci: self,
481            interner,
482        }
483    }
484}
485
486/// Helper struct for showing debug output for application types.
487pub struct TyKindDebug<'a, I: Interner> {
488    ty: &'a TyKind<I>,
489    interner: I,
490}
491
492impl<'a, I: Interner> Debug for TyKindDebug<'a, I> {
493    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
494        let interner = self.interner;
495        match self.ty {
496            TyKind::BoundVar(db) => write!(fmt, "{:?}", db),
497            TyKind::Dyn(clauses) => write!(fmt, "{:?}", clauses),
498            TyKind::InferenceVar(var, TyVariableKind::General) => write!(fmt, "{:?}", var),
499            TyKind::InferenceVar(var, TyVariableKind::Integer) => write!(fmt, "{:?}i", var),
500            TyKind::InferenceVar(var, TyVariableKind::Float) => write!(fmt, "{:?}f", var),
501            TyKind::Alias(alias) => write!(fmt, "{:?}", alias),
502            TyKind::Placeholder(index) => write!(fmt, "{:?}", index),
503            TyKind::Function(function) => write!(fmt, "{:?}", function),
504            TyKind::Adt(id, substitution) => {
505                write!(fmt, "{:?}{:?}", id, substitution.with_angle(interner))
506            }
507            TyKind::AssociatedType(assoc_ty, substitution) => {
508                write!(fmt, "{:?}{:?}", assoc_ty, substitution.with_angle(interner))
509            }
510            TyKind::Scalar(scalar) => write!(fmt, "{:?}", scalar),
511            TyKind::Str => write!(fmt, "Str"),
512            TyKind::Tuple(arity, substitution) => {
513                write!(fmt, "{:?}{:?}", arity, substitution.with_angle(interner))
514            }
515            TyKind::OpaqueType(opaque_ty, substitution) => write!(
516                fmt,
517                "!{:?}{:?}",
518                opaque_ty,
519                substitution.with_angle(interner)
520            ),
521            TyKind::Slice(ty) => write!(fmt, "[{:?}]", ty),
522            TyKind::FnDef(fn_def, substitution) => {
523                write!(fmt, "{:?}{:?}", fn_def, substitution.with_angle(interner))
524            }
525            TyKind::Ref(mutability, lifetime, ty) => match mutability {
526                Mutability::Mut => write!(fmt, "(&{:?} mut {:?})", lifetime, ty),
527                Mutability::Not => write!(fmt, "(&{:?} {:?})", lifetime, ty),
528            },
529            TyKind::Raw(mutability, ty) => match mutability {
530                Mutability::Mut => write!(fmt, "(*mut {:?})", ty),
531                Mutability::Not => write!(fmt, "(*const {:?})", ty),
532            },
533            TyKind::Never => write!(fmt, "Never"),
534            TyKind::Array(ty, const_) => write!(fmt, "[{:?}; {:?}]", ty, const_),
535            TyKind::Closure(id, substitution) => write!(
536                fmt,
537                "{{closure:{:?}}}{:?}",
538                id,
539                substitution.with_angle(interner)
540            ),
541            TyKind::Coroutine(coroutine, substitution) => write!(
542                fmt,
543                "{:?}{:?}",
544                coroutine,
545                substitution.with_angle(interner)
546            ),
547            TyKind::CoroutineWitness(witness, substitution) => {
548                write!(fmt, "{:?}{:?}", witness, substitution.with_angle(interner))
549            }
550            TyKind::Foreign(foreign_ty) => write!(fmt, "{:?}", foreign_ty,),
551            TyKind::Error => write!(fmt, "{{error}}"),
552        }
553    }
554}
555
556impl<I: Interner> TyKind<I> {
557    /// Show debug output for the application type.
558    pub fn debug(&self, interner: I) -> TyKindDebug<'_, I> {
559        TyKindDebug { ty: self, interner }
560    }
561}
562
563/// Helper struct for showing debug output for substitutions.
564pub struct SubstitutionDebug<'a, I: Interner> {
565    substitution: &'a Substitution<I>,
566    interner: I,
567}
568
569impl<'a, I: Interner> Debug for SubstitutionDebug<'a, I> {
570    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
571        let SubstitutionDebug {
572            substitution,
573            interner,
574        } = self;
575        let mut first = true;
576
577        write!(fmt, "[")?;
578
579        for (index, value) in substitution.iter(*interner).enumerate() {
580            if first {
581                first = false;
582            } else {
583                write!(fmt, ", ")?;
584            }
585
586            write!(fmt, "?{} := {:?}", index, value)?;
587        }
588
589        write!(fmt, "]")?;
590
591        Ok(())
592    }
593}
594
595impl<I: Interner> Substitution<I> {
596    /// Show debug output for the substitution.
597    pub fn debug(&self, interner: I) -> SubstitutionDebug<'_, I> {
598        SubstitutionDebug {
599            substitution: self,
600            interner,
601        }
602    }
603}
604
605impl Debug for PlaceholderIndex {
606    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
607        let PlaceholderIndex { ui, idx } = self;
608        write!(fmt, "!{}_{}", ui.counter, idx)
609    }
610}
611
612impl<I: Interner> TraitRef<I> {
613    /// Returns a "Debuggable" type that prints like `P0 as Trait<P1..>`.
614    pub fn with_as(&self) -> impl std::fmt::Debug + '_ {
615        SeparatorTraitRef {
616            trait_ref: self,
617            separator: " as ",
618        }
619    }
620
621    /// Returns a "Debuggable" type that prints like `P0: Trait<P1..>`.
622    pub fn with_colon(&self) -> impl std::fmt::Debug + '_ {
623        SeparatorTraitRef {
624            trait_ref: self,
625            separator: ": ",
626        }
627    }
628}
629
630impl<I: Interner> Debug for TraitRef<I> {
631    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
632        Debug::fmt(&self.with_as(), fmt)
633    }
634}
635
636/// Trait ref with associated separator used for debug output.
637pub struct SeparatorTraitRef<'me, I: Interner> {
638    /// The `TraitRef` itself.
639    pub trait_ref: &'me TraitRef<I>,
640
641    /// The separator used for displaying the `TraitRef`.
642    pub separator: &'me str,
643}
644
645/// Helper struct for showing debug output for the `SeperatorTraitRef`.
646pub struct SeparatorTraitRefDebug<'a, 'me, I: Interner> {
647    separator_trait_ref: &'a SeparatorTraitRef<'me, I>,
648    interner: I,
649}
650
651impl<'a, 'me, I: Interner> Debug for SeparatorTraitRefDebug<'a, 'me, I> {
652    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
653        let SeparatorTraitRefDebug {
654            separator_trait_ref,
655            interner,
656        } = self;
657        let parameters = separator_trait_ref
658            .trait_ref
659            .substitution
660            .as_slice(*interner);
661        write!(
662            fmt,
663            "{:?}{}{:?}{:?}",
664            parameters[0],
665            separator_trait_ref.separator,
666            separator_trait_ref.trait_ref.trait_id,
667            Angle(&parameters[1..])
668        )
669    }
670}
671
672impl<'me, I: Interner> SeparatorTraitRef<'me, I> {
673    /// Show debug output for the `SeperatorTraitRef`.
674    pub fn debug<'a>(&'a self, interner: I) -> SeparatorTraitRefDebug<'a, 'me, I> {
675        SeparatorTraitRefDebug {
676            separator_trait_ref: self,
677            interner,
678        }
679    }
680}
681
682impl<I: Interner> Debug for LifetimeOutlives<I> {
683    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
684        write!(fmt, "{:?}: {:?}", self.a, self.b)
685    }
686}
687
688impl<I: Interner> Debug for TypeOutlives<I> {
689    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
690        write!(fmt, "{:?}: {:?}", self.ty, self.lifetime)
691    }
692}
693
694/// Helper struct for showing debug output for projection types.
695pub struct ProjectionTyDebug<'a, I: Interner> {
696    projection_ty: &'a ProjectionTy<I>,
697    interner: I,
698}
699
700impl<'a, I: Interner> Debug for ProjectionTyDebug<'a, I> {
701    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
702        let ProjectionTyDebug {
703            projection_ty,
704            interner,
705        } = self;
706        write!(
707            fmt,
708            "({:?}){:?}",
709            projection_ty.associated_ty_id,
710            projection_ty.substitution.with_angle(*interner)
711        )
712    }
713}
714
715impl<I: Interner> ProjectionTy<I> {
716    /// Show debug output for the projection type.
717    pub fn debug(&self, interner: I) -> ProjectionTyDebug<'_, I> {
718        ProjectionTyDebug {
719            projection_ty: self,
720            interner,
721        }
722    }
723}
724
725/// Helper struct for showing debug output for opaque types.
726pub struct OpaqueTyDebug<'a, I: Interner> {
727    opaque_ty: &'a OpaqueTy<I>,
728    interner: I,
729}
730
731impl<'a, I: Interner> Debug for OpaqueTyDebug<'a, I> {
732    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
733        let OpaqueTyDebug {
734            opaque_ty,
735            interner,
736        } = self;
737        write!(
738            fmt,
739            "{:?}{:?}",
740            opaque_ty.opaque_ty_id,
741            opaque_ty.substitution.with_angle(*interner)
742        )
743    }
744}
745
746impl<I: Interner> OpaqueTy<I> {
747    /// Show debug output for the opaque type.
748    pub fn debug(&self, interner: I) -> OpaqueTyDebug<'_, I> {
749        OpaqueTyDebug {
750            opaque_ty: self,
751            interner,
752        }
753    }
754}
755
756/// Wraps debug output in angle brackets (`<>`).
757pub struct Angle<'a, T>(pub &'a [T]);
758
759impl<'a, T: Debug> Debug for Angle<'a, T> {
760    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
761        if !self.0.is_empty() {
762            write!(fmt, "<")?;
763            for (index, elem) in self.0.iter().enumerate() {
764                if index > 0 {
765                    write!(fmt, ", {:?}", elem)?;
766                } else {
767                    write!(fmt, "{:?}", elem)?;
768                }
769            }
770            write!(fmt, ">")?;
771        }
772        Ok(())
773    }
774}
775
776impl<I: Interner> Debug for Normalize<I> {
777    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
778        write!(fmt, "Normalize({:?} -> {:?})", self.alias, self.ty)
779    }
780}
781
782impl<I: Interner> Debug for AliasEq<I> {
783    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
784        write!(fmt, "AliasEq({:?} = {:?})", self.alias, self.ty)
785    }
786}
787
788impl<I: Interner> Debug for WhereClause<I> {
789    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
790        match self {
791            WhereClause::Implemented(tr) => write!(fmt, "Implemented({:?})", tr.with_colon()),
792            WhereClause::AliasEq(a) => write!(fmt, "{:?}", a),
793            WhereClause::LifetimeOutlives(l_o) => write!(fmt, "{:?}", l_o),
794            WhereClause::TypeOutlives(t_o) => write!(fmt, "{:?}", t_o),
795        }
796    }
797}
798
799impl<I: Interner> Debug for FromEnv<I> {
800    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
801        match self {
802            FromEnv::Trait(t) => write!(fmt, "FromEnv({:?})", t.with_colon()),
803            FromEnv::Ty(t) => write!(fmt, "FromEnv({:?})", t),
804        }
805    }
806}
807
808impl<I: Interner> Debug for WellFormed<I> {
809    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
810        match self {
811            WellFormed::Trait(t) => write!(fmt, "WellFormed({:?})", t.with_colon()),
812            WellFormed::Ty(t) => write!(fmt, "WellFormed({:?})", t),
813        }
814    }
815}
816
817impl<I: Interner> Debug for DomainGoal<I> {
818    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
819        match self {
820            DomainGoal::Holds(n) => write!(fmt, "{:?}", n),
821            DomainGoal::WellFormed(n) => write!(fmt, "{:?}", n),
822            DomainGoal::FromEnv(n) => write!(fmt, "{:?}", n),
823            DomainGoal::Normalize(n) => write!(fmt, "{:?}", n),
824            DomainGoal::IsLocal(n) => write!(fmt, "IsLocal({:?})", n),
825            DomainGoal::IsUpstream(n) => write!(fmt, "IsUpstream({:?})", n),
826            DomainGoal::IsFullyVisible(n) => write!(fmt, "IsFullyVisible({:?})", n),
827            DomainGoal::LocalImplAllowed(tr) => {
828                write!(fmt, "LocalImplAllowed({:?})", tr.with_colon(),)
829            }
830            DomainGoal::Compatible => write!(fmt, "Compatible"),
831            DomainGoal::DownstreamType(n) => write!(fmt, "DownstreamType({:?})", n),
832            DomainGoal::Reveal => write!(fmt, "Reveal"),
833            DomainGoal::ObjectSafe(n) => write!(fmt, "ObjectSafe({:?})", n),
834        }
835    }
836}
837
838impl<I: Interner> Debug for EqGoal<I> {
839    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
840        write!(fmt, "({:?} = {:?})", self.a, self.b)
841    }
842}
843
844impl<I: Interner> Debug for SubtypeGoal<I> {
845    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
846        write!(fmt, "({:?} <: {:?})", self.a, self.b)
847    }
848}
849
850impl<T: HasInterner + Debug> Debug for Binders<T> {
851    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
852        let Binders {
853            ref binders,
854            ref value,
855        } = *self;
856        write!(fmt, "for{:?} ", binders.debug())?;
857        Debug::fmt(value, fmt)
858    }
859}
860
861impl<I: Interner> Debug for ProgramClauseData<I> {
862    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
863        write!(fmt, "{:?}", self.0)
864    }
865}
866
867impl<I: Interner> Debug for Environment<I> {
868    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
869        write!(fmt, "Env({:?})", self.clauses)
870    }
871}
872
873impl<I: Interner> Debug for CanonicalVarKinds<I> {
874    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
875        I::debug_canonical_var_kinds(self, fmt)
876            .unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
877    }
878}
879
880impl<T: HasInterner + Display> Canonical<T> {
881    /// Display the canonicalized item.
882    pub fn display(&self, interner: T::Interner) -> CanonicalDisplay<'_, T> {
883        CanonicalDisplay {
884            canonical: self,
885            interner,
886        }
887    }
888}
889
890/// Helper struct for displaying canonicalized items.
891pub struct CanonicalDisplay<'a, T: HasInterner> {
892    canonical: &'a Canonical<T>,
893    interner: T::Interner,
894}
895
896impl<'a, T: HasInterner + Display> Display for CanonicalDisplay<'a, T> {
897    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
898        let Canonical { binders, value } = self.canonical;
899        let interner = self.interner;
900        let binders = binders.as_slice(interner);
901        if binders.is_empty() {
902            // Ordinarily, we try to print all binder levels, if they
903            // are empty, but we can skip in this *particular* case
904            // because we know that `Canonical` terms are never
905            // supposed to contain free variables.  In other words,
906            // all "bound variables" that appear inside the canonical
907            // value must reference values that appear in `binders`.
908            write!(f, "{}", value)?;
909        } else {
910            write!(f, "for<")?;
911
912            for (i, pk) in binders.iter().enumerate() {
913                if i > 0 {
914                    write!(f, ",")?;
915                }
916                write!(f, "?{}", pk.skip_kind())?;
917            }
918
919            write!(f, "> {{ {} }}", value)?;
920        }
921
922        Ok(())
923    }
924}
925
926impl<I: Interner> Debug for GenericArgData<I> {
927    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
928        match self {
929            GenericArgData::Ty(t) => write!(fmt, "Ty({:?})", t),
930            GenericArgData::Lifetime(l) => write!(fmt, "Lifetime({:?})", l),
931            GenericArgData::Const(c) => write!(fmt, "Const({:?})", c),
932        }
933    }
934}
935
936impl<I: Interner> Debug for VariableKind<I> {
937    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
938        match self {
939            VariableKind::Ty(TyVariableKind::General) => write!(fmt, "type"),
940            VariableKind::Ty(TyVariableKind::Integer) => write!(fmt, "integer type"),
941            VariableKind::Ty(TyVariableKind::Float) => write!(fmt, "float type"),
942            VariableKind::Lifetime => write!(fmt, "lifetime"),
943            VariableKind::Const(ty) => write!(fmt, "const: {:?}", ty),
944        }
945    }
946}
947
948impl<I: Interner, T: Debug> Debug for WithKind<I, T> {
949    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
950        let value = self.skip_kind();
951        match &self.kind {
952            VariableKind::Ty(TyVariableKind::General) => write!(fmt, "{:?} with kind type", value),
953            VariableKind::Ty(TyVariableKind::Integer) => {
954                write!(fmt, "{:?} with kind integer type", value)
955            }
956            VariableKind::Ty(TyVariableKind::Float) => {
957                write!(fmt, "{:?} with kind float type", value)
958            }
959            VariableKind::Lifetime => write!(fmt, "{:?} with kind lifetime", value),
960            VariableKind::Const(ty) => write!(fmt, "{:?} with kind {:?}", value, ty),
961        }
962    }
963}
964
965impl<I: Interner> Debug for Constraint<I> {
966    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
967        match self {
968            Constraint::LifetimeOutlives(a, b) => write!(fmt, "{:?}: {:?}", a, b),
969            Constraint::TypeOutlives(ty, lifetime) => write!(fmt, "{:?}: {:?}", ty, lifetime),
970        }
971    }
972}
973
974impl<I: Interner> Display for ConstrainedSubst<I> {
975    #[rustfmt::skip]
976    fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), Error> {
977        let ConstrainedSubst { subst, constraints } = self;
978
979        let mut first = true;
980
981        let subst = format!("{}", Fmt(|f| Display::fmt(subst, f)));
982        if subst != "[]" {
983            write!(f, "substitution {}", subst)?;
984            first = false;
985        }
986
987        let constraints = format!("{}", Fmt(|f| Debug::fmt(constraints, f)));
988        if constraints != "[]" {
989            if !first { write!(f, ", ")?; }
990            write!(f, "lifetime constraints {}", constraints)?;
991            first = false;
992        }
993
994        let _ = first;
995        Ok(())
996    }
997}
998
999impl<I: Interner> Substitution<I> {
1000    /// Displays the substitution in the form `< P0, .. Pn >`, or (if
1001    /// the substitution is empty) as an empty string.
1002    pub fn with_angle(&self, interner: I) -> Angle<'_, GenericArg<I>> {
1003        Angle(self.as_slice(interner))
1004    }
1005}
1006
1007impl<I: Interner> Debug for Substitution<I> {
1008    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
1009        Display::fmt(self, fmt)
1010    }
1011}
1012
1013impl<I: Interner> Debug for Variances<I> {
1014    fn fmt(&self, fmt: &mut Formatter<'_>) -> Result<(), Error> {
1015        I::debug_variances(self, fmt).unwrap_or_else(|| write!(fmt, "{:?}", self.interned))
1016    }
1017}