ref: 5bf79c58e3124fa34d04403e0558b5a2ee9233c9
parent: 4dd119870c7bc83217c5719d187ebadb0a3d1bb7
author: Ori Bernstein <[email protected]>
date: Tue Jul 17 10:54:37 EDT 2012
Only allow generics in valid places. Don't allow generics outside of generic declarations. This means you should no longer be able to do 'const foo : @a' and have it get past type checking.
--- a/parse/infer.c
+++ b/parse/infer.c
@@ -680,13 +680,13 @@
switch (n->type) {
case Nfile:
pushstab(n->file.globls);
- /* exports allow us to specify types later in the body, so we
- * need to patch the types in if they don't have a definition */
inferstab(st, n->file.globls);
inferstab(st, n->file.exports);
for (i = 0; i < n->file.nstmts; i++) {
d = n->file.stmts[i];
infernode(st, d, NULL, sawret);
+ /* exports allow us to specify types later in the body, so we
+ * need to patch the types in if they don't have a definition */
if (d->type == Ndecl) {
s = getdcl(file->file.exports, d->decl.name);
if (s)
@@ -696,9 +696,15 @@
popstab();
break;
case Ndecl:
+ if (n->decl.isgeneric)
+ st->ingeneric++;
bind(st, n);
inferdecl(st, n);
unbind(st, n);
+ if (type(st, n)->type == Typaram && !st->ingeneric)
+ fatal(n->line, "Generic type %s in non-generic near %s\n", tystr(type(st, n)), ctxstr(n));
+ if (n->decl.isgeneric)
+ st->ingeneric--;
break;
case Nblock:
setsuper(n->block.scope, curstab());
--- a/test/tests
+++ b/test/tests
@@ -60,3 +60,4 @@
F union-extraarg
F union-missingarg
F match-badtypes
+F generic-in-const