summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2019-03-04 00:17:19 -0800
committerOri Bernstein <ori@eigenstate.org>2019-03-14 00:20:54 -0700
commit01cf9608db97e2b4fe6bec921ab1c28201605f82 (patch)
treeb5a73222282fac3210f36020fae4aaff92ed93b3
parent1c20d382566fcdfdf5585b1bd8f1f27d7dbd6425 (diff)
downloadmc-01cf9608db97e2b4fe6bec921ab1c28201605f82.tar.gz
Get a bit better at wrangling type bindings.
-rw-r--r--parse/gram.y7
-rw-r--r--parse/infer.c20
-rw-r--r--parse/stab.c2
-rw-r--r--parse/use.c2
4 files changed, 14 insertions, 17 deletions
diff --git a/parse/gram.y b/parse/gram.y
index 77d9f44..a5151fd 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -1250,10 +1250,11 @@ mergeenv(Node *dcl, Node *init)
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);
}
diff --git a/parse/infer.c b/parse/infer.c
index 61af0a5..75ca5ec 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -339,14 +339,8 @@ typeerror(Type *a, Type *b, Node *ctx, char *msg)
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 @@ unifyparams(Node *ctx, Type *a, Type *b)
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 @@ initvar(Node *n, Node *s)
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 @@ inferstab(Stab *s)
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);
diff --git a/parse/stab.c b/parse/stab.c
index cc7a644..54ccfaa 100644
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -719,7 +719,7 @@ bindtype(Tyenv *env, Type *t)
{
Bitset *visited;
- if (!t)
+ if (!t || !env)
return;
visited = mkbs();
bindtype_rec(env, t, visited);
diff --git a/parse/use.c b/parse/use.c
index 7d22103..b08aced 100644
--- a/parse/use.c
+++ b/parse/use.c
@@ -1019,6 +1019,8 @@ foundextlib:
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':