1use crate::{
3 common::{TAB_INCR, repeat_except_first},
4 formatter::*,
5 gast,
6 llbc_ast::{self as llbc, *},
7 reorder_decls::*,
8 transform::utils::GenericsSource,
9 ullbc_ast::{self as ullbc, *},
10};
11use either::Either;
12use itertools::Itertools;
13use std::{
14 borrow::Cow,
15 fmt::{self, Debug, Display},
16};
17
18pub struct WithCtx<'a, C, T: ?Sized> {
19 val: &'a T,
20 ctx: &'a C,
21}
22
23impl<'a, C, T: ?Sized> Display for WithCtx<'a, C, T>
24where
25 T: FmtWithCtx<C>,
26{
27 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
28 self.val.fmt_with_ctx(self.ctx, f)
29 }
30}
31
32pub trait FmtWithCtx<C> {
34 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result;
35
36 fn with_ctx<'a>(&'a self, ctx: &'a C) -> WithCtx<'a, C, Self> {
41 WithCtx { val: self, ctx }
42 }
43
44 fn to_string_with_ctx(&self, ctx: &C) -> String {
45 self.with_ctx(ctx).to_string()
46 }
47}
48
49macro_rules! impl_display_via_ctx {
50 ($ty:ty) => {
51 impl Display for $ty {
52 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
53 self.fmt_with_ctx(&FmtCtx::new(), f)
54 }
55 }
56 };
57}
58macro_rules! impl_debug_via_display {
59 ($ty:ty) => {
60 impl Debug for $ty {
61 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
62 <_ as Display>::fmt(self, f)
63 }
64 }
65 };
66}
67
68impl<C: AstFormatter> FmtWithCtx<C> for AbortKind {
71 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
72 match self {
73 AbortKind::Panic(name) => {
74 write!(f, "panic")?;
75 if let Some(name) = name {
76 write!(f, "({})", name.with_ctx(ctx))?;
77 }
78 Ok(())
79 }
80 AbortKind::UndefinedBehavior => write!(f, "undefined_behavior"),
81 AbortKind::UnwindTerminate => write!(f, "unwind_terminate"),
82 }
83 }
84}
85
86impl<C: AstFormatter> FmtWithCtx<C> for AnyTransId {
87 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
88 match ctx
89 .get_crate()
90 .and_then(|translated| translated.item_short_name(*self))
91 {
92 None => write!(f, "{self}"),
93 Some(name) => name.fmt_with_ctx(ctx, f),
94 }
95 }
96}
97
98impl Display for AnyTransId {
99 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
100 let s = match self {
101 AnyTransId::Type(x) => x.to_pretty_string(),
102 AnyTransId::Fun(x) => x.to_pretty_string(),
103 AnyTransId::Global(x) => x.to_pretty_string(),
104 AnyTransId::TraitDecl(x) => x.to_pretty_string(),
105 AnyTransId::TraitImpl(x) => x.to_pretty_string(),
106 };
107 f.write_str(&s)
108 }
109}
110
111impl<C: AstFormatter> FmtWithCtx<C> for AnyTransItem<'_> {
112 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
113 match self {
114 AnyTransItem::Type(d) => write!(f, "{}", d.with_ctx(ctx)),
115 AnyTransItem::Fun(d) => write!(f, "{}", d.with_ctx(ctx)),
116 AnyTransItem::Global(d) => write!(f, "{}", d.with_ctx(ctx)),
117 AnyTransItem::TraitDecl(d) => write!(f, "{}", d.with_ctx(ctx)),
118 AnyTransItem::TraitImpl(d) => write!(f, "{}", d.with_ctx(ctx)),
119 }
120 }
121}
122
123impl<C: AstFormatter> FmtWithCtx<C> for Assert {
124 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
125 write!(
126 f,
127 "assert({} == {})",
128 self.cond.with_ctx(ctx),
129 self.expected,
130 )
131 }
132}
133
134impl<T> Binder<T> {
135 fn fmt_split<'a, C>(&'a self, ctx: &'a C) -> (String, String)
138 where
139 C: AstFormatter,
140 T: FmtWithCtx<C::Reborrow<'a>>,
141 {
142 let ctx = &ctx.push_binder(Cow::Borrowed(&self.params));
143 (
144 self.params.fmt_with_ctx_single_line(ctx),
145 self.skip_binder.to_string_with_ctx(ctx),
146 )
147 }
148}
149
150impl Display for OverflowMode {
151 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
152 match self {
153 OverflowMode::Panic => write!(f, "panic"),
154 OverflowMode::Wrap => write!(f, "wrap"),
155 OverflowMode::UB => write!(f, "ub"),
156 }
157 }
158}
159
160impl Display for BinOp {
161 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
162 match self {
163 BinOp::BitXor => write!(f, "^"),
164 BinOp::BitAnd => write!(f, "&"),
165 BinOp::BitOr => write!(f, "|"),
166 BinOp::Eq => write!(f, "=="),
167 BinOp::Lt => write!(f, "<"),
168 BinOp::Le => write!(f, "<="),
169 BinOp::Ne => write!(f, "!="),
170 BinOp::Ge => write!(f, ">="),
171 BinOp::Gt => write!(f, ">"),
172 BinOp::Add(mode) => write!(f, "{}.+", mode),
173 BinOp::Sub(mode) => write!(f, "{}.-", mode),
174 BinOp::Mul(mode) => write!(f, "{}.*", mode),
175 BinOp::Div(mode) => write!(f, "{}./", mode),
176 BinOp::Rem(mode) => write!(f, "{}.%", mode),
177 BinOp::AddChecked => write!(f, "checked.+"),
178 BinOp::SubChecked => write!(f, "checked.-"),
179 BinOp::MulChecked => write!(f, "checked.*"),
180 BinOp::Shl(mode) => write!(f, "{}.<<", mode),
181 BinOp::Shr(mode) => write!(f, "{}.>>", mode),
182 BinOp::Cmp => write!(f, "cmp"),
183 BinOp::Offset => write!(f, "offset"),
184 }
185 }
186}
187
188impl<C: AstFormatter> FmtWithCtx<C> for llbc::Block {
189 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
190 for st in &self.statements {
191 writeln!(f, "{}", st.with_ctx(ctx))?;
192 }
193 Ok(())
194 }
195}
196
197impl<C: AstFormatter> FmtWithCtx<C> for ullbc::BlockData {
198 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
199 for statement in &self.statements {
200 writeln!(f, "{};", statement.with_ctx(ctx))?;
201 }
202 write!(f, "{};", self.terminator.with_ctx(ctx))?;
203 Ok(())
204 }
205}
206
207impl<C: AstFormatter> FmtWithCtx<C> for gast::Body {
208 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
209 match self {
210 Body::Unstructured(b) => write!(f, "{}", b.with_ctx(ctx)),
211 Body::Structured(b) => write!(f, "{}", b.with_ctx(ctx)),
212 }
213 }
214}
215
216impl Display for BorrowKind {
217 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
218 write!(f, "{self:?}")
220 }
221}
222
223impl Display for BuiltinFunId {
224 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
225 let name = match *self {
226 BuiltinFunId::BoxNew => "BoxNew",
227 BuiltinFunId::ArrayToSliceShared => "ArrayToSliceShared",
228 BuiltinFunId::ArrayToSliceMut => "ArrayToSliceMut",
229 BuiltinFunId::ArrayRepeat => "ArrayRepeat",
230 BuiltinFunId::Index(BuiltinIndexOp {
231 is_array,
232 mutability,
233 is_range,
234 }) => {
235 let ty = if is_array { "Array" } else { "Slice" };
236 let op = if is_range { "SubSlice" } else { "Index" };
237 let mutability = mutability.variant_name();
238 &format!("{ty}{op}{mutability}")
239 }
240 BuiltinFunId::PtrFromParts(mutability) => {
241 let mutability = mutability.variant_name();
242 &format!("PtrFromParts{mutability}")
243 }
244 };
245 f.write_str(name)
246 }
247}
248
249impl<C: AstFormatter> FmtWithCtx<C> for Call {
250 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
251 let dest = self.dest.with_ctx(ctx);
252 let func = self.func.with_ctx(ctx);
253 let args = self.args.iter().map(|x| x.with_ctx(ctx)).format(", ");
254 write!(f, "{dest} := {func}({args})")
255 }
256}
257
258impl<C: AstFormatter> FmtWithCtx<C> for CastKind {
259 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
260 match self {
261 CastKind::Scalar(src, tgt) => write!(f, "cast<{src}, {tgt}>"),
262 CastKind::FnPtr(src, tgt) | CastKind::RawPtr(src, tgt) => {
263 write!(f, "cast<{}, {}>", src.with_ctx(ctx), tgt.with_ctx(ctx))
264 }
265 CastKind::Unsize(src, tgt, meta) => {
266 write!(
267 f,
268 "unsize_cast<{}, {}",
269 src.with_ctx(ctx),
270 tgt.with_ctx(ctx),
271 )?;
272 match meta {
273 UnsizingMetadata::Length(len) => write!(f, ", {}", len.with_ctx(ctx))?,
274 UnsizingMetadata::VTablePtr(tref) => write!(f, ", {}", tref.with_ctx(ctx))?,
275 UnsizingMetadata::Unknown => {}
276 }
277 write!(f, ">")
278 }
279 CastKind::Transmute(src, tgt) => {
280 write!(f, "transmute<{}, {}>", src.with_ctx(ctx), tgt.with_ctx(ctx))
281 }
282 }
283 }
284}
285
286impl<C: AstFormatter> FmtWithCtx<C> for ClauseDbVar {
287 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
288 ctx.format_bound_var(f, *self, "@TraitClause", |_| None)
289 }
290}
291
292impl_display_via_ctx!(ConstantExpr);
293impl<C: AstFormatter> FmtWithCtx<C> for ConstantExpr {
294 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
295 write!(f, "{}", self.value.with_ctx(ctx))
296 }
297}
298
299impl<C: AstFormatter> FmtWithCtx<C> for ConstGeneric {
300 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
301 match self {
302 ConstGeneric::Var(id) => write!(f, "{}", id.with_ctx(ctx)),
303 ConstGeneric::Value(v) => write!(f, "{v}"),
304 ConstGeneric::Global(id) => write!(f, "{}", id.with_ctx(ctx)),
305 }
306 }
307}
308
309impl<C: AstFormatter> FmtWithCtx<C> for ConstGenericDbVar {
310 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
311 ctx.format_bound_var(f, *self, "@ConstGeneric", |v| Some(v.to_string()))
312 }
313}
314
315impl_display_via_ctx!(ConstGenericVar);
316impl<C: AstFormatter> FmtWithCtx<C> for ConstGenericVar {
317 fn fmt_with_ctx(&self, _ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
318 write!(f, "const {} : {}", self.name, self.ty)
319 }
320}
321
322impl Display for DeBruijnId {
323 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
324 write!(f, "{}", self.index)
325 }
326}
327
328impl<Id: Display> Display for DeBruijnVar<Id> {
329 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
330 match self {
331 Self::Bound(dbid, varid) => write!(f, "{dbid}_{varid}"),
332 Self::Free(varid) => write!(f, "{varid}"),
333 }
334 }
335}
336
337impl<C: AstFormatter> FmtWithCtx<C> for DeclarationGroup {
338 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
339 use DeclarationGroup::*;
340 match self {
341 Type(g) => write!(f, "Type decls group: {}", g.with_ctx(ctx)),
342 Fun(g) => write!(f, "Fun decls group: {}", g.with_ctx(ctx)),
343 Global(g) => write!(f, "Global decls group: {}", g.with_ctx(ctx)),
344 TraitDecl(g) => write!(f, "Trait decls group: {}", g.with_ctx(ctx)),
345 TraitImpl(g) => write!(f, "Trait impls group: {}", g.with_ctx(ctx)),
346 Mixed(g) => write!(f, "Mixed group: {}", g.with_ctx(ctx)),
347 }
348 }
349}
350
351impl<C: AstFormatter> FmtWithCtx<C> for DynPredicate {
352 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
353 let ctx = &ctx.push_binder(Cow::Borrowed(&self.binder.params));
354 let ty = self.binder.skip_binder.with_ctx(ctx);
355 let clauses = self.binder.params.formatted_clauses(ctx).format(" + ");
356 write!(f, "exists<{ty}> {clauses}")
357 }
358}
359
360impl_display_via_ctx!(Field);
361impl<C: AstFormatter> FmtWithCtx<C> for Field {
362 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
363 if let Some(name) = &self.name {
364 write!(f, "{}: ", name)?
365 }
366 write!(f, "{}", self.ty.with_ctx(ctx))
367 }
368}
369
370impl Display for FileName {
371 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
372 match self {
373 FileName::Virtual(path_buf) | FileName::Local(path_buf) => {
374 write!(f, "{}", path_buf.display())
375 }
376 FileName::NotReal(name) => write!(f, "{}", name),
377 }
378 }
379}
380
381impl Display for FloatTy {
382 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
383 match self {
384 FloatTy::F16 => write!(f, "f16"),
385 FloatTy::F32 => write!(f, "f32"),
386 FloatTy::F64 => write!(f, "f64"),
387 FloatTy::F128 => write!(f, "f128"),
388 }
389 }
390}
391
392impl Display for FloatValue {
393 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
394 let v = &self.value;
395 match self.ty {
396 FloatTy::F16 => write!(f, "{v} : f16"),
397 FloatTy::F32 => write!(f, "{v} : f32"),
398 FloatTy::F64 => write!(f, "{v} : f64"),
399 FloatTy::F128 => write!(f, "{v} : f128"),
400 }
401 }
402}
403
404impl<C: AstFormatter> FmtWithCtx<C> for FnOperand {
405 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
406 match self {
407 FnOperand::Regular(func) => write!(f, "{}", func.with_ctx(ctx)),
408 FnOperand::Move(p) => write!(f, "(move {})", p.with_ctx(ctx)),
409 }
410 }
411}
412
413impl<C: AstFormatter> FmtWithCtx<C> for FnPtr {
414 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
415 match self.func.as_ref() {
416 FunIdOrTraitMethodRef::Fun(FunId::Regular(def_id)) => {
417 write!(f, "{}", def_id.with_ctx(ctx))?
418 }
419 FunIdOrTraitMethodRef::Fun(FunId::Builtin(builtin)) => write!(f, "@{}", builtin)?,
420 FunIdOrTraitMethodRef::Trait(trait_ref, method_id, _) => {
421 write!(f, "{}::{}", trait_ref.with_ctx(ctx), &method_id.0)?
422 }
423 };
424 write!(f, "{}", self.generics.with_ctx(ctx))
425 }
426}
427
428impl<C: AstFormatter> FmtWithCtx<C> for FunDecl {
429 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
430 let keyword = if self.signature.is_unsafe {
431 "unsafe fn"
432 } else {
433 "fn"
434 };
435 self.item_meta
436 .fmt_item_intro(f, ctx, keyword, self.def_id)?;
437
438 let ctx = &ctx.set_generics(&self.signature.generics);
440
441 let (params, preds) = self.signature.generics.fmt_with_ctx_with_trait_clauses(ctx);
443 write!(f, "{params}")?;
444
445 let mut args: Vec<String> = Vec::new();
447 for (i, ty) in self.signature.inputs.iter().enumerate() {
448 let id = LocalId::new(i + 1);
451 args.push(format!("{}: {}", id.to_pretty_string(), ty.with_ctx(ctx)));
452 }
453 let args = args.join(", ");
454 write!(f, "({args})")?;
455
456 if !self.signature.output.is_unit() {
458 write!(f, " -> {}", self.signature.output.with_ctx(ctx))?;
459 };
460 write!(f, "{preds}")?;
461
462 match &self.body {
464 Ok(body) => {
465 let tab = ctx.indent();
466 let body = body.with_ctx(ctx);
467 write!(f, "\n{tab}{{\n{body}{tab}}}")?;
468 }
469 Err(Opaque) => {}
470 }
471
472 Ok(())
473 }
474}
475
476impl<C: AstFormatter> FmtWithCtx<C> for FunDeclId {
477 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
478 AnyTransId::from(*self).fmt_with_ctx(ctx, f)
479 }
480}
481
482impl<C: AstFormatter> FmtWithCtx<C> for FunDeclRef {
483 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
484 let id = self.id.with_ctx(ctx);
485 let generics = self.generics.with_ctx(ctx);
486 write!(f, "{id}{generics}")
487 }
488}
489
490impl<C: AstFormatter> FmtWithCtx<C> for FunSig {
491 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
492 let ctx = &ctx.set_generics(&self.generics);
493
494 if self.is_unsafe {
496 write!(f, "unsafe ")?;
497 }
498
499 let (params, clauses) = self.generics.fmt_with_ctx_with_trait_clauses(ctx);
501 write!(f, "fn{params}")?;
502
503 let args = self
505 .inputs
506 .iter()
507 .map(|ty| ty.with_ctx(ctx).to_string())
508 .format(", ");
509 write!(f, "({args})")?;
510
511 if !self.output.is_unit() {
513 write!(f, " -> {}", self.output.with_ctx(ctx))?;
514 }
515
516 write!(f, "{clauses}")?;
517 Ok(())
518 }
519}
520
521impl<Id: Copy, C: AstFormatter> FmtWithCtx<C> for GDeclarationGroup<Id>
522where
523 Id: FmtWithCtx<C>,
524{
525 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
526 use GDeclarationGroup::*;
527 match self {
528 NonRec(id) => write!(f, "Non rec: {}", id.with_ctx(ctx)),
529 Rec(ids) => {
530 let ids = ids.iter().map(|id| id.with_ctx(ctx)).format(", ");
531 write!(f, "Rec: {}", ids)
532 }
533 }
534 }
535}
536
537impl GenericArgs {
538 pub(crate) fn fmt_explicits<'a, C: AstFormatter>(
539 &'a self,
540 ctx: &'a C,
541 ) -> impl Iterator<Item = impl Display + 'a> {
542 let regions = self.regions.iter().map(|x| x.with_ctx(ctx));
543 let types = self.types.iter().map(|x| x.with_ctx(ctx));
544 let const_generics = self.const_generics.iter().map(|x| x.with_ctx(ctx));
545 regions.map(Either::Left).chain(
546 types
547 .map(Either::Left)
548 .chain(const_generics.map(Either::Right))
549 .map(Either::Right),
550 )
551 }
552
553 pub(crate) fn fmt_implicits<'a, C: AstFormatter>(
554 &'a self,
555 ctx: &'a C,
556 ) -> impl Iterator<Item = impl Display + 'a> {
557 self.trait_refs.iter().map(|x| x.with_ctx(ctx))
558 }
559}
560
561impl_display_via_ctx!(GenericArgs);
562impl_debug_via_display!(GenericArgs);
563impl<C: AstFormatter> FmtWithCtx<C> for GenericArgs {
564 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
565 if self.has_explicits() {
566 write!(f, "<{}>", self.fmt_explicits(ctx).format(", "))?;
567 }
568 if self.has_implicits() {
569 write!(f, "[{}]", self.fmt_implicits(ctx).format(", "))?;
570 }
571 Ok(())
572 }
573}
574
575impl GenericParams {
576 fn formatted_params<'a, C>(&'a self, ctx: &'a C) -> impl Iterator<Item = impl Display + 'a>
577 where
578 C: AstFormatter,
579 {
580 let regions = self.regions.iter().map(|x| x.with_ctx(ctx));
581 let types = self.types.iter();
582 let const_generics = self.const_generics.iter();
583 regions.map(Either::Left).chain(
584 types
585 .map(Either::Left)
586 .chain(const_generics.map(Either::Right))
587 .map(Either::Right),
588 )
589 }
590
591 fn formatted_clauses<'a, C>(&'a self, ctx: &'a C) -> impl Iterator<Item = impl Display + 'a>
592 where
593 C: AstFormatter,
594 {
595 let trait_clauses = self.trait_clauses.iter().map(|x| x.to_string_with_ctx(ctx));
596 let types_outlive = self.types_outlive.iter().map(|x| x.fmt_as_for(ctx));
597 let regions_outlive = self.regions_outlive.iter().map(|x| x.fmt_as_for(ctx));
598 let type_constraints = self
599 .trait_type_constraints
600 .iter()
601 .map(|x| x.fmt_as_for(ctx));
602 trait_clauses.map(Either::Left).chain(
603 types_outlive
604 .chain(regions_outlive)
605 .chain(type_constraints)
606 .map(Either::Right),
607 )
608 }
609
610 pub fn fmt_with_ctx_with_trait_clauses<C>(&self, ctx: &C) -> (String, String)
611 where
612 C: AstFormatter,
613 {
614 let tab = ctx.indent();
615 let params = if self.has_explicits() {
616 let params = self.formatted_params(ctx).format(", ");
617 format!("<{}>", params)
618 } else {
619 String::new()
620 };
621 let clauses = if self.has_predicates() {
622 let clauses = self
623 .formatted_clauses(ctx)
624 .map(|x| format!("\n{tab}{TAB_INCR}{x},"))
625 .format("");
626 format!("\n{tab}where{clauses}")
627 } else {
628 String::new()
629 };
630 (params, clauses)
631 }
632
633 pub fn fmt_with_ctx_single_line<C>(&self, ctx: &C) -> String
634 where
635 C: AstFormatter,
636 {
637 if self.is_empty() {
638 String::new()
639 } else {
640 let params = self
641 .formatted_params(ctx)
642 .map(Either::Left)
643 .chain(self.formatted_clauses(ctx).map(Either::Right))
644 .format(", ");
645 format!("<{}>", params)
646 }
647 }
648}
649
650impl_debug_via_display!(GenericParams);
651impl Display for GenericParams {
652 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
653 write!(f, "{}", self.fmt_with_ctx_single_line(&FmtCtx::new()))
654 }
655}
656
657impl<C: AstFormatter> FmtWithCtx<C> for GenericsSource {
658 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
659 match self {
660 GenericsSource::Item(id) => write!(f, "{}", id.with_ctx(ctx)),
661 GenericsSource::Method(id, name) => write!(f, "{}::{name}", id.with_ctx(ctx)),
662 GenericsSource::Builtin => write!(f, "<builtin>"),
663 GenericsSource::Other => write!(f, "<unknown>"),
664 }
665 }
666}
667
668impl<T> GExprBody<T> {
669 fn fmt_with_ctx_and_callback<C: AstFormatter>(
670 &self,
671 ctx: &C,
672 f: &mut fmt::Formatter<'_>,
673 fmt_body: impl FnOnce(
674 &mut fmt::Formatter<'_>,
675 &<<C as AstFormatter>::Reborrow<'_> as AstFormatter>::Reborrow<'_>,
676 &T,
677 ) -> fmt::Result,
678 ) -> fmt::Result {
679 let ctx = &ctx.set_locals(&self.locals);
681 let ctx = &ctx.increase_indent();
682 let tab = ctx.indent();
683
684 for v in &self.locals.locals {
686 write!(f, "{tab}")?;
687 write!(f, "let {v}: {};", v.ty.with_ctx(ctx))?;
688
689 write!(f, " // ")?;
690 let index = v.index.index();
691 if index == 0 {
692 write!(f, "return")?;
693 } else if index <= self.locals.arg_count {
694 write!(f, "arg #{index}")?
695 } else {
696 match &v.name {
697 Some(_) => write!(f, "local")?,
698 None => write!(f, "anonymous local")?,
699 }
700 }
701 writeln!(f)?;
702 }
703
704 fmt_body(f, ctx, &self.body)?;
705
706 Ok(())
707 }
708}
709
710impl<C: AstFormatter> FmtWithCtx<C> for GExprBody<llbc_ast::Block> {
711 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
712 fn fmt_body<C: AstFormatter>(
714 f: &mut fmt::Formatter<'_>,
715 ctx: &<<C as AstFormatter>::Reborrow<'_> as AstFormatter>::Reborrow<'_>,
716 body: &Block,
717 ) -> Result<(), fmt::Error> {
718 writeln!(f)?;
719 body.fmt_with_ctx(ctx, f)?;
720 Ok(())
721 }
722 self.fmt_with_ctx_and_callback(ctx, f, fmt_body::<C>)
723 }
724}
725impl<C: AstFormatter> FmtWithCtx<C> for GExprBody<ullbc_ast::BodyContents> {
726 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
727 fn fmt_body<C: AstFormatter>(
729 f: &mut fmt::Formatter<'_>,
730 ctx: &<<C as AstFormatter>::Reborrow<'_> as AstFormatter>::Reborrow<'_>,
731 body: &Vector<BlockId, BlockData>,
732 ) -> Result<(), fmt::Error> {
733 let tab = ctx.indent();
734 let ctx = &ctx.increase_indent();
735 for (bid, block) in body.iter_indexed_values() {
736 writeln!(f)?;
737 writeln!(f, "{tab}bb{}: {{", bid.index())?;
738 writeln!(f, "{}", block.with_ctx(ctx))?;
739 writeln!(f, "{tab}}}")?;
740 }
741 Ok(())
742 }
743 self.fmt_with_ctx_and_callback(ctx, f, fmt_body::<C>)
744 }
745}
746
747impl<C> FmtWithCtx<C> for GlobalDecl
748where
749 C: AstFormatter,
750{
751 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
752 let keyword = match self.global_kind {
753 GlobalKind::Static => "static",
754 GlobalKind::AnonConst | GlobalKind::NamedConst => "const",
755 };
756 self.item_meta
757 .fmt_item_intro(f, ctx, keyword, self.def_id)?;
758
759 let ctx = &ctx.set_generics(&self.generics);
761
762 let (params, preds) = self.generics.fmt_with_ctx_with_trait_clauses(ctx);
764
765 let ty = self.ty.with_ctx(ctx);
767 write!(f, "{params}: {ty}")?;
768
769 write!(f, "{preds}")?;
771 if self.generics.has_predicates() {
772 write!(f, "\n")?;
773 }
774 write!(f, " ")?;
775
776 let initializer = self.init.with_ctx(ctx);
778 write!(f, "= {initializer}()")?;
779
780 Ok(())
781 }
782}
783
784impl<C: AstFormatter> FmtWithCtx<C> for GlobalDeclId {
785 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
786 AnyTransId::from(*self).fmt_with_ctx(ctx, f)
787 }
788}
789
790impl<C: AstFormatter> FmtWithCtx<C> for GlobalDeclRef {
791 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
792 let id = self.id.with_ctx(ctx);
793 let generics = self.generics.with_ctx(ctx);
794 write!(f, "{id}{generics}")
795 }
796}
797
798impl<C: AstFormatter> FmtWithCtx<C> for ImplElem {
799 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
800 write!(f, "{{")?;
801 match self {
802 ImplElem::Ty(bound_ty) => {
803 let ctx = ctx.set_generics(&bound_ty.params);
805 bound_ty.skip_binder.fmt_with_ctx(&ctx, f)?
806 }
807 ImplElem::Trait(impl_id) => {
808 match ctx.get_crate().and_then(|tr| tr.trait_impls.get(*impl_id)) {
809 None => write!(f, "impl#{impl_id}")?,
810 Some(timpl) => {
811 let ctx = &ctx.set_generics(&timpl.generics);
814 let mut impl_trait = timpl.impl_trait.clone();
815 match impl_trait
816 .generics
817 .types
818 .remove_and_shift_ids(TypeVarId::ZERO)
819 {
820 Some(self_ty) => {
821 let self_ty = self_ty.with_ctx(ctx);
822 let impl_trait = impl_trait.with_ctx(ctx);
823 write!(f, "impl {impl_trait} for {self_ty}")?;
824 }
825 None => {
827 let impl_trait = impl_trait.with_ctx(ctx);
828 write!(f, "impl {impl_trait}")?;
829 }
830 }
831 }
832 }
833 }
834 }
835 write!(f, "}}")
836 }
837}
838
839impl Display for IntTy {
840 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
841 match self {
842 IntTy::Isize => write!(f, "isize"),
843 IntTy::I8 => write!(f, "i8"),
844 IntTy::I16 => write!(f, "i16"),
845 IntTy::I32 => write!(f, "i32"),
846 IntTy::I64 => write!(f, "i64"),
847 IntTy::I128 => write!(f, "i128"),
848 }
849 }
850}
851
852impl Display for UIntTy {
853 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
854 match self {
855 UIntTy::Usize => write!(f, "usize"),
856 UIntTy::U8 => write!(f, "u8"),
857 UIntTy::U16 => write!(f, "u16"),
858 UIntTy::U32 => write!(f, "u32"),
859 UIntTy::U64 => write!(f, "u64"),
860 UIntTy::U128 => write!(f, "u128"),
861 }
862 }
863}
864
865impl Display for IntegerTy {
866 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
867 match self {
868 IntegerTy::Signed(int_ty) => write!(f, "{int_ty}"),
869 IntegerTy::Unsigned(uint_ty) => write!(f, "{uint_ty}"),
870 }
871 }
872}
873
874impl ItemMeta {
875 pub fn fmt_item_intro<C: AstFormatter>(
877 &self,
878 f: &mut fmt::Formatter<'_>,
879 ctx: &C,
880 keyword: &str,
881 id: impl Into<AnyTransId>,
882 ) -> fmt::Result {
883 let tab = ctx.indent();
884 let full_name = self.name.with_ctx(ctx);
885 let name = if let Some(tr) = ctx.get_crate()
886 && let Some(short_name) = tr.short_names.get(&id.into())
887 {
888 writeln!(f, "// Full name: {full_name}")?;
889 short_name.with_ctx(ctx)
890 } else {
891 full_name
892 };
893 if let Some(id) = &self.lang_item {
894 writeln!(f, "{tab}#[lang_item(\"{id}\")]")?;
895 }
896 write!(f, "{tab}")?;
897 if self.attr_info.public {
898 write!(f, "pub ")?;
899 }
900 write!(f, "{keyword} {name}")
901 }
902}
903
904impl Display for Literal {
905 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
906 match self {
907 Literal::Scalar(v) => write!(f, "{v}"),
908 Literal::Float(v) => write!(f, "{v}"),
909 Literal::Bool(v) => write!(f, "{v}"),
910 Literal::Char(v) => write!(f, "{v}"),
911 Literal::Str(v) => write!(f, "\"{}\"", v.replace("\\", "\\\\").replace("\n", "\\n")),
912 Literal::ByteStr(v) => write!(f, "{v:?}"),
913 }
914 }
915}
916
917impl Display for LiteralTy {
918 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
919 match self {
920 LiteralTy::Int(ty) => write!(f, "{ty}"),
921 LiteralTy::UInt(ty) => write!(f, "{ty}"),
922 LiteralTy::Float(ty) => write!(f, "{ty}"),
923 LiteralTy::Char => write!(f, "char"),
924 LiteralTy::Bool => write!(f, "bool"),
925 }
926 }
927}
928
929impl Display for Loc {
930 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
931 write!(f, "{}:{}", self.line, self.col)
932 }
933}
934
935impl Display for Local {
936 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
937 if let Some(name) = &self.name {
940 write!(f, "{name}")?
941 }
942 write!(f, "{}", self.index.to_pretty_string())?;
943 Ok(())
944 }
945}
946
947impl<C: AstFormatter> FmtWithCtx<C> for LocalId {
948 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
949 ctx.format_local_id(f, *self)
950 }
951}
952
953impl<C: AstFormatter> FmtWithCtx<C> for Name {
954 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
955 let name = self.name.iter().map(|x| x.with_ctx(ctx)).format("::");
956 write!(f, "{}", name)
957 }
958}
959
960impl<C: AstFormatter> FmtWithCtx<C> for NullOp {
961 fn fmt_with_ctx(&self, _ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
962 let op = match self {
963 NullOp::SizeOf => "size_of",
964 NullOp::AlignOf => "align_of",
965 NullOp::OffsetOf(_) => "offset_of(?)",
966 NullOp::UbChecks => "ub_checks",
967 };
968 write!(f, "{op}")
969 }
970}
971
972impl_display_via_ctx!(Operand);
973impl<C: AstFormatter> FmtWithCtx<C> for Operand {
974 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
975 match self {
976 Operand::Copy(p) => write!(f, "copy ({})", p.with_ctx(ctx)),
977 Operand::Move(p) => write!(f, "move ({})", p.with_ctx(ctx)),
978 Operand::Const(c) => write!(f, "const ({})", c.with_ctx(ctx)),
979 }
980 }
981}
982
983impl<C: AstFormatter, T, U> FmtWithCtx<C> for OutlivesPred<T, U>
984where
985 T: FmtWithCtx<C>,
986 U: FmtWithCtx<C>,
987{
988 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
989 write!(f, "{} : {}", self.0.with_ctx(ctx), self.1.with_ctx(ctx))
990 }
991}
992
993impl<C: AstFormatter> FmtWithCtx<C> for PathElem {
994 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
995 match self {
996 PathElem::Ident(s, d) => {
997 write!(f, "{s}")?;
998 if !d.is_zero() {
999 write!(f, "#{}", d)?;
1000 }
1001 Ok(())
1002 }
1003 PathElem::Impl(impl_elem) => {
1004 write!(f, "{}", impl_elem.with_ctx(ctx))
1005 }
1006 PathElem::Monomorphized(args) => {
1007 write!(f, "<{}>", args.fmt_explicits(ctx).format(", "))
1008 }
1009 }
1010 }
1011}
1012
1013impl_display_via_ctx!(Place);
1014impl<C: AstFormatter> FmtWithCtx<C> for Place {
1015 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1016 match &self.kind {
1017 PlaceKind::Local(var_id) => write!(f, "{}", var_id.with_ctx(ctx)),
1018 PlaceKind::Global(global_ref) => global_ref.fmt_with_ctx(ctx, f),
1019 PlaceKind::Projection(subplace, projection) => {
1020 let sub = subplace.with_ctx(ctx);
1021 match projection {
1022 ProjectionElem::Deref => {
1023 write!(f, "*({sub})")
1024 }
1025 ProjectionElem::Field(proj_kind, field_id) => match proj_kind {
1026 FieldProjKind::Adt(adt_id, opt_variant_id) => {
1027 write!(f, "({sub}")?;
1028 if let Some(variant_id) = opt_variant_id {
1029 write!(f, " as variant ")?;
1030 ctx.format_enum_variant(f, *adt_id, *variant_id)?;
1031 }
1032 write!(f, ").")?;
1033 ctx.format_field_name(f, *adt_id, *opt_variant_id, *field_id)?;
1034 Ok(())
1035 }
1036 FieldProjKind::Tuple(_) => {
1037 write!(f, "({sub}).{field_id}")
1038 }
1039 },
1040 ProjectionElem::Index {
1041 offset,
1042 from_end: true,
1043 ..
1044 } => write!(f, "({sub})[-{}]", offset.with_ctx(ctx)),
1045 ProjectionElem::Index {
1046 offset,
1047 from_end: false,
1048 ..
1049 } => write!(f, "({sub})[{}]", offset.with_ctx(ctx)),
1050 ProjectionElem::Subslice {
1051 from,
1052 to,
1053 from_end: true,
1054 ..
1055 } => write!(f, "({sub})[{}..-{}]", from.with_ctx(ctx), to.with_ctx(ctx)),
1056 ProjectionElem::Subslice {
1057 from,
1058 to,
1059 from_end: false,
1060 ..
1061 } => write!(f, "({sub})[{}..{}]", from.with_ctx(ctx), to.with_ctx(ctx)),
1062 }
1063 }
1064 }
1065 }
1066}
1067
1068impl<C: AstFormatter> FmtWithCtx<C> for PolyTraitDeclRef {
1069 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1070 write!(f, "{}", self.fmt_as_for(ctx))
1071 }
1072}
1073
1074impl Display for RawAttribute {
1075 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
1076 write!(f, "{}", self.path)?;
1077 if let Some(args) = &self.args {
1078 write!(f, "({args})")?;
1079 }
1080 Ok(())
1081 }
1082}
1083
1084impl<C: AstFormatter> FmtWithCtx<C> for RawConstantExpr {
1085 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1086 match self {
1087 RawConstantExpr::Literal(c) => write!(f, "{}", c.to_string()),
1088 RawConstantExpr::Adt(variant_id, values) => {
1089 let variant_id = match variant_id {
1093 Some(id) => format!("Some({id})"),
1094 None => "None".to_string(),
1095 };
1096 let values = values.iter().map(|v| v.with_ctx(ctx)).format(", ");
1097 write!(f, "ConstAdt {} [{}]", variant_id, values)
1098 }
1099 RawConstantExpr::Array(values) => {
1100 let values = values.iter().map(|v| v.with_ctx(ctx)).format(", ");
1101 write!(f, "[{}]", values)
1102 }
1103 RawConstantExpr::Global(global_ref) => {
1104 write!(f, "{}", global_ref.with_ctx(ctx))
1105 }
1106 RawConstantExpr::TraitConst(trait_ref, name) => {
1107 write!(f, "{}::{name}", trait_ref.with_ctx(ctx),)
1108 }
1109 RawConstantExpr::Ref(cv) => {
1110 write!(f, "&{}", cv.with_ctx(ctx))
1111 }
1112 RawConstantExpr::Ptr(rk, cv) => match rk {
1113 RefKind::Mut => write!(f, "&raw mut {}", cv.with_ctx(ctx)),
1114 RefKind::Shared => write!(f, "&raw const {}", cv.with_ctx(ctx)),
1115 },
1116 RawConstantExpr::Var(id) => write!(f, "{}", id.with_ctx(ctx)),
1117 RawConstantExpr::FnPtr(fp) => {
1118 write!(f, "{}", fp.with_ctx(ctx))
1119 }
1120 RawConstantExpr::PtrNoProvenance(v) => write!(f, "no-provenance {v}"),
1121 RawConstantExpr::RawMemory(bytes) => write!(f, "RawMemory({bytes:?})"),
1122 RawConstantExpr::Opaque(cause) => write!(f, "Opaque({cause})"),
1123 }
1124 }
1125}
1126
1127impl<C: AstFormatter> FmtWithCtx<C> for Region {
1128 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1129 match self {
1130 Region::Static => write!(f, "'static"),
1131 Region::Var(var) => write!(f, "{}", var.with_ctx(ctx)),
1132 Region::Erased => write!(f, "'_"),
1133 }
1134 }
1135}
1136
1137impl<T> RegionBinder<T> {
1138 fn fmt_split<'a, C>(&'a self, ctx: &'a C) -> (String, String)
1140 where
1141 C: AstFormatter,
1142 T: FmtWithCtx<C::Reborrow<'a>>,
1143 {
1144 let ctx = &ctx.push_bound_regions(&self.regions);
1145 (
1146 self.regions
1147 .iter()
1148 .map(|r| r.with_ctx(ctx))
1149 .format(", ")
1150 .to_string(),
1151 self.skip_binder.to_string_with_ctx(ctx),
1152 )
1153 }
1154
1155 fn fmt_as_for<'a, C>(&'a self, ctx: &'a C) -> String
1157 where
1158 C: AstFormatter,
1159 T: FmtWithCtx<C::Reborrow<'a>>,
1160 {
1161 let (regions, value) = self.fmt_split(ctx);
1162 let regions = if regions.is_empty() {
1163 "".to_string()
1164 } else {
1165 format!("for<{regions}> ",)
1166 };
1167 format!("{regions}{value}",)
1168 }
1169}
1170
1171impl<C: AstFormatter> FmtWithCtx<C> for RegionDbVar {
1172 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1173 ctx.format_bound_var(f, *self, "'_", |v| {
1174 v.name.as_ref().map(|name| name.to_string())
1175 })
1176 }
1177}
1178
1179impl_display_via_ctx!(RegionVar);
1180impl<C: AstFormatter> FmtWithCtx<C> for RegionVar {
1181 fn fmt_with_ctx(&self, _ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1182 match &self.name {
1183 Some(name) => write!(f, "{name}"),
1184 None => write!(f, "'_{}", self.index),
1185 }
1186 }
1187}
1188
1189impl_display_via_ctx!(Rvalue);
1190impl<C: AstFormatter> FmtWithCtx<C> for Rvalue {
1191 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1192 match self {
1193 Rvalue::Use(x) => write!(f, "{}", x.with_ctx(ctx)),
1194 Rvalue::Ref(place, borrow_kind) => {
1195 let borrow_kind = match borrow_kind {
1196 BorrowKind::Shared => "&",
1197 BorrowKind::Mut => "&mut ",
1198 BorrowKind::TwoPhaseMut => "&two-phase-mut ",
1199 BorrowKind::UniqueImmutable => "&uniq ",
1200 BorrowKind::Shallow => "&shallow ",
1201 };
1202 write!(f, "{borrow_kind}{}", place.with_ctx(ctx))
1203 }
1204 Rvalue::RawPtr(place, mutability) => {
1205 let ptr_kind = match mutability {
1206 RefKind::Shared => "&raw const ",
1207 RefKind::Mut => "&raw mut ",
1208 };
1209 write!(f, "{ptr_kind}{}", place.with_ctx(ctx))
1210 }
1211
1212 Rvalue::BinaryOp(binop, x, y) => {
1213 write!(f, "{} {} {}", x.with_ctx(ctx), binop, y.with_ctx(ctx))
1214 }
1215 Rvalue::UnaryOp(unop, x) => {
1216 write!(f, "{}({})", unop.with_ctx(ctx), x.with_ctx(ctx))
1217 }
1218 Rvalue::NullaryOp(op, ty) => {
1219 write!(f, "{}<{}>", op.with_ctx(ctx), ty.with_ctx(ctx))
1220 }
1221 Rvalue::Discriminant(p) => {
1222 write!(f, "@discriminant({})", p.with_ctx(ctx),)
1223 }
1224 Rvalue::Aggregate(kind, ops) => {
1225 let ops_s = ops.iter().map(|op| op.with_ctx(ctx)).format(", ");
1226 match kind {
1227 AggregateKind::Adt(ty_ref, variant_id, field_id) => {
1228 match ty_ref.id {
1229 TypeId::Tuple => write!(f, "({})", ops_s),
1230 TypeId::Builtin(_) => unreachable!(),
1231 TypeId::Adt(ty_id) => {
1232 match variant_id {
1233 None => ty_id.fmt_with_ctx(ctx, f)?,
1234 Some(variant_id) => {
1235 ctx.format_enum_variant(f, ty_id, *variant_id)?
1236 }
1237 }
1238 write!(f, " {{ ")?;
1239 for (comma, (i, op)) in
1240 repeat_except_first(", ").zip(ops.iter().enumerate())
1241 {
1242 write!(f, "{}", comma.unwrap_or_default())?;
1243 let field_id = match *field_id {
1244 None => FieldId::new(i),
1245 Some(field_id) => {
1246 assert_eq!(i, 0); field_id
1248 }
1249 };
1250 ctx.format_field_name(f, ty_id, *variant_id, field_id)?;
1251 write!(f, ": {}", op.with_ctx(ctx))?;
1252 }
1253 write!(f, " }}")
1254 }
1255 }
1256 }
1257 AggregateKind::Array(..) => {
1258 write!(f, "[{}]", ops_s)
1259 }
1260 AggregateKind::RawPtr(_, rmut) => {
1261 let mutability = match rmut {
1262 RefKind::Shared => "const",
1263 RefKind::Mut => "mut ",
1264 };
1265 write!(f, "*{} ({})", mutability, ops_s)
1266 }
1267 }
1268 }
1269 Rvalue::Len(place, ..) => write!(f, "len({})", place.with_ctx(ctx)),
1270 Rvalue::Repeat(op, _ty, cg) => {
1271 write!(f, "[{}; {}]", op.with_ctx(ctx), cg.with_ctx(ctx))
1272 }
1273 Rvalue::ShallowInitBox(op, ty) => {
1274 write!(
1275 f,
1276 "shallow_init_box::<{}>({})",
1277 ty.with_ctx(ctx),
1278 op.with_ctx(ctx)
1279 )
1280 }
1281 }
1282 }
1283}
1284
1285impl Display for ScalarValue {
1286 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
1287 match self {
1288 ScalarValue::Signed(ty, v) => write!(f, "{v} : {}", ty),
1289 ScalarValue::Unsigned(ty, v) => write!(f, "{v} : {}", ty),
1290 }
1291 }
1292}
1293
1294impl<C: AstFormatter> FmtWithCtx<C> for ullbc::Statement {
1295 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1296 let tab = ctx.indent();
1297 use ullbc::RawStatement;
1298 for line in &self.comments_before {
1299 writeln!(f, "{tab}// {line}")?;
1300 }
1301 match &self.content {
1302 RawStatement::Assign(place, rvalue) => write!(
1303 f,
1304 "{tab}{} := {}",
1305 place.with_ctx(ctx),
1306 rvalue.with_ctx(ctx),
1307 ),
1308 RawStatement::SetDiscriminant(place, variant_id) => write!(
1309 f,
1310 "{tab}@discriminant({}) := {}",
1311 place.with_ctx(ctx),
1312 variant_id
1313 ),
1314 RawStatement::CopyNonOverlapping(box CopyNonOverlapping { src, dst, count }) => write!(
1315 f,
1316 "{}copy_nonoverlapping({}, {}, {})",
1317 tab,
1318 src.with_ctx(ctx),
1319 dst.with_ctx(ctx),
1320 count.with_ctx(ctx),
1321 ),
1322 RawStatement::StorageLive(var_id) => {
1323 write!(f, "{tab}storage_live({})", var_id.with_ctx(ctx))
1324 }
1325 RawStatement::StorageDead(var_id) => {
1326 write!(f, "{tab}storage_dead({})", var_id.with_ctx(ctx))
1327 }
1328 RawStatement::Deinit(place) => {
1329 write!(f, "{tab}deinit({})", place.with_ctx(ctx))
1330 }
1331 RawStatement::Drop(place, tref) => {
1332 write!(
1333 f,
1334 "{tab}drop[{}] {}",
1335 tref.with_ctx(ctx),
1336 place.with_ctx(ctx),
1337 )
1338 }
1339 RawStatement::Assert(assert) => write!(f, "{tab}{}", assert.with_ctx(ctx)),
1340 RawStatement::Nop => write!(f, "{tab}nop"),
1341 RawStatement::Error(s) => write!(f, "{tab}@Error({})", s),
1342 }
1343 }
1344}
1345
1346impl<C: AstFormatter> FmtWithCtx<C> for llbc::Statement {
1347 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1348 let tab = ctx.indent();
1349 use llbc::RawStatement;
1350 for line in &self.comments_before {
1351 writeln!(f, "{tab}// {line}")?;
1352 }
1353 write!(f, "{tab}")?;
1354 match &self.content {
1355 RawStatement::Assign(place, rvalue) => {
1356 write!(f, "{} := {}", place.with_ctx(ctx), rvalue.with_ctx(ctx),)
1357 }
1358 RawStatement::SetDiscriminant(place, variant_id) => write!(
1359 f,
1360 "@discriminant({}) := {}",
1361 place.with_ctx(ctx),
1362 variant_id
1363 ),
1364 RawStatement::CopyNonOverlapping(box CopyNonOverlapping { src, dst, count }) => write!(
1365 f,
1366 "copy_nonoverlapping({}, {}, {})",
1367 src.with_ctx(ctx),
1368 dst.with_ctx(ctx),
1369 count.with_ctx(ctx),
1370 ),
1371 RawStatement::StorageLive(var_id) => {
1372 write!(f, "storage_live({})", var_id.with_ctx(ctx))
1373 }
1374 RawStatement::StorageDead(var_id) => {
1375 write!(f, "storage_dead({})", var_id.with_ctx(ctx))
1376 }
1377 RawStatement::Deinit(place) => {
1378 write!(f, "deinit({})", place.with_ctx(ctx))
1379 }
1380 RawStatement::Drop(place, tref) => {
1381 write!(f, "drop[{}] {}", tref.with_ctx(ctx), place.with_ctx(ctx),)
1382 }
1383 RawStatement::Assert(assert) => {
1384 write!(f, "{}", assert.with_ctx(ctx),)
1385 }
1386 RawStatement::Call(call) => {
1387 write!(f, "{}", call.with_ctx(ctx))
1388 }
1389 RawStatement::Abort(kind) => {
1390 write!(f, "{}", kind.with_ctx(ctx))
1391 }
1392 RawStatement::Return => write!(f, "return"),
1393 RawStatement::Break(index) => write!(f, "break {index}"),
1394 RawStatement::Continue(index) => write!(f, "continue {index}"),
1395 RawStatement::Nop => write!(f, "nop"),
1396 RawStatement::Switch(switch) => match switch {
1397 Switch::If(discr, true_st, false_st) => {
1398 let ctx = &ctx.increase_indent();
1399 write!(
1400 f,
1401 "if {} {{\n{}{tab}}}\n{tab}else {{\n{}{tab}}}",
1402 discr.with_ctx(ctx),
1403 true_st.with_ctx(ctx),
1404 false_st.with_ctx(ctx),
1405 )
1406 }
1407 Switch::SwitchInt(discr, _ty, maps, otherwise) => {
1408 writeln!(f, "switch {} {{", discr.with_ctx(ctx))?;
1409 let ctx1 = &ctx.increase_indent();
1410 let inner_tab1 = ctx1.indent();
1411 let ctx2 = &ctx1.increase_indent();
1412 for (pvl, st) in maps {
1413 let pvl = pvl.iter().format(" | ");
1415 writeln!(
1416 f,
1417 "{inner_tab1}{} => {{\n{}{inner_tab1}}},",
1418 pvl,
1419 st.with_ctx(ctx2),
1420 )?;
1421 }
1422 writeln!(
1423 f,
1424 "{inner_tab1}_ => {{\n{}{inner_tab1}}},",
1425 otherwise.with_ctx(ctx2),
1426 )?;
1427 write!(f, "{tab}}}")
1428 }
1429 Switch::Match(discr, maps, otherwise) => {
1430 writeln!(f, "match {} {{", discr.with_ctx(ctx))?;
1431 let ctx1 = &ctx.increase_indent();
1432 let inner_tab1 = ctx1.indent();
1433 let ctx2 = &ctx1.increase_indent();
1434 let discr_type: Option<TypeDeclId> = discr
1435 .ty
1436 .kind()
1437 .as_adt()
1438 .and_then(|tref| tref.id.as_adt())
1439 .copied();
1440 for (cases, st) in maps {
1441 write!(f, "{inner_tab1}",)?;
1442 for (bar, v) in repeat_except_first(" | ").zip(cases.iter()) {
1444 write!(f, "{}", bar.unwrap_or_default())?;
1445 match discr_type {
1446 Some(type_id) => ctx.format_enum_variant(f, type_id, *v)?,
1447 None => write!(f, "{}", v.to_pretty_string())?,
1448 }
1449 }
1450 writeln!(f, " => {{\n{}{inner_tab1}}},", st.with_ctx(ctx2),)?;
1451 }
1452 if let Some(otherwise) = otherwise {
1453 writeln!(
1454 f,
1455 "{inner_tab1}_ => {{\n{}{inner_tab1}}},",
1456 otherwise.with_ctx(ctx2),
1457 )?;
1458 }
1459 write!(f, "{tab}}}")
1460 }
1461 },
1462 RawStatement::Loop(body) => {
1463 let ctx = &ctx.increase_indent();
1464 write!(f, "loop {{\n{}{tab}}}", body.with_ctx(ctx))
1465 }
1466 RawStatement::Error(s) => write!(f, "@ERROR({})", s),
1467 }
1468 }
1469}
1470
1471impl<C: AstFormatter> FmtWithCtx<C> for Terminator {
1472 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1473 let tab = ctx.indent();
1474 for line in &self.comments_before {
1475 writeln!(f, "{tab}// {line}")?;
1476 }
1477 write!(f, "{tab}")?;
1478 match &self.content {
1479 RawTerminator::Goto { target } => write!(f, "goto bb{target}"),
1480 RawTerminator::Switch { discr, targets } => match targets {
1481 SwitchTargets::If(true_block, false_block) => write!(
1482 f,
1483 "if {} -> bb{} else -> bb{}",
1484 discr.with_ctx(ctx),
1485 true_block,
1486 false_block
1487 ),
1488 SwitchTargets::SwitchInt(_ty, maps, otherwise) => {
1489 let maps = maps
1490 .iter()
1491 .map(|(v, bid)| format!("{}: bb{}", v.to_string(), bid))
1492 .chain([format!("otherwise: bb{otherwise}")])
1493 .format(", ");
1494 write!(f, "switch {} -> {}", discr.with_ctx(ctx), maps)
1495 }
1496 },
1497 RawTerminator::Call {
1498 call,
1499 target,
1500 on_unwind,
1501 } => {
1502 let call = call.with_ctx(ctx);
1503 write!(f, "{call} -> bb{target} (unwind: bb{on_unwind})",)
1504 }
1505 RawTerminator::Abort(kind) => write!(f, "{}", kind.with_ctx(ctx)),
1506 RawTerminator::Return => write!(f, "return"),
1507 RawTerminator::UnwindResume => write!(f, "unwind_continue"),
1508 }
1509 }
1510}
1511
1512impl<C: AstFormatter> FmtWithCtx<C> for TraitClause {
1513 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1514 let clause_id = self.clause_id.to_pretty_string();
1515 let trait_ = self.trait_.with_ctx(ctx);
1516 write!(f, "[{clause_id}]: {trait_}")
1517 }
1518}
1519
1520impl<C: AstFormatter> FmtWithCtx<C> for TraitDecl {
1521 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1522 let ctx = &ctx.set_generics(&self.generics);
1524
1525 self.item_meta
1526 .fmt_item_intro(f, ctx, "trait", self.def_id)?;
1527
1528 let (generics, clauses) = self.generics.fmt_with_ctx_with_trait_clauses(ctx);
1529 write!(f, "{generics}{clauses}")?;
1530
1531 let any_item = !self.parent_clauses.is_empty()
1532 || !self.type_clauses.is_empty()
1533 || !self.consts.is_empty()
1534 || !self.types.is_empty()
1535 || self.methods().count() > 0;
1536 if any_item {
1537 write!(f, "\n{{\n")?;
1538 for c in &self.parent_clauses {
1539 writeln!(
1540 f,
1541 "{TAB_INCR}parent_clause{} : {}",
1542 c.clause_id,
1543 c.with_ctx(ctx)
1544 )?;
1545 }
1546 for (name, clauses) in &self.type_clauses {
1547 for c in clauses {
1548 writeln!(
1549 f,
1550 "{TAB_INCR}item_clause_{name}_{} : {}",
1551 c.clause_id.to_string(),
1552 c.with_ctx(ctx)
1553 )?;
1554 }
1555 }
1556 for (name, ty) in &self.consts {
1557 let ty = ty.with_ctx(ctx);
1558 writeln!(f, "{TAB_INCR}const {name} : {ty}")?;
1559 }
1560 for name in &self.types {
1561 writeln!(f, "{TAB_INCR}type {name}")?;
1562 }
1563 for (name, bound_fn) in self.methods() {
1564 let (params, fn_ref) = bound_fn.fmt_split(ctx);
1565 writeln!(f, "{TAB_INCR}fn {name}{params} = {fn_ref}")?;
1566 }
1567 if let Some(vtb_ref) = &self.vtable {
1568 writeln!(f, "{TAB_INCR}vtable: {}", vtb_ref.with_ctx(ctx))?;
1569 } else {
1570 writeln!(f, "{TAB_INCR}non-dyn-compatible")?;
1571 }
1572 write!(f, "}}")?;
1573 }
1574 Ok(())
1575 }
1576}
1577
1578impl<C: AstFormatter> FmtWithCtx<C> for TraitDeclId {
1579 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1580 AnyTransId::from(*self).fmt_with_ctx(ctx, f)
1581 }
1582}
1583
1584impl<C: AstFormatter> FmtWithCtx<C> for TraitDeclRef {
1585 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1586 let trait_id = self.id.with_ctx(ctx);
1587 let generics = self.generics.with_ctx(ctx);
1588 write!(f, "{trait_id}{generics}")
1589 }
1590}
1591
1592impl<C: AstFormatter> FmtWithCtx<C> for TraitImpl {
1593 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1594 let full_name = self.item_meta.name.with_ctx(ctx);
1595 writeln!(f, "// Full name: {full_name}")?;
1596
1597 let ctx = &ctx.set_generics(&self.generics);
1599
1600 let (generics, clauses) = self.generics.fmt_with_ctx_with_trait_clauses(ctx);
1601 write!(f, "impl{generics} ")?;
1602 let mut impl_trait = self.impl_trait.clone();
1603 match impl_trait
1604 .generics
1605 .types
1606 .remove_and_shift_ids(TypeVarId::ZERO)
1607 {
1608 Some(self_ty) => {
1609 let self_ty = self_ty.with_ctx(ctx);
1610 let impl_trait = impl_trait.with_ctx(ctx);
1611 write!(f, "{impl_trait} for {self_ty}")?;
1612 }
1613 None => {
1615 let impl_trait = impl_trait.with_ctx(ctx);
1616 write!(f, "{impl_trait}")?;
1617 }
1618 }
1619 write!(f, "{clauses}")?;
1620
1621 let newline = if clauses.is_empty() {
1622 " ".to_string()
1623 } else {
1624 "\n".to_string()
1625 };
1626 write!(f, "{newline}{{")?;
1627
1628 let any_item = !self.parent_trait_refs.is_empty()
1629 || !self.type_clauses.is_empty()
1630 || !self.consts.is_empty()
1631 || !self.types.is_empty()
1632 || self.methods().count() > 0;
1633 if any_item {
1634 writeln!(f)?;
1635 for (i, c) in self.parent_trait_refs.iter().enumerate() {
1636 let i = TraitClauseId::new(i);
1637 writeln!(f, "{TAB_INCR}parent_clause{i} = {}", c.with_ctx(ctx))?;
1638 }
1639 for (name, clauses) in &self.type_clauses {
1640 for (i, c) in clauses.iter().enumerate() {
1641 let i = TraitClauseId::new(i);
1642 writeln!(f, "{TAB_INCR}item_clause_{name}_{i} = {}", c.with_ctx(ctx))?;
1643 }
1644 }
1645 for (name, global) in &self.consts {
1646 writeln!(f, "{TAB_INCR}const {name} = {}", global.with_ctx(ctx))?;
1647 }
1648 for (name, ty) in &self.types {
1649 writeln!(f, "{TAB_INCR}type {name} = {}", ty.with_ctx(ctx))?;
1650 }
1651 for (name, bound_fn) in self.methods() {
1652 let (params, fn_ref) = bound_fn.fmt_split(ctx);
1653 writeln!(f, "{TAB_INCR}fn {name}{params} = {fn_ref}")?;
1654 }
1655 }
1656 if let Some(vtb_ref) = &self.vtable {
1657 writeln!(f, "{TAB_INCR}vtable: {}", vtb_ref.with_ctx(ctx))?;
1658 } else {
1659 writeln!(f, "{TAB_INCR}non-dyn-compatible")?;
1660 }
1661 write!(f, "}}")?;
1662 Ok(())
1663 }
1664}
1665
1666impl<C: AstFormatter> FmtWithCtx<C> for TraitImplId {
1667 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1668 AnyTransId::from(*self).fmt_with_ctx(ctx, f)
1669 }
1670}
1671
1672impl<C: AstFormatter> FmtWithCtx<C> for TraitImplRef {
1673 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1674 let id = self.id.with_ctx(ctx);
1675 let generics = self.generics.with_ctx(ctx);
1676 write!(f, "{id}{generics}")
1677 }
1678}
1679
1680impl Display for TraitItemName {
1681 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> std::result::Result<(), fmt::Error> {
1682 write!(f, "{}", self.0)
1683 }
1684}
1685
1686impl<C: AstFormatter> FmtWithCtx<C> for TraitRefKind {
1687 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1688 match self {
1689 TraitRefKind::SelfId => write!(f, "Self"),
1690 TraitRefKind::ParentClause(sub, clause_id) => {
1691 let sub = sub.with_ctx(ctx);
1692 write!(f, "{sub}::parent_clause{clause_id}")
1693 }
1694 TraitRefKind::ItemClause(sub, type_name, clause_id) => {
1695 let sub = sub.with_ctx(ctx);
1696 let clause = clause_id.to_pretty_string();
1699 write!(f, "({sub}::{type_name}::[{clause}])")
1700 }
1701 TraitRefKind::TraitImpl(impl_ref) => {
1702 write!(f, "{}", impl_ref.with_ctx(ctx))
1703 }
1704 TraitRefKind::Clause(id) => write!(f, "{}", id.with_ctx(ctx)),
1705 TraitRefKind::BuiltinOrAuto {
1706 trait_decl_ref: tr,
1707 types,
1708 ..
1709 } => {
1710 write!(f, "{}", tr.with_ctx(ctx))?;
1711 if !types.is_empty() {
1712 let types = types
1713 .iter()
1714 .map(|(name, ty, _)| {
1715 let ty = ty.with_ctx(ctx);
1716 format!("{name} = {ty}")
1717 })
1718 .join(", ");
1719 write!(f, " where {types}")?;
1720 }
1721 Ok(())
1722 }
1723 TraitRefKind::Dyn(tr) => write!(f, "{}", tr.with_ctx(ctx)),
1724 TraitRefKind::Unknown(msg) => write!(f, "UNKNOWN({msg})"),
1725 }
1726 }
1727}
1728
1729impl<C: AstFormatter> FmtWithCtx<C> for TraitRef {
1730 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1731 self.kind.fmt_with_ctx(ctx, f)
1732 }
1733}
1734
1735impl<C: AstFormatter> FmtWithCtx<C> for TraitTypeConstraint {
1736 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1737 let trait_ref = self.trait_ref.with_ctx(ctx);
1738 let ty = self.ty.with_ctx(ctx);
1739 write!(f, "{}::{} = {}", trait_ref, self.type_name, ty)
1740 }
1741}
1742
1743impl<C: AstFormatter> FmtWithCtx<C> for RegionBinder<(Vec<Ty>, Ty)> {
1744 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1745 let ctx = &ctx.push_bound_regions(&self.regions);
1747
1748 write!(f, "fn")?;
1749 if !self.regions.is_empty() {
1750 write!(
1751 f,
1752 "<{}>",
1753 self.regions.iter().map(|r| r.with_ctx(ctx)).format(", ")
1754 )?;
1755 }
1756 let (inputs, output) = &self.skip_binder;
1757 let inputs = inputs.iter().map(|x| x.with_ctx(ctx)).format(", ");
1758 write!(f, "({inputs})")?;
1759 if !output.is_unit() {
1760 let output = output.with_ctx(ctx);
1761 write!(f, " -> {output}")?;
1762 }
1763 Ok(())
1764 }
1765}
1766
1767impl<C: AstFormatter> FmtWithCtx<C> for Ty {
1768 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1769 match self.kind() {
1770 TyKind::Adt(tref) => {
1771 if tref.id.is_tuple() {
1772 assert!(tref.generics.trait_refs.is_empty());
1773 let generics = tref.generics.fmt_explicits(ctx).format(", ");
1774 write!(f, "({generics})")
1775 } else {
1776 write!(f, "{}", tref.with_ctx(ctx))
1777 }
1778 }
1779 TyKind::TypeVar(id) => write!(f, "{}", id.with_ctx(ctx)),
1780 TyKind::Literal(kind) => write!(f, "{kind}"),
1781 TyKind::Never => write!(f, "!"),
1782 TyKind::Ref(r, ty, kind) => {
1783 write!(f, "&{} ", r.with_ctx(ctx))?;
1784 if let RefKind::Mut = kind {
1785 write!(f, "mut ")?;
1786 }
1787 write!(f, "({})", ty.with_ctx(ctx))
1788 }
1789 TyKind::RawPtr(ty, kind) => {
1790 write!(f, "*")?;
1791 match kind {
1792 RefKind::Shared => write!(f, "const")?,
1793 RefKind::Mut => write!(f, "mut")?,
1794 }
1795 write!(f, " {}", ty.with_ctx(ctx))
1796 }
1797 TyKind::TraitType(trait_ref, name) => {
1798 write!(f, "{}::{name}", trait_ref.with_ctx(ctx),)
1799 }
1800 TyKind::DynTrait(pred) => {
1801 write!(f, "(dyn {})", pred.with_ctx(ctx))
1802 }
1803 TyKind::FnPtr(io) => {
1804 write!(f, "{}", io.with_ctx(ctx))
1805 }
1806 TyKind::FnDef(binder) => {
1807 let (regions, value) = binder.fmt_split(ctx);
1808 if !regions.is_empty() {
1809 write!(f, "for<{regions}> ",)?
1810 };
1811 write!(f, "{value}",)
1812 }
1813 TyKind::Error(msg) => write!(f, "type_error(\"{msg}\")"),
1814 }
1815 }
1816}
1817
1818impl<C: AstFormatter> FmtWithCtx<C> for TypeDbVar {
1819 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1820 ctx.format_bound_var(f, *self, "@Type", |v| Some(v.to_string()))
1821 }
1822}
1823
1824impl<C: AstFormatter> FmtWithCtx<C> for TypeDecl {
1825 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1826 let keyword = match &self.kind {
1827 TypeDeclKind::Struct(..) => "struct",
1828 TypeDeclKind::Union(..) => "union",
1829 TypeDeclKind::Enum(..) => "enum",
1830 TypeDeclKind::Alias(..) => "type",
1831 TypeDeclKind::Opaque | TypeDeclKind::Error(..) => "opaque type",
1832 };
1833 self.item_meta
1834 .fmt_item_intro(f, ctx, keyword, self.def_id)?;
1835
1836 let ctx = &ctx.set_generics(&self.generics);
1837 let (params, preds) = self.generics.fmt_with_ctx_with_trait_clauses(ctx);
1838 write!(f, "{params}{preds}")?;
1839
1840 let nl_or_space = if !self.generics.has_predicates() {
1841 " ".to_string()
1842 } else {
1843 "\n".to_string()
1844 };
1845 match &self.kind {
1846 TypeDeclKind::Struct(fields) => {
1847 write!(f, "{nl_or_space}{{")?;
1848 if !fields.is_empty() {
1849 writeln!(f)?;
1850 for field in fields {
1851 writeln!(f, " {},", field.with_ctx(ctx))?;
1852 }
1853 }
1854 write!(f, "}}")
1855 }
1856 TypeDeclKind::Union(fields) => {
1857 write!(f, "{nl_or_space}{{")?;
1858 writeln!(f)?;
1859 for field in fields {
1860 writeln!(f, " {},", field.with_ctx(ctx))?;
1861 }
1862 write!(f, "}}")
1863 }
1864 TypeDeclKind::Enum(variants) => {
1865 write!(f, "{nl_or_space}{{")?;
1866 writeln!(f)?;
1867 for variant in variants {
1868 writeln!(f, " {},", variant.with_ctx(ctx))?;
1869 }
1870 write!(f, "}}")
1871 }
1872 TypeDeclKind::Alias(ty) => write!(f, " = {}", ty.with_ctx(ctx)),
1873 TypeDeclKind::Opaque => write!(f, ""),
1874 TypeDeclKind::Error(msg) => write!(f, " = ERROR({msg})"),
1875 }
1876 }
1877}
1878
1879impl<C: AstFormatter> FmtWithCtx<C> for TypeDeclId {
1880 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1881 AnyTransId::from(*self).fmt_with_ctx(ctx, f)
1882 }
1883}
1884
1885impl<C: AstFormatter> FmtWithCtx<C> for TypeDeclRef {
1886 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1887 let id = self.id.with_ctx(ctx);
1888 let generics = self.generics.with_ctx(ctx);
1889 write!(f, "{id}{generics}")
1890 }
1891}
1892
1893impl<C: AstFormatter> FmtWithCtx<C> for TypeId {
1894 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1895 match self {
1896 TypeId::Tuple => Ok(()),
1897 TypeId::Adt(def_id) => write!(f, "{}", def_id.with_ctx(ctx)),
1898 TypeId::Builtin(aty) => write!(f, "{}", aty.get_name().with_ctx(ctx)),
1899 }
1900 }
1901}
1902
1903impl_display_via_ctx!(TypeVar);
1904impl<C: AstFormatter> FmtWithCtx<C> for TypeVar {
1905 fn fmt_with_ctx(&self, _ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1906 write!(f, "{}", self.name)
1907 }
1908}
1909
1910impl<C: AstFormatter> FmtWithCtx<C> for UnOp {
1911 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1912 match self {
1913 UnOp::Not => write!(f, "~"),
1914 UnOp::Neg(mode) => write!(f, "{}.-", mode),
1915 UnOp::PtrMetadata => write!(f, "ptr_metadata"),
1916 UnOp::Cast(kind) => write!(f, "{}", kind.with_ctx(ctx)),
1917 }
1918 }
1919}
1920
1921impl_display_via_ctx!(Variant);
1922impl<C: AstFormatter> FmtWithCtx<C> for Variant {
1923 fn fmt_with_ctx(&self, ctx: &C, f: &mut fmt::Formatter<'_>) -> fmt::Result {
1924 write!(f, "{}", self.name)?;
1925 if !self.fields.is_empty() {
1926 let fields = self.fields.iter().map(|f| f.with_ctx(ctx)).format(", ");
1927 write!(f, "({})", fields)?;
1928 }
1929 Ok(())
1930 }
1931}