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