lust/ast/
types.rs

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