shithub: mc

Download patch

ref: 6a8e8597118325f5d43f065acbec97c2407c228f
parent: 57ea63821dfbf31401b7e40e86d4eb6e31015eaf
author: Ori Bernstein <[email protected]>
date: Fri Jun 22 21:02:23 EDT 2012

Fix infinite recursion on infinite types.

    This solves the occur check problem.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -249,6 +249,18 @@
     return (a->type == Tyvar && a->nsub > 0) || a->type == Tyarray || a->type == Tyslice;
 }
 
+static int occurs(Type *a, Type *b)
+{
+    size_t i;
+
+    if (a == b)
+        return 1;
+    for (i = 0; i < b->nsub; i++)
+        if (occurs(a, b->sub[i]))
+            return 1;
+    return 0;
+}
+
 static Type *unify(Node *ctx, Type *a, Type *b)
 {
     Type *t;
@@ -272,6 +284,10 @@
         tytab[a->tid] = b;
         r = b;
     }
+    if (b->type != Tyvar) 
+        if (occurs(a, b))
+            fatal(ctx->line, "Infinite type %s in %s near %s", tystr(a), tystr(b), ctxstr(ctx));
+
     if (a->type == b->type || idxhacked(&a, &b)) {
         for (i = 0; i < b->nsub; i++) {
             /* types must have same arity */
--- a/test/tests
+++ b/test/tests
@@ -40,3 +40,4 @@
 F declmismatch
 F infermismatch
 F flow
+F occur