Commit 6761b1eb authored by Robert Griesemer's avatar Robert Griesemer

cmd/compile: better errors for structs with conflicting fields and methods

If a field and method have the same name, mark the respective struct field
so that we don't report follow-on errors when the field/method is accessed.

Per suggestion of @mdempsky.

Fixes #28268.

Change-Id: Ia1ca4cdfe9bacd3739d1fd7ca5e014ca094245ee
Reviewed-on: https://go-review.googlesource.com/c/144259Reviewed-by: 's avatarMatthew Dempsky <mdempsky@google.com>
parent 4be3851d
......@@ -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)
......
......@@ -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
}
......
// 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
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment