1use super::Span;
2use std::fmt;
3#[derive(Debug, Clone, Eq, Hash)]
4pub struct Type {
5 pub kind: TypeKind,
6 pub span: Span,
7}
8
9impl PartialEq for Type {
10 fn eq(&self, other: &Self) -> bool {
11 self.kind == other.kind
12 }
13}
14
15impl Type {
16 pub fn new(kind: TypeKind, span: Span) -> Self {
17 Self { kind, span }
18 }
19}
20
21impl fmt::Display for Type {
22 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
23 self.kind.fmt(f)
24 }
25}
26
27#[derive(Debug, Clone, PartialEq, Eq, Hash)]
28pub enum TypeKind {
29 Int,
30 Float,
31 String,
32 Bool,
33 Named(String),
34 Generic(String),
35 Array(Box<Type>),
36 Map(Box<Type>, Box<Type>),
37 Table,
38 Function {
39 params: Vec<Type>,
40 return_type: Box<Type>,
41 },
42 Tuple(Vec<Type>),
43 Option(Box<Type>),
44 Result(Box<Type>, Box<Type>),
45 Ref(Box<Type>),
46 MutRef(Box<Type>),
47 Pointer {
48 mutable: bool,
49 pointee: Box<Type>,
50 },
51 GenericInstance {
52 name: String,
53 type_args: Vec<Type>,
54 },
55 Unknown,
56 Union(Vec<Type>),
57 Trait(String),
58 TraitBound(Vec<String>),
59 Unit,
60 Infer,
61}
62
63impl TypeKind {
64 pub fn is_primitive(&self) -> bool {
65 matches!(
66 self,
67 TypeKind::Int | TypeKind::Float | TypeKind::String | TypeKind::Bool
68 )
69 }
70}
71
72impl fmt::Display for TypeKind {
73 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
74 match self {
75 TypeKind::Int => write!(f, "int"),
76 TypeKind::Float => write!(f, "float"),
77 TypeKind::String => write!(f, "string"),
78 TypeKind::Bool => write!(f, "bool"),
79 TypeKind::Named(name) => write!(f, "{name}"),
80 TypeKind::Generic(name) => write!(f, "{name}"),
81 TypeKind::Array(inner) => write!(f, "Array<{}>", inner),
82 TypeKind::Map(key, value) => write!(f, "Map<{}, {}>", key, value),
83 TypeKind::Table => write!(f, "Table"),
84 TypeKind::Function {
85 params,
86 return_type,
87 } => {
88 let params = params
89 .iter()
90 .map(|p| p.to_string())
91 .collect::<Vec<_>>()
92 .join(", ");
93 write!(f, "function({}) -> {}", params, return_type)
94 }
95
96 TypeKind::Tuple(elements) => {
97 let elems = elements
98 .iter()
99 .map(|t| t.to_string())
100 .collect::<Vec<_>>()
101 .join(", ");
102 write!(f, "Tuple<{}>", elems)
103 }
104
105 TypeKind::Option(inner) => write!(f, "Option<{}>", inner),
106 TypeKind::Result(ok, err) => write!(f, "Result<{}, {}>", ok, err),
107 TypeKind::Ref(inner) => write!(f, "&{}", inner),
108 TypeKind::MutRef(inner) => write!(f, "&mut {}", inner),
109 TypeKind::Pointer { mutable, pointee } => {
110 if *mutable {
111 write!(f, "*mut {}", pointee)
112 } else {
113 write!(f, "*{}", pointee)
114 }
115 }
116
117 TypeKind::GenericInstance { name, type_args } => {
118 let args = type_args
119 .iter()
120 .map(|t| t.to_string())
121 .collect::<Vec<_>>()
122 .join(", ");
123 write!(f, "{name}<{}>", args)
124 }
125
126 TypeKind::Unknown => write!(f, "unknown"),
127 TypeKind::Union(types) => {
128 let parts = types
129 .iter()
130 .map(|t| t.to_string())
131 .collect::<Vec<_>>()
132 .join(" | ");
133 write!(f, "{parts}")
134 }
135
136 TypeKind::Trait(name) => write!(f, "{name}"),
137 TypeKind::TraitBound(traits) => write!(f, "{}", traits.join(" + ")),
138 TypeKind::Unit => write!(f, "()"),
139 TypeKind::Infer => write!(f, "_"),
140 }
141 }
142}