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