cl_typeck/entry/
display.rs

1use super::*;
2use crate::{format_utils::*, type_kind::Adt};
3use std::fmt::{self, Write};
4
5/// Printing the name of a named type stops infinite recursion
6fn 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::Slice(id) => {
32                    write_name_or(self.with_id(*id), &mut f.delimit_with("[", "]"))
33                }
34                &TypeKind::Array(t, cnt) => {
35                    let mut f = f.delimit_with("[", "]");
36                    write_name_or(self.with_id(t), &mut f)?;
37                    write!(f, "; {cnt}")
38                }
39                TypeKind::Tuple(ids) => {
40                    let mut f = f.delimit_with("(", ")");
41                    for (index, &id) in ids.iter().enumerate() {
42                        if index > 0 {
43                            write!(f, ", ")?;
44                        }
45                        write_name_or(self.with_id(id), &mut f)?;
46                    }
47                    Ok(())
48                }
49                TypeKind::FnSig { args, rety } => {
50                    write!(f, "fn {} -> ", self.with_id(*args))?;
51                    write_name_or(self.with_id(*rety), f)
52                }
53                TypeKind::Empty => write!(f, "()"),
54                TypeKind::Never => write!(f, "!"),
55                TypeKind::Module => write!(f, "module?"),
56            }
57        } else {
58            write!(f, "{kind}")
59        }
60    }
61}
62
63fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result {
64    match adt {
65        Adt::Enum(variants) => {
66            let mut variants = variants.iter();
67            separate(", ", || {
68                variants.next().map(|(name, def)| {
69                    move |f: &mut Delimit<_>| {
70                        write!(f, "{name}: ")?;
71                        write_name_or(h.with_id(*def), f)
72                    }
73                })
74            })(f.delimit_with("enum {", "}"))
75        }
76        Adt::Struct(members) => {
77            let mut members = members.iter();
78            separate(", ", || {
79                let (name, vis, id) = members.next()?;
80                Some(move |f: &mut Delimit<_>| {
81                    write!(f, "{vis}{name}: ")?;
82                    write_name_or(h.with_id(*id), f)
83                })
84            })(f.delimit_with("struct {", "}"))
85        }
86        Adt::TupleStruct(members) => {
87            let mut members = members.iter();
88            separate(", ", || {
89                let (vis, def) = members.next()?;
90                Some(move |f: &mut Delimit<_>| {
91                    write!(f, "{vis}")?;
92                    write_name_or(h.with_id(*def), f)
93                })
94            })(f.delimit_with("struct (", ")"))
95        }
96        Adt::UnitStruct => write!(f, "struct"),
97        Adt::Union(_) => todo!("Display union types"),
98    }
99}