diff options
| author | Russ Cox <rsc@golang.org> | 2009-06-25 21:02:39 -0700 |
|---|---|---|
| committer | Russ Cox <rsc@golang.org> | 2009-06-25 21:02:39 -0700 |
| commit | 3bcbb610293bec97cd2ae3ac8f575ff756bb8271 (patch) | |
| tree | a6c9d8788ff4acbaf70e011972a3e487cd42f854 /src | |
| parent | b26cd1bfcd7107d8208595614ba45f54d5efacf6 (diff) | |
| download | golang-3bcbb610293bec97cd2ae3ac8f575ff756bb8271.tar.gz | |
bug165
R=ken
OCL=30783
CL=30783
Diffstat (limited to 'src')
| -rw-r--r-- | src/cmd/gc/dcl.c | 11 | ||||
| -rw-r--r-- | src/cmd/gc/go.h | 2 | ||||
| -rw-r--r-- | src/cmd/gc/subr.c | 15 |
3 files changed, 26 insertions, 2 deletions
diff --git a/src/cmd/gc/dcl.c b/src/cmd/gc/dcl.c index c33ead564..38bc022d2 100644 --- a/src/cmd/gc/dcl.c +++ b/src/cmd/gc/dcl.c @@ -93,6 +93,7 @@ updatetype(Type *n, Type *t) { Sym *s; int local; + int maplineno, lno; s = n->sym; if(s == S || s->def == N || s->def->op != OTYPE || s->def->type != n) @@ -124,6 +125,7 @@ updatetype(Type *n, Type *t) // type n t; // copy t, but then zero out state associated with t // that is no longer associated with n. + maplineno = n->maplineno; local = n->local; *n = *t; n->sym = s; @@ -133,6 +135,7 @@ updatetype(Type *n, Type *t) n->method = nil; n->vargen = 0; n->nod = N; + // catch declaration of incomplete type switch(n->etype) { case TFORWSTRUCT: @@ -141,6 +144,14 @@ updatetype(Type *n, Type *t) default: checkwidth(n); } + + // double-check use of type as map key + if(maplineno) { + lno = lineno; + lineno = maplineno; + maptype(n, types[TBOOL]); + lineno = lno; + } } diff --git a/src/cmd/gc/go.h b/src/cmd/gc/go.h index 876a03a93..3b521dd2d 100644 --- a/src/cmd/gc/go.h +++ b/src/cmd/gc/go.h @@ -171,6 +171,8 @@ struct Type // TARRAY int32 bound; // negative is dynamic array + + int32 maplineno; // first use of TFORW as map key }; #define T ((Type*)0) diff --git a/src/cmd/gc/subr.c b/src/cmd/gc/subr.c index 9dfb445c6..2e0c6b07d 100644 --- a/src/cmd/gc/subr.c +++ b/src/cmd/gc/subr.c @@ -345,8 +345,19 @@ maptype(Type *key, Type *val) { Type *t; - if(key != nil && key->etype != TANY && algtype(key) == ANOEQ) - yyerror("invalid map key type %T", key); + 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); + } t = typ(TMAP); t->down = key; t->type = val; |
