// function. It is ignored when comparing signatures for identity.
//
// For an abstract method, Recv returns the enclosing interface either
-// as a *Named or an *Interface. Due to embedding, an interface may
+// as a *[Named] or an *[Interface]. Due to embedding, an interface may
// contain methods whose receiver type is a different interface.
func (s *Signature) Recv() *Var { return s.recv }
// Audit to ensure all lookups honor scopePos and simplify.
scope := NewScope(check.scope, nopos, nopos, "function body (temp. scope)")
scopePos := syntax.EndPos(ftyp) // all parameters' scopes start after the signature
- var recvList []*Var // TODO(gri) remove the need for making a list here
- if recvPar != nil {
- recvList, _ = check.collectParams(scope, []*syntax.Field{recvPar}, false, scopePos) // use rewritten receiver type, if any
- }
- params, variadic := check.collectParams(scope, ftyp.ParamList, true, scopePos)
- results, _ := check.collectParams(scope, ftyp.ResultList, false, scopePos)
- scope.Squash(func(obj, alt Object) {
- err := check.newError(DuplicateDecl)
- err.addf(obj, "%s redeclared in this block", obj.Name())
- err.addAltDecl(alt)
- err.report()
- })
+ // collect and typecheck receiver, incoming parameters, and results
+ var recv *Var
if recvPar != nil {
- // recv parameter list present (may be empty)
// spec: "The receiver is specified via an extra parameter section preceding the
// method name. That parameter section must declare a single parameter, the receiver."
- var recv *Var
+ recvList, _ := check.collectParams(scope, []*syntax.Field{recvPar}, false, scopePos) // use rewritten receiver type, if any
switch len(recvList) {
case 0:
- // error reported by resolver
- recv = NewParam(nopos, nil, "", Typ[Invalid]) // ignore recv below
+ // error reported by parser
+ recv = NewParam(nopos, nil, "", Typ[Invalid]) // use invalid type so it's ignored by check.later code below
default:
- // more than one receiver
- check.error(recvList[len(recvList)-1].Pos(), InvalidRecv, "method must have exactly one receiver")
+ // error reported by parser
+ check.error(recvList[len(recvList)-1].Pos(), InvalidRecv, "method has multiple receivers")
fallthrough // continue with first receiver
case 1:
recv = recvList[0]
}
sig.recv = recv
+ }
+ params, variadic := check.collectParams(scope, ftyp.ParamList, true, scopePos)
+ results, _ := check.collectParams(scope, ftyp.ResultList, false, scopePos)
+
+ scope.Squash(func(obj, alt Object) {
+ err := check.newError(DuplicateDecl)
+ err.addf(obj, "%s redeclared in this block", obj.Name())
+ err.addAltDecl(alt)
+ err.report()
+ })
+ if recv != nil {
// Delay validation of receiver type as it may cause premature expansion
// of types the receiver type is dependent on (see issues go.dev/issue/51232, go.dev/issue/51233).
check.later(func() {
// Variadic reports whether the signature s is variadic.
func (s *Signature) Variadic() bool { return s.variadic }
-func (t *Signature) Underlying() Type { return t }
-func (t *Signature) String() string { return TypeString(t, nil) }
+func (s *Signature) Underlying() Type { return s }
+func (s *Signature) String() string { return TypeString(s, nil) }
// ----------------------------------------------------------------------------
// Implementation
// Audit to ensure all lookups honor scopePos and simplify.
scope := NewScope(check.scope, nopos, nopos, "function body (temp. scope)")
scopePos := ftyp.End() // all parameters' scopes start after the signature
- recvList, _ := check.collectParams(scope, recvPar, false, scopePos)
- params, variadic := check.collectParams(scope, ftyp.Params, true, scopePos)
- results, _ := check.collectParams(scope, ftyp.Results, false, scopePos)
- scope.squash(func(obj, alt Object) {
- err := check.newError(DuplicateDecl)
- err.addf(obj, "%s redeclared in this block", obj.Name())
- err.addAltDecl(alt)
- err.report()
- })
+ // collect and typecheck receiver, incoming parameters, and results
+ var recv *Var
if recvPar != nil {
- // recv parameter list present (may be empty)
// spec: "The receiver is specified via an extra parameter section preceding the
// method name. That parameter section must declare a single parameter, the receiver."
- var recv *Var
+ recvList, _ := check.collectParams(scope, recvPar, false, scopePos) // use rewritten receiver type, if any
switch len(recvList) {
case 0:
// error reported by resolver
- recv = NewParam(nopos, nil, "", Typ[Invalid]) // ignore recv below
+ recv = NewParam(nopos, nil, "", Typ[Invalid]) // use invalid type so it's ignored by check.later code below
default:
// more than one receiver
check.error(recvList[len(recvList)-1], InvalidRecv, "method has multiple receivers")
recv = recvList[0]
}
sig.recv = recv
+ }
+ params, variadic := check.collectParams(scope, ftyp.Params, true, scopePos)
+ results, _ := check.collectParams(scope, ftyp.Results, false, scopePos)
+
+ scope.squash(func(obj, alt Object) {
+ err := check.newError(DuplicateDecl)
+ err.addf(obj, "%s redeclared in this block", obj.Name())
+ err.addAltDecl(alt)
+ err.report()
+ })
+ if recv != nil {
// Delay validation of receiver type as it may cause premature expansion
// of types the receiver type is dependent on (see issues go.dev/issue/51232, go.dev/issue/51233).
check.later(func() {