shithub: mc

Download patch

ref: 65f7649caf6581f62d87e15bb74d72474f582a55
parent: 013bffde621d421e1914491e6249a7486b9a1380
author: Ori Bernstein <[email protected]>
date: Fri Jul 20 13:33:24 EDT 2012

Improve error messages.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -254,24 +254,42 @@
     return tf(st, t);
 }
 
-static char *ctxstr(Node *n)
+static char *ctxstr(Inferstate *st, Node *n)
 {
     char *s;
+    char *t;
+    char *u;
+    char buf[512];
+
     switch (n->type) {
-        default:        s = nodestr(n->type);   break;
-        case Ndecl:     s = declname(n);        break;
-        case Nname:     s = namestr(n);         break;
+        default:
+            s = nodestr(n->type);
+            break;
+        case Ndecl:
+            u = declname(n);
+            t = tystr(tf(st, decltype(n)));
+            snprintf(buf, 512, "%s:%s", u, t);
+            s = strdup(buf);
+            free(t);
+            break;
+        case Nname:
+            s = namestr(n);
+            break;
         case Nexpr:
             if (exprop(n) == Ovar)
-                s = namestr(n->expr.args[0]);
+                u = namestr(n->expr.args[0]);
             else
-                s = opstr(exprop(n));
+                u = opstr(exprop(n));
+            t = tystr(tf(st, exprtype(n)));
+            snprintf(buf, 512, "%s:%s", u, t);
+            s = strdup(buf);
+            free(t);
             break;
     }
     return s;
 }
 
-static void constrain(Node *ctx, Type *a, Cstr *c)
+static void constrain(Inferstate *st, Node *ctx, Type *a, Cstr *c)
 {
     if (a->type == Tyvar) {
         if (!a->cstrs)
@@ -278,7 +296,7 @@
             a->cstrs = mkbs();
         setcstr(a, c);
     } else if (!bshas(a->cstrs, c->cid)) {
-            fatal(ctx->line, "%s needs %s near %s", tystr(a), c->name, ctxstr(ctx));
+            fatal(ctx->line, "%s needs %s near %s", tystr(a), c->name, ctxstr(st, ctx));
     }
 }
 
@@ -296,7 +314,7 @@
     return bsissubset(b->cstrs, a->cstrs);
 }
 
-static void mergecstrs(Node *ctx, Type *a, Type *b)
+static void mergecstrs(Inferstate *st, Node *ctx, Type *a, Type *b)
 {
     if (b->type == Tyvar) {
         /* make sure that if a = b, both have same cstrs */
@@ -309,7 +327,7 @@
     } else {
         if (!cstrcheck(a, b)) {
             dump(file, stdout);
-            fatal(ctx->line, "%s missing constraints for %s near %s", tystr(b), tystr(a), ctxstr(ctx));
+            fatal(ctx->line, "%s missing constraints for %s near %s", tystr(b), tystr(a), ctxstr(st, ctx));
         }
     }
 }
@@ -361,7 +379,7 @@
     }
 
     r = NULL;
-    mergecstrs(ctx, a, b);
+    mergecstrs(st, ctx, a, b);
     if (a->type == Tyvar) {
         tytab[a->tid] = b;
         r = b;
@@ -368,19 +386,19 @@
     }
     if (a->type == Tyvar && b->type != Tyvar) 
         if (occurs(a, b))
-            fatal(ctx->line, "Infinite type %s in %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+            fatal(ctx->line, "Infinite type %s in %s near %s", tystr(a), tystr(b), ctxstr(st, ctx));
 
     if (a->type == b->type || idxhacked(&a, &b)) {
         for (i = 0; i < b->nsub; i++) {
             /* types must have same arity */
             if (i >= a->nsub)
-                fatal(ctx->line, "%s has wrong subtypes for %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(st, ctx));
 
             unify(st, ctx, a->sub[i], b->sub[i]);
         }
         r = b;
     } else if (a->type != Tyvar) {
-        fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+        fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(st, ctx));
     }
     return r;
 }
@@ -527,7 +545,7 @@
         case Oidx:      /* @a[@b::tcint] -> @a */
             t = mktyidxhack(n->line, mktyvar(n->line));
             unify(st, n, type(st, args[0]), t);
-            constrain(n, type(st, args[1]), cstrtab[Tcint]);
+            constrain(st, n, type(st, args[1]), cstrtab[Tcint]);
             settype(st, n, tf(st, t->sub[0]));
             break;
         case Oslice:    /* @a[@b::tcint,@b::tcint] -> @a[,] */
@@ -572,7 +590,7 @@
                 return;
             s = getdcl(curstab(), args[0]);
             if (!s)
-                fatal(n->line, "Undeclared var %s", ctxstr(args[0]));
+                fatal(n->line, "Undeclared var %s", ctxstr(st, args[0]));
 
             if (s->decl.isgeneric)
                 t = freshen(st, s->decl.type);
