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