add type comparison function

This commit is contained in:
NotAFile 2022-02-20 18:26:14 +01:00
parent b890c0594d
commit cce8a3bde4
2 changed files with 11 additions and 5 deletions

View File

@ -282,7 +282,7 @@ impl Context {
))) )))
} }
pub fn infer_expr_types(&self, expr: &typed_ir::Expr) -> typed_ir::Expr { pub fn infer_expr_types(&mut self, expr: &typed_ir::Expr) -> typed_ir::Expr {
if self.types.is_fully_typed(expr.typ) { if self.types.is_fully_typed(expr.typ) {
// there is nothing more to infer // there is nothing more to infer
return expr.clone(); return expr.clone();
@ -295,18 +295,17 @@ impl Context {
args, args,
genargs, genargs,
} => { } => {
let args_typed: Vec<_> = args.iter().map(|ex| self.infer_expr_types(ex)).collect();
let callee_def = self.callables.get(*called); let callee_def = self.callables.get(*called);
if self.types.is_fully_typed(callee_def.ret_type) { if self.types.is_fully_typed(callee_def.ret_type) {
expr.clone().with_type(callee_def.ret_type) expr.clone().with_type(callee_def.ret_type)
} else { } else {
let args_typed: Vec<_> =
args.iter().map(|ex| self.infer_expr_types(ex)).collect();
let param_types: Vec<_> = callee_def.args.iter().map(|param| param.1).collect(); let param_types: Vec<_> = callee_def.args.iter().map(|param| param.1).collect();
let mut genargs = callee_def.genargs.clone(); let mut genargs = callee_def.genargs.clone();
let inferred_args: Vec<_> = param_types let inferred_args: Vec<_> = param_types
.iter() .iter()
.zip(args_typed) .zip(args_typed)
.map(|(param, arg)| {}) .map(|(param, arg)| self.types.infer_type(*param, arg.typ))
.collect(); .collect();
expr.clone().with_type(callee_def.ret_type) expr.clone().with_type(callee_def.ret_type)
} }
@ -314,7 +313,7 @@ impl Context {
} }
} }
pub fn infer_types(&self, mut block: typed_ir::Block) -> typed_ir::Block { pub fn infer_types(&mut self, mut block: typed_ir::Block) -> typed_ir::Block {
let new_root = self.infer_expr_types(&block.expr); let new_root = self.infer_expr_types(&block.expr);
block.expr = new_root; block.expr = new_root;
block block

View File

@ -172,6 +172,13 @@ impl TypingContext {
} }
} }
/// Given the type of a variable in two locations, infer what the true type should be
pub fn infer_type(&mut self, typ_a: Type, typ_b: Type) -> Type {
match (&self.get(typ_a).kind, &self.get(typ_b).kind) {
(a, b) => panic!("cannot infer between: {:?}, {:?}", a, b),
}
}
/// return whether the type has no unfilled parameters /// return whether the type has no unfilled parameters
pub fn is_fully_typed(&self, typ: Type) -> bool { pub fn is_fully_typed(&self, typ: Type) -> bool {
match &self.get(typ).kind { match &self.get(typ).kind {