Commit 480f5124 authored by Russ Cox's avatar Russ Cox

bug165

R=ken
OCL=30783
CL=30783
parent a0bcaf4c
...@@ -93,6 +93,7 @@ updatetype(Type *n, Type *t) ...@@ -93,6 +93,7 @@ updatetype(Type *n, Type *t)
{ {
Sym *s; Sym *s;
int local; int local;
int maplineno, lno;
s = n->sym; s = n->sym;
if(s == S || s->def == N || s->def->op != OTYPE || s->def->type != n) if(s == S || s->def == N || s->def->op != OTYPE || s->def->type != n)
...@@ -124,6 +125,7 @@ updatetype(Type *n, Type *t) ...@@ -124,6 +125,7 @@ updatetype(Type *n, Type *t)
// type n t; // type n t;
// copy t, but then zero out state associated with t // copy t, but then zero out state associated with t
// that is no longer associated with n. // that is no longer associated with n.
maplineno = n->maplineno;
local = n->local; local = n->local;
*n = *t; *n = *t;
n->sym = s; n->sym = s;
...@@ -133,6 +135,7 @@ updatetype(Type *n, Type *t) ...@@ -133,6 +135,7 @@ updatetype(Type *n, Type *t)
n->method = nil; n->method = nil;
n->vargen = 0; n->vargen = 0;
n->nod = N; n->nod = N;
// catch declaration of incomplete type // catch declaration of incomplete type
switch(n->etype) { switch(n->etype) {
case TFORWSTRUCT: case TFORWSTRUCT:
...@@ -141,6 +144,14 @@ updatetype(Type *n, Type *t) ...@@ -141,6 +144,14 @@ updatetype(Type *n, Type *t)
default: default:
checkwidth(n); checkwidth(n);
} }
// double-check use of type as map key
if(maplineno) {
lno = lineno;
lineno = maplineno;
maptype(n, types[TBOOL]);
lineno = lno;
}
} }
......
...@@ -171,6 +171,8 @@ struct Type ...@@ -171,6 +171,8 @@ struct Type
// TARRAY // TARRAY
int32 bound; // negative is dynamic array int32 bound; // negative is dynamic array
int32 maplineno; // first use of TFORW as map key
}; };
#define T ((Type*)0) #define T ((Type*)0)
......
...@@ -345,8 +345,19 @@ maptype(Type *key, Type *val) ...@@ -345,8 +345,19 @@ maptype(Type *key, Type *val)
{ {
Type *t; Type *t;
if(key != nil && key->etype != TANY && algtype(key) == ANOEQ) if(key != nil && key->etype != TANY && algtype(key) == ANOEQ) {
if(key->etype == TFORW) {
// map[key] used during definition of key.
// postpone check until key is fully defined.
// if there are multiple uses of map[key]
// before key is fully defined, the error
// will only be printed for the first one.
// good enough.
if(key->maplineno == 0)
key->maplineno = lineno;
} else
yyerror("invalid map key type %T", key); yyerror("invalid map key type %T", key);
}
t = typ(TMAP); t = typ(TMAP);
t->down = key; t->down = key;
t->type = val; t->type = val;
......
...@@ -7,5 +7,9 @@ ...@@ -7,5 +7,9 @@
package main package main
type I interface { type I interface {
m(map[I] bool) m(map[I] bool); // ok
}
type S struct {
m map[S] bool; // ERROR "map key type"
} }
...@@ -111,10 +111,6 @@ BUG: should not compile ...@@ -111,10 +111,6 @@ BUG: should not compile
=========== bugs/bug164.go =========== bugs/bug164.go
BUG: should not compile BUG: should not compile
=========== bugs/bug165.go
bugs/bug165.go:6: invalid map key type I
BUG: should compile
=========== fixedbugs/bug016.go =========== fixedbugs/bug016.go
fixedbugs/bug016.go:7: constant -3 overflows uint fixedbugs/bug016.go:7: constant -3 overflows uint
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment