1use crate::{handle::Handle, table::Table, type_kind::TypeKind};
5use cl_ast::{PathPart, Ty, TyArray, TyFn, TyKind, TyRef, TySlice, TyTuple};
6
7#[derive(Clone, Debug, PartialEq, Eq)] pub enum Error {
9 BadPath { parent: Handle, path: Vec<PathPart> },
10}
11
12impl std::error::Error for Error {}
13impl std::fmt::Display for Error {
14 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
15 match self {
16 Error::BadPath { parent, path } => {
17 write!(f, "No item at path {parent}")?;
18 for part in path {
19 write!(f, "::{part}")?;
20 }
21 }
22 }
23 Ok(())
24 }
25}
26
27pub trait TypeExpression<Out = Handle> {
30 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Out, Error>;
32}
33
34impl TypeExpression for Ty {
35 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
36 self.kind.evaluate(table, node)
37 }
38}
39
40impl TypeExpression for TyKind {
41 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
42 match self {
43 TyKind::Never => Ok(table.anon_type(TypeKind::Never)),
44 TyKind::Empty => Ok(table.anon_type(TypeKind::Empty)),
45 TyKind::Infer => Ok(table.inferred_type()),
46 TyKind::Path(p) => p.evaluate(table, node),
47 TyKind::Array(a) => a.evaluate(table, node),
48 TyKind::Slice(s) => s.evaluate(table, node),
49 TyKind::Tuple(t) => t.evaluate(table, node),
50 TyKind::Ref(r) => r.evaluate(table, node),
51 TyKind::Fn(f) => f.evaluate(table, node),
52 }
53 }
54}
55
56impl TypeExpression for cl_ast::Path {
57 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
58 let Self { absolute, parts } = self;
59 parts.evaluate(table, if *absolute { table.root() } else { node })
60 }
61}
62
63impl TypeExpression for [PathPart] {
64 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
65 table
66 .nav(node, self)
67 .ok_or_else(|| Error::BadPath { parent: node, path: self.to_owned() })
68 }
69}
70
71impl TypeExpression for TyArray {
72 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
73 let Self { ty, count } = self;
74 let kind = TypeKind::Array(ty.evaluate(table, node)?, *count);
75 Ok(table.anon_type(kind))
76 }
77}
78
79impl TypeExpression for TySlice {
80 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
81 let Self { ty } = self;
82 let kind = TypeKind::Slice(ty.evaluate(table, node)?);
83 Ok(table.anon_type(kind))
84 }
85}
86
87impl TypeExpression for TyTuple {
88 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
89 let Self { types } = self;
90 let kind = match types.len() {
91 0 => TypeKind::Empty,
92 _ => TypeKind::Tuple(types.evaluate(table, node)?),
93 };
94 Ok(table.anon_type(kind))
95 }
96}
97
98impl TypeExpression for TyRef {
99 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
100 let Self { mutable: _, count, to } = self;
101 let mut t = to.evaluate(table, node)?;
102 for _ in 0..*count {
103 let kind = TypeKind::Ref(t);
104 t = table.anon_type(kind)
105 }
106 Ok(t)
107 }
108}
109
110impl TypeExpression for TyFn {
111 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
112 let Self { args, rety } = self;
113 let kind = TypeKind::FnSig {
114 args: args.evaluate(table, node)?,
115 rety: match rety {
116 Some(ty) => ty.evaluate(table, node)?,
117 None => TyKind::Empty.evaluate(table, node)?,
118 },
119 };
120 Ok(table.anon_type(kind))
121 }
122}
123
124impl<T: TypeExpression<U>, U> TypeExpression<Vec<U>> for [T] {
125 fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Vec<U>, Error> {
126 let mut out = Vec::with_capacity(self.len());
127 for te in self {
128 out.push(te.evaluate(table, node)?) }
130 Ok(out)
131 }
132}