mirror of
https://github.com/golang/go
synced 2024-11-18 14:14:46 -07:00
go.tools/go/types: handle all receiver errors in go/types
Pending parser change in CL 123010044. LGTM=adonovan R=adonovan CC=golang-codereviews https://golang.org/cl/125830043
This commit is contained in:
parent
3bbc63016b
commit
8ce35843de
20
go/types/testdata/decls2a.src
vendored
20
go/types/testdata/decls2a.src
vendored
@ -80,12 +80,24 @@ type T5 interface {
|
||||
func (T5 /* ERROR "invalid receiver" */ ) m1() {}
|
||||
func (T5 /* ERROR "invalid receiver" */ ) m2() {}
|
||||
|
||||
// Methods associated with a named pointer type.
|
||||
type ptr *int
|
||||
func (ptr /* ERROR "invalid receiver" */ ) _() {}
|
||||
func (* /* ERROR "invalid receiver" */ ptr) _() {}
|
||||
|
||||
// Methods with zero or multiple receivers.
|
||||
func ( /* ERROR "missing receiver" */ ) _() {}
|
||||
func (T3, * /* ERROR "exactly one receiver" */ T3) _() {}
|
||||
func (T3, T3, T3 /* ERROR "exactly one receiver" */ ) _() {}
|
||||
func (a, b /* ERROR "exactly one receiver" */ T3) _() {}
|
||||
func (a, b, c /* ERROR "exactly one receiver" */ T3) _() {}
|
||||
|
||||
// Methods associated with non-local or unnamed types.
|
||||
func (int /* ERROR "invalid receiver" */ ) m() {}
|
||||
func ([ /* ERROR "identifier" */ ]int) m() {}
|
||||
func (time /* ERROR "identifier" */ .Time) m() {}
|
||||
func (*time /* ERROR "identifier" */ .Time) m() {}
|
||||
func (x interface /* ERROR "identifier" */ {}) m() {}
|
||||
func ([ /* ERROR "invalid receiver" */ ]int) m() {}
|
||||
func (time /* ERROR "invalid receiver" */ .Time) m() {}
|
||||
func (* /* ERROR "invalid receiver" */ time.Time) m() {}
|
||||
func (x /* ERROR "invalid receiver" */ interface{}) m() {}
|
||||
|
||||
// Unsafe.Pointer is treated like a pointer when used as receiver type.
|
||||
type UP unsafe.Pointer
|
||||
|
@ -139,21 +139,30 @@ func (check *Checker) typ(e ast.Expr) Type {
|
||||
}
|
||||
|
||||
// funcType type-checks a function or method type and returns its signature.
|
||||
func (check *Checker) funcType(sig *Signature, recv *ast.FieldList, ftyp *ast.FuncType) *Signature {
|
||||
func (check *Checker) funcType(sig *Signature, recvPar *ast.FieldList, ftyp *ast.FuncType) *Signature {
|
||||
scope := NewScope(check.scope, "function")
|
||||
check.recordScope(ftyp, scope)
|
||||
|
||||
recv_, _ := check.collectParams(scope, recv, false)
|
||||
recvList, _ := check.collectParams(scope, recvPar, false)
|
||||
params, variadic := check.collectParams(scope, ftyp.Params, true)
|
||||
results, _ := check.collectParams(scope, ftyp.Results, false)
|
||||
|
||||
if len(recv_) > 0 {
|
||||
// There must be exactly one receiver.
|
||||
if len(recv_) > 1 {
|
||||
check.invalidAST(recv_[1].Pos(), "method must have exactly one receiver")
|
||||
// ok to continue
|
||||
if recvPar != nil {
|
||||
// recv parameter list present (may be empty)
|
||||
// spec: "The receiver is specified via an extra parameter section preceeding the
|
||||
// method name. That parameter section must declare a single parameter, the receiver."
|
||||
var recv *Var
|
||||
switch len(recvList) {
|
||||
case 0:
|
||||
check.error(recvPar.Pos(), "method is missing receiver")
|
||||
recv = NewParam(0, nil, "", Typ[Invalid]) // ignore recv below
|
||||
default:
|
||||
// more than one receiver
|
||||
check.error(recvList[len(recvList)-1].Pos(), "method must have exactly one receiver")
|
||||
fallthrough // continue with first receiver
|
||||
case 1:
|
||||
recv = recvList[0]
|
||||
}
|
||||
recv := recv_[0]
|
||||
// spec: "The receiver type must be of the form T or *T where T is a type name."
|
||||
// (ignore invalid types - error was reported before)
|
||||
if t, _ := deref(recv.typ); t != Typ[Invalid] {
|
||||
|
Loading…
Reference in New Issue
Block a user