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 #[strum(to_string = "Prim8")]
93 prim8,
94 #[strum(to_string = "Prim16")]
95 prim16,
96 #[strum(to_string = "Prim32")]
97 prim32,
98 #[strum(to_string = "Prim64")]
99 prim64,
100}
101
102#[derive(Debug, Clone, PartialEq, Hash)]
104pub struct TyFunc {
105 pub params: Vec<TyFuncParam>,
107
108 pub body: Option<Box<Ty>>,
110
111 pub ty_params: Vec<TyParam>,
112}
113
114#[derive(Debug, Clone, PartialEq, Hash)]
116pub struct TyFuncParam {
117 pub constant: bool,
118 pub label: Option<String>,
119 pub ty: Option<Ty>,
120}
121
122impl TyFuncParam {
123 pub fn simple(ty: Option<Ty>) -> Self {
124 TyFuncParam {
125 constant: false,
126 label: None,
127 ty,
128 }
129 }
130}
131
132#[derive(Debug, Clone)]
134pub struct TyParam {
135 pub name: String,
137
138 pub domain: TyDomain,
139
140 pub span: Option<Span>,
141}
142
143#[derive(Debug, Clone)]
147pub enum TyDomain {
148 Open,
150
151 OneOf(Vec<Ty>),
153
154 TupleHasFields(Vec<TyDomainTupleField>),
156
157 TupleLen { n: usize },
159
160 EnumVariants(Vec<TyDomainEnumVariant>),
162}
163
164#[derive(Clone)]
165pub struct TyDomainTupleField {
166 pub location: super::Lookup,
167 pub ty: Ty,
168
169 pub span: Span,
170}
171
172#[derive(Debug, Clone)]
173pub struct TyDomainEnumVariant {
174 pub name: String,
175 pub ty: Ty,
176}
177
178#[derive(Debug, Clone, PartialEq, Hash)]
179pub struct TyTupleComprehension {
180 pub tuple: Box<Ty>,
181
182 pub variable_name: String,
183 pub variable_ty: String,
184
185 pub body_name: Option<String>,
186 pub body_ty: Box<Ty>,
187}
188
189impl Ty {
190 pub fn new(kind: impl Into<TyKind>) -> Ty {
191 Ty {
192 kind: kind.into(),
193 span: None,
194 name: None,
195 target: None,
196 scope_id: None,
197 variants_force_ptr: Vec::new(),
198 }
199 }
200
201 pub fn new_with_span(kind: impl Into<TyKind>, span: Span) -> Ty {
202 Ty {
203 kind: kind.into(),
204 span: Some(span),
205 name: None,
206 target: None,
207 scope_id: None,
208 variants_force_ptr: Vec::new(),
209 }
210 }
211
212 pub fn new_std(name: &str) -> Self {
213 Ty::new(TyKind::Ident(Path::new([NS_STD, name])))
214 }
215
216 pub fn with_span(mut self, span: Span) -> Self {
217 self.span = Some(span);
218 self
219 }
220}
221
222impl From<TyPrimitive> for TyKind {
223 fn from(value: TyPrimitive) -> Self {
224 TyKind::Primitive(value)
225 }
226}
227
228impl From<TyFunc> for TyKind {
229 fn from(value: TyFunc) -> Self {
230 TyKind::Func(value)
231 }
232}
233
234impl From<Path> for TyKind {
235 fn from(value: Path) -> Self {
236 TyKind::Ident(value)
237 }
238}
239
240impl PartialEq for Ty {
241 fn eq(&self, other: &Self) -> bool {
242 self.kind == other.kind
243 }
244}
245
246impl Eq for Ty {}
247
248impl std::hash::Hash for Ty {
249 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
250 self.kind.hash(state);
251 }
252}
253
254impl PartialEq for TyParam {
255 fn eq(&self, other: &Self) -> bool {
256 self.name == other.name
257 }
259}
260
261impl Eq for TyParam {}
262
263impl std::hash::Hash for TyParam {
264 fn hash<H: std::hash::Hasher>(&self, state: &mut H) {
265 self.name.hash(state);
266 }
268}
269
270impl TyTupleField {
271 pub(crate) fn matches_name(&self, name: &str) -> bool {
272 self.name.as_ref().is_some_and(|n| n == name)
273 }
274}
275
276impl std::fmt::Debug for TyDomainTupleField {
277 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
278 f.debug_struct("TyDomainTupleField")
279 .field("location", &self.location)
280 .field("ty", &self.ty)
281 .finish()
282 }
283}