summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-01-02 22:14:43 -0800
committerOri Bernstein <ori@eigenstate.org>2018-01-11 22:16:11 -0800
commit9424339d8d453f5c559edd5d23549d662d1c9d8d (patch)
treefc725c32315c782b60eae6d48a1bb9171d3040b4
parente6967548eec255e4518b1cdff5955d4b333f103b (diff)
downloadmc-9424339d8d453f5c559edd5d23549d662d1c9d8d.tar.gz
Fix how we bind types.
Now we accept most valid programs, and reject most invalid ones.
-rw-r--r--parse/infer.c12
-rw-r--r--parse/parse.h2
-rw-r--r--parse/specialize.c3
-rw-r--r--parse/stab.c3
-rw-r--r--parse/type.c1
5 files changed, 17 insertions, 4 deletions
diff --git a/parse/infer.c b/parse/infer.c
index 7e6d6d1..24f5f88 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -37,6 +37,7 @@ static int tryconstrain(Type *ty, Trait *tr, int update);
static Type *tyfreshen(Tysubst *subst, Type *orig);
static Type *tf(Type *t);
+static Type *basetype(Type *a);
static Type *unify(Node *ctx, Type *a, Type *b);
static Type *tyfix(Node *ctx, Type *orig, int noerr);
@@ -463,7 +464,7 @@ needfreshen(Type *t)
static Type *
tyfreshen(Tysubst *subst, Type *orig)
{
- Type *ty;
+ Type *ty, *base;
if (!needfreshen(orig))
return orig;
@@ -477,6 +478,9 @@ tyfreshen(Tysubst *subst, Type *orig)
}
ty->spec = orig->spec;
ty->nspec = orig->nspec;
+ base = basetype(ty);
+ if (base)
+ htput(seqbase, ty, base);
popenv(orig->env);
return ty;
}
@@ -2594,7 +2598,8 @@ typesub(Node *n, int noerr)
typesub(n->iterstmt.elt, noerr);
typesub(n->iterstmt.seq, noerr);
typesub(n->iterstmt.body, noerr);
- additerspecialization(n, curstab());
+ if (!ingeneric)
+ additerspecialization(n, curstab());
break;
case Nmatchstmt:
typesub(n->matchstmt.val, noerr);
@@ -2693,6 +2698,8 @@ specialize(void)
tr = traittab[Tciter];
assert(tr->nproto == 2);
ty = exprtype(n->iterstmt.seq);
+ if (ty->type == Typaram)
+ continue;
it = itertype(n->iterstmt.seq, mktype(n->loc, Tybool));
d = specializedcl(tr->proto[0], ty, it, &name);
@@ -2855,6 +2862,7 @@ initimpl(void)
Type *ty;
pushstab(file->file.globls);
+ seqbase = mkht(tyhash, tyeq);
traitmap = zalloc(sizeof(Traitmap));
builtintraits();
for (i = 0; i < nimpltab; i++) {
diff --git a/parse/parse.h b/parse/parse.h
index e3be605..175bc08 100644
--- a/parse/parse.h
+++ b/parse/parse.h
@@ -360,7 +360,6 @@ struct Node {
};
/* globals */
-extern Htab *seqbase;
extern Srcloc curloc;
extern char *filename;
extern Tok *curtok; /* the last token we tokenized */
@@ -378,6 +377,7 @@ extern Node **nodes; /* node id -> node map */
extern size_t ndecls;
extern Node **exportimpls;
extern size_t nexportimpls;
+extern Htab *seqbase;
/* property tables */
extern int opispure[];
diff --git a/parse/specialize.c b/parse/specialize.c
index 74af0e9..622a3f8 100644
--- a/parse/specialize.c
+++ b/parse/specialize.c
@@ -98,6 +98,9 @@ tyspecialize(Type *orig, Tysubst *tsmap, Htab *delayed, Htab *trbase)
ret = mktyvar(t->loc);
ret->trneed = bsdup(t->trneed);
substput(tsmap, t, ret);
+ tmp = htget(seqbase, t);
+ if (tmp)
+ htput(seqbase, ret, tmp);
break;
case Tygeneric:
var = mktyvar(t->loc);
diff --git a/parse/stab.c b/parse/stab.c
index 1d89238..2d190d9 100644
--- a/parse/stab.c
+++ b/parse/stab.c
@@ -671,6 +671,9 @@ bindtype_rec(Tyenv *e, Type *t, Bitset *visited)
tytab[t->tid] = tt;
else if (!boundtype(t))
htput(e->tab, t, t);
+ for (i = 0; i < t->nspec; i++)
+ if (t->spec[i]->aux)
+ bindtype_rec(e, t->spec[i]->aux, visited);
break;
case Tygeneric:
for (i = 0; i < t->ngparam; i++)
diff --git a/parse/type.c b/parse/type.c
index ab033cb..de7237f 100644
--- a/parse/type.c
+++ b/parse/type.c
@@ -1084,7 +1084,6 @@ tyinit(Stab *st)
Type *ty;
Trait *tr;
- seqbase = mkht(tyhash, tyeq);
eqcache = mkht(typairhash, typaireq);
tydeduptab = mkht(tyhash, tystricteq);
/* this must be done after all the types are created, otherwise we will