// Add a method, declared as a function.
// - msym is the method symbol
// - t is function type (with receiver)
-// Returns a pointer to the existing or added Field.
+// Returns a pointer to the existing or added Field; or nil if there's an error.
func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.Field {
if msym == nil {
Fatalf("no method symbol")
for _, f := range mt.Fields().Slice() {
if f.Sym == msym {
yyerror("type %v has both field and method named %v", mt, msym)
+ f.SetBroke(true)
return nil
}
}
if msym.Name != f.Sym.Name {
continue
}
- // eqtype only checks that incoming and result parameters match,
+ // types.Identical only checks that incoming and result parameters match,
// so explicitly check that the receiver parameters match too.
if !types.Identical(t, f.Type) || !types.Identical(t.Recv().Type, f.Type.Recv().Type) {
yyerror("method redeclared: %v.%v\n\t%v\n\t%v", mt, msym, f.Type, t)
--- /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.
+
+// Verify that follow-on errors due to conflicting
+// struct field and method names are suppressed.
+
+package p
+
+type T struct {
+ a, b, c int
+ E
+}
+
+type E struct{}
+
+func (T) b() {} // ERROR "field and method named b"
+func (*T) E() {} // ERROR "field and method named E"
+
+func _() {
+ var x T
+ _ = x.a
+ _ = x.b // no follow-on error here
+ x.b() // no follow-on error here
+ _ = x.c
+ _ = x.E // no follow-on error here
+ x.E() // no follow-on error here
+}