Commit 6d781dec authored by Michael Fraenkel's avatar Michael Fraenkel Committed by Daniel Martí

cmd/compile: confusing error if composite literal field is a method

When looking for the field specified in a composite literal, check that
the specified name is actually a field and not a method.

Fixes #29855.

Change-Id: Id77666e846f925907b1eec64213b1d25af8a2466
Reviewed-on: https://go-review.googlesource.com/c/158938
Run-TryBot: Robert Griesemer <gri@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: default avatarRobert Griesemer <gri@golang.org>
parent c6e47069
...@@ -375,7 +375,7 @@ func methods(t *types.Type) []*Sig { ...@@ -375,7 +375,7 @@ func methods(t *types.Type) []*Sig {
// generating code if necessary. // generating code if necessary.
var ms []*Sig var ms []*Sig
for _, f := range mt.AllMethods().Slice() { 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) Fatalf("non-method on %v method %v %v\n", mt, f.Sym, f)
} }
if f.Type.Recv() == nil { if f.Type.Recv() == nil {
......
...@@ -1180,7 +1180,7 @@ func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool) ...@@ -1180,7 +1180,7 @@ func lookdot0(s *types.Sym, t *types.Type, save **types.Field, ignorecase bool)
c := 0 c := 0
if u.IsStruct() || u.IsInterface() { if u.IsStruct() || u.IsInterface() {
for _, f := range u.Fields().Slice() { 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 { if save != nil {
*save = f *save = f
} }
...@@ -1420,7 +1420,7 @@ func expandmeth(t *types.Type) { ...@@ -1420,7 +1420,7 @@ func expandmeth(t *types.Type) {
} }
// dotpath may have dug out arbitrary fields, we only want methods. // dotpath may have dug out arbitrary fields, we only want methods.
if f.Type.Etype != TFUNC || f.Type.Recv() == nil { if !f.IsMethod() {
continue continue
} }
...@@ -1631,7 +1631,7 @@ func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field, ...@@ -1631,7 +1631,7 @@ func ifacelookdot(s *types.Sym, t *types.Type, ignorecase bool) (m *types.Field,
} }
} }
if m.Type.Etype != TFUNC || m.Type.Recv() == nil { if !m.IsMethod() {
yyerror("%v.%v is a field, not a method", t, s) yyerror("%v.%v is a field, not a method", t, s)
return nil, followptr return nil, followptr
} }
......
...@@ -3250,8 +3250,9 @@ func typecheckcomplit(n *Node) (res *Node) { ...@@ -3250,8 +3250,9 @@ func typecheckcomplit(n *Node) (res *Node) {
} }
continue continue
} }
p, _ := dotpath(l.Sym, t, nil, true) var f *types.Field
if p == nil { 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) yyerror("unknown field '%v' in struct literal of type %v", l.Sym, t)
continue continue
} }
......
...@@ -392,6 +392,11 @@ func (f *Field) End() int64 { ...@@ -392,6 +392,11 @@ func (f *Field) End() int64 {
return f.Offset + f.Type.Width 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. // Fields is a pointer to a slice of *Field.
// This saves space in Types that do not have fields or methods // This saves space in Types that do not have fields or methods
// compared to a simple slice of *Field. // compared to a simple slice of *Field.
......
// 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
}
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