]> Cypherpunks repositories - gostls13.git/commitdiff
bug165
authorRuss Cox <rsc@golang.org>
Fri, 26 Jun 2009 04:02:39 +0000 (21:02 -0700)
committerRuss Cox <rsc@golang.org>
Fri, 26 Jun 2009 04:02:39 +0000 (21:02 -0700)
R=ken
OCL=30783
CL=30783

src/cmd/gc/dcl.c
src/cmd/gc/go.h
src/cmd/gc/subr.c
test/fixedbugs/bug165.go [moved from test/bugs/bug165.go with 72% similarity]
test/golden.out

index c33ead564da7d8501f1e417eb57f3921cb3121f8..38bc022d2889d026be81e8d3475c72ad6e7a5e36 100644 (file)
@@ -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;
+       }
 }
 
 
index 876a03a93a9dbb28b1a16b3a8e0d4dbf948788a6..3b521dd2dd7ae959ab3979c3fdacbb636c11ff9a 100644 (file)
@@ -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)
 
index 9dfb445c637b4dc256d1b36ad45cc5cc63f87e64..2e0c6b07da82ff7c922f12a719e48276c9f68225 100644 (file)
@@ -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;
similarity index 72%
rename from test/bugs/bug165.go
rename to test/fixedbugs/bug165.go
index 02a6c379b409b56f29b232d3f45043297f30e44e..8ce67a46db574fa73c830f8164926a8f2c2b6054 100644 (file)
@@ -7,5 +7,9 @@
 package main
 
 type I interface {
-       m(map[I] bool)
+       m(map[I] bool); // ok
+}
+
+type S struct {
+       m map[S] bool;  // ERROR "map key type"
 }
index 09ac96269a0862a6b40b6a13e0f67eab89284882..695a68cd411a7f98cf77398532ac07ecedd8d7c9 100644 (file)
@@ -111,10 +111,6 @@ BUG: should not compile
 =========== bugs/bug164.go
 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:7: constant -3 overflows uint