shithub: mc

Download patch

ref: 2fa02e1d1d3df890d4349316389633d58c986254
parent: 404ed1ddb3faa4fec7ee4fd8fddc5bbdec284bde
author: Ori Bernstein <ori@eigenstate.org>
date: Sat Jul 29 11:14:05 EDT 2017

Finally do a by-scope comparison of generic types.

	This should clear the way for better deduplication.

--- a/parse/infer.c
+++ b/parse/infer.c
@@ -500,7 +500,7 @@
 		infernode(&t->asize, NULL, NULL);
 		break;
 	case Typaram:
-		if (!isbound(t))
+		if (!boundtype(t))
 			lfatal(t->loc, "type parameter %s is undefined in generic context", tystr(t));
 		break;
 	default:
@@ -594,7 +594,7 @@
 tf(Type *orig)
 {
 	int isgeneric;
-	Type *t;
+	Type *t, *tt;
 
 	assert(orig != NULL);
 	t = tylookup(orig);
@@ -611,6 +611,10 @@
 		pushenv(orig->env);
 		t = tysubst(t, orig);
 		popenv(orig->env);
+	} else if (orig->type == Typaram) {
+		tt = boundtype(t);
+		if (tt)
+			t = tt;
 	}
 	ingeneric -= isgeneric;
 	return t;
@@ -1892,8 +1896,7 @@
 		pushenv(n->decl.env);
 		inferdecl(n);
 		if (hasparams(type(n)) && !ingeneric)
-			fatal(n, "generic type %s in non-generic near %s", tystr(type(n)),
-					ctxstr(n));
+			fatal(n, "generic type in non-generic near %s", ctxstr(n));
 		if (n->decl.isauto)
 			constrain(n, type(n), traittab[Tcdisp]);
 		popenv(n->decl.env);
@@ -1993,6 +1996,7 @@
 {
 	static Type *tyint, *tyflt;
 	Type *t, *d, *base;
+	Tyenv *env;
 	char *from, *to;
 	size_t i;
 	char buf[1024];
@@ -2003,6 +2007,9 @@
 		tyflt = mktype(Zloc, Tyflt64);
 
 	t = tysearch(tf(orig));
+	env = t->env;
+	if (env)
+		pushenv(env);
 	base = htget(seqbase, orig);
 	if (orig->type == Tyvar && hthas(delayed, orig)) {
 		d = htget(delayed, orig);
@@ -2060,6 +2067,8 @@
 	}
 	if (base)
 		htput(seqbase, t, base);
+	if (env)
+		popenv(env);
 	return t;
 }
 
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -427,7 +427,7 @@
 void popstab(void);
 
 void bindtype(Tyenv *env, Type *t);
-int isbound(Type *t);
+Type *boundtype(Type *t);
 Tyenv *mkenv(void);
 Tyenv *curenv(void);
 void pushenv(Tyenv *e);
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -693,7 +693,7 @@
 		tt = htget(e->tab, t);
 		if (tt && tt != t)
 			tytab[t->tid] = tt;
-		else if (!isbound(t))
+		else if (!boundtype(t))
 			htput(e->tab, t, t);
 		break;
 	case Tygeneric:
@@ -740,13 +740,16 @@
 
 /* If the current environment binds a type,
  * we return true */
-int
-isbound(Type *t)
+Type*
+boundtype(Type *t)
 {
-
 	Tyenv *e;
-	for (e = curenv(); e; e = e->super)
-		if (htget(e->tab, t))
-			return 1;
-	return 0;
+	Type *r;
+
+	for (e = curenv(); e; e = e->super) {
+		r = htget(e->tab, t);
+		if (r)
+			return r;
+	}
+	return NULL;
 }
--- a/test/generictype.myr
+++ b/test/generictype.myr
@@ -1,7 +1,7 @@
 use std
 
 /* checks that parameterized types work. exits with 0. */
-type option(@a) = union
+type option(@a::(integral,numeric)) = union
 	`Some @a::(integral,numeric)
 	`None
 ;;