fe_mir/ir/
types.rs

1use fe_analyzer::namespace::items as analyzer_items;
2use fe_analyzer::namespace::types as analyzer_types;
3use fe_common::{impl_intern_key, Span};
4use smol_str::SmolStr;
5
6#[derive(Debug, Clone, PartialEq, Eq, Hash)]
7pub struct Type {
8    pub kind: TypeKind,
9    pub analyzer_ty: Option<analyzer_types::TypeId>,
10}
11
12impl Type {
13    pub fn new(kind: TypeKind, analyzer_ty: Option<analyzer_types::TypeId>) -> Self {
14        Self { kind, analyzer_ty }
15    }
16}
17
18#[derive(Debug, Clone, PartialEq, Eq, Hash)]
19pub enum TypeKind {
20    I8,
21    I16,
22    I32,
23    I64,
24    I128,
25    I256,
26    U8,
27    U16,
28    U32,
29    U64,
30    U128,
31    U256,
32    Bool,
33    Address,
34    Unit,
35    Array(ArrayDef),
36    // TODO: we should consider whether we really need `String` type.
37    String(usize),
38    Tuple(TupleDef),
39    Struct(StructDef),
40    Enum(EnumDef),
41    Contract(StructDef),
42    Map(MapDef),
43    MPtr(TypeId),
44    SPtr(TypeId),
45}
46
47/// An interned Id for [`ArrayDef`].
48#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
49pub struct TypeId(pub u32);
50impl_intern_key!(TypeId);
51
52/// A static array type definition.
53#[derive(Debug, Clone, PartialEq, Eq, Hash)]
54pub struct ArrayDef {
55    pub elem_ty: TypeId,
56    pub len: usize,
57}
58
59/// A tuple type definition.
60#[derive(Debug, Clone, PartialEq, Eq, Hash)]
61pub struct TupleDef {
62    pub items: Vec<TypeId>,
63}
64
65/// A user defined struct type definition.
66#[derive(Debug, Clone, PartialEq, Eq, Hash)]
67pub struct StructDef {
68    pub name: SmolStr,
69    pub fields: Vec<(SmolStr, TypeId)>,
70    pub span: Span,
71    pub module_id: analyzer_items::ModuleId,
72}
73
74/// A user defined struct type definition.
75#[derive(Debug, Clone, PartialEq, Eq, Hash)]
76pub struct EnumDef {
77    pub name: SmolStr,
78    pub variants: Vec<EnumVariant>,
79    pub span: Span,
80    pub module_id: analyzer_items::ModuleId,
81}
82
83impl EnumDef {
84    pub fn tag_type(&self) -> TypeKind {
85        let variant_num = self.variants.len() as u64;
86        if variant_num <= u8::MAX as u64 {
87            TypeKind::U8
88        } else if variant_num <= u16::MAX as u64 {
89            TypeKind::U16
90        } else if variant_num <= u32::MAX as u64 {
91            TypeKind::U32
92        } else {
93            TypeKind::U64
94        }
95    }
96}
97
98/// A user defined struct type definition.
99#[derive(Debug, Clone, PartialEq, Eq, Hash)]
100pub struct EnumVariant {
101    pub name: SmolStr,
102    pub span: Span,
103    pub ty: TypeId,
104}
105
106/// A user defined struct type definition.
107#[derive(Debug, Clone, PartialEq, Eq, Hash)]
108pub struct EventDef {
109    pub name: SmolStr,
110    pub fields: Vec<(SmolStr, TypeId, bool)>,
111    pub span: Span,
112    pub module_id: analyzer_items::ModuleId,
113}
114
115/// A map type definition.
116#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
117pub struct MapDef {
118    pub key_ty: TypeId,
119    pub value_ty: TypeId,
120}