cl-typeck: Give inference its own result type

This commit is contained in:
John 2025-05-18 04:01:13 -04:00
parent a5590168ee
commit e08bf57dc1

View File

@ -15,19 +15,21 @@ use cl_ast::*;
// TODO: "Infer" the types of Items // TODO: "Infer" the types of Items
type IfResult = Result<Handle, InferenceError>;
pub trait Inference<'a> { pub trait Inference<'a> {
/// Performs type inference /// Performs type inference
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError>; fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult;
} }
impl<'a> Inference<'a> for cl_ast::Expr { impl<'a> Inference<'a> for cl_ast::Expr {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
self.kind.infer(e) self.kind.infer(e)
} }
} }
impl<'a> Inference<'a> for cl_ast::ExprKind { impl<'a> Inference<'a> for cl_ast::ExprKind {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
match self { match self {
ExprKind::Empty => Ok(e.empty()), ExprKind::Empty => Ok(e.empty()),
ExprKind::Closure(_) => todo!("Infer the type of a closure"), ExprKind::Closure(_) => todo!("Infer the type of a closure"),
@ -64,7 +66,7 @@ impl<'a> Inference<'a> for cl_ast::ExprKind {
} }
impl<'a> Inference<'a> for Tuple { impl<'a> Inference<'a> for Tuple {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Tuple { exprs } = self; let Tuple { exprs } = self;
exprs exprs
.iter() .iter()
@ -78,7 +80,7 @@ impl<'a> Inference<'a> for Tuple {
} }
impl<'a> Inference<'a> for Structor { impl<'a> Inference<'a> for Structor {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Structor { to, init } = self; let Structor { to, init } = self;
// Evaluate the path in the current context // Evaluate the path in the current context
let to = to.infer(e)?; let to = to.infer(e)?;
@ -119,7 +121,7 @@ impl<'a> Inference<'a> for Structor {
} }
impl<'a> Inference<'a> for Array { impl<'a> Inference<'a> for Array {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Array { values } = self; let Array { values } = self;
let out = e.new_var(); let out = e.new_var();
for value in values { for value in values {
@ -131,7 +133,7 @@ impl<'a> Inference<'a> for Array {
} }
impl<'a> Inference<'a> for ArrayRep { impl<'a> Inference<'a> for ArrayRep {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let ArrayRep { value, repeat } = self; let ArrayRep { value, repeat } = self;
let ty = value.infer(e)?; let ty = value.infer(e)?;
Ok(e.new_array(ty, *repeat)) Ok(e.new_array(ty, *repeat))
@ -139,7 +141,7 @@ impl<'a> Inference<'a> for ArrayRep {
} }
impl<'a> Inference<'a> for AddrOf { impl<'a> Inference<'a> for AddrOf {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let AddrOf { mutable: _, expr } = self; let AddrOf { mutable: _, expr } = self;
// TODO: mut ref // TODO: mut ref
let ty = expr.infer(e)?; let ty = expr.infer(e)?;
@ -148,13 +150,13 @@ impl<'a> Inference<'a> for AddrOf {
} }
impl<'a> Inference<'a> for Quote { impl<'a> Inference<'a> for Quote {
fn infer(&'a self, _e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, _e: &mut InferenceEngine<'_, 'a>) -> IfResult {
todo!("Quote: {self}") todo!("Quote: {self}")
} }
} }
impl<'a> Inference<'a> for Literal { impl<'a> Inference<'a> for Literal {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let ty = match self { let ty = match self {
Literal::Bool(_) => e.bool(), Literal::Bool(_) => e.bool(),
Literal::Char(_) => e.char(), Literal::Char(_) => e.char(),
@ -170,14 +172,14 @@ impl<'a> Inference<'a> for Literal {
} }
impl<'a> Inference<'a> for Group { impl<'a> Inference<'a> for Group {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Group { expr } = self; let Group { expr } = self;
expr.infer(e) expr.infer(e)
} }
} }
impl<'a> Inference<'a> for Block { impl<'a> Inference<'a> for Block {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Block { stmts } = self; let Block { stmts } = self;
let mut e = e.block_scope(); let mut e = e.block_scope();
let empty = e.empty(); let empty = e.empty();
@ -209,7 +211,7 @@ impl<'a> Inference<'a> for Block {
} }
impl<'a> Inference<'a> for Assign { impl<'a> Inference<'a> for Assign {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Assign { parts } = self; let Assign { parts } = self;
let (head, tail) = parts.as_ref(); let (head, tail) = parts.as_ref();
// Infer the tail expression // Infer the tail expression
@ -224,7 +226,7 @@ impl<'a> Inference<'a> for Assign {
} }
impl<'a> Inference<'a> for Modify { impl<'a> Inference<'a> for Modify {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Modify { kind: _, parts } = self; let Modify { kind: _, parts } = self;
let (head, tail) = parts.as_ref(); let (head, tail) = parts.as_ref();
// Infer the tail expression // Infer the tail expression
@ -239,7 +241,7 @@ impl<'a> Inference<'a> for Modify {
} }
impl<'a> Inference<'a> for Binary { impl<'a> Inference<'a> for Binary {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
use BinaryKind as Bk; use BinaryKind as Bk;
let Binary { kind, parts } = self; let Binary { kind, parts } = self;
let (head, tail) = parts.as_ref(); let (head, tail) = parts.as_ref();
@ -308,7 +310,7 @@ impl<'a> Inference<'a> for Binary {
} }
impl<'a> Inference<'a> for Unary { impl<'a> Inference<'a> for Unary {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Unary { kind, tail } = self; let Unary { kind, tail } = self;
match kind { match kind {
UnaryKind::Deref => { UnaryKind::Deref => {
@ -344,7 +346,7 @@ impl<'a> Inference<'a> for Unary {
} }
impl<'a> Inference<'a> for Member { impl<'a> Inference<'a> for Member {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Member { head, kind } = self; let Member { head, kind } = self;
// Infer the head expression // Infer the head expression
let head = head.infer(e)?; let head = head.infer(e)?;
@ -390,7 +392,7 @@ impl<'a> Inference<'a> for Member {
} }
impl<'a> Inference<'a> for Index { impl<'a> Inference<'a> for Index {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Index { head, indices } = self; let Index { head, indices } = self;
let usize = e.usize(); let usize = e.usize();
// Infer the head expression // Infer the head expression
@ -424,7 +426,7 @@ impl<'a> Inference<'a> for Index {
} }
impl<'a> Inference<'a> for Cast { impl<'a> Inference<'a> for Cast {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Cast { head, ty } = self; let Cast { head, ty } = self;
// Infer the head expression // Infer the head expression
let _head = head.infer(e)?; let _head = head.infer(e)?;
@ -440,14 +442,14 @@ impl<'a> Inference<'a> for Cast {
} }
impl<'a> Inference<'a> for Path { impl<'a> Inference<'a> for Path {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
e.by_name(self) e.by_name(self)
.map_err(|_| InferenceError::NotFound(self.clone())) .map_err(|_| InferenceError::NotFound(self.clone()))
} }
} }
impl<'a> Inference<'a> for Let { impl<'a> Inference<'a> for Let {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Let { mutable: _, name, ty, init } = self; let Let { mutable: _, name, ty, init } = self;
// Deep copy the ty, if it exists // Deep copy the ty, if it exists
let ty = match ty { let ty = match ty {
@ -477,7 +479,7 @@ impl<'a> Inference<'a> for Let {
} }
impl<'a> Inference<'a> for Match { impl<'a> Inference<'a> for Match {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Match { scrutinee, arms } = self; let Match { scrutinee, arms } = self;
// Infer the scrutinee // Infer the scrutinee
let scrutinee = scrutinee.infer(e)?; let scrutinee = scrutinee.infer(e)?;
@ -508,7 +510,7 @@ impl<'a> Inference<'a> for Match {
impl<'a> Inference<'a> for Pattern { impl<'a> Inference<'a> for Pattern {
// TODO: This is the wrong way to typeck pattern matching. // TODO: This is the wrong way to typeck pattern matching.
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
match self { match self {
Pattern::Name(name) => { Pattern::Name(name) => {
// Evaluating a pattern creates and enters a new scope. // Evaluating a pattern creates and enters a new scope.
@ -572,7 +574,7 @@ impl<'a> Inference<'a> for Pattern {
} }
impl<'a> Inference<'a> for While { impl<'a> Inference<'a> for While {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let While { cond, pass, fail } = self; let While { cond, pass, fail } = self;
// Infer the condition // Infer the condition
let cond = cond.infer(e)?; let cond = cond.infer(e)?;
@ -597,7 +599,7 @@ impl<'a> Inference<'a> for While {
} }
impl<'a> Inference<'a> for If { impl<'a> Inference<'a> for If {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let If { cond, pass, fail } = self; let If { cond, pass, fail } = self;
// Do inference on the condition' // Do inference on the condition'
let cond = cond.infer(e)?; let cond = cond.infer(e)?;
@ -616,7 +618,7 @@ impl<'a> Inference<'a> for If {
} }
impl<'a> Inference<'a> for For { impl<'a> Inference<'a> for For {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let For { bind, cond, pass, fail } = self; let For { bind, cond, pass, fail } = self;
let mut e = e.block_scope(); let mut e = e.block_scope();
@ -654,13 +656,13 @@ impl<'a> Inference<'a> for For {
} }
impl<'a> Inference<'a> for Else { impl<'a> Inference<'a> for Else {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
self.body.infer(e) self.body.infer(e)
} }
} }
impl<'a> Inference<'a> for Break { impl<'a> Inference<'a> for Break {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Break { body } = self; let Break { body } = self;
// Infer the body of the break // Infer the body of the break
let ty = body.infer(e)?; let ty = body.infer(e)?;
@ -672,7 +674,7 @@ impl<'a> Inference<'a> for Break {
} }
impl<'a> Inference<'a> for Return { impl<'a> Inference<'a> for Return {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
let Return { body } = self; let Return { body } = self;
// Infer the body of the return // Infer the body of the return
let ty = body.infer(e)?; let ty = body.infer(e)?;
@ -684,7 +686,7 @@ impl<'a> Inference<'a> for Return {
} }
impl<'a, I: Inference<'a>> Inference<'a> for Option<I> { impl<'a, I: Inference<'a>> Inference<'a> for Option<I> {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
match self { match self {
Some(expr) => expr.infer(e), Some(expr) => expr.infer(e),
None => Ok(e.empty()), None => Ok(e.empty()),
@ -692,7 +694,7 @@ impl<'a, I: Inference<'a>> Inference<'a> for Option<I> {
} }
} }
impl<'a, I: Inference<'a>> Inference<'a> for Box<I> { impl<'a, I: Inference<'a>> Inference<'a> for Box<I> {
fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> Result<Handle, InferenceError> { fn infer(&'a self, e: &mut InferenceEngine<'_, 'a>) -> IfResult {
self.as_ref().infer(e) self.as_ref().infer(e)
} }
} }