1#![no_std]
2#![deny(warnings)]
3
4extern crate alloc;
5
6mod alignable;
7mod array_type;
8mod function_type;
9mod layout;
10mod pointer_type;
11mod struct_type;
12
13use alloc::{boxed::Box, sync::Arc};
14use core::fmt;
15
16use miden_formatting::prettier::PrettyPrint;
17
18pub use self::{
19 alignable::Alignable, array_type::ArrayType, function_type::*, pointer_type::*, struct_type::*,
20};
21
22#[derive(Debug, Clone, PartialEq, Eq, Hash)]
24#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
25pub enum Type {
26 Unknown,
28 Never,
30 I1,
34 I8,
36 U8,
38 I16,
40 U16,
42 I32,
44 U32,
46 I64,
48 U64,
50 I128,
52 U128,
54 U256,
56 F64,
60 Felt,
62 Ptr(Arc<PointerType>),
67 Struct(Arc<StructType>),
69 Array(Arc<ArrayType>),
71 List(Arc<Type>),
77 Function(Arc<FunctionType>),
79}
80impl Type {
81 pub fn is_zst(&self) -> bool {
88 match self {
89 Self::Unknown => false,
90 Self::Never => true,
91 Self::Array(ref ty) => ty.is_zst(),
92 Self::Struct(ref struct_ty) => struct_ty.fields.iter().all(|f| f.ty.is_zst()),
93 Self::I1
94 | Self::I8
95 | Self::U8
96 | Self::I16
97 | Self::U16
98 | Self::I32
99 | Self::U32
100 | Self::I64
101 | Self::U64
102 | Self::I128
103 | Self::U128
104 | Self::U256
105 | Self::F64
106 | Self::Felt
107 | Self::Ptr(_)
108 | Self::List(_)
109 | Self::Function(_) => false,
110 }
111 }
112
113 pub fn is_numeric(&self) -> bool {
115 matches!(
116 self,
117 Self::I1
118 | Self::I8
119 | Self::U8
120 | Self::I16
121 | Self::U16
122 | Self::I32
123 | Self::U32
124 | Self::I64
125 | Self::U64
126 | Self::I128
127 | Self::U128
128 | Self::U256
129 | Self::F64
130 | Self::Felt
131 )
132 }
133
134 pub fn is_integer(&self) -> bool {
136 matches!(
137 self,
138 Self::I1
139 | Self::I8
140 | Self::U8
141 | Self::I16
142 | Self::U16
143 | Self::I32
144 | Self::U32
145 | Self::I64
146 | Self::U64
147 | Self::I128
148 | Self::U128
149 | Self::U256
150 | Self::Felt
151 )
152 }
153
154 pub fn is_signed_integer(&self) -> bool {
156 matches!(self, Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128)
157 }
158
159 pub fn is_unsigned_integer(&self) -> bool {
161 matches!(self, Self::I1 | Self::U8 | Self::U16 | Self::U32 | Self::U64 | Self::U128)
162 }
163
164 pub fn as_unsigned(&self) -> Type {
169 match self {
170 Self::I8 | Self::U8 => Self::U8,
171 Self::I16 | Self::U16 => Self::U16,
172 Self::I32 | Self::U32 => Self::U32,
173 Self::I64 | Self::U64 => Self::U64,
174 Self::I128 | Self::U128 => Self::U128,
175 Self::Felt => Self::Felt,
176 ty => panic!("invalid conversion to unsigned integer type: {ty} is not an integer"),
177 }
178 }
179
180 pub fn as_signed(&self) -> Type {
184 match self {
185 Self::I8 | Self::U8 => Self::I8,
186 Self::I16 | Self::U16 => Self::I16,
187 Self::I32 | Self::U32 => Self::I32,
188 Self::I64 | Self::U64 => Self::I64,
189 Self::I128 | Self::U128 => Self::I128,
190 Self::Felt => {
191 panic!("invalid conversion to signed integer type: felt has no signed equivalent")
192 }
193 ty => panic!("invalid conversion to signed integer type: {ty} is not an integer"),
194 }
195 }
196
197 #[inline]
199 pub fn is_float(&self) -> bool {
200 matches!(self, Self::F64)
201 }
202
203 #[inline]
205 pub fn is_felt(&self) -> bool {
206 matches!(self, Self::Felt)
207 }
208
209 #[inline]
211 pub fn is_pointer(&self) -> bool {
212 matches!(self, Self::Ptr(_))
213 }
214
215 #[inline]
217 pub fn pointee(&self) -> Option<&Type> {
218 match self {
219 Self::Ptr(ty) => Some(ty.pointee()),
220 _ => None,
221 }
222 }
223
224 #[inline]
226 pub fn is_struct(&self) -> bool {
227 matches!(self, Self::Struct(_))
228 }
229
230 #[inline]
232 pub fn is_array(&self) -> bool {
233 matches!(self, Self::Array(_))
234 }
235
236 #[inline]
238 pub fn is_list(&self) -> bool {
239 matches!(self, Self::List(_))
240 }
241
242 #[inline]
244 pub fn is_function(&self) -> bool {
245 matches!(self, Self::Function(_))
246 }
247}
248
249impl From<StructType> for Type {
250 #[inline]
251 fn from(ty: StructType) -> Type {
252 Type::Struct(Arc::new(ty))
253 }
254}
255
256impl From<Box<StructType>> for Type {
257 #[inline]
258 fn from(ty: Box<StructType>) -> Type {
259 Type::Struct(Arc::from(ty))
260 }
261}
262
263impl From<Arc<StructType>> for Type {
264 #[inline]
265 fn from(ty: Arc<StructType>) -> Type {
266 Type::Struct(ty)
267 }
268}
269
270impl From<ArrayType> for Type {
271 #[inline]
272 fn from(ty: ArrayType) -> Type {
273 Type::Array(Arc::new(ty))
274 }
275}
276
277impl From<Box<ArrayType>> for Type {
278 #[inline]
279 fn from(ty: Box<ArrayType>) -> Type {
280 Type::Array(Arc::from(ty))
281 }
282}
283
284impl From<Arc<ArrayType>> for Type {
285 #[inline]
286 fn from(ty: Arc<ArrayType>) -> Type {
287 Type::Array(ty)
288 }
289}
290
291impl From<PointerType> for Type {
292 #[inline]
293 fn from(ty: PointerType) -> Type {
294 Type::Ptr(Arc::new(ty))
295 }
296}
297
298impl From<Box<PointerType>> for Type {
299 #[inline]
300 fn from(ty: Box<PointerType>) -> Type {
301 Type::Ptr(Arc::from(ty))
302 }
303}
304
305impl From<Arc<PointerType>> for Type {
306 #[inline]
307 fn from(ty: Arc<PointerType>) -> Type {
308 Type::Ptr(ty)
309 }
310}
311
312impl From<FunctionType> for Type {
313 #[inline]
314 fn from(ty: FunctionType) -> Type {
315 Type::Function(Arc::new(ty))
316 }
317}
318
319impl From<Box<FunctionType>> for Type {
320 #[inline]
321 fn from(ty: Box<FunctionType>) -> Type {
322 Type::Function(Arc::from(ty))
323 }
324}
325
326impl From<Arc<FunctionType>> for Type {
327 #[inline]
328 fn from(ty: Arc<FunctionType>) -> Type {
329 Type::Function(ty)
330 }
331}
332
333impl fmt::Display for Type {
334 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
336 self.pretty_print(f)
337 }
338}
339
340impl PrettyPrint for Type {
341 fn render(&self) -> miden_formatting::prettier::Document {
342 use miden_formatting::prettier::*;
343
344 match self {
345 Self::Unknown => const_text("?"),
346 Self::Never => const_text("!"),
347 Self::I1 => const_text("i1"),
348 Self::I8 => const_text("i8"),
349 Self::U8 => const_text("u8"),
350 Self::I16 => const_text("i16"),
351 Self::U16 => const_text("u16"),
352 Self::I32 => const_text("i32"),
353 Self::U32 => const_text("u32"),
354 Self::I64 => const_text("i64"),
355 Self::U64 => const_text("u64"),
356 Self::I128 => const_text("i128"),
357 Self::U128 => const_text("u128"),
358 Self::U256 => const_text("u256"),
359 Self::F64 => const_text("f64"),
360 Self::Felt => const_text("felt"),
361 Self::Ptr(ptr_ty) => ptr_ty.render(),
362 Self::Struct(struct_ty) => struct_ty.render(),
363 Self::Array(array_ty) => array_ty.render(),
364 Self::List(ty) => const_text("list<") + ty.render() + const_text(">"),
365 Self::Function(ty) => ty.render(),
366 }
367 }
368}