summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2017-07-08 00:45:47 -0700
committerOri Bernstein <ori@eigenstate.org>2017-07-08 00:45:47 -0700
commit021df0555170075f937fd3cb62a273eea29147d4 (patch)
treefd585e9a125d5b7fe9fc21cc77dfad1df693091b
parent9512779a27fb78fa0bfe505da59b8af681466e11 (diff)
downloadmc-021df0555170075f937fd3cb62a273eea29147d4.tar.gz
Factor out genericness checks.
It's the same on every use, might as well put it into the function.
-rw-r--r--parse/infer.c28
1 files changed, 14 insertions, 14 deletions
diff --git a/parse/infer.c b/parse/infer.c
index 4623a73..9a11b34 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -58,7 +58,7 @@ static void tybind(Inferstate *st, Type *t);
static Type *tyfix(Inferstate *st, Node *ctx, Type *orig, int noerr);
static void bind(Inferstate *st, Node *n);
static void tyunbind(Inferstate *st);
-static void unbind(Inferstate *st);
+static void unbind(Inferstate *st, Node *n);
static Type *unify(Inferstate *st, Node *ctx, Type *a, Type *b);
static Type *tf(Inferstate *st, Type *t);
@@ -776,6 +776,8 @@ static void bind(Inferstate *st, Node *n)
assert(n->type == Ndecl);
+ if(!n->decl.isgeneric)
+ return;
st->ingeneric++;
bt = mkht(strhash, streq);
lappend(&st->tybindings, &st->ntybindings, bt);
@@ -787,8 +789,10 @@ static void bind(Inferstate *st, Node *n)
/* Rolls back the binding of type parameters in
* the type environment */
-static void unbind(Inferstate *st)
+static void unbind(Inferstate *st, Node *n)
{
+ if(!n->decl.isgeneric)
+ return;
htfree(st->tybindings[st->ntybindings - 1]);
lpop(&st->tybindings, &st->ntybindings);
st->ingeneric--;
@@ -1881,11 +1885,9 @@ static void inferstab(Inferstate *st, Stab *s)
k = htkeys(s->dcl, &n);
for (i = 0; i < n; i++) {
dcl = htget(s->dcl, k[i]);
- if (dcl->decl.isgeneric)
- bind(st, dcl);
+ bind(st, dcl);
tf(st, type(st, dcl));
- if (dcl->decl.isgeneric)
- unbind(st);
+ unbind(st, dcl);
}
free(k);
@@ -1927,14 +1929,12 @@ static void infernode(Inferstate *st, Node **np, Type *ret, int *sawret)
if (debugopt['u'])
indentf(st->indentdepth, "--- infer %s ---\n", declname(n));
st->indentdepth++;
- if (n->decl.isgeneric)
- bind(st, n);
+ bind(st, n);
inferdecl(st, n);
if (type(st, n)->type == Typaram && !st->ingeneric)
fatal(n, "generic type %s in non-generic near %s", tystr(type(st, n)),
ctxstr(st, n));
- if (n->decl.isgeneric)
- unbind(st);
+ unbind(st, n);
st->indentdepth--;
if (debugopt['u'])
indentf(st->indentdepth, "--- done ---\n");
@@ -2288,7 +2288,9 @@ static void stabsub(Inferstate *st, Stab *s)
k = htkeys(s->dcl, &n);
for (i = 0; i < n; i++) {
d = getdcl(s, k[i]);
+ bind(st, d);
d->decl.type = tyfix(st, d, d->decl.type, 0);
+ unbind(st, d);
if (!d->decl.isconst && !d->decl.isgeneric)
continue;
if (d->decl.trait)
@@ -2402,8 +2404,7 @@ static void typesub(Inferstate *st, Node *n, int noerr)
popstab();
break;
case Ndecl:
- if(n->decl.isgeneric)
- bind(st, n);
+ bind(st, n);
settype(st, n, tyfix(st, n, type(st, n), noerr));
if (n->decl.init)
typesub(st, n->decl.init, noerr);
@@ -2414,8 +2415,7 @@ static void typesub(Inferstate *st, Node *n, int noerr)
if (streq(declname(n), "__init__"))
if (!initcompatible(tybase(decltype(n))))
fatal(n, "__init__ must be (->void), got %s", tystr(decltype(n)));
- if (n->decl.isgeneric)
- unbind(st);
+ unbind(st, n);
break;
case Nblock:
pushstab(n->block.scope);