ref: 92c71814af7cba149c2320dbc37627f7da8fa638
parent: f50159ce18288e7c22fbef33617e6226bd1ef87b
author: Ori Bernstein <ori@eigenstate.org>
date: Fri Jan 29 20:03:45 EST 2016
Error on unmatchable types.
--- a/mi/match.c
+++ b/mi/match.c
@@ -199,8 +199,8 @@
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 @@
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 @@
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 @@
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);
--- a/parse/types.def
+++ b/parse/types.def
@@ -45,4 +45,4 @@
Ty(Tyunres, NULL, 1) /* unresolved */
Ty(Tyname, NULL, 1)
Ty(Tygeneric, NULL, 1)
-Ty(Tycode, NULL, 0)
+Ty(Tycode, NULL, 0) /* code ptr without env: backend-only */