shithub: mc

Download patch

ref: e3b7056a409cf0480dc12b7d3f5e3eb34c36db15
parent: e30e522d8b8ddc893c622c34207e24abc1ec12c0
author: Ori Bernstein <[email protected]>
date: Mon Jan 9 19:52:09 EST 2012

Constrain conditional tests to be testable

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -145,7 +145,7 @@
     return s;
 }
 
-static void matchcstrs(Node *ctx, Type *a, Type *b)
+static void mergecstrs(Node *ctx, Type *a, Type *b)
 {
     if (b->type == Tyvar) {
         /* make sure that if a = b, both have same cstrs */
@@ -181,7 +181,7 @@
         b = t;
     }
 
-    matchcstrs(ctx, a, b);
+    mergecstrs(ctx, a, b);
     if (a->type != b->type) {
         if (a->type == Tyvar)
             tytab[a->tid] = b;
@@ -195,7 +195,7 @@
                 fatal(ctx->line, "%s incompatible with %s near %s", tystr(a), tystr(b), ctxstr(ctx));
 
             /* FIXME: recurse properly.
-               matchcstrs(ctx, a, b);
+               mergecstrs(ctx, a, b);
                unify(ctx, a->sub[i], b->sub[i]);
                */
         }
@@ -382,12 +382,14 @@
             infernode(n->ifstmt.cond, NULL, sawret);
             infernode(n->ifstmt.iftrue, ret, sawret);
             infernode(n->ifstmt.iffalse, ret, sawret);
+            constrain(type(n->ifstmt.cond), cstrtab[Tctest]);
             break;
         case Nloopstmt:
-            infernode(n->loopstmt.cond, NULL, sawret);
             infernode(n->loopstmt.init, ret, sawret);
+            infernode(n->loopstmt.cond, NULL, sawret);
             infernode(n->loopstmt.step, ret, sawret);
             infernode(n->loopstmt.body, ret, sawret);
+            constrain(type(n->loopstmt.cond), cstrtab[Tctest]);
             break;
         case Nexpr:
             inferexpr(n, ret, sawret);