Skip to main content

lisette_syntax/
display.rs

1use std::fmt;
2
3use crate::types::{Type, TypeVariableState, unqualified_name};
4
5impl Type {
6    pub fn stringify(&self) -> String {
7        match self {
8            Type::Constructor {
9                id, params: args, ..
10            } => {
11                let args_formatted = args
12                    .iter()
13                    .map(|a| a.stringify())
14                    .collect::<Vec<_>>()
15                    .join(", ");
16
17                let name = unqualified_name(id);
18
19                if name == "Unit" {
20                    return "()".to_string();
21                }
22
23                if name == "bool" {
24                    return "bool".to_string();
25                }
26
27                if name.starts_with("Tuple") {
28                    return format!("({})", args_formatted);
29                }
30
31                if name == "Ref" {
32                    return format!("Ref<{}>", args_formatted);
33                }
34
35                if args.is_empty() {
36                    return name.to_string();
37                }
38
39                format!("{}<{}>", name, args_formatted)
40            }
41
42            Type::Variable(var) => match &*var.borrow() {
43                TypeVariableState::Unbound { id, hint } => match hint {
44                    Some(name) => format!("?{}", name),
45                    None => format!("?{}", id),
46                },
47                TypeVariableState::Link(ty) => format!("{}", ty),
48            },
49
50            Type::Function {
51                params: args,
52                param_mutability,
53                return_type,
54                ..
55            } => {
56                let args_formatted = args
57                    .iter()
58                    .enumerate()
59                    .map(|(i, a)| {
60                        let is_mut = param_mutability.get(i).copied().unwrap_or(false);
61                        if is_mut {
62                            format!("mut {}", a.stringify())
63                        } else {
64                            a.stringify()
65                        }
66                    })
67                    .collect::<Vec<_>>()
68                    .join(", ");
69
70                let ret_formatted = (*return_type).stringify();
71
72                format!("fn ({}) -> {}", args_formatted, ret_formatted)
73            }
74
75            Type::Forall { .. } => {
76                unreachable!("Forall types are always instantiated before display")
77            }
78
79            Type::Parameter(name) => name.to_string(),
80
81            Type::Never => "Never".to_string(),
82
83            Type::Tuple(elements) => {
84                let formatted = elements
85                    .iter()
86                    .map(|e| e.stringify())
87                    .collect::<Vec<_>>()
88                    .join(", ");
89                format!("({})", formatted)
90            }
91
92            Type::Error => "<error>".to_string(),
93        }
94    }
95}
96
97impl fmt::Display for Type {
98    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
99        let (types, _generics) = Self::remove_vars(&[self]);
100        write!(f, "{}", types[0].stringify())
101    }
102}