import (
"go/ast"
"go/token"
+ "unicode"
)
func (check *Checker) call(x *operand, e *ast.CallExpr) exprKind {
switch {
case index != nil:
// TODO(gri) should provide actual type where the conflict happens
- check.errorf(e.Sel.Pos(), "ambiguous selector %s", sel)
+ check.errorf(e.Sel.Pos(), "ambiguous selector %s.%s", x.expr, sel)
case indirect:
- // 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)
+ check.errorf(e.Sel.Pos(), "cannot call pointer method %s on %s", sel, x.typ)
default:
- // TODO(gri) should check if capitalization of sel matters and provide better error message in that case
+ // Check if capitalization of sel matters and provide better error
+ // message in that case.
+ if len(sel) > 0 {
+ var changeCase string
+ if r := rune(sel[0]); unicode.IsUpper(r) {
+ changeCase = string(unicode.ToLower(r)) + sel[1:]
+ } else {
+ changeCase = string(unicode.ToUpper(r)) + sel[1:]
+ }
+ if obj, _, _ = check.lookupFieldOrMethod(x.typ, x.mode == variable, check.pkg, changeCase); obj != nil {
+ check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s, but does have %s)", x.expr, sel, x.typ, sel, changeCase)
+ break
+ }
+ }
check.errorf(e.Sel.Pos(), "%s.%s undefined (type %s has no field or method %s)", x.expr, sel, x.typ, sel)
}
goto Error
)
var t T3
- _ = t.X /* ERROR "ambiguous selector" */
+ _ = t.X /* ERROR "ambiguous selector t.X" */
}
func _() {
)
var t T4
- _ = t.X /* ERROR "ambiguous selector" */
+ _ = t.X /* ERROR "ambiguous selector t.X" */
}
func issue4355() {
)
var t T5
- _ = t.X /* ERROR "ambiguous selector" */
+ _ = t.X /* ERROR "ambiguous selector t.X" */
}
func _() {
type T struct{ A; B }
var t T
- _ = t.State /* ERROR "ambiguous selector" */
+ _ = t.State /* ERROR "ambiguous selector t.State" */
}
// Embedded fields can be predeclared types.
_ = S2{}.B
_ = S2{}.C
_ = S2{}.D /* ERROR "no field or method" */
- _ = S3{}.S1 /* ERROR "ambiguous selector" */
+ _ = S3{}.S1 /* ERROR "ambiguous selector \(S3 literal\).S1" */
_ = S3{}.A
- _ = S3{}.B /* ERROR "ambiguous selector" */
+ _ = S3{}.B /* ERROR "ambiguous selector" \(S3 literal\).B */
_ = S3{}.D
_ = S3{}.E
_ = S4{}.A
_ = S4{}.B /* ERROR "no field or method" */
- _ = S5{}.X /* ERROR "ambiguous selector" */
+ _ = S5{}.X /* ERROR "ambiguous selector \(S5 literal\).X" */
_ = S5{}.Y
- _ = S10{}.X /* ERROR "ambiguous selector" */
+ _ = S10{}.X /* ERROR "ambiguous selector \(S10 literal\).X" */
_ = S10{}.Y
}
type R23 R21
type R24 R21
-var _ = R0{}.X /* ERROR "ambiguous selector" */
\ No newline at end of file
+var _ = R0{}.X /* ERROR "ambiguous selector \(R0 literal\).X" */
\ No newline at end of file
}
var (
- _ = eD{}.xf /* ERROR ambiguous selector */
- _ = eD{}.xm /* ERROR ambiguous selector */
+ _ = eD{}.xf /* ERROR ambiguous selector \(eD literal\).xf */
+ _ = eD{}.xm /* ERROR ambiguous selector \(eD literal\).xm */
)
var (
func method_expressions() {
_ = T.a /* ERROR "no field or method" */
_ = T.x /* ERROR "has no method" */
- _ = T.m /* ERROR "not in method set" */
+ _ = T.m /* ERROR "cannot call pointer method m on T" */
_ = (*T).m
- var f func(*T) = T.m /* ERROR "not in method set" */
+ var f func(*T) = T.m /* ERROR "cannot call pointer method m on T" */
var g func(*T) = (*T).m
_, _ = f, g
)
func (T4) m4() {}
-func _() { (T{}).m4 /* ERROR m4 is not in method set of T */ () }
+func _() { (T{}).m4 /* ERROR "cannot call pointer method m4 on T" */ () }
func _() { (&T{}).m4() }
type (
)
func (T6) m6() {}
-func _() { (T{}).m6 /* ERROR m6 is not in method set of T */ () }
+func _() { (T{}).m6 /* ERROR "cannot call pointer method m6 on T" */ () }
func _() { (&T{}).m6() }
type (
t2 *T2
)
- var x I1 = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {}
+ var x I1
+ x = T1 /* ERROR cannot use .*: missing method foo \(foo has pointer receiver\) */ {}
_ = x /* ERROR .* cannot have dynamic type T1 \(missing method foo \(foo has pointer receiver\)\) */ .(T1)
+ T1{}.foo /* ERROR cannot call pointer method foo on T1 */ ()
+ x.Foo /* ERROR "x.Foo undefined \(type I1 has no field or method Foo, but does have foo\)" */ ()
+
_ = i2 /* ERROR i2 .* cannot have dynamic type \*T1 \(wrong type for method foo \(have func\(\), want func\(x int\)\)\) */ .(*T1)
i1 = i0 /* ERROR cannot use .* missing method foo */
type E2 struct{ f int }
func issue26234b(x T) {
- _ = x.f /* ERROR ambiguous selector f */
+ _ = x.f /* ERROR ambiguous selector x.f */
}
func issue26234c() {
func _() {
var (
_ func(T0) = T0.v0
- _ = T0.p0 /* ERROR "not in method set" */
+ _ = T0.p0 /* ERROR "cannot call pointer method p0 on T0" */
_ func (*T0) = (*T0).v0
_ func (*T0) = (*T0).p0
_ func(T2) = T2.p2
_ func(T3) = T3.v0
- _ func(T3) = T3.p0 /* ERROR "not in method set" */
+ _ func(T3) = T3.p0 /* ERROR "cannot call pointer method p0 on T3" */
_ func(T3) = T3.v1
_ func(T3) = T3.p1
_ func(T3) = T3.v2
func _() {
var (
_ func() = T0{}.v0
- _ func() = T0{}.p0 /* ERROR "not in method set" */
+ _ func() = T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */
_ func() = (&T0{}).v0
_ func() = (&T0{}).p0
// no values for T2
_ func() = T3{}.v0
- _ func() = T3{}.p0 /* ERROR "not in method set" */
+ _ func() = T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */
_ func() = T3{}.v1
_ func() = T3{}.p1
_ func() = T3{}.v2
// Method calls with value receivers
func _() {
T0{}.v0()
- T0{}.p0 /* ERROR "not in method set" */ ()
+ T0{}.p0 /* ERROR "cannot call pointer method p0 on T0" */ ()
(&T0{}).v0()
(&T0{}).p0()
// no values for T2
T3{}.v0()
- T3{}.p0 /* ERROR "not in method set" */ ()
+ T3{}.p0 /* ERROR "cannot call pointer method p0 on T3" */ ()
T3{}.v1()
T3{}.p1()
T3{}.v2()