]> Cypherpunks repositories - gostls13.git/commitdiff
gc: explain why invalid receiver types are invalid
authorRuss Cox <rsc@golang.org>
Mon, 25 Apr 2011 21:16:44 +0000 (17:16 -0400)
committerRuss Cox <rsc@golang.org>
Mon, 25 Apr 2011 21:16:44 +0000 (17:16 -0400)
Fixes #1680.

R=ken2
CC=golang-dev
https://golang.org/cl/4446061

src/cmd/gc/dcl.c
test/method2.go

index 80cb74408adc8dc93ea0cd39e455044aa763bf08..05ec0803925d0f3f0ce56bb35f550d170d6b4c85 100644 (file)
@@ -1139,6 +1139,32 @@ addmethod(Sym *sf, Type *t, int local)
        pa = pa->type;
        f = methtype(pa);
        if(f == T) {
+               t = pa;
+               if(t != T) {
+                       if(isptr[t->etype]) {
+                               if(t->sym != S) {
+                                       yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
+                                       return;
+                               }
+                               t = t->type;
+                       }
+               }
+               if(t != T) {
+                       if(t->sym == S) {
+                               yyerror("invalid receiver type %T (%T is an unnamed type)", pa, t);
+                               return;
+                       }
+                       if(isptr[t->etype]) {
+                               yyerror("invalid receiver type %T (%T is a pointer type)", pa, t);
+                               return;
+                       }
+                       if(t->etype == TINTER) {
+                               yyerror("invalid receiver type %T (%T is an interface type)", pa, t);
+                               return;
+                       }
+               }
+               // Should have picked off all the reasons above,
+               // but just in case, fall back to generic error.
                yyerror("invalid receiver type %T", pa);
                return;
        }
index a72536e7b33da791d64ac328f778ada44d46fc31..2fdc9fc3c562309fa678b589b8b63457ddc7905d 100644 (file)
@@ -12,8 +12,14 @@ type T struct {
 type P *T
 type P1 *T
 
-func (p P) val() int   { return 1 } // ERROR "receiver"
-func (p *P1) val() int { return 1 } // ERROR "receiver"
+func (p P) val() int   { return 1 } // ERROR "receiver.* pointer"
+func (p *P1) val() int { return 1 } // ERROR "receiver.* pointer"
+
+type I interface{}
+type I1 interface{}
+
+func (p I) val() int { return 1 } // ERROR "receiver.*interface"
+func (p *I1) val() int { return 1 } // ERROR "receiver.*interface"
 
 type Val interface {
        val() int