shithub: mc

Download patch

ref: 6950e5fccf4ebe1da730493bca2284e092b43e90
parent: 555799dbfd11dc0a2edaa53b78100d1eeea6ff06
author: Ori Bernstein <ori@eigenstate.org>
date: Tue Dec 15 18:10:52 EST 2015

Improve trait error messages.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -1560,7 +1560,7 @@
 
 static void specializeimpl(Inferstate *st, Node *n)
 {
-	Node *dcl, *proto, *name;
+	Node *dcl, *proto, *name, *sym;
 	Type *ty;
 	Htab *ht;
 	Trait *t;
@@ -1620,6 +1620,11 @@
 
 		/* and put the specialization into the global stab */
 		name = genericname(proto, ty);
+		sym = getdcl(file->file.globls, name);
+		if (sym)
+			fatal(n, "trait %s already specialized with %s on %s:%d",
+				namestr(t->name), tystr(n->impl.type),
+				fname(sym->loc), lnum(sym->loc));
 		dcl->decl.name = name;
 		putdcl(file->file.globls, dcl);
 		if (debugopt['S'])
@@ -1848,8 +1853,7 @@
 	if (t->type == Tyvar && !noerr) {
 		if (debugopt['T'])
 			dump(file, stdout);
-		fatal(
-				ctx, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(st, ctx));
+		fatal(ctx, "underconstrained type %s near %s", tyfmt(buf, 1024, t), ctxstr(st, ctx));
 	}
 
 	if (debugopt['u'] && !tyeq(orig, t)) {
@@ -1964,9 +1968,11 @@
 static void checkvar(Inferstate *st, Node *n)
 {
 	Node *dcl;
+	Type *ty;
 
 	dcl = decls[n->expr.did];
-	unify(st, n, type(st, n), tyfreshen(st, NULL, type(st, dcl)));
+	ty = tyfreshen(st, NULL, type(st, dcl));
+	unify(st, n, type(st, n), ty);
 }
 
 static void postcheck(Inferstate *st, Node *file)
@@ -2412,7 +2418,7 @@
 			trait = gettrait(f->file.globls, n->impl.traitname);
 			if (!trait)
 				fatal(n, "trait %s does not exist near %s",
-						namestr(n->impl.traitname), ctxstr(st, n));
+					namestr(n->impl.traitname), ctxstr(st, n));
 			ty = tf(st, n->impl.type);
 			settrait(ty, trait);
 		}
@@ -2433,7 +2439,7 @@
 			/* we merge, so we need to get it back again when error checking */
 			if (n->impl.isproto)
 				fatal(n, "missing implementation for prototype '%s %s'",
-						namestr(n->impl.traitname), tystr(n->impl.type));
+					namestr(n->impl.traitname), tystr(n->impl.type));
 		}
 	}
 }
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -415,7 +415,7 @@
 		return d;
 	if (g->decl.trait) {
 		printf("%s\n", namestr(n));
-		fatal(g, "No trait implemented for for %s:%s", namestr(g->decl.name), tystr(to));
+		fatal(g, "no trait implemented for for %s:%s", namestr(g->decl.name), tystr(to));
 	}
 	/* namespaced names need to be looked up in their correct
 	 * context. */