diff options
author | Ori Bernstein <ori@eigenstate.org> | 2014-07-14 21:42:12 -0400 |
---|---|---|
committer | Ori Bernstein <ori@eigenstate.org> | 2014-07-14 21:42:12 -0400 |
commit | 17dda8e9ba00a68218db115871dad8aa17da146f (patch) | |
tree | 857cdca9b5ba326876b8715d1c1ce5f21cd80da0 | |
parent | 44e5ed3ebbb9c3a8e5e5d809e0f5a6991c4b9570 (diff) | |
download | mc-17dda8e9ba00a68218db115871dad8aa17da146f.tar.gz |
Fix generic type construction.
-rw-r--r-- | parse/infer.c | 11 | ||||
-rw-r--r-- | parse/specialize.c | 34 | ||||
-rwxr-xr-x | test/genericmake | bin | 0 -> 179952 bytes | |||
-rw-r--r-- | test/tests | 1 |
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 Binary files differnew file mode 100755 index 0000000..d86f873 --- /dev/null +++ b/test/genericmake @@ -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 |