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