cl_typeck/entry/
display.rs1use super::*;
2use crate::{format_utils::*, type_kind::Adt};
3use std::fmt::{self, Write};
4
5fn write_name_or(h: Entry, f: &mut impl Write) -> fmt::Result {
7    match h.name() {
8        Some(name) => write!(f, "{name}"),
9        None => write!(f, "{h}"),
10    }
11}
12
13impl fmt::Display for Entry<'_, '_> {
14    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
15        let Some(&kind) = self.kind() else {
16            return write!(f, "<invalid type: {}>", self.id);
17        };
18
19        if let Some(ty) = self.ty() {
20            match ty {
21                TypeKind::Inferred => write!(f, "<_{}>", self.id),
22                TypeKind::Variable => write!(f, "<?{}>", self.id),
23                TypeKind::Instance(id) => write!(f, "{}", self.with_id(*id)),
24                TypeKind::Primitive(kind) => write!(f, "{kind}"),
25                TypeKind::Adt(adt) => write_adt(adt, self, f),
26                &TypeKind::Ref(id) => {
27                    f.write_str("&")?;
28                    let h_id = self.with_id(id);
29                    write_name_or(h_id, f)
30                }
31                &TypeKind::Ptr(id) => {
32                    f.write_str("*")?;
33                    let h_id = self.with_id(id);
34                    write_name_or(h_id, f)
35                }
36                TypeKind::Slice(id) => {
37                    write_name_or(self.with_id(*id), &mut f.delimit_with("[", "]"))
38                }
39                &TypeKind::Array(t, cnt) => {
40                    let mut f = f.delimit_with("[", "]");
41                    write_name_or(self.with_id(t), &mut f)?;
42                    write!(f, "; {cnt}")
43                }
44                TypeKind::Tuple(ids) => {
45                    let mut f = f.delimit_with("(", ")");
46                    for (index, &id) in ids.iter().enumerate() {
47                        if index > 0 {
48                            write!(f, ", ")?;
49                        }
50                        write_name_or(self.with_id(id), &mut f)?;
51                    }
52                    Ok(())
53                }
54                TypeKind::FnSig { args, rety } => {
55                    write!(f, "fn {} -> ", self.with_id(*args))?;
56                    write_name_or(self.with_id(*rety), f)
57                }
58                TypeKind::Module => write!(f, "module?"),
59            }
60        } else {
61            match kind {
62                NodeKind::Type
63                | NodeKind::Const
64                | NodeKind::Static
65                | NodeKind::Temporary
66                | NodeKind::Let => write!(f, "WARNING: NO TYPE ASSIGNED FOR {}", self.id),
67                _ => write!(f, "{kind}"),
68            }
69        }
70    }
71}
72
73fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result {
74    match adt {
75        Adt::Enum(variants) => {
76            let mut variants = variants.iter();
77            separate(", ", || {
78                variants.next().map(|(name, def)| {
79                    move |f: &mut Delimit<_>| write!(f, "{name}: {}", h.with_id(*def))
80                })
81            })(f.delimit_with("enum {", "}"))
82        }
83        Adt::Struct(members) => {
84            let mut members = members.iter();
85            separate(", ", || {
86                let (name, vis, id) = members.next()?;
87                Some(move |f: &mut Delimit<_>| write!(f, "{vis}{name}: {}", h.with_id(*id)))
88            })(f.delimit_with("struct {", "}"))
89        }
90        Adt::TupleStruct(members) => {
91            let mut members = members.iter();
92            separate(", ", || {
93                let (vis, def) = members.next()?;
94                Some(move |f: &mut Delimit<_>| write!(f, "{vis}{}", h.with_id(*def)))
95            })(f.delimit_with("struct (", ")"))
96        }
97        Adt::UnitStruct => write!(f, "struct"),
98        Adt::Union(_) => todo!("Display union types"),
99    }
100}