shithub: mc

Download patch

ref: c90b97b335a792b54d2f33523623a56b29297d84
parent: 0b8d09bb5198fb4d60d88e33b46862aec69f6e27
author: Ori Bernstein <[email protected]>
date: Sun Apr 19 17:20:37 EDT 2015

Improve error messages.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -212,16 +212,14 @@
 static void typeerror(Inferstate *st, Type *a, Type *b, Node *ctx, char *msg)
 {
     char *t1, *t2, *c;
-    int line;
 
     t1 = tystr(tyfix(st, NULL, a, 1));
     t2 = tystr(tyfix(st, NULL, b, 1));
-    line = ctx->loc.line;
     c = ctxstr(st, ctx);
     if (msg)
-        fatal(ctx, "Type \"%s\" incompatible with \"%s\" near line %d, line %d, %s: %s", t1, t2, line, c, msg);
+        fatal(ctx, "Type \"%s\" incompatible with \"%s\" near %s: %s", t1, t2, c, msg);
     else
-        fatal(ctx, "Type \"%s\" incompatible with \"%s\" near line %d, line %d, %s", t1, t2, line, c);
+        fatal(ctx, "Type \"%s\" incompatible with \"%s\" near %s", t1, t2, c);
     free(t1);
     free(t2);
     free(c);
@@ -678,7 +676,7 @@
             a->traits = mkbs();
         settrait(a, c);
     } else if (!a->traits || !bshas(a->traits, c->uid)) {
-        fatal(ctx, "%s needs %s near line %d, line %d, %s", tystr(a), namestr(c->name), ctx->loc.line, ctxstr(st, ctx));
+        fatal(ctx, "%s needs %s near %s", tystr(a), namestr(c->name), ctxstr(st, ctx));
     }
 }
 
@@ -722,7 +720,7 @@
             }
             tyfmt(abuf, sizeof abuf, a);
             tyfmt(bbuf, sizeof bbuf, b);
-            fatal(ctx, "%s missing traits %s for %s near line %d, %s", bbuf, traitbuf, abuf, ctx->loc.line, ctxstr(st, ctx));
+            fatal(ctx, "%s missing traits %s for %s near %s", bbuf, traitbuf, abuf, ctxstr(st, ctx));
         }
     }
 }
@@ -778,7 +776,7 @@
     int found;
 
     if (u->nmemb != v->nmemb)
-        fatal(ctx, "can't unify %s and %s near line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
+        fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
 
     for (i = 0; i < u->nmemb; i++) {
         found = 0;
@@ -791,10 +789,10 @@
             else if (u->udecls[i]->etype && v->udecls[i]->etype)
                 unify(st, ctx, u->udecls[i]->etype, v->udecls[i]->etype);
             else
-                fatal(ctx, "can't unify %s and %s near line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
+                fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
         }
         if (!found)
-            fatal(ctx, "can't unify %s and %s near line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
+            fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
     }
 }
 
@@ -804,7 +802,7 @@
     int found;
 
     if (u->nmemb != v->nmemb)
-        fatal(ctx, "can't unify %s and %s near line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
+        fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
 
     for (i = 0; i < u->nmemb; i++) {
         found = 0;
@@ -815,7 +813,7 @@
             unify(st, u->sdecls[i], type(st, u->sdecls[i]), type(st, v->sdecls[i]));
         }
         if (!found)
-            fatal(ctx, "can't unify %s and %s near line %d, %s\n", tystr(u), tystr(v), ctx->loc.line, ctxstr(st, ctx));
+            fatal(ctx, "can't unify %s and %s near %s\n", tystr(u), tystr(v), ctxstr(st, ctx));
     }
 }
 
