shithub: mc

Download patch

ref: 836b83db913333f7954d84a34ae9804865d65dd8
parent: 79428e454cf05c659a18b1928cae8d7ab96dd879
author: Ori Bernstein <[email protected]>
date: Fri Aug 9 07:13:02 EDT 2013

Step towards making generics work.

    We still leave types uninferred sometimes, but it's far closer
    to working.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -281,7 +281,11 @@
             break;
         t = tytab[t->tid];
     }
+    if (t->type == Tygeneric)
+        st->ingeneric++;
     tyresolve(st, t);
+    if (t->type == Tygeneric)
+        st->ingeneric--;
     return t;
 }
 
@@ -1048,7 +1052,8 @@
     Type *t;
 
     t = tf(st, decltype(n));
-    if (decltype(n)->type == Tygeneric) {
+    if (t->type == Tygeneric) {
+        t = tyfreshen(st, t);
         unifyparams(st, n, t, decltype(n));
     }
     settype(st, n, t);
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -62,8 +62,10 @@
             break;
         case Tystruct:
             ret = tydup(t);
+            pushstab(NULL);
             for (i = 0; i < t->nmemb; i++)
                 ret->sdecls[i] = specializenode(t->sdecls[i], tsmap);
+            popstab();
             break;
         case Tyunion:
             ret = tydup(t);
@@ -279,7 +281,8 @@
             r->decl.isconst = n->decl.isconst;
             r->decl.isgeneric = n->decl.isgeneric;
             r->decl.isextern = n->decl.isextern;
-            putdcl(curstab(), r);
+	    if (curstab())
+                putdcl(curstab(), r);
 
             /* init */
             r->decl.init = specializenode(n->decl.init, tsmap);