shithub: mc

Download patch

ref: fa7c9a073813587594aaced70309fb7f7d133a7a
parent: 8dbfb1c654f6589369c518b400368e725e69f808
author: Ori Bernstein <[email protected]>
date: Thu Jun 21 16:39:03 EDT 2012

Start implementation of freshening.

    Note, we should use the correct bindings. We currently create
    a new generic for every instance of the typaram, even if it's
    not unique. This is broken, but it's worth a commit.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -32,7 +32,7 @@
     st->super = super;
 }
 
-static int bound(Type *t)
+static int isbound(Type *t)
 {
     ssize_t i;
     Type *p;
@@ -45,6 +45,27 @@
     return 0;
 }
 
+static Type *freshen(Type *t)
+{
+    Type *ret;
+    size_t i;
+
+    t = tf(t);
+    if (t->type == Typaram && !isbound(t))
+        return mktyvar(t->line);
+    if (t->nsub == 0)
+        return t;
+
+    ret = zalloc(sizeof(Type));
+    *ret = *t;
+    ret->sub = zalloc(t->nsub * sizeof(Type *));
+    for (i = 0; i < t->nsub; i++)
+        ret->sub[i] = freshen(t->sub[i]);
+    printf("Freshened %s to %s\n", tystr(t), tystr(ret));
+    return ret;
+}
+
+
 static void tyresolve(Type *t)
 {
     size_t i, nn;
@@ -117,7 +138,6 @@
             die("can't set type of %s", nodestr(n->type));
             break;
     }
-
 }
 
 static Type *littype(Node *n)
@@ -191,8 +211,10 @@
         else if (b->cstrs)
             a->cstrs = bsdup(b->cstrs);
     } else {
-        if (!cstrcheck(a, b))
-            fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+        if (!cstrcheck(a, b)) {
+            dump(file, stdout);
+            fatal(ctx->line, "%s does not match constraints for %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+        }
     }
 }
 
@@ -238,7 +260,7 @@
         for (i = 0; i < b->nsub; i++) {
             /* types must have same arity */
             if (i >= a->nsub)
-                fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+                fatal(ctx->line, "%s has wrong subtypes for %s near %s", tystr(a), tystr(b), ctxstr(ctx));
 
             unify(ctx, a->sub[i], b->sub[i]);
         }
@@ -258,7 +280,6 @@
     if (ft->type == Tyvar) {
         /* the first arg is the function itself, so it shouldn't be counted */
         ft = mktyfunc(n->line, &n->expr.args[1], n->expr.nargs - 1, mktyvar(n->line));
-        unify(n, type(n->expr.args[0]), ft);
     }
     for (i = 1; i < n->expr.nargs; i++) {
         if (ft->sub[i]->type == Tyvalist)
@@ -295,13 +316,6 @@
     *ret = var;
 }
 
-static Type *freshen(Type *t)
-{
-    if (t->type != Typaram || bound(t))
-        return t;
-    return mktyvar(t->line);
-}
-
 static void inferexpr(Node *n, Type *ret, int *sawret)
 {
     Node **args;
@@ -431,8 +445,12 @@
             s = getdcl(curstab(), args[0]);
             if (!s)
                 fatal(n->line, "Undeclared var %s", ctxstr(args[0]));
+
+            if (s->decl.isgeneric)
+                t = freshen(s->decl.type);
             else
-                settype(n, freshen(s->decl.type));
+                t = s->decl.type;
+            settype(n, t);
             n->expr.did = s->decl.did;
             break;
         case Olit:      /* <lit>:@a::tyclass -> @a */
@@ -508,7 +526,7 @@
 
     if (hthas(bt, t->pname))
         unify(NULL, htget(bt, t->pname), t);
-    else if (bound(t))
+    else if (isbound(t))
         return;
 
     htput(bt, t->pname, t);