@@ -879,7 +877,10 @@
         if (a->type == Tyname && !nameeq(a->name, b->name))
             typeerror(st, a, b, ctx, NULL);
         if (a->nsub != b->nsub) {
-            typeerror(st, a, b, ctx, "subtypes are incompatible");
+            if (tybase(a)->type == Tyfunc)
+                typeerror(st, a, b, ctx, "function arity mismatch");
+            else
+                typeerror(st, a, b, ctx, "subtype counts incompatible");
         }
         for (i = 0; i < b->nsub; i++)
             unify(st, ctx, a->sub[i], b->sub[i]);
@@ -943,7 +944,7 @@
     /* first arg: function itself */
     for (i = 1; i < n->expr.nargs; i++)
         if (exprtype(n->expr.args[i])->type == Tyvoid)
-            fatal(n, "void passed where value expected, near line %d, %s", n->loc.line, ctxstr(st, n));
+            fatal(n, "void passed where value expected, near %s", ctxstr(st, n));
     for (i = 1; i < n->expr.nargs; i++) {
         if (i == ft->nsub)
             fatal(n, "%s arity mismatch (expected %zd args, got %zd)",
@@ -985,7 +986,7 @@
         return;
 
     if (a->narg != b->narg)
-        fatal(ctx, "Mismatched parameter list sizes: %s with %s near line %d, %s", tystr(a), tystr(b), ctx->loc.line, ctxstr(st, ctx));
+        fatal(ctx, "Mismatched parameter list sizes: %s with %s near %s", tystr(a), tystr(b), ctxstr(st, ctx));
     for (i = 0; i < a->narg; i++)
         unify(st, ctx, a->arg[i], b->arg[i]);
 }
@@ -1180,7 +1181,7 @@
                 else if (s->decl.isconst)
                     t = s->decl.type;
                 else
-                    fatal(n, "Can't match against non-constant variables near line %d, %s", n->loc.line, ctxstr(st, n));
+                    fatal(n, "Can't match against non-constant variables near %s", ctxstr(st, n));
             } else {
                 t = mktyvar(n->loc);
                 s = mkdecl(n->loc, n->expr.args[0], t);
@@ -1498,8 +1499,8 @@
             }
         }
         if (!proto)
-            fatal(n, "Declaration %s missing in %s, near line %d, %s",
-                  namestr(dcl->decl.name), namestr(t->name), n->loc.line, ctxstr(st, n));
+            fatal(n, "Declaration %s missing in %s, near %s",
+                  namestr(dcl->decl.name), namestr(t->name), ctxstr(st, n));
 
         /* infer and unify types */
         if (n->impl.type->type == Tygeneric || n->impl.type->type == Typaram)
@@ -1587,7 +1588,7 @@
             bind(st, n);
             inferdecl(st, n);
             if (type(st, n)->type == Typaram && !st->ingeneric)
-                fatal(n, "Generic type %s in non-generic near line %d, %s", tystr(type(st, n)), n->loc.line, ctxstr(st, n));
+                fatal(n, "Generic type %s in non-generic near %s", tystr(type(st, n)), ctxstr(st, n));
             unbind(st, n);
             st->indentdepth--;
             if (debugopt['u'])
@@ -1633,7 +1634,7 @@
         case Nmatchstmt:
             infernode(st, &n->matchstmt.val, NULL, sawret);
             if (tybase(type(st, n->matchstmt.val))->type == Tyvoid)
