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