mirror of
https://github.com/golang/go.git
synced 2026-02-06 18:00:01 +00:00
go/types, types2: better error when selecting field on type rather than value
Fixes #6814. Change-Id: I659670998f8e89400d03d40189e8c54f7e705cdc Reviewed-on: https://go-review.googlesource.com/c/go/+/738040 Reviewed-by: Alan Donovan <adonovan@google.com> Auto-Submit: Robert Griesemer <gri@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com> Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
parent
455282911a
commit
2d37c20778
5 changed files with 43 additions and 6 deletions
|
|
@ -835,6 +835,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
|
|||
check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
|
||||
goto Error
|
||||
}
|
||||
// obj != nil
|
||||
|
||||
// methods may not have a fully set up signature yet
|
||||
if m, _ := obj.(*Func); m != nil {
|
||||
|
|
@ -845,7 +846,7 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, wantType bool
|
|||
// method expression
|
||||
m, _ := obj.(*Func)
|
||||
if m == nil {
|
||||
check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
|
||||
check.errorf(e.X, MissingFieldOrMethod, "operand for field selector %s must be value of type %s", sel, x.typ)
|
||||
goto Error
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -838,6 +838,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
|
|||
check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (%s)", x.expr, sel, why)
|
||||
goto Error
|
||||
}
|
||||
// obj != nil
|
||||
|
||||
// methods may not have a fully set up signature yet
|
||||
if m, _ := obj.(*Func); m != nil {
|
||||
|
|
@ -848,7 +849,7 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, wantType bool) {
|
|||
// method expression
|
||||
m, _ := obj.(*Func)
|
||||
if m == nil {
|
||||
check.errorf(e.Sel, MissingFieldOrMethod, "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
|
||||
check.errorf(e.X, MissingFieldOrMethod, "operand for field selector %s must be value of type %s", sel, x.typ)
|
||||
goto Error
|
||||
}
|
||||
|
||||
|
|
|
|||
6
src/internal/types/testdata/check/expr3.go
vendored
6
src/internal/types/testdata/check/expr3.go
vendored
|
|
@ -156,7 +156,7 @@ func (*T) m() {}
|
|||
|
||||
func method_expressions() {
|
||||
_ = T.a /* ERROR "no field or method" */
|
||||
_ = T.x /* ERROR "has no method" */
|
||||
_ = T /* ERROR "operand for field selector x must be value of type T" */ .x
|
||||
_ = T.m /* ERROR "invalid method expression T.m (needs pointer receiver (*T).m)" */
|
||||
_ = (*T).m
|
||||
|
||||
|
|
@ -164,8 +164,8 @@ func method_expressions() {
|
|||
var g func(*T) = (*T).m
|
||||
_, _ = f, g
|
||||
|
||||
_ = T.y /* ERROR "has no method" */
|
||||
_ = (*T).y /* ERROR "has no method" */
|
||||
_ = T /* ERROR "operand for field selector y must be value of type T" */ .y
|
||||
_ = ( /* ERROR "operand for field selector y must be value of type *T" */ *T).y
|
||||
}
|
||||
|
||||
func struct_literals() {
|
||||
|
|
|
|||
2
src/internal/types/testdata/check/issues0.go
vendored
2
src/internal/types/testdata/check/issues0.go
vendored
|
|
@ -351,7 +351,7 @@ func issue26234b(x T) {
|
|||
}
|
||||
|
||||
func issue26234c() {
|
||||
T.x /* ERROR "T.x undefined (type T has no method x)" */ ()
|
||||
T /* ERROR "operand for field selector x must be value of type T" */ .x()
|
||||
}
|
||||
|
||||
func issue35895() {
|
||||
|
|
|
|||
35
src/internal/types/testdata/fixedbugs/issue6814.go
vendored
Normal file
35
src/internal/types/testdata/fixedbugs/issue6814.go
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2026 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 p
|
||||
|
||||
type E struct {
|
||||
e int
|
||||
}
|
||||
|
||||
func (E) m() {}
|
||||
|
||||
type S struct {
|
||||
E
|
||||
x int
|
||||
}
|
||||
|
||||
func (S) n() {}
|
||||
|
||||
func _() {
|
||||
_ = S.X // ERROR "S.X undefined (type S has no field or method X, but does have field x)"
|
||||
_ = S /* ERROR "operand for field selector E must be value of type S" */ .E
|
||||
_ = S /* ERROR "operand for field selector x must be value of type S" */ .x
|
||||
_ = S /* ERROR "operand for field selector e must be value of type S" */ .e
|
||||
_ = S.m
|
||||
_ = S.n
|
||||
|
||||
var s S
|
||||
_ = s.X // ERROR "s.X undefined (type S has no field or method X, but does have field x)"
|
||||
_ = s.E
|
||||
_ = s.x
|
||||
_ = s.e
|
||||
_ = s.m
|
||||
_ = s.n
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue