]> Cypherpunks repositories - gostls13.git/commitdiff
[dev.typeparams] go/types: better recv Var for method expressions
authorRob Findley <rfindley@google.com>
Thu, 3 Jun 2021 14:12:37 +0000 (10:12 -0400)
committerRobert Findley <rfindley@google.com>
Fri, 4 Jun 2021 10:59:39 +0000 (10:59 +0000)
This is a port of CL 320489 to go/types, adjusted to be consistent about
named/unnamed parameters. TestEvalPos was failing without this addition.

For #46209

Change-Id: Icdf86e84ebce8ccdb7846a63b5605e360e2b8781
Reviewed-on: https://go-review.googlesource.com/c/go/+/324733
Trust: Robert Findley <rfindley@google.com>
Run-TryBot: Robert Findley <rfindley@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
src/go/types/call.go
src/go/types/testdata/check/decls0.src

index 631ea426c6bbf42e5fe613e4936942a2e253d055..3a04121e98494539d94e97e1e72321e0f14c7aef 100644 (file)
@@ -575,17 +575,38 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
 
                check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
 
+               sig := m.typ.(*Signature)
+               if sig.recv == nil {
+                       check.error(e, _InvalidDeclCycle, "illegal cycle in method declaration")
+                       goto Error
+               }
+
                // the receiver type becomes the type of the first function
                // argument of the method expression's function type
                var params []*Var
-               sig := m.typ.(*Signature)
                if sig.params != nil {
                        params = sig.params.vars
                }
+               // Be consistent about named/unnamed parameters.
+               needName := true
+               for _, param := range params {
+                       if param.Name() == "" {
+                               needName = false
+                               break
+                       }
+               }
+               name := ""
+               if needName {
+                       name = sig.recv.name
+                       if name == "" {
+                               name = "_"
+                       }
+               }
+               params = append([]*Var{NewVar(sig.recv.pos, sig.recv.pkg, name, x.typ)}, params...)
                x.mode = value
                x.typ = &Signature{
                        tparams:  sig.tparams,
-                       params:   NewTuple(append([]*Var{NewVar(token.NoPos, check.pkg, "_", x.typ)}, params...)...),
+                       params:   NewTuple(params...),
                        results:  sig.results,
                        variadic: sig.variadic,
                }
index 5ad8f53f65ab20b5e21b753119df153a67bd206b..09904bb303016746b8bf6dea93893ab6686c9267 100644 (file)
@@ -187,10 +187,10 @@ func f4() (x *f4 /* ERROR "not a type" */ ) { return }
 // TODO(#43215) this should be detected as a cycle error
 func f5([unsafe.Sizeof(f5)]int) {}
 
-func (S0) m1 (x S0 /* ERROR value .* is not a type */ .m1) {}
-func (S0) m2 (x *S0 /* ERROR value .* is not a type */ .m2) {}
-func (S0) m3 () (x S0 /* ERROR value .* is not a type */ .m3) { return }
-func (S0) m4 () (x *S0 /* ERROR value .* is not a type */ .m4) { return }
+func (S0) m1 (x S0 /* ERROR illegal cycle in method declaration */ .m1) {}
+func (S0) m2 (x *S0 /* ERROR illegal cycle in method declaration */ .m2) {}
+func (S0) m3 () (x S0 /* ERROR illegal cycle in method declaration */ .m3) { return }
+func (S0) m4 () (x *S0 /* ERROR illegal cycle in method declaration */ .m4) { return }
 
 // interfaces may not have any blank methods
 type BlankI interface {