diff --git a/src/frontend.rs b/src/frontend.rs index 170ca2c..ea77959 100644 --- a/src/frontend.rs +++ b/src/frontend.rs @@ -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) { // there is nothing more to infer return expr.clone(); @@ -295,18 +295,17 @@ impl Context { args, genargs, } => { + let args_typed: Vec<_> = args.iter().map(|ex| self.infer_expr_types(ex)).collect(); let callee_def = self.callables.get(*called); if self.types.is_fully_typed(callee_def.ret_type) { expr.clone().with_type(callee_def.ret_type) } 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 mut genargs = callee_def.genargs.clone(); let inferred_args: Vec<_> = param_types .iter() .zip(args_typed) - .map(|(param, arg)| {}) + .map(|(param, arg)| self.types.infer_type(*param, arg.typ)) .collect(); 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); block.expr = new_root; block diff --git a/src/frontend/types.rs b/src/frontend/types.rs index 9a794a2..b791c4a 100644 --- a/src/frontend/types.rs +++ b/src/frontend/types.rs @@ -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 pub fn is_fully_typed(&self, typ: Type) -> bool { match &self.get(typ).kind {