diff --git a/src/cmd/compile/internal/gc/dcl.go b/src/cmd/compile/internal/gc/dcl.go index 516c33d0bb..22201e5044 100644 --- a/src/cmd/compile/internal/gc/dcl.go +++ b/src/cmd/compile/internal/gc/dcl.go @@ -863,7 +863,7 @@ func methodSymSuffix(recv *types.Type, msym *types.Sym, suffix string) *types.Sy // 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") @@ -918,6 +918,7 @@ func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.F 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 } } @@ -927,7 +928,7 @@ func addmethod(msym *types.Sym, t *types.Type, local, nointerface bool) *types.F 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) diff --git a/src/cmd/compile/internal/gc/typecheck.go b/src/cmd/compile/internal/gc/typecheck.go index 0bbd89f05e..38d9fe078f 100644 --- a/src/cmd/compile/internal/gc/typecheck.go +++ b/src/cmd/compile/internal/gc/typecheck.go @@ -2443,7 +2443,7 @@ func lookdot(n *Node, t *types.Type, dostrcmp int) *types.Field { } if f1 != nil { - if dostrcmp > 1 { + if dostrcmp > 1 || f1.Broke() { // Already in the process of diagnosing an error. return f1 } diff --git a/test/fixedbugs/issue28268.go b/test/fixedbugs/issue28268.go new file mode 100644 index 0000000000..fdc6974d1c --- /dev/null +++ b/test/fixedbugs/issue28268.go @@ -0,0 +1,30 @@ +// 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 +}