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