summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--parse/specialize.c19
-rw-r--r--test/recgeneric.myr14
-rw-r--r--test/tests1
3 files changed, 28 insertions, 6 deletions
diff --git a/parse/specialize.c b/parse/specialize.c
index 4961230..1db921f 100644
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -32,12 +32,12 @@ void addtraits(Type *t, Bitset *traits)
* 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 @@ Type *tyspecialize(Type *t, Htab *tsmap, Htab *delayed)
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);
diff --git a/test/recgeneric.myr b/test/recgeneric.myr
new file mode 100644
index 0000000..28b9fab
--- /dev/null
+++ b/test/recgeneric.myr
@@ -0,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")
+}
diff --git a/test/tests b/test/tests
index 4f47773..f9da77c 100644
--- a/test/tests
+++ b/test/tests
@@ -94,6 +94,7 @@ B generictype E 0
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