ref: 2f319b2408075aa5165cbc8201bca4ec8a5a58b2
parent: f2fa59d669b6e1470a3c18c545abfbb6fda39ff8
author: Ori Bernstein <[email protected]>
date: Fri Dec 20 06:28:53 EST 2013
Specialize specializes specialized types correctly If we specialize option(@a) -> option(@b), we used to respecialize on @a, not @b. This would lead to spurious type variables if we had, for example: (x:foo(@x) -> option(@x)) Because we would generate the following specializations: foo(@x) => foo($123) option(@a) => foo($234) instead of foo(@x) => foo($123) option(@x) => foo($123)
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -45,6 +45,7 @@
{
Type *ret, *tmp;
size_t i;
+ Type **subst;
if (hthas(tsmap, t))
return htget(tsmap, t);
@@ -57,17 +58,21 @@
if (!hasparams(t)) {
ret = t;
} else {
+ if (t->narg)
+ subst = t->arg;
+ else
+ subst = t->param;
for (i = 0; i < t->nparam; i++) {
- if (hthas(tsmap, t->param[i]))
+ if (subst[i]->type != Typaram || hthas(tsmap, subst[i]))
continue;
- tmp = mktyvar(t->param[i]->line);
- htput(tsmap, t->param[i], tmp);
+ tmp = mktyvar(subst[i]->line);
+ htput(tsmap, subst[i], tmp);
}
ret = mktyname(t->line, t->name, t->param, t->nparam, tyspecialize(t->sub[0], tsmap));
ret->issynth = 1;
htput(tsmap, t, ret);
for (i = 0; i < t->nparam; i++)
- lappend(&ret->arg, &ret->narg, tyspecialize(t->param[i], tsmap));
+ lappend(&ret->arg, &ret->narg, tyspecialize(subst[i], tsmap));
ret->isgeneric = hasparams(ret);
}
break;