summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-01-02 00:02:19 -0800
committerOri Bernstein <ori@eigenstate.org>2018-01-11 22:16:11 -0800
commite6967548eec255e4518b1cdff5955d4b333f103b (patch)
tree5ff790acdb562f18a14b00672cd8a17894dc5580 /parse
parent90e26e0f687da28530b3b967df0cedf20407c071 (diff)
downloadmc-e6967548eec255e4518b1cdff5955d4b333f103b.tar.gz
Try harder to specialize. Still some bugs.
Diffstat (limited to 'parse')
-rw-r--r--parse/gram.y8
-rw-r--r--parse/infer.c19
-rw-r--r--parse/parse.h4
3 files changed, 18 insertions, 13 deletions
diff --git a/parse/gram.y b/parse/gram.y
index c3db284..f9fa892 100644
--- a/parse/gram.y
+++ b/parse/gram.y
@@ -317,15 +317,15 @@ traits : traitvar {
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;
}
diff --git a/parse/infer.c b/parse/infer.c
index 69419d3..7e6d6d1 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -35,6 +35,7 @@ static void inferexpr(Node **np, Type *ret, int *sawret);
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 @@ additerspecialization(Node *n, Stab *stab)
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,20 +463,22 @@ needfreshen(Type *t)
static Type *
tyfreshen(Tysubst *subst, Type *orig)
{
- Type *t;
+ Type *ty;
if (!needfreshen(orig))
return orig;
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 @@ tyresolve(Type *t)
}
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);
}
}
diff --git a/parse/parse.h b/parse/parse.h
index c8db0f5..e3be605 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -120,8 +120,8 @@ struct Tyenv {
};
struct Traitspec {
- Node **traits;
- size_t ntraits;
+ Node **trait;
+ size_t ntrait;
Type *param;
Type *aux;
};