ref: 0116ef24cb193165de85d3a707d4dbd64ba1b60f
parent: f9c8f07de30e44dc51e82d8c8a83553ac36b92f6
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jul 28 11:40:57 EDT 2012
Fix up type index hacks a bit. We rank and order types by their unifiability.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -335,18 +335,8 @@
}
}
-static int idxhacked(Type **pa, Type **pb)
+static int idxhacked(Type *a, Type *b)
{
- Type *a, *b;
-
- a = *pa;
- b = *pb;
- /* we want to unify Tyidxhack => concrete indexable. Flip
- * to make this happen, if needed */
- if (b->type == Tyvar && b->nsub > 0) {
- *pb = a;
- *pa = b;
- }
return (a->type == Tyvar && a->nsub > 0) || a->type == Tyarray || a->type == Tyslice;
}
@@ -364,6 +354,16 @@
return 0;
}
+static int tyrank(Type *t)
+{
+ if (t->type == Tyvar && t->nsub == 0)
+ return 0;
+ if (t->type == Tyvar && t->nsub > 0)
+ return 1;
+ else
+ return 2;
+}
+
static Type *unify(Inferstate *st, Node *ctx, Type *a, Type *b)
{
Type *t;
@@ -375,7 +375,7 @@
b = tf(st, b);
if (a == b)
return a;
- if (b->type == Tyvar) {
+ if (tyrank(b) < tyrank(a)) {
t = a;
a = b;
b = t;
@@ -391,7 +391,7 @@
if (occurs(a, b))
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)) {
+ if ((a->type == b->type || idxhacked(a, b)) && tyrank(a) != 0) {
for (i = 0; i < b->nsub; i++) {
/* types must have same arity */
if (i >= a->nsub)
--- a/parse/type.c
+++ b/parse/type.c
@@ -403,7 +403,7 @@
p += snprintf(p, end - p, "@$%d", t->tid);
if (t->nsub) {
p += snprintf(p, end - p, "(");
- for (i = 1; i < t->nsub; i++) {
+ for (i = 0; i < t->nsub; i++) {
p += snprintf(p, end - p, "%s", sep);
p += tybfmt(p, end - p, t->sub[i]);
sep = ", ";
--
⑨