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 Function {
43 params: Vec<Type>,
44 return_type: Box<Type>,
45 },
46 Tuple(Vec<Type>),
47 Option(Box<Type>),
48 Result(Box<Type>, Box<Type>),
49 Ref(Box<Type>),
50 MutRef(Box<Type>),
51 Pointer {
52 mutable: bool,
53 pointee: Box<Type>,
54 },
55 GenericInstance {
56 name: String,
57 type_args: Vec<Type>,
58 },
59 Unknown,
60 Union(Vec<Type>),
61 Trait(String),
62 TraitBound(Vec<String>),
63 Unit,
64 Infer,
65}
66
67impl TypeKind {
68 pub fn is_primitive(&self) -> bool {
69 matches!(
70 self,
71 TypeKind::Int | TypeKind::Float | TypeKind::String | TypeKind::Bool
72 )
73 }
74}
75
76impl fmt::Display for TypeKind {
77 fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
78 match self {
79 TypeKind::Int => write!(f, "int"),
80 TypeKind::Float => write!(f, "float"),
81 TypeKind::String => write!(f, "string"),
82 TypeKind::Bool => write!(f, "bool"),
83 TypeKind::Named(name) => write!(f, "{name}"),
84 TypeKind::Generic(name) => write!(f, "{name}"),
85 TypeKind::Array(inner) => write!(f, "Array<{}>", inner),
86 TypeKind::Map(key, value) => write!(f, "Map<{}, {}>", key, value),
87 TypeKind::Function {
88 params,
89 return_type,
90 } => {
91 let params = params
92 .iter()
93 .map(|p| p.to_string())
94 .collect::<Vec<_>>()
95 .join(", ");
96 write!(f, "function({}): {}", params, return_type)
97 }
98
99 TypeKind::Tuple(elements) => {
100 let elems = elements
101 .iter()
102 .map(|t| t.to_string())
103 .collect::<Vec<_>>()
104 .join(", ");
105 write!(f, "Tuple<{}>", elems)
106 }
107
108 TypeKind::Option(inner) => write!(f, "Option<{}>", inner),
109 TypeKind::Result(ok, err) => write!(f, "Result<{}, {}>", ok, err),
110 TypeKind::Ref(inner) => write!(f, "&{}", inner),
111 TypeKind::MutRef(inner) => write!(f, "&mut {}", inner),
112 TypeKind::Pointer { mutable, pointee } => {
113 if *mutable {
114 write!(f, "*mut {}", pointee)
115 } else {
116 write!(f, "*{}", pointee)
117 }
118 }
119
120 TypeKind::GenericInstance { name, type_args } => {
121 let args = type_args
122 .iter()
123 .map(|t| t.to_string())
124 .collect::<Vec<_>>()
125 .join(", ");
126 write!(f, "{name}<{}>", args)
127 }
128
129 TypeKind::Unknown => write!(f, "unknown"),
130 TypeKind::Union(types) => {
131 let parts = types
132 .iter()
133 .map(|t| t.to_string())
134 .collect::<Vec<_>>()
135 .join(" | ");
136 write!(f, "{parts}")
137 }
138
139 TypeKind::Trait(name) => write!(f, "{name}"),
140 TypeKind::TraitBound(traits) => write!(f, "{}", traits.join(" + ")),
141 TypeKind::Unit => write!(f, "()"),
142 TypeKind::Infer => write!(f, "_"),
143 }
144 }
145}