@@ -589,11 +607,11 @@
         case Ocons:
             uc = getucon(curstab(), args[0]);
             if (!uc)
-                fatal(n->line, "No union constructor %s", ctxstr(args[0]));
+                fatal(n->line, "No union constructor %s", ctxstr(st, args[0]));
             if (!uc->etype && n->expr.nargs > 1)
-                fatal(n->line, "nullary union constructor %s passed arg ", ctxstr(args[0]));
+                fatal(n->line, "nullary union constructor %s passed arg ", ctxstr(st, args[0]));
             else if (uc->etype && n->expr.nargs != 2)
-                fatal(n->line, "union constructor %s needs arg ", ctxstr(args[0]));
+                fatal(n->line, "union constructor %s needs arg ", ctxstr(st, args[0]));
             else if (uc->etype)
                 unify(st, n, uc->etype, type(st, args[1]));
             settype(st, n, uc->utype);
@@ -653,7 +671,7 @@
         unify(st, n, type(st, n), type(st, n->decl.init));
     } else {
         if (n->decl.isconst && !n->decl.isextern)
-            fatal(n->line, "non-extern \"%s\" has no initializer", ctxstr(n));
+            fatal(n->line, "non-extern \"%s\" has no initializer", ctxstr(st, n));
     }
 }
 
@@ -747,7 +765,7 @@
             inferdecl(st, n);
             unbind(st, n);
             if (type(st, n)->type == Typaram && !st->ingeneric)
-                fatal(n->line, "Generic type %s in non-generic near %s\n", tystr(type(st, n)), ctxstr(n));
+                fatal(n->line, "Generic type %s in non-generic near %s\n", tystr(type(st, n)), ctxstr(st, n));
             if (n->decl.isgeneric)
                 st->ingeneric--;
             break;
@@ -765,7 +783,7 @@
             infernode(st, n->ifstmt.cond, NULL, sawret);
             infernode(st, n->ifstmt.iftrue, ret, sawret);
             infernode(st, n->ifstmt.iffalse, ret, sawret);
-            constrain(n, type(st, n->ifstmt.cond), cstrtab[Tctest]);
+            constrain(st, n, type(st, n->ifstmt.cond), cstrtab[Tctest]);
             break;
         case Nloopstmt:
             infernode(st, n->loopstmt.init, ret, sawret);
@@ -772,7 +790,7 @@
             infernode(st, n->loopstmt.cond, NULL, sawret);
             infernode(st, n->loopstmt.step, ret, sawret);
             infernode(st, n->loopstmt.body, ret, sawret);
-            constrain(n, type(st, n->loopstmt.cond), cstrtab[Tctest]);
+            constrain(st, n, type(st, n->loopstmt.cond), cstrtab[Tctest]);
             break;
         case Nmatchstmt:
             infernode(st, n->matchstmt.val, NULL, sawret);
@@ -850,7 +868,7 @@
             t->sub[i] = tyfix(st, ctx, t->sub[i]);
     }
     if (t->type == Tyvar) {
-        fatal(t->line, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(ctx));
+        fatal(t->line, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(st, ctx));
     }
 
     return t;
@@ -879,9 +897,9 @@
         t = tybase(tf(st, type(st, aggr)));
         if (t->type == Tyslice || t->type == Tyarray) {
             if (!strcmp(namestr(memb), "len")) {
-                constrain(n, type(st, n), cstrtab[Tcnum]);
-                constrain(n, type(st, n), cstrtab[Tcint]);
-                constrain(n, type(st, n), cstrtab[Tctest]);
+                constrain(st, n, type(st, n), cstrtab[Tcnum]);
+                constrain(st, n, type(st, n), cstrtab[Tcint]);
+                constrain(st, n, type(st, n), cstrtab[Tctest]);
                 found = 1;
             }
         } else {
@@ -898,7 +916,7 @@
         }
         if (!found)
             fatal(aggr->line, "Type %s has no member \"%s\" near %s",
-                  tystr(type(st, aggr)), ctxstr(memb), ctxstr(aggr));
+                  tystr(type(st, aggr)), ctxstr(st, memb), ctxstr(st, aggr));
     }
 }
 
@@ -919,7 +937,7 @@
     k = htkeys(s->dcl, &n);
     for (i = 0; i < n; i++) {
         d = getdcl(s, k[i]);
-        d->decl.type = tyfix(st, d->decl.name, d->decl.type);
+        d->decl.type = tyfix(st, d, d->decl.type);
     }
     free(k);
 }
@@ -1044,7 +1062,7 @@
         /* if an export has an initializer, it shouldn't be declared in the
          * body */
         if (nl->decl.init && ng)
-            fatal(nl->line, "Export %s double-defined on line %d", ctxstr(nl), ng->line);
+            fatal(nl->line, "Export %s double-defined on line %d", ctxstr(st, nl), ng->line);
         if (!ng)
             putdcl(globls, nl);
         else