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;
};