shithub: mc

Download patch

ref: a555f36aad5963dc600bc0af9433c39ced49b476
parent: fb8f4a81096140b3c35e0932d20420708a7845ef
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jan 23 20:10:15 EST 2016

Fix recursive types nested inside generics.

--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -32,12 +32,12 @@
  * parameters (type schemes in most literature)
  * replaced with type variables that we can unify
  * against */
-Type *tyspecialize(Type *t, Htab *tsmap, Htab *delayed)
+Type *tyspecialize(Type *orig, Htab *tsmap, Htab *delayed)
 {
-	Type *ret, *tmp, **arg;
+	Type *t, *ret, *tmp, **arg, *var;
 	size_t i, narg;
 
-	t = tysearch(t);
+	t = tysearch(orig);
 	if (hthas(tsmap, t))
 		return htget(tsmap, t);
 	arg = NULL;
@@ -49,20 +49,27 @@
 		htput(tsmap, t, ret);
 		break;
 	case Tygeneric:
+		var = mktyvar(t->loc);
+		htput(tsmap, t, var);
+		for (i = 0; i < t->ngparam; i++)
+			lappend(&arg, &narg, tyspecialize(t->gparam[i], tsmap, delayed));
 		ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
 		ret->issynth = 1;
-		htput(tsmap, t, ret);
-		for (i = 0; i < t->ngparam; i++)
-			lappend(&ret->arg, &ret->narg, tyspecialize(t->gparam[i], tsmap, delayed));
+		ret->arg = arg;
+		ret->narg = narg;
+		tytab[var->tid] = ret;
 		break;
 	case Tyname:
 		if (!hasparams(t))
 			return t;
+		var = mktyvar(t->loc);
+		htput(tsmap, t, var);
 		for (i = 0; i < t->narg; i++)
 			lappend(&arg, &narg, tyspecialize(t->arg[i], tsmap, delayed));
 		ret = mktyname(t->loc, t->name, tyspecialize(t->sub[0], tsmap, delayed));
 		ret->arg = arg;
 		ret->narg = narg;
+		tytab[var->tid] = ret;
 		break;
 	case Tystruct:
 		ret = tydup(t);
--- /dev/null
+++ b/test/recgeneric.myr
@@ -1,0 +1,14 @@
+use std
+
+type o(@a::integral) = union
+	`S @a
+;;
+
+type x(@k) = struct
+	n  : o(x(@k)#)
+;;
+
+const main = {
+	var test : x(int)
+	std.put("built\n")
+}
--- a/test/tests
+++ b/test/tests
@@ -94,6 +94,7 @@
 B genericret	E	42
 B genericmatch	E	15
 B genericrec	E	0
+B recgeneric	P	'built'
 # B genericchain	P	'val = 123' ## BUGGERED
 B genericmake	P	'val = 123'
 B genericuret	E	42