ref: 01cf9608db97e2b4fe6bec921ab1c28201605f82
parent: 1c20d382566fcdfdf5585b1bd8f1f27d7dbd6425
author: Ori Bernstein <ori@eigenstate.org>
date: Sun Mar 3 19:17:19 EST 2019
Get a bit better at wrangling type bindings.
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -1250,10 +1250,11 @@
if (init->type != Nexpr || exprop(init) != Olit)
return;
- if (init->lit.littype != Lfunc)
+ if (init->expr.args[0]->lit.littype != Lfunc)
return;
- f = init->lit.fnval;
- f->func.env = dcl->decl.env;
+ f = init->expr.args[0]->lit.fnval;
+ if (!dcl->decl.env)
+ dcl->decl.env = mkenv();
bindtype(dcl->decl.env, f->func.type);
}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -339,14 +339,8 @@
static void
setsuperenv(Tyenv *e, Tyenv *super)
{
- Tyenv *te;
-
- /* verify that we don't accidentally create loops */
- if (!e)
- return;
- for (te = super; te; te = te->super)
- assert(te->super != e);
- e->super = super;
+ if (e)
+ e->super = super;
}
/* Set a scope's enclosing scope up correctly. */
@@ -1333,7 +1327,7 @@
static Type *
initvar(Node *n, Node *s)
{
- Type *t, *param;
+ Type *t, *u, *param;
Tysubst *subst;
if (s->decl.ishidden && !allowhidden)
@@ -1348,12 +1342,13 @@
substput(subst, s->decl.trait->param, param);
pushenv(s->decl.env);
t = tysubstmap(subst, tf(s->decl.type), s->decl.type);
- popenv(s->decl.env);
if (s->decl.trait && !param) {
- param = substget(subst, s->decl.trait->param);
+ u = tf(s->decl.trait->param);
+ param = substget(subst, u);
if (!param)
fatal(n, "ambiguous trait decl %s", ctxstr(s));
}
+ popenv(s->decl.env);
substfree(subst);
} else {
t = s->decl.type;
@@ -2045,8 +2040,7 @@
if (!t)
fatal(k[i], "undefined type %s", namestr(k[i]));
t = tysearch(t);
- if (t->env)
- setsuperenv(t->env, curenv());
+ setsuperenv(t->env, curenv());
pushenv(t->env);
tyresolve(t);
popenv(t->env);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -719,7 +719,7 @@
{
Bitset *visited;
- if (!t)
+ if (!t || !env)
return;
visited = mkbs();
bindtype_rec(env, t, visited);
--- a/parse/use.c
+++ b/parse/use.c
@@ -1019,6 +1019,8 @@
for (i = 0; i < tr->nproto; i++) {
putdcl(s, tr->proto[i]);
tr->proto[i]->decl.ishidden = tr->ishidden;
+ if (tr->proto[i]->decl.env)
+ tr->proto[i]->decl.env->super = tr->env;
}
break;
case 'T':