shithub: mc

Download patch

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':