diff options
author | Griffin Smith <grfn@gws.fyi> | 2021-03-20T22·14-0400 |
---|---|---|
committer | glittershark <grfn@gws.fyi> | 2021-03-20T22·20+0000 |
commit | 8d5f3029e531d1163668f34e65b73cb6d639767f (patch) | |
tree | 48c511fc7eac8d1b46c98af7daa5708b78959449 /users/glittershark/achilles/src/tc | |
parent | e7033bd8b066c8f4163a4f6aa618a39d8110dc6c (diff) |
feat(gs/achilles): Implement very basic monomorphization r/2296
Implement very basic monomorphization, by recording type variable instantiations when typechecking Call nodes and then using those in a new hir Visitor trait to copy the body of any generic decls for each possible set of instantiation of the type variables. Change-Id: Iab54030973e5d66e2b8bcd074b4cb6c001a90123 Reviewed-on: https://cl.tvl.fyi/c/depot/+/2617 Reviewed-by: glittershark <grfn@gws.fyi> Tested-by: BuildkiteCI
Diffstat (limited to 'users/glittershark/achilles/src/tc')
-rw-r--r-- | users/glittershark/achilles/src/tc/mod.rs | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/users/glittershark/achilles/src/tc/mod.rs b/users/glittershark/achilles/src/tc/mod.rs index f3cb40a8b010..137561978f00 100644 --- a/users/glittershark/achilles/src/tc/mod.rs +++ b/users/glittershark/achilles/src/tc/mod.rs @@ -266,6 +266,7 @@ impl<'ast> Typechecker<'ast> { args: args.iter().map(|(_, ty)| ty.clone()).collect(), ret: Box::new(body.type_().clone()), }, + type_args: vec![], // TODO fill in once we do let generalization args, body: Box::new(body), }) @@ -289,9 +290,10 @@ impl<'ast> Typechecker<'ast> { Ok(arg) }) .try_collect()?; - self.commit_instantiations(); + let type_args = self.commit_instantiations(); Ok(hir::Expr::Call { fun: Box::new(fun), + type_args, args, type_: ret_ty, }) @@ -325,8 +327,14 @@ impl<'ast> Typechecker<'ast> { self.env.set(name.clone(), type_); self.env.pop(); match body { - hir::Expr::Fun { args, body, type_ } => Ok(Some(hir::Decl::Fun { + hir::Expr::Fun { + type_args, + args, + body, + type_, + } => Ok(Some(hir::Decl::Fun { name, + type_args, args, body, type_, @@ -538,17 +546,21 @@ impl<'ast> Typechecker<'ast> { }) } - fn commit_instantiations(&mut self) { + fn commit_instantiations(&mut self) -> HashMap<Ident<'ast>, Type> { + let mut res = HashMap::new(); let mut ctx = mem::take(&mut self.ctx); for (_, v) in ctx.iter_mut() { if let Type::Univ(tv) = v { - if let Some(concrete) = self.instantiations.resolve(&self.name_univ(*tv)) { + let tv_name = self.name_univ(*tv); + if let Some(concrete) = self.instantiations.resolve(&tv_name) { + res.insert(tv_name, concrete.clone()); *v = concrete.clone(); } } } self.ctx = ctx; self.instantiations.pop(); + res } fn types_match(&self, type_: &Type, ast_type: &ast::Type<'ast>) -> bool { |