summaryrefslogtreecommitdiff
path: root/parse
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2018-04-17 22:28:18 -0700
committerOri Bernstein <ori@eigenstate.org>2018-04-17 22:28:18 -0700
commit3d71446ecb6569add0d9eaf2e7e4a05d99bd2625 (patch)
tree2010e52b6a5d62d98920bcb0706d5f99f3b2b60b /parse
parent35b4358b60d0afdff7e4599a9e625c0fc1580288 (diff)
downloadmc-3d71446ecb6569add0d9eaf2e7e4a05d99bd2625.tar.gz
Don't mutate the traits on builtin types.
mktylike() should return a generic type based on the builtin, and that means that if we mutate the builtin, we will be adding traits to our literals. This is wrong on multiple levels. First off, it means that '@t :: numeric,integral @t' will now require whatever other types are implemented over literals. And second, it means that if, for example, a trait is implemented for flt64, flt32 literals will also need it.
Diffstat (limited to 'parse')
-rw-r--r--parse/infer.c47
1 files changed, 27 insertions, 20 deletions
diff --git a/parse/infer.c b/parse/infer.c
index 02b3f90..e5aa09e 100644
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -70,6 +70,7 @@ static size_t nspecializations;
static Stab **specializationscope;
static size_t nspecializationscope;
static Traitmap *traitmap;
+static Bitset *tytraits[Ntypes];
static void
@@ -687,7 +688,7 @@ mktylike(Srcloc l, Ty other)
t = mktyvar(l);
/* not perfect in general, but good enough for all places mktylike is used. */
- t->trneed = bsdup(traitmap->sub[other]->traits);
+ t->trneed = bsdup(tytraits[other]);
return t;
}
@@ -2785,41 +2786,47 @@ builtintraits(void)
/* char::(numeric,integral) */
for (i = 0; i < Ntypes; i++)
- traitmap->sub[i] = mktraitmap();
+ tytraits[i] = mkbs();
- bsput(traitmap->sub[Tychar]->traits, Tcnum);
- bsput(traitmap->sub[Tychar]->traits, Tcint);
+ bsput(tytraits[Tychar], Tcnum);
+ bsput(tytraits[Tychar], Tcint);
- bsput(traitmap->sub[Tybyte]->traits, Tcnum);
- bsput(traitmap->sub[Tybyte]->traits, Tcint);
+ bsput(tytraits[Tybyte], Tcnum);
+ bsput(tytraits[Tybyte], Tcint);
/* <integer types>::(numeric,integral) */
for (i = Tyint8; i < Tyflt32; i++) {
- bsput(traitmap->sub[i]->traits, Tcnum);
- bsput(traitmap->sub[i]->traits, Tcint);
+ bsput(tytraits[i], Tcnum);
+ bsput(tytraits[i], Tcint);
}
/* <floats>::(numeric,floating) */
- bsput(traitmap->sub[Tyflt32]->traits, Tcnum);
- bsput(traitmap->sub[Tyflt32]->traits, Tcflt);
- bsput(traitmap->sub[Tyflt64]->traits, Tcnum);
- bsput(traitmap->sub[Tyflt64]->traits, Tcflt);
+ bsput(tytraits[Tyflt32], Tcnum);
+ bsput(tytraits[Tyflt32], Tcflt);
+ bsput(tytraits[Tyflt64], Tcnum);
+ bsput(tytraits[Tyflt64], Tcflt);
/* @a*::(sliceable) */
- bsput(traitmap->sub[Typtr]->traits, Tcslice);
+ bsput(tytraits[Typtr], Tcslice);
/* @a[:]::(indexable,sliceable) */
- bsput(traitmap->sub[Tyslice]->traits, Tcidx);
- bsput(traitmap->sub[Tyslice]->traits, Tcslice);
- bsput(traitmap->sub[Tyslice]->traits, Tciter);
+ bsput(tytraits[Tyslice], Tcidx);
+ bsput(tytraits[Tyslice], Tcslice);
+ bsput(tytraits[Tyslice], Tciter);
/* @a[SZ]::(indexable,sliceable) */
- bsput(traitmap->sub[Tyarray]->traits, Tcidx);
- bsput(traitmap->sub[Tyarray]->traits, Tcslice);
- bsput(traitmap->sub[Tyarray]->traits, Tciter);
+ bsput(tytraits[Tyarray], Tcidx);
+ bsput(tytraits[Tyarray], Tcslice);
+ bsput(tytraits[Tyarray], Tciter);
/* @a::function */
- bsput(traitmap->sub[Tyfunc]->traits, Tcfunc);
+ bsput(tytraits[Tyfunc], Tcfunc);
+
+ for (i = 0; i < Ntypes; i++) {
+ traitmap->sub[i] = mktraitmap();
+ bsunion(traitmap->sub[i]->traits, tytraits[i]);
+ }
+
}
static Trait*