Skip to main content

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