Skip to content

Commit

Permalink
Auto-lift functions to aggregates
Browse files Browse the repository at this point in the history
This is the last piece of our basic type checker, I believe.
  • Loading branch information
emk committed Nov 6, 2023
1 parent fa5d5d2 commit d25839f
Showing 1 changed file with 18 additions and 3 deletions.
21 changes: 18 additions & 3 deletions src/types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1042,8 +1042,20 @@ impl FunctionSignature {
for tv in &self.type_vars {
table.declare(tv.clone(), spanned)?;
}
let mut lift_to_aggregate = false;
for (i, param_ty) in self.params.iter().enumerate() {
// Try to unify normally.
if param_ty.unify(&arg_types[i], &mut table, spanned).is_err() {
// We failed, but let's see if we can lift a scalar function to
// an aggregate function by adjusting the return type.
if let ArgumentType::Aggregating(arg_ty) = &arg_types[i] {
if param_ty.unify(arg_ty.as_ref(), &mut table, spanned).is_ok() {
lift_to_aggregate = true;
continue;
}
}

// We can't match this parameter, so fail.
return Ok(None);
}
}
Expand All @@ -1057,9 +1069,12 @@ impl FunctionSignature {
} else if self.params.len() < arg_types.len() {
return Ok(None);
}
self.return_type
.resolve(&table, spanned)
.map(|ty| Some(ArgumentType::Value(ty)))
let return_ty = ArgumentType::Value(self.return_type.resolve(&table, spanned)?);
if lift_to_aggregate {
Ok(Some(ArgumentType::Aggregating(Box::new(return_ty))))
} else {
Ok(Some(return_ty))
}
}
}

Expand Down

0 comments on commit d25839f

Please sign in to comment.