about summary refs log tree commit diff
path: root/users/glittershark/achilles/src/tc
diff options
context:
space:
mode:
authorGriffin Smith <grfn@gws.fyi>2021-03-20T22·14-0400
committerglittershark <grfn@gws.fyi>2021-03-20T22·20+0000
commit8d5f3029e531d1163668f34e65b73cb6d639767f (patch)
tree48c511fc7eac8d1b46c98af7daa5708b78959449 /users/glittershark/achilles/src/tc
parente7033bd8b066c8f4163a4f6aa618a39d8110dc6c (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.rs20
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 {