// generating code if necessary.
var ms []*Sig
for _, f := range mt.AllMethods().Slice() {
- if f.Type.Etype != TFUNC || f.Type.Recv() == nil {
+ if !f.IsMethod() {
Fatalf("non-method on %v method %v %v\n", mt, f.Sym, f)
}
if f.Type.Recv() == nil {
c := 0
if u.IsStruct() || u.IsInterface() {
for _, f := range u.Fields().Slice() {
- if f.Sym == s || (ignorecase && f.Type.Etype == TFUNC && f.Type.Recv() != nil && strings.EqualFold(f.Sym.Name, s.Name)) {
+ if f.Sym == s || (ignorecase && f.IsMethod() && strings.EqualFold(f.Sym.Name, s.Name)) {
if save != nil {
*save = f
}
}
// dotpath may have dug out arbitrary fields, we only want methods.
- if f.Type.Etype != TFUNC || f.Type.Recv() == nil {
+ if !f.IsMethod() {
continue
}
}
}
- if m.Type.Etype != TFUNC || m.Type.Recv() == nil {
+ if !m.IsMethod() {
yyerror("%v.%v is a field, not a method", t, s)
return nil, followptr
}
}
continue
}
- p, _ := dotpath(l.Sym, t, nil, true)
- if p == nil {
+ var f *types.Field
+ p, _ := dotpath(l.Sym, t, &f, true)
+ if p == nil || f.IsMethod() {
yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
continue
}
return f.Offset + f.Type.Width
}
+// IsMethod reports whether f represents a method rather than a struct field.
+func (f *Field) IsMethod() bool {
+ return f.Type.Etype == TFUNC && f.Type.Recv() != nil
+}
+
// Fields is a pointer to a slice of *Field.
// This saves space in Types that do not have fields or methods
// compared to a simple slice of *Field.
--- /dev/null
+// errorcheck
+
+// Copyright 2018 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package main
+
+type T struct {
+ GlobalName string
+}
+
+var t = T{Name: "foo"} // ERROR "unknown field 'Name' in struct literal of type T"
+
+func (t T) Name() string {
+ return t.GlobalName
+}