shithub: mc

Download patch

ref: e6967548eec255e4518b1cdff5955d4b333f103b
parent: 90e26e0f687da28530b3b967df0cedf20407c071
author: Ori Bernstein <[email protected]>
date: Mon Jan 1 19:02:19 EST 2018

Try harder to specialize. Still some bugs.

--- a/parse/gram.y
+++ b/parse/gram.y
@@ -317,15 +317,15 @@
 traitvar
 	: traitlist generictype {
 		$$ = calloc(sizeof(Traitspec), 1);
-		$$->traits = $1.nl;
-		$$->ntraits = $1.nn;
+		$$->trait = $1.nl;
+		$$->ntrait = $1.nn;
 		$$->param = $2;
 		$$->aux = NULL;
 	}
 	| traitlist generictype Tret type {
 		$$ = calloc(sizeof(Traitspec), 1);
-		$$->traits = $1.nl;
-		$$->ntraits = $1.nn;
+		$$->trait = $1.nl;
+		$$->ntrait = $1.nn;
 		$$->param = $2;
 		$$->aux = $4;
 	}
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -35,6 +35,7 @@
 static void inferdecl(Node *n);
 static int tryconstrain(Type *ty, Trait *tr, int update);
 
+static Type *tyfreshen(Tysubst *subst, Type *orig);
 static Type *tf(Type *t);
 
 static Type *unify(Node *ctx, Type *a, Type *b);
@@ -278,6 +279,7 @@
 	ty = exprtype(n->iterstmt.seq);
 	if (ty->type == Tyslice || ty->type == Tyarray || ty->type == Typtr)
 		return;
+	ty = tyfreshen(NULL, ty);
 	for (i = 0; i < tr->nproto; i++) {
 		ty = exprtype(n->iterstmt.seq);
 		if (hthas(tr->proto[i]->decl.impls, ty))
@@ -461,7 +463,7 @@
 static Type *
 tyfreshen(Tysubst *subst, Type *orig)
 {
-	Type *t;
+	Type *ty;
 
 	if (!needfreshen(orig))
 		return orig;
@@ -468,13 +470,15 @@
 	pushenv(orig->env);
 	if (!subst) {
 		subst = mksubst();
-		t = tyspecialize(orig, subst, delayed, seqbase);
+		ty = tyspecialize(orig, subst, delayed, seqbase);
 		substfree(subst);
 	} else {
-		t = tyspecialize(orig, subst, delayed, seqbase);
+		ty = tyspecialize(orig, subst, delayed, seqbase);
 	}
+	ty->spec = orig->spec;
+	ty->nspec = orig->nspec;
 	popenv(orig->env);
-	return t;
+	return ty;
 }
 
 /* Resolves a type and all its subtypes recursively. */
@@ -526,13 +530,14 @@
 	}
 
 	for (i = 0; i < t->nspec; i++) {
-		for (j = 0; j < t->spec[i]->ntraits; j++) {
-			tr = gettrait(curstab(), t->spec[i]->traits[j]);
+		for (j = 0; j < t->spec[i]->ntrait; j++) {
+			tr = gettrait(curstab(), t->spec[i]->trait[j]);
 			if (!tr)
-				lfatal(t->loc, "trait %s does not exist", ctxstr(t->spec[i]->traits[j]));
+				lfatal(t->loc, "trait %s does not exist", ctxstr(t->spec[i]->trait[j]));
 			if (!t->trneed)
 				t->trneed = mkbs();
 			bsput(t->trneed, tr->uid);
+			htput(seqbase, t, t->spec[i]->aux);
 		}
 	}
 
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -120,8 +120,8 @@
 };
 
 struct Traitspec {
-	Node **traits;
-	size_t ntraits;
+	Node **trait;
+	size_t ntrait;
 	Type *param;
 	Type *aux;
 };