cl_typeck/
type_kind.rs

1//! A [TypeKind] is a node in the [Table](crate::table::Table)'s type graph
2
3use crate::handle::Handle;
4use cl_ast::{Sym, Visibility};
5use std::{fmt::Debug, str::FromStr};
6
7mod display;
8
9/// A [TypeKind] represents an item
10/// (a component of a [Table](crate::table::Table))
11#[derive(Clone, Debug, PartialEq, Eq, Hash)]
12pub enum TypeKind {
13    /// A type that is yet to be inferred!
14    Inferred,
15    /// A type variable, to be monomorphized
16    Variable,
17    /// An alias for an already-defined type
18    Instance(Handle),
19    /// A primitive type, built-in to the compiler
20    Primitive(Primitive),
21    /// A user-defined aromatic data type
22    Adt(Adt),
23    /// A reference to an already-defined type: &T
24    Ref(Handle),
25    /// A contiguous view of dynamically sized memory
26    Slice(Handle),
27    /// A contiguous view of statically sized memory
28    Array(Handle, usize),
29    /// A tuple of existing types
30    Tuple(Vec<Handle>),
31    /// A function which accepts multiple inputs and produces an output
32    FnSig { args: Handle, rety: Handle },
33    /// The unit type
34    Empty,
35    /// The never type
36    Never,
37    /// An untyped module
38    Module,
39}
40
41/// A user-defined Aromatic Data Type
42#[derive(Clone, Debug, PartialEq, Eq, Hash)]
43pub enum Adt {
44    /// A union-like enum type
45    Enum(Vec<(Sym, Handle)>),
46
47    /// A structural product type with named members
48    Struct(Vec<(Sym, Visibility, Handle)>),
49    /// A structural product type with unnamed members
50    TupleStruct(Vec<(Visibility, Handle)>),
51    /// A structural product type of neither named nor unnamed members
52    UnitStruct,
53
54    /// A choose your own undefined behavior type
55    /// TODO: should unions be a language feature?
56    Union(Vec<(Sym, Handle)>),
57}
58
59/// The set of compiler-intrinsic types.
60/// These primitive types have native implementations of the basic operations.
61#[rustfmt::skip]
62#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)]
63pub enum Primitive {
64    I8, I16, I32, I64, I128, Isize, // Signed integers
65    U8, U16, U32, U64, U128, Usize, // Unsigned integers
66    F8, F16, F32, F64, F128, Fsize, // Floating point numbers
67    Integer, Float,                 // Inferred int and float
68    Bool,                           // boolean value
69    Char,                           // Unicode codepoint
70}
71
72#[rustfmt::skip]
73impl Primitive {
74    /// Checks whether self is an integer
75    pub fn is_integer(self) -> bool {
76        matches!(
77            self, 
78            | Self::I8 | Self::I16 | Self::I32 | Self::I64 | Self::I128 | Self::Isize
79            | Self::U8 | Self::U16 | Self::U32 | Self::U64 | Self::U128 | Self::Usize
80            | Self::Integer
81        )
82    }
83    /// Checks whether self is a floating point number
84    pub fn is_float(self) -> bool {
85        matches!(
86            self, 
87            | Self::F8 | Self::F16 | Self::F32 | Self::F64 | Self::F128 | Self::Fsize
88            | Self::Float
89        )
90    }
91}
92
93// Author's note: the fsize type is a meme
94
95impl FromStr for Primitive {
96    type Err = ();
97
98    fn from_str(s: &str) -> Result<Self, Self::Err> {
99        Ok(match s {
100            "i8" => Primitive::I8,
101            "i16" => Primitive::I16,
102            "i32" => Primitive::I32,
103            "i64" => Primitive::I64,
104            "i128" => Primitive::I128,
105            "isize" => Primitive::Isize,
106            "u8" => Primitive::U8,
107            "u16" => Primitive::U16,
108            "u32" => Primitive::U32,
109            "u64" => Primitive::U64,
110            "u128" => Primitive::U128,
111            "usize" => Primitive::Usize,
112            "f8" => Primitive::F8,
113            "f16" => Primitive::F16,
114            "f32" => Primitive::F32,
115            "f64" => Primitive::F64,
116            "f128" => Primitive::F128,
117            "fsize" => Primitive::Fsize,
118            "bool" => Primitive::Bool,
119            "char" => Primitive::Char,
120            _ => Err(())?,
121        })
122    }
123}