-                fatal(n, "Can't match against a void type near line %d, %s", n->loc.line, ctxstr(st, n->matchstmt.val));
+                fatal(n, "Can't match against a void type near %s", ctxstr(st, n->matchstmt.val));
             for (i = 0; i < n->matchstmt.nmatches; i++) {
                 infernode(st, &n->matchstmt.matches[i], ret, sawret);
                 unify(st, n->matchstmt.matches[i]->match.pat, type(st, n->matchstmt.val), type(st, n->matchstmt.matches[i]->match.pat));
@@ -1693,7 +1694,7 @@
         if (t->type == Tyvar)
             t = delayed;
         else if (tybase(t)->type != delayed->type && !noerr)
-            fatal(ctx, "Type %s not compatible with %s near line %d, %s\n", tystr(t), tystr(delayed), ctx->loc.line, ctxstr(st, ctx));
+            fatal(ctx, "Type %s not compatible with %s near %s\n", tystr(t), tystr(delayed), ctxstr(st, ctx));
     }
     if (t->type == Tyvar) {
         if (hastrait(t, traittab[Tcint]) && checktraits(t, tyint))
@@ -1725,7 +1726,7 @@
     if (t->type == Tyvar && !noerr) {
         if (debugopt['T'])
             dump(file, stdout);
-        lfatal(t->loc, "underconstrained type %s near line %d, %s", tyfmt(buf, 1024, t), ctx->loc.line, ctxstr(st, ctx));
+        lfatal(t->loc, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(st, ctx));
     }
 
     if (debugopt['u'] && !tyeq(orig, t)) {
@@ -1777,7 +1778,7 @@
         if (tybase(t)->type == Typtr)
             t = tybase(tf(st, t->sub[0]));
         if (tybase(t)->type != Tystruct)
-            fatal(n, "type %s does not support member operators near line %d, %s", tystr(t), n->loc.line, ctxstr(st, n));
+            fatal(n, "type %s does not support member operators near %s", tystr(t), ctxstr(st, n));
         nl = t->sdecls;
         for (i = 0; i < t->nmemb; i++) {
             if (!strcmp(namestr(memb), declname(nl[i]))) {
@@ -1788,8 +1789,8 @@
         }
     }
     if (!found)
-        fatal(aggr, "Type %s has no member \"%s\" near line %d, %s",
-              tystr(type(st, aggr)), ctxstr(st, memb), n->loc.line, ctxstr(st, aggr));
+        fatal(aggr, "Type %s has no member \"%s\" near %s",
+              tystr(type(st, aggr)), ctxstr(st, memb), ctxstr(st, aggr));
 }
 
 static void checkstruct(Inferstate *st, Node *n)
@@ -1800,7 +1801,7 @@
 
     t = tybase(tf(st, n->lit.type));
     if (t->type != Tystruct)
-        fatal(n, "Type %s for struct literal is not struct near line %d, %s", tystr(t), n->loc.line, ctxstr(st, n));
+        fatal(n, "Type %s for struct literal is not struct near %s", tystr(t), ctxstr(st, n));
 
     for (i = 0; i < n->expr.nargs; i++) {
         val = n->expr.args[i];
@@ -1815,8 +1816,8 @@
         }
 
         if (!et)
-            fatal(n, "Could not find member %s in struct %s, near line %d, %s",
-                  namestr(name), tystr(t), n->loc.line, ctxstr(st, n));
+            fatal(n, "Could not find member %s in struct %s, near %s",
+                  namestr(name), tystr(t), ctxstr(st, n));
 
         unify(st, val, et, type(st, val));
     }
@@ -2222,11 +2223,10 @@
 
 void applytraits(Inferstate *st, Node *f)
 {
-    char *ctx, *name;
-    Trait *trait;
-    Type *ty;
     size_t i;
     Node *n;
+    Trait *trait;
+    Type *ty;
 
     pushstab(f->file.globls);
     /* for now, traits can only be declared globally */
@@ -2234,12 +2234,8 @@
         if (f->file.stmts[i]->type == Nimpl) {
             n = f->file.stmts[i];
             trait = gettrait(f->file.globls, n->impl.traitname);
-            if (!trait) {
-                name = namestr(n->impl.traitname);
-                ctx = ctxstr(st, n);
-                fatal(n, "trait %s does not exist near line %d, %s", name, n->loc.line, ctx);
-                free(ctx);
-            }
+            if (!trait)
+                fatal(n, "trait %s does not exist near %s", namestr(n->impl.traitname), ctxstr(st, n));
             ty = tf(st, n->impl.type);
             settrait(ty, trait);
         }