diff options
Diffstat (limited to 'parse')
-rw-r--r-- | parse/gram.y | 8 | ||||
-rw-r--r-- | parse/infer.c | 19 | ||||
-rw-r--r-- | parse/parse.h | 4 |
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; }; |