shithub: mc

Download patch

ref: 57813d7182bbe8320407b6722a4093d3bf4f8dcd
parent: 7ce4415a83be2d05432727ee8f672542e1d5e54e
author: Ori Bernstein <[email protected]>
date: Fri Oct 26 11:18:02 EDT 2012

Check if types are generic before specializing them.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -115,24 +115,6 @@
     return 0;
 }
 
-/* Freshens the type of a declaration. */
-static Type *tyfreshen(Inferstate *st, Type *t)
-{
-    Htab *ht;
-
-    st->ingeneric++;
-    t = tf(st, t);
-    st->ingeneric--;
-
-    tybind(st, t);
-    ht = mkht(strhash, streq);
-    t = tyspecialize(t, ht);
-    htfree(ht);
-    tyunbind(st, t);
-
-    return t;
-}
-
 /* Checks if a type that directly contains itself.
  * Recursive types that contain themselves through
  * pointers or slices are fine, but any other self-inclusion
@@ -174,6 +156,55 @@
     }
     return 0;
 }
+
+
+static int isgeneric(Inferstate *st, Type *t)
+{
+    size_t i;
+
+    switch (t->type) {
+        case Tygeneric: return 1;
+        case Typaram:   return 1;
+        case Tystruct:
+            for (i = 0; i < t->nmemb; i++)
+                if (isgeneric(st, decltype(t->sdecls[i])))
+                    return 1;
+            break;
+        case Tyunion:
+            for (i = 0; i < t->nmemb; i++)
+                if (isgeneric(st, t->udecls[i]->etype))
+                    return 1;
+            break;
+        default:
+            for (i = 0; i < t->nsub; i++)
+                if (isgeneric(st, t->sub[i]))
+                    return 1;
+            break;
+    }
+    return 0;
+}
+
+/* Freshens the type of a declaration. */
+static Type *tyfreshen(Inferstate *st, Type *t)
+{
+    Htab *ht;
+
+    st->ingeneric++;
+    t = tf(st, t);
+    st->ingeneric--;
+
+    if (!isgeneric(st, t))
+        return t;
+
+    tybind(st, t);
+    ht = mkht(strhash, streq);
+    t = tyspecialize(t, ht);
+    htfree(ht);
+    tyunbind(st, t);
+
+    return t;
+}
+
 
 /* Resolves a type and all it's subtypes recursively.*/
 static void tyresolve(Inferstate *st, Type *t)