summaryrefslogtreecommitdiff
path: root/mi
diff options
context:
space:
mode:
authorOri Bernstein <ori@eigenstate.org>2016-01-30 01:03:45 -0800
committerOri Bernstein <ori@eigenstate.org>2016-01-30 01:03:45 -0800
commit92c71814af7cba149c2320dbc37627f7da8fa638 (patch)
tree90d201006c64cfc2e1bd8383b4c6bfaf245e4f99 /mi
parentf50159ce18288e7c22fbef33617e6226bd1ef87b (diff)
downloadmc-92c71814af7cba149c2320dbc37627f7da8fa638.tar.gz
Error on unmatchable types.
Diffstat (limited to 'mi')
-rw-r--r--mi/match.c21
1 files changed, 14 insertions, 7 deletions
diff --git a/mi/match.c b/mi/match.c
index ceccab6..95e09f7 100644
--- a/mi/match.c
+++ b/mi/match.c
@@ -199,8 +199,8 @@ static size_t nconstructors(Type *t)
case Tyvar: case Typaram: case Tyunres: case Tyname:
case Tybad: case Tyvalist: case Tygeneric: case Ntypes:
case Tyfunc: case Tycode:
- die("Invalid constructor type %s in match", tystr(t));
- break;
+ die("Invalid constructor type %s in match", tystr(t));
+ break;
}
return 0;
}
@@ -252,6 +252,11 @@ static int isbasictype(Dtree *dt, Type *ty)
return istyprimitive(ty) || ty->type == Tyvoid || ty->type == Tyfunc;
}
+static int ismatchable(Type *ty)
+{
+ return ty->type != Tyfunc && ty->type != Tycode && ty->type != Tyvalist;
+}
+
static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree ***end, size_t *nend)
{
Dtree *next, **last, **tail;
@@ -349,10 +354,9 @@ static int addwildrec(Srcloc loc, Type *ty, Dtree *start, Dtree *accept, Dtree *
break;
case Typtr:
ret = addwildrec(loc, ty->sub[0], start, accept, &last, &nlast);
- default:
- ret = 1;
- lappend(&last, &nlast, accept);
break;
+ default:
+ die("unreachable");
}
lcat(end, nend, last, nlast);
lfree(&last, &nlast);
@@ -615,10 +619,13 @@ static int addpat(Node *pat, Node *val, Dtree *start, Dtree *accept, Node ***cap
switch (exprop(pat)) {
case Ovar:
dcl = decls[pat->expr.did];
- if (dcl->decl.isconst)
+ if (dcl->decl.isconst) {
+ if (!ismatchable(decltype(dcl)))
+ fatal(dcl, "matching unmatchable type %s", tystr(decltype(dcl)));
ret = addpat(dcl->decl.init, val, start, accept, cap, ncap, end, nend);
- else
+ } else {
ret = addwild(pat, val, start, accept, cap, ncap, end, nend);
+ }
break;
case Oucon:
ret = addunion(pat, val, start, accept, cap, ncap, end, nend);