1use enum_as_inner::EnumAsInner;
2
3use crate::Span;
4use crate::pr::path::Path;
5use crate::resolver::NS_STD;
6
7use super::Ref;
8
9#[derive(Debug, Clone)]
10pub struct Ty {
11 pub kind: TyKind,
12
13 pub span: Option<Span>,
14
15 pub name: Option<String>,
17
18 pub scope_id: Option<usize>,
22
23 pub target: Option<Ref>,
26
27 pub variants_force_ptr: Vec<u16>,
28}
29
30#[derive(Debug, Clone)]
32pub struct TyLayout {
33 pub head_size: u32,
36
37 pub body_ptrs: Vec<u32>,
41}
42
43#[derive(Debug, Clone, PartialEq, Hash, EnumAsInner, strum::AsRefStr)]
44pub enum TyKind {
45 Ident(Path),
47
48 Primitive(TyPrimitive),
50
51 Tuple(Vec<TyTupleField>),
53
54 Array(Box<Ty>),
56
57 Option(Box<Ty>),
59
60 Enum(Vec<TyEnumVariant>),
62
63 Func(TyFunc),
65
66 TupleComprehension(TyTupleComprehension),
68 }
72
73#[derive(Debug, Clone, PartialEq, Hash)]
74pub struct TyTupleField {
75 pub name: Option<String>,
76
77 pub unpack: bool,
78
79 pub ty: Ty,
80}
81
82#[derive(Debug, Clone, PartialEq, Hash)]
83pub struct TyEnumVariant {
84 pub name: String,
85 pub ty: Ty,
86}
87
88#[derive(Debug, Clone, PartialEq, Eq, Hash, strum::Display)]
90#[allow(non_camel_case_types)]
91pub enum TyPrimitive {
92 prim8,
93 prim16,
94 prim32,
95 prim64,
96}
97
98#[derive(Debug, Clone, PartialEq, Hash)]
100pub struct TyFunc {
101 pub params: Vec<TyFuncParam>,
103
104 pub body: Option<Box<Ty>>,
106
107 pub ty_params: Vec<TyParam>,
108}
109
110#[derive(Debug, Clone, PartialEq, Hash)]
112pub struct TyFuncParam {
113 pub constant: bool,
114 pub label: Option<String>,
115 pub ty: Option<Ty>,
116}
117
118impl TyFuncParam {
119 pub fn simple(ty: Option<Ty>) -> Self {
120 TyFuncParam {
121 constant: false,
122 label: None,
123 ty,
124 }
125 }
126}
127
128#[derive(Debug, Clone)]
130pub struct TyParam {
131 pub name: String,
133
134 pub domain: TyDomain,
135
136 pub span: Option<Span>,
137}
138
139#[derive(Debug, Clone)]
143pub enum TyDomain {
144 Open,
146
147 OneOf(Vec<Ty>),
149
150 TupleHasFields(Vec<TyDomainTupleField>),
152
153 TupleLen { n: usize },
155
156 EnumVariants(Vec<TyDomainEnumVariant>),
158}
159
160#[derive(Clone)]
161pub struct TyDomainTupleField {
162 pub location: super::Lookup,
163 pub ty: Ty,
164
165 pub span: Span,
166}
167
168#[derive(Debug, Clone)]
169pub struct TyDomainEnumVariant {
170 pub name: String,
171 pub ty: Ty,
172}
173
174#[derive(Debug, Clone, PartialEq, Hash)]
175pub struct TyTupleComprehension {
176 pub tuple: Box<Ty>,
177
178 pub variable_name: String,
179 pub variable_ty: String,
180
181 pub body_name: Option<String>,
182 pub body_ty: Box<Ty>,
183}
184
185impl Ty {
186 pub fn new(kind: impl Into<TyKind>) -> Ty {
187 Ty {
188 kind: kind.into(),
189 span: None,
190 name: None,
191 target: None,
192 scope_id: None,
193 variants_force_ptr: Vec::new(),
194 }
195 }
196
197 pub fn new_with_span(kind: impl Into<TyKind>, span: Span) -> Ty {
198 Ty {
199 kind: kind.into(),
200 span: Some(span),
201 name: None,
202 target: None,
203 scope_id: None,
204 variants_force_ptr: Vec::new(),
205 }
206 }
207
208 pub fn new_std(name: &str) -> Self {
209 Ty::new(TyKind::Ident(Path::new([NS_STD, name])))
210 }
211
212 pub fn with_span(mut self, span: Span) -> Self {
213 self.span = Some(span);
214 self
215 }
216}
217
218impl From<TyPrimitive> for TyKind {
219 fn from(value: TyPrimitive) -> Self {
220 TyKind::Primitive(value)
221 }
222}
223
224impl From<TyFunc> for TyKind {
225 fn from(value: TyFunc) -> Self {
226 TyKind::Func(value)
227 }
228}
229
230impl From<Path> for TyKind {
231 fn from(value: Path) -> Self {
232 TyKind::Ident(value)
233 }
234}
235
236impl PartialEq for Ty {
237 fn eq(&self, other: &Self) -> bool {
238 self.kind == other.kind
239 }
240}
241
242impl Eq for Ty {}
243
244impl std::hash::Hash for Ty {
245 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
246 self.kind.hash(state);
247 }
248}
249
250impl PartialEq for TyParam {
251 fn eq(&self, other: &Self) -> bool {
252 self.name == other.name
253 }
255}
256
257impl Eq for TyParam {}
258
259impl std::hash::Hash for TyParam {
260 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
261 self.name.hash(state);
262 }
264}
265
266impl TyTupleField {
267 pub(crate) fn matches_name(&self, name: &str) -> bool {
268 self.name.as_ref().is_some_and(|n| n == name)
269 }
270}
271
272impl std::fmt::Debug for TyDomainTupleField {
273 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
274 f.debug_struct("TyDomainTupleField")
275 .field("location", &self.location)
276 .field("ty", &self.ty)
277 .finish()
278 }
279}