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) => write_name_or(self.with_id(*id), &mut f.delimit("[", "]")),
37 &TypeKind::Array(t, cnt) => {
38 let mut f = f.delimit("[", "]");
39 write_name_or(self.with_id(t), &mut f)?;
40 write!(f, "; {cnt}")
41 }
42 TypeKind::Tuple(ids) => {
43 let mut f = f.delimit("(", ")");
44 for (index, &id) in ids.iter().enumerate() {
45 if index > 0 {
46 write!(f, ", ")?;
47 }
48 write_name_or(self.with_id(id), &mut f)?;
49 }
50 Ok(())
51 }
52 TypeKind::FnSig { args, rety } => {
53 write!(f, "fn {} -> ", self.with_id(*args))?;
54 write_name_or(self.with_id(*rety), f)
55 }
56 TypeKind::Module => write!(f, "module?"),
57 }
58 } else {
59 match kind {
60 NodeKind::Type
61 | NodeKind::Const
62 | NodeKind::Static
63 | NodeKind::Temporary
64 | NodeKind::Let => write!(f, "WARNING: NO TYPE ASSIGNED FOR {}", self.id),
65 _ => write!(f, "{kind}"),
66 }
67 }
68 }
69}
70
71fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result {
72 match adt {
73 Adt::Enum(variants) => {
74 let mut variants = variants.iter();
75 separate(", ", || {
76 variants.next().map(|(name, def)| {
77 move |f: &mut Delimit<_>| write!(f, "{name}: {}", h.with_id(*def))
78 })
79 })(f.delimit("enum {", "}"))
80 }
81 Adt::Struct(members) => {
82 let mut members = members.iter();
83 separate(", ", || {
84 let (name, vis, id) = members.next()?;
85 Some(move |f: &mut Delimit<_>| write!(f, "{vis}{name}: {}", h.with_id(*id)))
86 })(f.delimit("struct {", "}"))
87 }
88 Adt::TupleStruct(members) => {
89 let mut members = members.iter();
90 separate(", ", || {
91 let (vis, def) = members.next()?;
92 Some(move |f: &mut Delimit<_>| write!(f, "{vis}{}", h.with_id(*def)))
93 })(f.delimit("struct (", ")"))
94 }
95 Adt::UnitStruct => write!(f, "struct"),
96 Adt::Union(_) => todo!("Display union types"),
97 }
98}