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 = ", ";
--
⑨