ref: 021df0555170075f937fd3cb62a273eea29147d4
parent: 9512779a27fb78fa0bfe505da59b8af681466e11
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Jul 7 20:45:47 EDT 2017
Factor out genericness checks. It's the same on every use, might as well put it into the function.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -58,7 +58,7 @@
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 @@
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 @@
/* 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 @@
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 @@
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 @@
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 @@
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 @@
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);