1use std::{
2 fmt::{self, Write},
3 iter,
4};
5
6use expr::{FieldBind, pretty::aggregate_nested};
7use rustc_data_structures::snapshot_map::SnapshotMap;
8use rustc_type_ir::DebruijnIndex;
9use ty::{UnevaluatedConst, ValTree, region_to_string};
10
11use super::{fold::TypeVisitable, *};
12use crate::pretty::*;
13
14impl Pretty for ClauseKind {
15 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
16 match self {
17 ClauseKind::Trait(pred) => w!(cx, f, "Trait ({:?})", ^pred),
18 ClauseKind::Projection(pred) => w!(cx, f, "Projection ({:?})", ^pred),
19 ClauseKind::RegionOutlives(pred) => {
20 w!(cx, f, "Outlives ({:?}, {:?})", &pred.0, &pred.1)
21 }
22 ClauseKind::TypeOutlives(pred) => w!(cx, f, "Outlives ({:?}, {:?})", &pred.0, &pred.1),
23 ClauseKind::ConstArgHasType(c, ty) => w!(cx, f, "ConstArgHasType ({:?}, {:?})", c, ty),
24 ClauseKind::UnstableFeature(_) => w!(cx, f, "UnstableFeature (..)"),
25 }
26 }
27}
28
29impl Pretty for BoundRegionKind {
30 fn fmt(&self, _cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
31 match self {
32 BoundRegionKind::Anon => w!(cx, f, "'<annon>"),
33 BoundRegionKind::NamedAnon(sym) => w!(cx, f, "'{sym}"),
34 BoundRegionKind::Named(def_id) => w!(cx, f, "'{def_id:?}"),
35 BoundRegionKind::ClosureEnv => w!(cx, f, "'<env>"),
36 }
37 }
38}
39
40impl<T> Pretty for Binder<T>
41where
42 T: Pretty,
43{
44 default fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
45 cx.with_bound_vars(self.vars(), || {
46 if !self.vars().is_empty() {
47 cx.fmt_bound_vars(true, "for<", self.vars(), "> ", f)?;
48 }
49 w!(cx, f, "{:?}", self.skip_binder_ref())
50 })
51 }
52}
53
54impl<T: Pretty> std::fmt::Debug for Binder<T> {
55 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56 pprint_with_default_cx(f, self, None)
57 }
58}
59
60fn format_fn_root_binder<T: Pretty + TypeVisitable>(
61 binder: &Binder<T>,
62 cx: &PrettyCx,
63 fn_root_layer_type: FnRootLayerType,
64 binder_name: &str,
65 f: &mut fmt::Formatter<'_>,
66) -> fmt::Result {
67 let vars = binder.vars();
68 let redundant_bvars = binder.skip_binder_ref().redundant_bvars();
69
70 cx.with_bound_vars_removable(vars, redundant_bvars, Some(fn_root_layer_type), || {
71 let body = format_cx!(cx, "{:?}", binder.skip_binder_ref());
73
74 let filtered_vars = cx.bvar_env.peek_layer().unwrap().filter_vars(vars);
78 if filtered_vars.is_empty() {
79 write!(f, "{}", body)
80 } else {
81 let left = format!("{binder_name}<");
82 let right = format!("> {}", body);
83 cx.fmt_bound_vars(true, &left, &filtered_vars, &right, f)
84 }
85 })
86}
87
88impl<T: Pretty> Pretty for EarlyBinder<T> {
89 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
90 cx.with_early_params(|| self.skip_binder_ref().fmt(cx, f))
91 }
92}
93
94impl Pretty for PolyFnSig {
95 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
96 format_fn_root_binder(self, cx, FnRootLayerType::FnArgs, "for", f)
97 }
98}
99
100impl Pretty for SortCtor {
101 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
102 match self {
103 SortCtor::Set => w!(cx, f, "Set"),
104 SortCtor::Map => w!(cx, f, "Map"),
105 SortCtor::User(def_id) => w!(cx, f, "{}", ^def_id.name()),
106 SortCtor::Adt(adt_sort_def) => {
107 w!(cx, f, "{:?}", adt_sort_def.did())
108 }
109 }
110 }
111}
112
113impl Pretty for Sort {
114 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
115 match self {
116 Sort::Bool => w!(cx, f, "bool"),
117 Sort::Int => w!(cx, f, "int"),
118 Sort::Real => w!(cx, f, "real"),
119 Sort::Str => w!(cx, f, "str"),
120 Sort::Char => w!(cx, f, "char"),
121 Sort::BitVec(size) => w!(cx, f, "bitvec<{:?}>", size),
122 Sort::Loc => w!(cx, f, "loc"),
123 Sort::Var(n) => w!(cx, f, "@{}", ^n.index()),
124 Sort::Func(sort) => w!(cx, f, "{:?}", sort),
125 Sort::Tuple(sorts) => {
126 if let [sort] = &sorts[..] {
127 w!(cx, f, "({:?},)", sort)
128 } else {
129 w!(cx, f, "({:?})", join!(", ", sorts))
130 }
131 }
132 Sort::Alias(kind, alias_ty) => {
133 fmt_alias_ty(cx, f, *kind, alias_ty)?;
134 w!(cx, f, "::sort")
135 }
136 Sort::App(ctor, sorts) => {
137 if sorts.is_empty() {
138 w!(cx, f, "{:?}", ctor)
139 } else {
140 w!(cx, f, "{:?}<{:?}>", ctor, join!(", ", sorts))
141 }
142 }
143 Sort::Param(param_ty) => w!(cx, f, "{}::sort", ^param_ty),
144 Sort::Infer(svar) => w!(cx, f, "{:?}", ^svar),
145 Sort::RawPtr => w!(cx, f, "ptr"),
146 Sort::Err => w!(cx, f, "err"),
147 }
148 }
149
150 fn default_cx(tcx: TyCtxt) -> PrettyCx {
151 PrettyCx::default(tcx).hide_refinements(true)
152 }
153}
154
155impl Pretty for SortArg {
156 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
157 match self {
158 SortArg::Sort(sort) => w!(cx, f, "{:?}", sort),
159 SortArg::BvSize(size) => w!(cx, f, "{:?}", size),
160 }
161 }
162}
163
164impl Pretty for BvSize {
165 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
166 match self {
167 BvSize::Fixed(size) => w!(cx, f, "{}", ^size),
168 BvSize::Param(param) => w!(cx, f, "{:?}", ^param),
169 BvSize::Infer(size_vid) => w!(cx, f, "{:?}", ^size_vid),
170 }
171 }
172}
173
174impl Pretty for FuncSort {
175 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
176 match self.inputs() {
177 [input] => {
178 w!(cx, f, "{:?} -> {:?}", input, self.output())
179 }
180 inputs => {
181 w!(cx, f,
182 "({}) -> {:?}",
183 ^inputs
184 .iter()
185 .format_with(", ", |s, f| f(&format_args_cx!(cx, "{:?}", s))),
186 self.output()
187 )
188 }
189 }
190 }
191}
192
193impl Pretty for PolyFuncSort {
194 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
195 if self.params.is_empty() {
196 w!(cx, f, "{:?}", &self.fsort)
197 } else {
198 w!(cx, f, "for<{}> {:?}", ^self.params.len(), &self.fsort)
199 }
200 }
201}
202
203impl Pretty for FnSig {
204 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
205 w!(
206 cx,
207 f,
208 "fn({:?}) -> {:?}",
209 join!(", ", self.inputs.iter().map(|input| input.shallow_canonicalize())),
210 &self.output
211 )?;
212 if !self.requires.is_empty() {
213 w!(cx, f, " requires {:?}", join!(" ∧ ", &self.requires))?;
214 }
215 Ok(())
216 }
217}
218
219impl Pretty for Binder<FnOutput> {
220 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
221 format_fn_root_binder(self, cx, FnRootLayerType::FnRet, "exists", f)
222 }
223}
224
225impl Pretty for FnOutput {
226 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
227 w!(cx, f, "{:?}", &self.ret.shallow_canonicalize())?;
228 if !self.ensures.is_empty() {
229 w!(cx, f, " ensures {:?}", join!(" ∧ ", &self.ensures))?;
230 }
231 Ok(())
232 }
233}
234
235impl Pretty for Ensures {
236 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
237 match self {
238 Ensures::Type(loc, ty) => w!(cx, f, "{:?}: {:?}", ^loc, ty),
239 Ensures::Pred(e) => w!(cx, f, "{:?}", e),
240 }
241 }
242}
243
244impl Pretty for SubsetTy {
245 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
246 w!(cx, f, "{:?}", &self.to_ty())
247 }
248}
249
250struct IdxFmt(Expr);
253
254impl PrettyNested for IdxFmt {
255 fn fmt_nested(&self, cx: &PrettyCx) -> Result<NestedString, fmt::Error> {
256 let kind = self.0.kind();
257 match kind {
258 ExprKind::Ctor(ctor, flds) => aggregate_nested(cx, ctor, flds, false),
259 ExprKind::Tuple(flds) if flds.is_empty() => {
260 Ok(NestedString { text: String::new(), key: None, children: None })
261 }
262 ExprKind::Var(Var::Free(name)) => name.fmt_nested(cx),
263 _ => self.0.fmt_nested(cx),
264 }
265 }
266}
267
268impl Pretty for IdxFmt {
269 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
270 let e = if cx.simplify_exprs {
271 self.0.simplify(&SnapshotMap::default())
272 } else {
273 self.0.clone()
274 };
275 let mut buf = String::new();
276 match e.kind() {
277 ExprKind::Ctor(ctor, flds)
278 if let Some((def_id, _)) = ctor.def_id_and_variant()
279 && let Some(adt_sort_def) = cx.adt_sort_def_of(def_id)
280 && let Some(variant) = adt_sort_def.opt_struct_variant() =>
281 {
282 let fields = iter::zip(variant.field_names(), flds)
283 .map(|(name, value)| FieldBind { name: *name, value: value.clone() })
284 .collect_vec();
285 if let Some(var_fields) = fields
287 .iter()
288 .map(|field| {
289 if let ExprKind::Var(Var::Bound(debruijn, BoundReft { var, .. })) =
290 field.value.kind()
291 {
292 Some((*debruijn, *var, field.value.clone()))
293 } else {
294 None
295 }
296 })
297 .collect::<Option<Vec<_>>>()
298 {
299 if var_fields.iter().all(|(debruijn, var, _e)| {
301 cx.bvar_env
302 .should_remove_var(*debruijn, *var)
303 .unwrap_or(false)
304 }) {
305 var_fields.iter().for_each(|(debruijn, var, _e)| {
306 cx.bvar_env.mark_var_as_removed(*debruijn, *var);
307 });
308 } else {
314 let mut fields = var_fields.into_iter().map(|(debruijn, var, e)| {
315 if let Some((seen, layer_type)) =
316 cx.bvar_env.check_if_seen_fn_root_bvar(debruijn, var)
317 && !seen
318 {
319 match layer_type {
320 FnRootLayerType::FnArgs => {
321 format_cx!(cx, "@{:?}", e)
322 }
323 FnRootLayerType::FnRet => {
324 format_cx!(cx, "#{:?}", e)
325 }
326 }
327 } else {
328 format_cx!(cx, "{:?}", e)
329 }
330 });
331 buf.write_str(&fields.join(", "))?;
332 }
333 } else {
334 buf.write_str(&format_cx!(cx, "{{ {:?} }}", join!(", ", fields)))?;
335 }
336 }
337 ExprKind::Var(Var::Bound(debruijn, BoundReft { var, .. })) => {
349 if cx
350 .bvar_env
351 .should_remove_var(*debruijn, *var)
352 .unwrap_or(false)
353 {
354 cx.bvar_env.mark_var_as_removed(*debruijn, *var);
355 } else {
357 if let Some((seen, layer_type)) =
358 cx.bvar_env.check_if_seen_fn_root_bvar(*debruijn, *var)
359 && !seen
360 {
361 match layer_type {
362 FnRootLayerType::FnArgs => {
363 buf.write_str("@")?;
364 }
365 FnRootLayerType::FnRet => {
366 buf.write_str("#")?;
367 }
368 }
369 }
370 buf.write_str(&format_cx!(cx, "{:?}", e))?;
371 }
372 }
373 ExprKind::Var(Var::EarlyParam(ep)) => {
374 if let Some(param) = cx.earlyparam_env.borrow_mut().as_mut()
375 && param.insert(*ep)
376 {
377 buf.write_str(&format_cx!(cx, "@{:?}", e))?;
379 } else {
380 buf.write_str(&format_cx!(cx, "{:?}", e))?;
381 }
382 }
383 _ => {
384 buf.write_str(&format_cx!(cx, "{:?}", e))?;
385 }
386 }
387 if !buf.is_empty() { write!(f, "[{}]", buf) } else { Ok(()) }
388 }
389}
390
391impl Pretty for Ty {
392 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
393 match self.kind() {
394 TyKind::Indexed(bty, idx) => {
395 if cx.hide_refinements {
396 w!(cx, f, "{:?}", bty)?;
397 return Ok(());
398 }
399 if idx.is_unit() {
400 w!(cx, f, "{:?}", bty)?;
401 } else {
402 w!(cx, f, "{:?}{:?}", parens!(bty, !bty.is_atom()), IdxFmt(idx.clone()))?;
403 }
404 Ok(())
405 }
406 TyKind::Exists(_ty_ctor) => {
407 w!(cx, f, "{:?}", self.shallow_canonicalize())
408 }
409 TyKind::Uninit => w!(cx, f, "uninit"),
410 TyKind::StrgRef(re, loc, ty) => w!(cx, f, "&{:?} strg <{:?}: {:?}>", re, loc, ty),
411 TyKind::Ptr(pk, loc) => w!(cx, f, "ptr({:?}, {:?})", pk, loc),
412 TyKind::Discr(adt_def, place) => {
413 w!(cx, f, "discr({:?}, {:?})", adt_def.did(), ^place)
414 }
415 TyKind::Constr(pred, ty) => {
416 if cx.hide_refinements {
417 w!(cx, f, "{:?}", ty)
418 } else {
419 w!(cx, f, "{{ {:?} | {:?} }}", ty, pred.clone())
420 }
421 }
422 TyKind::Param(param_ty) => w!(cx, f, "{}", ^param_ty),
423 TyKind::Downcast(adt, .., variant_idx, fields) => {
424 w!(cx, f, "{:?}", adt.did())?;
426 if !adt.is_struct() {
428 w!(cx, f, "::{}", ^adt.variant(*variant_idx).name)?;
429 }
430 if adt.is_struct() {
432 let field_binds = iter::zip(&adt.variant(*variant_idx).fields, fields)
433 .map(|(field_def, value)| FieldBind { name: field_def.name, value });
434 w!(cx, f, " {{ {:?} }}", join!(", ", field_binds))?;
435 } else if !fields.is_empty() {
436 w!(cx, f, "({:?})", join!(", ", fields))?;
437 }
438 Ok(())
439 }
440 TyKind::Blocked(ty) => w!(cx, f, "†{:?}", ty),
441 TyKind::Infer(ty_vid) => {
442 w!(cx, f, "{ty_vid:?}")
443 }
444 }
445 }
446
447 fn default_cx(tcx: TyCtxt) -> PrettyCx {
448 PrettyCx::default(tcx).kvar_args(KVarArgs::Hide)
449 }
450}
451
452impl Pretty for PtrKind {
453 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
454 match self {
455 PtrKind::Mut(re) => {
456 w!(cx, f, "mut")?;
457 if !cx.hide_regions {
458 w!(cx, f, "[{:?}]", re)?;
459 }
460 Ok(())
461 }
462 PtrKind::Box => w!(cx, f, "box"),
463 }
464 }
465}
466
467impl Pretty for List<Ty> {
468 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
469 if let [ty] = &self[..] {
470 w!(cx, f, "({:?},)", ty)
471 } else {
472 w!(cx, f, "({:?})", join!(", ", self))
473 }
474 }
475}
476
477impl Pretty for ExistentialPredicate {
478 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
479 match self {
480 ExistentialPredicate::Trait(trait_ref) => w!(cx, f, "{:?}", trait_ref),
481 ExistentialPredicate::Projection(proj) => w!(cx, f, "({:?})", proj),
482 ExistentialPredicate::AutoTrait(def_id) => w!(cx, f, "{:?}", def_id),
483 }
484 }
485}
486
487impl Pretty for ExistentialTraitRef {
488 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
489 w!(cx, f, "{:?}", self.def_id)?;
490 if !self.args.is_empty() {
491 w!(cx, f, "<{:?}>", join!(", ", &self.args))?;
492 }
493 Ok(())
494 }
495}
496
497impl Pretty for ExistentialProjection {
498 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
499 w!(cx, f, "{:?}", self.def_id)?;
500 if !self.args.is_empty() {
501 w!(cx, f, "<{:?}>", join!(", ", &self.args))?;
502 }
503 w!(cx, f, " = {:?}", &self.term)
504 }
505}
506
507impl Pretty for BaseTy {
508 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
509 match self {
510 BaseTy::Int(int_ty) => w!(cx, f, "{}", ^int_ty.name_str()),
511 BaseTy::Uint(uint_ty) => w!(cx, f, "{}", ^uint_ty.name_str()),
512 BaseTy::Bool => w!(cx, f, "bool"),
513 BaseTy::Str => w!(cx, f, "str"),
514 BaseTy::Char => w!(cx, f, "char"),
515 BaseTy::Adt(adt_def, args) => {
516 w!(cx, f, "{:?}", adt_def.did())?;
517 let args = args
518 .iter()
519 .filter(|arg| !cx.hide_regions || !matches!(arg, GenericArg::Lifetime(_)))
520 .collect_vec();
521 if !args.is_empty() {
522 w!(cx, f, "<{:?}>", join!(", ", args))?;
523 }
524 Ok(())
525 }
526 BaseTy::FnDef(def_id, args) => {
527 w!(cx, f, "FnDef({:?}[{:?}])", def_id, join!(", ", args))
528 }
529 BaseTy::Param(param) => w!(cx, f, "{}", ^param),
530 BaseTy::Float(float_ty) => w!(cx, f, "{}", ^float_ty.name_str()),
531 BaseTy::Slice(ty) => w!(cx, f, "[{:?}]", ty),
532 BaseTy::RawPtr(ty, Mutability::Mut) => w!(cx, f, "*mut {:?}", ty),
533 BaseTy::RawPtr(ty, Mutability::Not) => w!(cx, f, "*const {:?}", ty),
534 BaseTy::RawPtrMetadata(ty) => {
535 w!(cx, f, "*raw {:?}", ty)
536 }
537 BaseTy::Ref(re, ty, mutbl) => {
538 w!(cx, f, "&")?;
539 if !cx.hide_regions {
540 w!(cx, f, "{:?} ", re)?;
541 }
542 w!(cx, f, "{}{:?}", ^mutbl.prefix_str(), ty)
543 }
544 BaseTy::FnPtr(poly_fn_sig) => {
545 w!(cx, f, "{:?}", poly_fn_sig)
546 }
547 BaseTy::Tuple(tys) => {
548 if let [ty] = &tys[..] {
549 w!(cx, f, "({:?},)", ty)
550 } else {
551 w!(cx, f, "({:?})", join!(", ", tys))
552 }
553 }
554 BaseTy::Alias(kind, alias_ty) => fmt_alias_ty(cx, f, *kind, alias_ty),
555 BaseTy::Array(ty, c) => w!(cx, f, "[{:?}; {:?}]", ty, ^c),
556 BaseTy::Never => w!(cx, f, "!"),
557 BaseTy::Closure(did, args, _, _) => {
558 w!(cx, f, "{:?}<{:?}>", did, args)
559 }
560 BaseTy::Coroutine(did, resume_ty, upvars, _) => {
561 w!(cx, f, "Coroutine({:?}, {:?})", did, resume_ty)?;
562 if !upvars.is_empty() {
563 w!(cx, f, "<{:?}>", join!(", ", upvars))?;
564 }
565 Ok(())
566 }
567 BaseTy::Dynamic(preds, re) => {
568 w!(cx, f, "dyn {:?} + {:?}", join!(" + ", preds), re)
569 }
570 BaseTy::Infer(ty_vid) => {
571 w!(cx, f, "{ty_vid:?}")
572 }
573 BaseTy::Foreign(def_id) => {
574 w!(cx, f, "{:?}", def_id)
575 }
576 BaseTy::Pat => todo!(),
577 }
578 }
579}
580
581fn fmt_alias_ty(
582 cx: &PrettyCx,
583 f: &mut fmt::Formatter<'_>,
584 kind: AliasKind,
585 alias_ty: &AliasTy,
586) -> fmt::Result {
587 match kind {
588 AliasKind::Free => {
589 w!(cx, f, "{:?}", alias_ty.def_id)?;
590 if !alias_ty.args.is_empty() {
591 w!(cx, f, "<{:?}>", join!(", ", &alias_ty.args))?;
592 }
593 }
594 AliasKind::Projection => {
595 let assoc_name = cx.tcx().item_name(alias_ty.def_id);
596 let trait_ref = cx.tcx().parent(alias_ty.def_id);
597 let trait_generic_count = cx.tcx().generics_of(trait_ref).count() - 1;
598
599 let [self_ty, args @ ..] = &alias_ty.args[..] else {
600 return w!(cx, f, "<alias_ty>");
601 };
602
603 w!(cx, f, "<{:?} as {:?}", self_ty, trait_ref)?;
604
605 let trait_generics = &args[..trait_generic_count];
606 if !trait_generics.is_empty() {
607 w!(cx, f, "<{:?}>", join!(", ", trait_generics))?;
608 }
609 w!(cx, f, ">::{}", ^assoc_name)?;
610
611 let assoc_generics = &args[trait_generic_count..];
612 if !assoc_generics.is_empty() {
613 w!(cx, f, "<{:?}>", join!(", ", assoc_generics))?;
614 }
615 }
616 AliasKind::Opaque => {
617 w!(cx, f, "{:?}", alias_ty.def_id)?;
618 if !alias_ty.args.is_empty() {
619 w!(cx, f, "<{:?}>", join!(", ", &alias_ty.args))?;
620 }
621 if !alias_ty.refine_args.is_empty() {
622 w!(cx, f, "⟨{:?}⟩", join!(", ", &alias_ty.refine_args))?;
623 }
624 }
625 }
626 Ok(())
627}
628
629impl Pretty for ValTree {
630 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
631 match self {
632 ValTree::Leaf(v) => w!(cx, f, "Leaf({v:?})"),
633 ValTree::Branch(children) => {
634 w!(cx, f, "Branch([{:?}])", join!(", ", children))
635 }
636 }
637 }
638}
639impl Pretty for UnevaluatedConst {
640 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
641 w!(cx, f, "UnevaluatedConst({:?}[...])", self.def)
642 }
643}
644
645impl Pretty for Const {
646 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
647 match &self.kind {
648 ConstKind::Param(p) => w!(cx, f, "{}", ^p.name.as_str()),
649 ConstKind::Value(_, v) => w!(cx, f, "{v:?}"),
650 ConstKind::Infer(infer_const) => w!(cx, f, "{:?}", ^infer_const),
651 ConstKind::Unevaluated(uneval_const) => w!(cx, f, "{:?}", uneval_const),
652 }
653 }
654}
655
656impl Pretty for GenericArg {
657 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
658 match self {
659 GenericArg::Ty(ty) => w!(cx, f, "{:?}", ty),
660 GenericArg::Base(ctor) => w!(cx, f, "{:?}", ctor.to_ty()),
661 GenericArg::Lifetime(re) => w!(cx, f, "{:?}", re),
662 GenericArg::Const(c) => w!(cx, f, "{:?}", c),
663 }
664 }
665}
666
667impl Pretty for VariantSig {
668 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
669 w!(cx, f, "({:?}) => {:?}", join!(", ", self.fields()), &self.idx)
670 }
671}
672
673impl Pretty for Region {
674 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
675 w!(cx, f, "{}", ^region_to_string(*self))
676 }
677}
678
679impl Pretty for DebruijnIndex {
680 fn fmt(&self, cx: &PrettyCx, f: &mut fmt::Formatter<'_>) -> fmt::Result {
681 w!(cx, f, "^{}", ^self.as_usize())
682 }
683}
684
685impl_debug_with_default_cx!(
686 Ensures,
687 Sort,
688 Ty => "ty",
689 BaseTy,
690 FnSig,
691 GenericArg => "generic_arg",
692 VariantSig,
693 PtrKind,
694 FuncSort,
695 SortCtor,
696 SubsetTy,
697 BvSize,
698 ExistentialPredicate,
699);
700
701impl PrettyNested for SubsetTy {
702 fn fmt_nested(&self, cx: &PrettyCx) -> Result<NestedString, fmt::Error> {
703 let bty_d = self.bty.fmt_nested(cx)?;
704 let idx_d = IdxFmt(self.idx.clone()).fmt_nested(cx)?;
705 if self.pred.is_trivially_true() || matches!(self.pred.kind(), ExprKind::KVar(..)) {
706 let text = format!("{}[{}]", bty_d.text, idx_d.text);
707 let children = float_children(vec![bty_d.children, idx_d.children]);
708 Ok(NestedString { text, children, key: None })
709 } else {
710 let pred_d = self.pred.fmt_nested(cx)?;
711 let text = format!("{{ {}[{}] | {} }}", bty_d.text, idx_d.text, pred_d.text);
712 let children = float_children(vec![bty_d.children, idx_d.children, pred_d.children]);
713 Ok(NestedString { text, children, key: None })
714 }
715 }
716}
717
718impl PrettyNested for GenericArg {
719 fn fmt_nested(&self, cx: &PrettyCx) -> Result<NestedString, fmt::Error> {
720 match self {
721 GenericArg::Ty(ty) => ty.fmt_nested(cx),
722 GenericArg::Base(ctor) => {
723 let inner = ctor.as_ref().skip_binder();
725 if ctor.vars().len() == 1 && inner.pred.is_trivially_true() && inner.idx.is_nu() {
726 inner.bty.fmt_nested(cx)
727 } else {
728 cx.nested_with_bound_vars("λ", ctor.vars(), None, |prefix| {
729 let ctor_d = ctor.skip_binder_ref().fmt_nested(cx)?;
730 let text = format!("{}{}", prefix, ctor_d.text);
731 Ok(NestedString { text, children: ctor_d.children, key: None })
732 })
733 }
734 }
735 GenericArg::Lifetime(..) | GenericArg::Const(..) => debug_nested(cx, self),
736 }
737 }
738}
739
740impl PrettyNested for BaseTy {
741 fn fmt_nested(&self, cx: &PrettyCx) -> Result<NestedString, fmt::Error> {
742 match self {
743 BaseTy::Int(..)
744 | BaseTy::Uint(..)
745 | BaseTy::Bool
746 | BaseTy::Str
747 | BaseTy::Char
748 | BaseTy::Float(..)
749 | BaseTy::Param(..)
750 | BaseTy::Never
751 | BaseTy::FnPtr(..)
752 | BaseTy::FnDef(..)
753 | BaseTy::Alias(..)
754 | BaseTy::Closure(..)
755 | BaseTy::Coroutine(..)
756 | BaseTy::Dynamic(..)
757 | BaseTy::Infer(..)
758 | BaseTy::Foreign(..) => {
759 let text = format_cx!(cx, "{:?}", self);
760 Ok(NestedString { text, children: None, key: None })
761 }
762 BaseTy::Slice(ty) => {
763 let ty_d = ty.fmt_nested(cx)?;
764 let text = format!("[{}]", ty_d.text);
765 Ok(NestedString { text, children: ty_d.children, key: None })
766 }
767 BaseTy::Array(ty, c) => {
768 let ty_d = ty.fmt_nested(cx)?;
769 let text = format_cx!(cx, "[{:?}; {:?}]", ty_d.text, c);
770 Ok(NestedString { text, children: ty_d.children, key: None })
771 }
772 BaseTy::RawPtr(ty, Mutability::Mut) => {
773 let ty_d = ty.fmt_nested(cx)?;
774 let text = format!("*mut {}", ty_d.text);
775 Ok(NestedString { text, children: ty_d.children, key: None })
776 }
777 BaseTy::RawPtr(ty, Mutability::Not) => {
778 let ty_d = ty.fmt_nested(cx)?;
779 let text = format!("*const {}", ty_d.text);
780 Ok(NestedString { text, children: ty_d.children, key: None })
781 }
782 BaseTy::RawPtrMetadata(ty) => {
783 let ty_d = ty.fmt_nested(cx)?;
784 let text = format!("*raw {}", ty_d.text);
785 Ok(NestedString { text, children: ty_d.children, key: None })
786 }
787 BaseTy::Ref(_, ty, mutbl) => {
788 let ty_d = ty.fmt_nested(cx)?;
789 let prefix = mutbl.prefix_str();
790 let text = if prefix.is_empty() {
791 format!("&{}", ty_d.text)
792 } else {
793 format!("&{} {}", prefix, ty_d.text)
794 };
795 Ok(NestedString { text, children: ty_d.children, key: None })
796 }
797 BaseTy::Tuple(tys) => {
798 let mut texts = vec![];
799 let mut kidss = vec![];
800 for ty in tys {
801 let ty_d = ty.fmt_nested(cx)?;
802 texts.push(ty_d.text);
803 kidss.push(ty_d.children);
804 }
805 let text = if let [text] = &texts[..] {
806 format!("({text},)")
807 } else {
808 format!("({})", texts.join(", "))
809 };
810 let children = float_children(kidss);
811 Ok(NestedString { text, children, key: None })
812 }
813 BaseTy::Adt(adt_def, args) => {
814 let mut texts = vec![];
815 let mut kidss = vec![];
816 for arg in args {
817 let arg_d = arg.fmt_nested(cx)?;
818 texts.push(arg_d.text);
819 kidss.push(arg_d.children);
820 }
821 let args_str = if !args.is_empty() {
822 format!("<{}>", texts.join(", "))
823 } else {
824 String::new()
825 };
826 let text = format_cx!(cx, "{:?}{:?}", adt_def.did(), args_str);
827 let children = float_children(kidss);
828 Ok(NestedString { text, children, key: None })
829 }
830 BaseTy::Pat => todo!(),
831 }
832 }
833}
834
835impl PrettyNested for Ty {
836 fn fmt_nested(&self, cx: &PrettyCx) -> Result<NestedString, fmt::Error> {
837 match self.kind() {
838 TyKind::Indexed(bty, idx) => {
839 let bty_d = bty.fmt_nested(cx)?;
840 let idx_d = IdxFmt(idx.clone()).fmt_nested(cx)?;
841 let text = if idx_d.text.is_empty() {
842 bty_d.text
843 } else {
844 format!("{}[{}]", bty_d.text, idx_d.text)
845 };
846 let children = float_children(vec![bty_d.children, idx_d.children]);
847 Ok(NestedString { text, children, key: None })
848 }
849 TyKind::Exists(ty_ctor) => {
850 if ty_ctor.vars().len() == 1
853 && let TyKind::Indexed(bty, idx) = ty_ctor.skip_binder_ref().kind()
854 && idx.is_nu()
855 {
856 bty.fmt_nested(cx)
857 } else {
858 cx.nested_with_bound_vars("∃", ty_ctor.vars(), None, |exi_str| {
859 let ty_ctor_d = ty_ctor.skip_binder_ref().fmt_nested(cx)?;
860 let text = format!("{}{}", exi_str, ty_ctor_d.text);
861 Ok(NestedString { text, children: ty_ctor_d.children, key: None })
862 })
863 }
864 }
865 TyKind::Constr(expr, ty) => {
866 let expr_d = expr.fmt_nested(cx)?;
867 let ty_d = ty.fmt_nested(cx)?;
868 let text = format!("{{ {} | {} }}", ty_d.text, expr_d.text);
869 let children = float_children(vec![expr_d.children, ty_d.children]);
870 Ok(NestedString { text, children, key: None })
871 }
872 TyKind::StrgRef(re, loc, ty) => {
873 let ty_d = ty.fmt_nested(cx)?;
874 let text = format!("&{:?} strg <{:?}: {}>", re, loc, ty_d.text);
875 Ok(NestedString { text, children: ty_d.children, key: None })
876 }
877 TyKind::Blocked(ty) => {
878 let ty_d = ty.fmt_nested(cx)?;
879 let text = format!("†{}", ty_d.text);
880 Ok(NestedString { text, children: ty_d.children, key: None })
881 }
882 TyKind::Downcast(adt, .., variant_idx, fields) => {
883 let is_struct = adt.is_struct();
884 let mut text = format_cx!(cx, "{:?}", adt.did());
885 if !is_struct {
886 text.push_str(&format!("::{}", adt.variant(*variant_idx).name));
887 }
888 if is_struct {
889 text.push_str("{..}");
890 } else {
891 text.push_str("(..)");
892 }
893 let keys: Vec<String> = if is_struct {
894 adt.variant(*variant_idx)
895 .fields
896 .iter()
897 .map(|f| f.name.to_string())
898 .collect()
899 } else {
900 (0..fields.len()).map(|i| format!("{i}")).collect()
901 };
902 let mut children = vec![];
903 for (key, field) in keys.into_iter().zip(fields) {
904 let field_d = field.fmt_nested(cx)?;
905 children.push(NestedString { key: Some(key), ..field_d });
906 }
907 Ok(NestedString { text, children: Some(children), key: None })
908 }
909 TyKind::Param(..)
910 | TyKind::Uninit
911 | TyKind::Ptr(..)
912 | TyKind::Discr(..)
913 | TyKind::Infer(..) => {
914 let text = format!("{self:?}");
915 Ok(NestedString { text, children: None, key: None })
916 }
917 }
918 }
919}