[dev.typeparams] go/types: better recv Var for method expressions

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>
This commit is contained in:
Rob Findley 2021-06-03 10:12:37 -04:00 committed by Robert Findley
parent e32fab145b
commit 62c40878e4
2 changed files with 27 additions and 6 deletions

View 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,
}

View 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 {