[dev.typeparams] cmd/compile/internal/types2: better recv Var for method expressions

When synthesizing the Signature to represent a method expression, keep
as much of the original parameter as possible, substituting only the
receiver type.

Fixes #46209.

Change-Id: Ic4531820ae7d203bb0ba25a985f72d219b4aa25f
Reviewed-on: https://go-review.googlesource.com/c/go/+/320489
Trust: Matthew Dempsky <mdempsky@google.com>
Run-TryBot: Matthew Dempsky <mdempsky@google.com>
TryBot-Result: Go Bot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@golang.org>
This commit is contained in:
Matthew Dempsky 2021-05-17 10:47:04 -07:00
parent 90b6e72605
commit c92ae885d9
2 changed files with 12 additions and 6 deletions

View file

@ -576,17 +576,23 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr) {
check.recordSelection(e, MethodExpr, x.typ, m, index, indirect)
sig := m.typ.(*Signature)
if sig.recv == nil {
check.error(e, "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
}
params = append([]*Var{NewVar(sig.recv.pos, sig.recv.pkg, sig.recv.name, x.typ)}, params...)
x.mode = value
x.typ = &Signature{
tparams: sig.tparams,
params: NewTuple(append([]*Var{NewVar(nopos, check.pkg, "_", x.typ)}, params...)...),
params: NewTuple(params...),
results: sig.results,
variadic: sig.variadic,
}

View file

@ -185,10 +185,10 @@ func f2(x *f2 /* ERROR "not a type" */ ) {}
func f3() (x f3 /* ERROR "not a type" */ ) { return }
func f4() (x *f4 /* ERROR "not a type" */ ) { return }
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 {