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}