shithub: mc

Download patch

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 */