cl_ast/ast_impl/
display.rs

1//! Implements [Display] for [AST](super::super) Types
2
3use super::*;
4use format::{delimiters::*, *};
5use std::{
6    borrow::Borrow,
7    fmt::{Display, Write},
8};
9
10fn separate<I: Display, W: Write>(
11    iterable: impl IntoIterator<Item = I>,
12    sep: &'static str,
13) -> impl FnOnce(W) -> std::fmt::Result {
14    move |mut f| {
15        for (idx, item) in iterable.into_iter().enumerate() {
16            if idx > 0 {
17                f.write_str(sep)?;
18            }
19            write!(f, "{item}")?;
20        }
21        Ok(())
22    }
23}
24
25impl Display for Mutability {
26    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
27        match self {
28            Mutability::Not => Ok(()),
29            Mutability::Mut => "mut ".fmt(f),
30        }
31    }
32}
33
34impl Display for Visibility {
35    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
36        match self {
37            Visibility::Private => Ok(()),
38            Visibility::Public => "pub ".fmt(f),
39        }
40    }
41}
42
43impl Display for Literal {
44    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
45        match self {
46            Literal::Bool(v) => v.fmt(f),
47            Literal::Char(v) => write!(f, "'{}'", v.escape_debug()),
48            Literal::Int(v) => v.fmt(f),
49            Literal::Float(v) => write!(f, "{:?}", f64::from_bits(*v)),
50            Literal::String(v) => write!(f, "\"{}\"", v.escape_debug()),
51        }
52    }
53}
54
55impl Display for File {
56    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
57        separate(&self.items, "\n\n")(f)
58    }
59}
60
61impl Display for Attrs {
62    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
63        let Self { meta } = self;
64        if meta.is_empty() {
65            return Ok(());
66        }
67        "#".fmt(f)?;
68        separate(meta, ", ")(&mut f.delimit(INLINE_SQUARE))?;
69        "\n".fmt(f)
70    }
71}
72
73impl Display for Meta {
74    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
75        let Self { name, kind } = self;
76        write!(f, "{name}{kind}")
77    }
78}
79
80impl Display for MetaKind {
81    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
82        match self {
83            MetaKind::Plain => Ok(()),
84            MetaKind::Equals(v) => write!(f, " = {v}"),
85            MetaKind::Func(args) => separate(args, ", ")(f.delimit(INLINE_PARENS)),
86        }
87    }
88}
89
90impl Display for Item {
91    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
92        let Self { span: _, attrs, vis, kind } = self;
93        attrs.fmt(f)?;
94        vis.fmt(f)?;
95        kind.fmt(f)
96    }
97}
98
99impl Display for ItemKind {
100    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
101        match self {
102            ItemKind::Alias(v) => v.fmt(f),
103            ItemKind::Const(v) => v.fmt(f),
104            ItemKind::Static(v) => v.fmt(f),
105            ItemKind::Module(v) => v.fmt(f),
106            ItemKind::Function(v) => v.fmt(f),
107            ItemKind::Struct(v) => v.fmt(f),
108            ItemKind::Enum(v) => v.fmt(f),
109            ItemKind::Impl(v) => v.fmt(f),
110            ItemKind::Use(v) => v.fmt(f),
111        }
112    }
113}
114
115impl Display for Generics {
116    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
117        let Generics { vars } = self;
118        if !vars.is_empty() {
119            separate(vars, ", ")(f.delimit_with("<", ">"))?
120        }
121        Ok(())
122    }
123}
124
125impl Display for Alias {
126    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
127        let Self { name, from } = self;
128        match from {
129            Some(from) => write!(f, "type {name} = {from};"),
130            None => write!(f, "type {name};"),
131        }
132    }
133}
134
135impl Display for Const {
136    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
137        let Self { name, ty, init } = self;
138        write!(f, "const {name}: {ty} = {init}")
139    }
140}
141
142impl Display for Static {
143    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
144        let Self { mutable, name, ty, init } = self;
145        write!(f, "static {mutable}{name}: {ty} = {init}")
146    }
147}
148
149impl Display for Module {
150    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
151        let Self { name, file } = self;
152        write!(f, "mod {name}")?;
153        match file {
154            Some(items) => {
155                ' '.fmt(f)?;
156                write!(f.delimit(BRACES), "{items}")
157            }
158            None => Ok(()),
159        }
160    }
161}
162
163impl Display for Function {
164    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
165        let Self { name, gens, sign: sign @ TyFn { args, rety }, bind, body } = self;
166        let types = match args.kind {
167            TyKind::Tuple(TyTuple { ref types }) => types.as_slice(),
168            _ => {
169                write!(f, "Invalid function signature: {sign}")?;
170                Default::default()
171            }
172        };
173        let bind = match bind {
174            Pattern::Tuple(patterns) => patterns.as_slice(),
175            _ => {
176                write!(f, "Invalid argument binder: {bind}")?;
177                Default::default()
178            }
179        };
180
181        debug_assert_eq!(bind.len(), types.len());
182        write!(f, "fn {name}{gens} ")?;
183        {
184            let mut f = f.delimit(INLINE_PARENS);
185
186            for (idx, (arg, ty)) in bind.iter().zip(types.iter()).enumerate() {
187                if idx != 0 {
188                    f.write_str(", ")?;
189                }
190                write!(f, "{arg}: {ty}")?;
191            }
192        }
193        if let TyKind::Tuple(TyTuple { types }) = &rety.kind
194            && !types.as_slice().is_empty()
195        {
196            write!(f, " -> {rety}")?
197        }
198
199        match body {
200            Some(body) => write!(f, " {body}"),
201            None => ';'.fmt(f),
202        }
203    }
204}
205
206impl Display for Struct {
207    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
208        let Self { name, gens, kind } = self;
209        write!(f, "struct {name}{gens}{kind}")
210    }
211}
212
213impl Display for StructKind {
214    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
215        match self {
216            StructKind::Empty => ';'.fmt(f),
217            StructKind::Tuple(v) => separate(v, ", ")(f.delimit(INLINE_PARENS)),
218            StructKind::Struct(v) => separate(v, ",\n")(f.delimit(SPACED_BRACES)),
219        }
220    }
221}
222
223impl Display for StructMember {
224    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
225        let Self { vis, name, ty } = self;
226        write!(f, "{vis}{name}: {ty}")
227    }
228}
229
230impl Display for Enum {
231    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232        let Self { name, gens, variants } = self;
233        write!(f, "enum {name}{gens}")?;
234        separate(variants, ",\n")(f.delimit(SPACED_BRACES))
235    }
236}
237
238impl Display for Variant {
239    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
240        let Self { name, kind, body } = self;
241        write!(f, "{name}{kind}")?;
242        match body {
243            Some(body) => write!(f, " {body}"),
244            None => Ok(()),
245        }
246    }
247}
248
249impl Display for Impl {
250    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
251        let Self { gens, target, body } = self;
252        write!(f, "impl{gens} {target} ")?;
253        write!(f.delimit(BRACES), "{body}")
254    }
255}
256
257impl Display for ImplKind {
258    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
259        match self {
260            ImplKind::Type(t) => t.fmt(f),
261            ImplKind::Trait { impl_trait, for_type } => {
262                write!(f, "{impl_trait} for {for_type}")
263            }
264        }
265    }
266}
267
268impl Display for Use {
269    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
270        let Self { absolute, tree } = self;
271        f.write_str(if *absolute { "use ::" } else { "use " })?;
272        write!(f, "{tree};")
273    }
274}
275
276impl Display for UseTree {
277    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
278        match self {
279            UseTree::Tree(tree) => separate(tree, ", ")(f.delimit(INLINE_BRACES)),
280            UseTree::Path(path, rest) => write!(f, "{path}::{rest}"),
281            UseTree::Alias(path, name) => write!(f, "{path} as {name}"),
282            UseTree::Name(name) => write!(f, "{name}"),
283            UseTree::Glob => write!(f, "*"),
284        }
285    }
286}
287
288impl Display for Ty {
289    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
290        let Self { span: _, kind, gens } = self;
291        write!(f, "{kind}{gens}")
292    }
293}
294
295impl Display for TyKind {
296    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
297        match self {
298            TyKind::Never => "!".fmt(f),
299            TyKind::Infer => "_".fmt(f),
300            TyKind::Path(v) => v.fmt(f),
301            TyKind::Array(v) => v.fmt(f),
302            TyKind::Slice(v) => v.fmt(f),
303            TyKind::Tuple(v) => v.fmt(f),
304            TyKind::Ref(v) => v.fmt(f),
305            TyKind::Ptr(v) => v.fmt(f),
306            TyKind::Fn(v) => v.fmt(f),
307        }
308    }
309}
310
311impl Display for TyArray {
312    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
313        let Self { ty, count } = self;
314        write!(f, "[{ty}; {count}]")
315    }
316}
317
318impl Display for TySlice {
319    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
320        let Self { ty } = self;
321        write!(f, "[{ty}]")
322    }
323}
324
325impl Display for TyTuple {
326    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
327        separate(&self.types, ", ")(f.delimit(INLINE_PARENS))
328    }
329}
330
331impl Display for TyRef {
332    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
333        let &Self { count, mutable, ref to } = self;
334        for _ in 0..count {
335            f.write_char('&')?;
336        }
337        write!(f, "{mutable}{to}")
338    }
339}
340
341impl Display for TyPtr {
342    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
343        let Self { to } = self;
344        write!(f, "*{to}")
345    }
346}
347
348impl Display for TyFn {
349    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
350        let Self { args, rety } = self;
351        write!(f, "fn {args}")?;
352        if let TyKind::Tuple(TyTuple { types }) = &rety.kind
353            && !types.as_slice().is_empty()
354        {
355            write!(f, " -> {rety}")?
356        }
357        Ok(())
358    }
359}
360
361impl Display for Path {
362    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
363        let Self { absolute, parts } = self;
364        if *absolute {
365            "::".fmt(f)?;
366        }
367        separate(parts, "::")(f)
368    }
369}
370
371impl Display for PathPart {
372    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
373        match self {
374            PathPart::SuperKw => "super".fmt(f),
375            PathPart::SelfTy => "Self".fmt(f),
376            PathPart::Ident(id) => id.fmt(f),
377        }
378    }
379}
380
381impl Display for Stmt {
382    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
383        let Stmt { span: _, kind, semi } = self;
384        write!(f, "{kind}{semi}")
385    }
386}
387
388impl Display for StmtKind {
389    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
390        match self {
391            StmtKind::Empty => Ok(()),
392            StmtKind::Item(v) => v.fmt(f),
393            StmtKind::Expr(v) => v.fmt(f),
394        }
395    }
396}
397
398impl Display for Semi {
399    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
400        match self {
401            Semi::Terminated => ';'.fmt(f),
402            Semi::Unterminated => Ok(()),
403        }
404    }
405}
406
407impl Display for Expr {
408    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
409        self.kind.fmt(f)
410    }
411}
412
413impl Display for ExprKind {
414    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
415        match self {
416            ExprKind::Empty => "()".fmt(f),
417            ExprKind::Closure(v) => v.fmt(f),
418            ExprKind::Quote(v) => v.fmt(f),
419            ExprKind::Let(v) => v.fmt(f),
420            ExprKind::Match(v) => v.fmt(f),
421            ExprKind::Assign(v) => v.fmt(f),
422            ExprKind::Modify(v) => v.fmt(f),
423            ExprKind::Binary(v) => v.fmt(f),
424            ExprKind::Unary(v) => v.fmt(f),
425            ExprKind::Cast(v) => v.fmt(f),
426            ExprKind::Member(v) => v.fmt(f),
427            ExprKind::Index(v) => v.fmt(f),
428            ExprKind::Structor(v) => v.fmt(f),
429            ExprKind::Path(v) => v.fmt(f),
430            ExprKind::Literal(v) => v.fmt(f),
431            ExprKind::Array(v) => v.fmt(f),
432            ExprKind::ArrayRep(v) => v.fmt(f),
433            ExprKind::AddrOf(v) => v.fmt(f),
434            ExprKind::Block(v) => v.fmt(f),
435            ExprKind::Group(v) => v.fmt(f),
436            ExprKind::Tuple(v) => v.fmt(f),
437            ExprKind::While(v) => v.fmt(f),
438            ExprKind::If(v) => v.fmt(f),
439            ExprKind::For(v) => v.fmt(f),
440            ExprKind::Break(v) => v.fmt(f),
441            ExprKind::Return(v) => v.fmt(f),
442            ExprKind::Continue => "continue".fmt(f),
443        }
444    }
445}
446
447impl Display for Closure {
448    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
449        let Self { arg, body } = self;
450        match arg.as_ref() {
451            Pattern::Tuple(args) => separate(args, ", ")(f.delimit_with("|", "|")),
452            _ => arg.fmt(f),
453        }?;
454        write!(f, " {body}")
455    }
456}
457
458impl Display for Quote {
459    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
460        let Self { quote } = self;
461        write!(f, "`{quote}`")
462    }
463}
464
465impl Display for Let {
466    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
467        let Self { mutable, name, ty, init } = self;
468        write!(f, "let {mutable}{name}")?;
469        if let Some(value) = ty {
470            write!(f, ": {value}")?;
471        }
472        if let Some(value) = init {
473            write!(f, " = {value}")?;
474        }
475        Ok(())
476    }
477}
478
479impl Display for Pattern {
480    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
481        match self {
482            Pattern::Name(sym) => sym.fmt(f),
483            Pattern::Path(path) => path.fmt(f),
484            Pattern::Literal(literal) => literal.fmt(f),
485            Pattern::Rest(Some(name)) => write!(f, "..{name}"),
486            Pattern::Rest(None) => "..".fmt(f),
487            Pattern::Ref(mutability, pattern) => write!(f, "&{mutability}{pattern}"),
488            Pattern::RangeExc(head, tail) => write!(f, "{head}..{tail}"),
489            Pattern::RangeInc(head, tail) => write!(f, "{head}..={tail}"),
490            Pattern::Tuple(patterns) => separate(patterns, ", ")(f.delimit(INLINE_PARENS)),
491            Pattern::Array(patterns) => separate(patterns, ", ")(f.delimit(INLINE_SQUARE)),
492            Pattern::Struct(path, items) => {
493                write!(f, "{path} ")?;
494                let f = &mut f.delimit(INLINE_BRACES);
495                for (idx, (name, item)) in items.iter().enumerate() {
496                    if idx != 0 {
497                        f.write_str(", ")?;
498                    }
499                    write!(f, "{name}")?;
500                    if let Some(pattern) = item {
501                        write!(f, ": {pattern}")?
502                    }
503                }
504                Ok(())
505            }
506            Pattern::TupleStruct(path, items) => {
507                write!(f, "{path}")?;
508                separate(items, ", ")(f.delimit(INLINE_PARENS))
509            }
510        }
511    }
512}
513
514impl Display for Match {
515    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
516        let Self { scrutinee, arms } = self;
517        write!(f, "match {scrutinee} ")?;
518        separate(arms, ",\n")(f.delimit(BRACES))
519    }
520}
521
522impl Display for MatchArm {
523    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
524        let Self(pat, expr) = self;
525        write!(f, "{pat} => {expr}")
526    }
527}
528
529impl Display for Assign {
530    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
531        let Self { parts } = self;
532        write!(f, "{} = {}", parts.0, parts.1)
533    }
534}
535
536impl Display for Modify {
537    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
538        let Self { kind, parts } = self;
539        write!(f, "{} {kind} {}", parts.0, parts.1)
540    }
541}
542
543impl Display for ModifyKind {
544    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
545        match self {
546            ModifyKind::Mul => "*=",
547            ModifyKind::Div => "/=",
548            ModifyKind::Rem => "%=",
549            ModifyKind::Add => "+=",
550            ModifyKind::Sub => "-=",
551            ModifyKind::And => "&=",
552            ModifyKind::Or => "|=",
553            ModifyKind::Xor => "^=",
554            ModifyKind::Shl => "<<=",
555            ModifyKind::Shr => ">>=",
556        }
557        .fmt(f)
558    }
559}
560
561impl Display for Binary {
562    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
563        let Self { kind, parts } = self;
564        let (head, tail) = parts.borrow();
565        match kind {
566            BinaryKind::Call => write!(f, "{head}{tail}"),
567            _ => write!(f, "{head} {kind} {tail}"),
568        }
569    }
570}
571
572impl Display for BinaryKind {
573    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
574        match self {
575            BinaryKind::Lt => "<",
576            BinaryKind::LtEq => "<=",
577            BinaryKind::Equal => "==",
578            BinaryKind::NotEq => "!=",
579            BinaryKind::GtEq => ">=",
580            BinaryKind::Gt => ">",
581            BinaryKind::RangeExc => "..",
582            BinaryKind::RangeInc => "..=",
583            BinaryKind::LogAnd => "&&",
584            BinaryKind::LogOr => "||",
585            BinaryKind::LogXor => "^^",
586            BinaryKind::BitAnd => "&",
587            BinaryKind::BitOr => "|",
588            BinaryKind::BitXor => "^",
589            BinaryKind::Shl => "<<",
590            BinaryKind::Shr => ">>",
591            BinaryKind::Add => "+",
592            BinaryKind::Sub => "-",
593            BinaryKind::Mul => "*",
594            BinaryKind::Div => "/",
595            BinaryKind::Rem => "%",
596            BinaryKind::Call => "()",
597        }
598        .fmt(f)
599    }
600}
601
602impl Display for Unary {
603    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
604        let Self { kind, tail } = self;
605        write!(f, "{kind}{tail}")
606    }
607}
608
609impl Display for UnaryKind {
610    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
611        match self {
612            UnaryKind::Loop => "loop ",
613            UnaryKind::Deref => "*",
614            UnaryKind::Neg => "-",
615            UnaryKind::Not => "!",
616            UnaryKind::RangeExc => "..",
617            UnaryKind::RangeInc => "..=",
618            UnaryKind::At => "@",
619            UnaryKind::Tilde => "~",
620        }
621        .fmt(f)
622    }
623}
624
625impl Display for Cast {
626    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
627        let Self { head, ty } = self;
628        write!(f, "{head} as {ty}")
629    }
630}
631
632impl Display for Member {
633    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
634        let Self { head, kind } = self;
635        write!(f, "{head}.{kind}")
636    }
637}
638
639impl Display for MemberKind {
640    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
641        match self {
642            MemberKind::Call(name, args) => write!(f, "{name}{args}"),
643            MemberKind::Struct(name) => write!(f, "{name}"),
644            MemberKind::Tuple(name) => write!(f, "{name}"),
645        }
646    }
647}
648
649impl Display for Index {
650    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
651        let Self { head, indices } = self;
652        write!(f, "{head}")?;
653        separate(indices, ", ")(f.delimit(INLINE_SQUARE))
654    }
655}
656
657impl Display for Structor {
658    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
659        let Self { to, init } = self;
660        write!(f, "{to} ")?;
661        separate(init, ", ")(f.delimit(INLINE_BRACES))
662    }
663}
664
665impl Display for Fielder {
666    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
667        let Self { name, init } = self;
668        write!(f, "{name}")?;
669        if let Some(init) = init {
670            write!(f, ": {init}")?;
671        }
672        Ok(())
673    }
674}
675
676impl Display for Array {
677    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
678        separate(&self.values, ", ")(f.delimit(INLINE_SQUARE))
679    }
680}
681
682impl Display for ArrayRep {
683    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
684        let Self { value, repeat } = self;
685        write!(f, "[{value}; {repeat}]")
686    }
687}
688
689impl Display for AddrOf {
690    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
691        let Self { mutable, expr } = self;
692        write!(f, "&{mutable}{expr}")
693    }
694}
695
696impl Display for Block {
697    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
698        let Self { stmts } = self;
699
700        match stmts.as_slice() {
701            [] => "{}".fmt(f),
702            stmts => separate(stmts, "\n")(f.delimit(BRACES)),
703        }
704    }
705}
706
707impl Display for Group {
708    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
709        write!(f, "({})", self.expr)
710    }
711}
712
713impl Display for Tuple {
714    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
715        let Self { exprs } = self;
716
717        match exprs.as_slice() {
718            [] => write!(f, "()"),
719            [expr] => write!(f, "({expr},)"),
720            exprs => separate(exprs, ", ")(f.delimit(INLINE_PARENS)),
721        }
722    }
723}
724
725impl Display for While {
726    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
727        let Self { cond, pass, fail } = self;
728        write!(f, "while {cond} {pass}{fail}")
729    }
730}
731
732impl Display for If {
733    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
734        let Self { cond, pass, fail } = self;
735        write!(f, "if {cond} {pass}{fail}")
736    }
737}
738
739impl Display for For {
740    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
741        let Self { bind, cond, pass, fail } = self;
742        write!(f, "for {bind} in {cond} {pass}{fail}")
743    }
744}
745
746impl Display for Else {
747    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
748        match &self.body {
749            Some(body) => write!(f, " else {body}"),
750            _ => Ok(()),
751        }
752    }
753}
754
755impl Display for Break {
756    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
757        write!(f, "break")?;
758        match &self.body {
759            Some(body) => write!(f, " {body}"),
760            _ => Ok(()),
761        }
762    }
763}
764
765impl Display for Return {
766    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
767        write!(f, "return")?;
768        match &self.body {
769            Some(body) => write!(f, " {body}"),
770            _ => Ok(()),
771        }
772    }
773}