1
0
mirror of https://github.com/golang/go synced 2024-11-18 01:54:45 -07:00

go/types, types2: better error message for invalid method expression

Fixes #53358.

Change-Id: I38528da1596b6e1aaedcab89b1513fb8acac596c
Reviewed-on: https://go-review.googlesource.com/c/go/+/455335
Reviewed-by: Robert Findley <rfindley@google.com>
Auto-Submit: Robert Griesemer <gri@google.com>
Run-TryBot: Robert Griesemer <gri@google.com>
TryBot-Result: Gopher Robot <gobot@golang.org>
Reviewed-by: Robert Griesemer <gri@google.com>
This commit is contained in:
Robert Griesemer 2022-12-05 16:17:56 -08:00 committed by Gopher Robot
parent 98da0fb43f
commit dfd13ce59d
5 changed files with 33 additions and 6 deletions

View File

@ -573,7 +573,11 @@ func (check *Checker) selector(x *operand, e *syntax.SelectorExpr, def *Named) {
}
if indirect {
check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
if x.mode == typexpr {
check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
} else {
check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
}
goto Error
}

View File

@ -577,7 +577,11 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr, def *Named) {
}
if indirect {
check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
if x.mode == typexpr {
check.errorf(e.Sel, InvalidMethodExpr, "invalid method expression %s.%s (needs pointer receiver (*%s).%s)", x.typ, sel, x.typ, sel)
} else {
check.errorf(e.Sel, InvalidMethodExpr, "cannot call pointer method %s on %s", sel, x.typ)
}
goto Error
}

View File

@ -157,10 +157,10 @@ func (*T) m() {}
func method_expressions() {
_ = T.a /* ERROR "no field or method" */
_ = T.x /* ERROR "has no method" */
_ = T.m /* ERROR "cannot call pointer method m on T" */
_ = T.m /* ERROR "invalid method expression T\.m \(needs pointer receiver \(\*T\)\.m\)" */
_ = (*T).m
var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */
var f func(*T) = T.m /* ERROR "invalid method expression T\.m \(needs pointer receiver \(\*T\)\.m\)" */
var g func(*T) = (*T).m
_, _ = f, g

View File

@ -29,7 +29,7 @@ type T3 struct {
func _() {
var (
_ func(T0) = T0.v0
_ = T0.p0 /* ERROR "cannot call pointer method p0 on T0" */
_ = T0.p0 /* ERROR invalid method expression T0\.p0 \(needs pointer receiver \(\*T0\)\.p0\) */
_ func (*T0) = (*T0).v0
_ func (*T0) = (*T0).p0
@ -40,7 +40,7 @@ func _() {
_ func(T2) = T2.p2
_ func(T3) = T3.v0
_ func(T3) = T3.p0 /* ERROR "cannot call pointer method p0 on T3" */
_ func(T3) = T3.p0 /* ERROR invalid method expression T3\.p0 \(needs pointer receiver \(\*T3\)\.p0\) */
_ func(T3) = T3.v1
_ func(T3) = T3.p1
_ func(T3) = T3.v2

View File

@ -0,0 +1,19 @@
// Copyright 2022 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 A struct{}
func (*A) m() int { return 0 }
var _ = A.m /* ERROR invalid method expression A\.m \(needs pointer receiver \(\*A\)\.m\) */ ()
var _ = (*A).m(nil)
type B struct{ A }
var _ = B.m // ERROR invalid method expression B\.m \(needs pointer receiver \(\*B\)\.m\)
var _ = (*B).m
var _ = struct{ A }.m // ERROR invalid method expression struct{A}\.m \(needs pointer receiver \(\*struct{A}\)\.m\)