mirror of https://github.com/golang/go.git
go/types: better error messages for field lookup errors
- follow wording of cmd/compile more closely - only print base of a package path to avoid overly long error messages Fixes #26234. Change-Id: I47a8c64b3adcf73980cd296a24cf8ac721e5df06 Reviewed-on: https://go-review.googlesource.com/c/152764 Run-TryBot: Robert Griesemer <gri@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org> Reviewed-by: Alan Donovan <adonovan@google.com>
This commit is contained in:
parent
dc7808d4f2
commit
9e0ec5ef59
|
|
@ -374,11 +374,13 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
|
||||||
switch {
|
switch {
|
||||||
case index != nil:
|
case index != nil:
|
||||||
// TODO(gri) should provide actual type where the conflict happens
|
// TODO(gri) should provide actual type where the conflict happens
|
||||||
check.invalidOp(e.Sel.Pos(), "ambiguous selector %s", sel)
|
check.errorf(e.Sel.Pos(), "ambiguous selector %s", sel)
|
||||||
case indirect:
|
case indirect:
|
||||||
check.invalidOp(e.Sel.Pos(), "%s is not in method set of %s", sel, x.typ)
|
// TODO(gri) be more specific with this error message
|
||||||
|
check.errorf(e.Sel.Pos(), "%s is not in method set of %s", sel, x.typ)
|
||||||
default:
|
default:
|
||||||
check.invalidOp(e.Sel.Pos(), "%s has no field or method %s", x, sel)
|
// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
|
||||||
|
check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel)
|
||||||
}
|
}
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
|
@ -392,7 +394,8 @@ func (check *Checker) selector(x *operand, e *ast.SelectorExpr) {
|
||||||
// method expression
|
// method expression
|
||||||
m, _ := obj.(*Func)
|
m, _ := obj.(*Func)
|
||||||
if m == nil {
|
if m == nil {
|
||||||
check.invalidOp(e.Sel.Pos(), "%s has no method %s", x, sel)
|
// TODO(gri) should check if capitalization of sel matters and provide better error message in that case
|
||||||
|
check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no method %s)", x.expr, sel, x.typ, sel)
|
||||||
goto Error
|
goto Error
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"go/ast"
|
"go/ast"
|
||||||
"go/token"
|
"go/token"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
@ -25,7 +26,7 @@ func unreachable() {
|
||||||
|
|
||||||
func (check *Checker) qualifier(pkg *Package) string {
|
func (check *Checker) qualifier(pkg *Package) string {
|
||||||
if pkg != check.pkg {
|
if pkg != check.pkg {
|
||||||
return pkg.path
|
return path.Base(pkg.path) // avoid excessively long path names in error messages
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@
|
||||||
package issues
|
package issues
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
import syn "cmd/compile/internal/syntax"
|
||||||
|
|
||||||
func issue7035() {
|
func issue7035() {
|
||||||
type T struct{ X int }
|
type T struct{ X int }
|
||||||
|
|
@ -312,4 +313,28 @@ func issue28281d(... /* ERROR can only use ... with final parameter */ int, int)
|
||||||
func issue28281e(a, b, c ... /* ERROR can only use ... with final parameter */ int, d int)
|
func issue28281e(a, b, c ... /* ERROR can only use ... with final parameter */ int, d int)
|
||||||
func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
|
func issue28281f(... /* ERROR can only use ... with final parameter */ int, ... /* ERROR can only use ... with final parameter */ int, int)
|
||||||
func (... /* ERROR expected type */ TT) f()
|
func (... /* ERROR expected type */ TT) f()
|
||||||
func issue28281g() (... /* ERROR expected type */ TT)
|
func issue28281g() (... /* ERROR expected type */ TT)
|
||||||
|
|
||||||
|
// Issue #26234: Make various field/method lookup errors easier to read by matching cmd/compile's output
|
||||||
|
func issue26234a(f *syn.File) {
|
||||||
|
// The error message below should refer to the actual package path base (syntax)
|
||||||
|
// not the local package name (syn).
|
||||||
|
f.foo /* ERROR f.foo undefined \(type \*syntax.File has no field or method foo\) */
|
||||||
|
}
|
||||||
|
|
||||||
|
type T struct {
|
||||||
|
x int
|
||||||
|
E1
|
||||||
|
E2
|
||||||
|
}
|
||||||
|
|
||||||
|
type E1 struct{ f int }
|
||||||
|
type E2 struct{ f int }
|
||||||
|
|
||||||
|
func issue26234b(x T) {
|
||||||
|
_ = x.f /* ERROR ambiguous selector f */
|
||||||
|
}
|
||||||
|
|
||||||
|
func issue26234c() {
|
||||||
|
T.x /* ERROR T.x undefined \(type T has no method x\) */ ()
|
||||||
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue