summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2014-07-14 21:42:12 -0400
committerOri Bernstein <ori@eigenstate.org>2014-07-14 21:42:12 -0400
commit17dda8e9ba00a68218db115871dad8aa17da146f (patch)
tree857cdca9b5ba326876b8715d1c1ce5f21cd80da0
parent44e5ed3ebbb9c3a8e5e5d809e0f5a6991c4b9570 (diff)
downloadmc-17dda8e9ba00a68218db115871dad8aa17da146f.tar.gz
Fix generic type construction.
-rw-r--r--parse/infer.c11
-rw-r--r--parse/specialize.c34
-rwxr-xr-xtest/genericmakebin0 -> 179952 bytes
-rw-r--r--test/tests1
4 files changed, 26 insertions, 20 deletions
diff --git a/parse/infer.c b/parse/infer.c
index cd11ec0..0e70b05 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -341,7 +341,6 @@ static Type *tf(Inferstate *st, Type *orig)
unify(st, NULL, t->arg[i], orig->arg[i]);
}
}
- assert(is == isgeneric(orig));
st->ingeneric -= isgeneric(orig);
return t;
}
@@ -727,8 +726,10 @@ static void unifycall(Inferstate *st, Node *n)
{
size_t i;
Type *ft;
+ char *ret, *ctx;
ft = type(st, n->expr.args[0]);
+
if (ft->type == Tyvar) {
/* the first arg is the function itself, so it shouldn't be counted */
ft = mktyfunc(n->line, &n->expr.args[1], n->expr.nargs - 1, mktyvar(n->line));
@@ -747,6 +748,14 @@ static void unifycall(Inferstate *st, Node *n)
if (i < ft->nsub && ft->sub[i]->type != Tyvalist)
fatal(n->line, "%s arity mismatch (expected %zd args, got %zd)",
ctxstr(st, n->expr.args[0]), ft->nsub - 1, i - 1);
+ if (debugopt['u']) {
+ ret = tystr(ft->sub[0]);
+ ctx = ctxstr(st, n->expr.args[0]);
+ printf("Call of %s returns %s\n", ctx, ret);
+ free(ctx);
+ free(ret);
+ }
+
settype(st, n, ft->sub[0]);
}
diff --git a/parse/specialize.c b/parse/specialize.c
index aacd87d..ca94237 100644
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -46,26 +46,22 @@ Type *tyspecialize(Type *t, Htab *tsmap)
htput(tsmap, t, ret);
break;
case Tyname:
- if (!hasparams(t)) {
- ret = t;
- } else {
- if (t->narg)
- subst = t->arg;
- else
- subst = t->param;
- for (i = 0; i < t->nparam; i++) {
- if (subst[i]->type != Typaram || hthas(tsmap, subst[i]))
- continue;
- tmp = mktyvar(subst[i]->line);
- addtraits(tmp, subst[i]->traits);
- 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(subst[i], tsmap));
+ if (t->narg)
+ subst = t->arg;
+ else
+ subst = t->param;
+ for (i = 0; i < t->nparam; i++) {
+ if (subst[i]->type != Typaram || hthas(tsmap, subst[i]))
+ continue;
+ tmp = mktyvar(subst[i]->line);
+ addtraits(tmp, subst[i]->traits);
+ 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(subst[i], tsmap));
break;
case Tystruct:
ret = tydup(t);
diff --git a/test/genericmake b/test/genericmake
new file mode 100755
index 0000000..d86f873
--- /dev/null
+++ b/test/genericmake
Binary files differ
diff --git a/test/tests b/test/tests
index e06e93a..f4b0faf 100644
--- a/test/tests
+++ b/test/tests
@@ -85,6 +85,7 @@ B genericret E 42
B genericmatch E 15
B genericrec E 0
# B genericchain P "val = 123" ## BUGGERED
+B genericmake P "val = 123"
B stdopt-some E 42
B stdopt-none E 42
B stdopt-mk E 42