ref: 8c6a9b940b85f46056519373fcca1d9aefd49eec
parent: 25e411cf4abf1437c5e7bfebbe8e1190a921d2dd
author: Ori Bernstein <[email protected]>
date: Mon Aug 19 21:31:51 EDT 2013
Unify generics with names.
--- a/parse/htab.c
+++ b/parse/htab.c
@@ -195,7 +195,7 @@
int streq(void *a, void *b)
{
- return !strcmp(a, b);
+ return a == b || !strcmp(a, b);
}
ulong ptrhash(void *key)
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -99,6 +99,14 @@
return s;
}
+
+static int nameeq(Node *a, Node *b)
+{
+ if (a == b)
+ return 1;
+ return streq(a->name.ns, b->name.ns) && streq(a->name.name, b->name.name);
+}
+
/* Set a scope's enclosing scope up correctly.
* We don't do this in the parser for some reason. */
static void setsuper(Stab *st, Stab *super)
@@ -530,6 +538,11 @@
return 2;
}
+static int hasparam(Type *t)
+{
+ return t->type == Tygeneric || t->type == Tyname;
+}
+
/* Unifies two types, or errors if the types are not unifiable. */
static Type *unify(Inferstate *st, Node *ctx, Type *a, Type *b)
{
@@ -574,11 +587,22 @@
* Otherwise, match up subtypes. */
if ((a->type == b->type || idxhacked(a, b)) && tyrank(a) != 0) {
if (a->nsub != b->nsub)
- fatal(ctx->line, "%s has wrong subtype count for %s (got %d, expected %d) near %s\n",
+ fatal(ctx->line, "%s has wrong subtype count for %s (got %d, expected %d) near %s",
tystr(a), tystr(b), a->nsub, b->nsub, ctxstr(st, ctx));
for (i = 0; i < b->nsub; i++)
unify(st, ctx, a->sub[i], b->sub[i]);
r = b;
+ } else if (hasparam(a) && hasparam(b)) {
+ /* Only Tygeneric and Tyname should be able to unify. And they
+ * should have the same names for this to be true. */
+ if (!nameeq(a->name, b->name))
+ fatal(ctx->line, "%s incompatible with %s near %s",
+ tystr(a), tystr(b), ctxstr(st, ctx));
+ if (a->nparam != b->nparam)
+ fatal(ctx->line, "%s has wrong parameter list for %s near %s",
+ tystr(a), tystr(b), ctxstr(st, ctx));
+ for (i = 0; i < a->nparam; i++)
+ unify(st, ctx, a->param[i], b->param[i]);
} else if (a->type != Tyvar) {
fatal(ctx->line, "%s incompatible with %s near %s",
tystr(a), tystr(b), ctxstr(st, ctx));