cmd/internal/gc: improve "type *X has no field or method M" message
Try to provide hints for common areas, either *interface
were interface would have been better, and note incorrect
capitalization (but don't be more ambitious than that, at
least not today).
Added code and test for cases
ptrInterface.ExistingMethod
ptrInterface.unexportedMethod
ptrInterface.MissingMethod
ptrInterface.withwRongcASEdMethod
interface.withwRongcASEdMethod
ptrStruct.withwRongcASEdMethod
struct.withwRongcASEdMethod
also included tests for related errors to check for
unintentional changes and consistent wording.
Somewhat simplified from previous versions to avoid second-
guessing user errors, yet also biased to point out most-likely
root cause.
Fixes #10700
Change-Id: I16693e93cc8d8ca195e7742a222d640c262105b4
Reviewed-on: https://go-review.googlesource.com/9731
Reviewed-by: Russ Cox <rsc@golang.org>
diff --git a/test/fixedbugs/issue10700.dir/other.go b/test/fixedbugs/issue10700.dir/other.go
new file mode 100644
index 0000000..12908b9
--- /dev/null
+++ b/test/fixedbugs/issue10700.dir/other.go
@@ -0,0 +1,10 @@
+// Copyright 2015 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 other
+
+type Exported interface {
+ Do()
+ secret()
+}
diff --git a/test/fixedbugs/issue10700.dir/test.go b/test/fixedbugs/issue10700.dir/test.go
new file mode 100644
index 0000000..2033efc
--- /dev/null
+++ b/test/fixedbugs/issue10700.dir/test.go
@@ -0,0 +1,49 @@
+// errorcheck -0 -m -l
+
+// Copyright 2015 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
+
+import "./other"
+
+type Imported interface {
+ Do()
+}
+
+type HasAMethod struct {
+ x int
+}
+
+func (me *HasAMethod) Do() {
+ println(me.x)
+}
+
+func InMyCode(x *Imported, y *HasAMethod, z *other.Exported) {
+ x.Do() // ERROR "x\.Do undefined \(type \*Imported is pointer to interface, not interface\)"
+ x.do() // ERROR "x\.do undefined \(type \*Imported is pointer to interface, not interface\)"
+ (*x).Do()
+ x.Dont() // ERROR "x\.Dont undefined \(type \*Imported is pointer to interface, not interface\)"
+ (*x).Dont() // ERROR "\(\*x\)\.Dont undefined \(type Imported has no field or method Dont\)"
+
+ y.Do()
+ y.do() // ERROR "y\.do undefined \(type \*HasAMethod has no field or method do, but does have Do\)"
+ (*y).Do()
+ (*y).do() // ERROR "\(\*y\)\.do undefined \(type HasAMethod has no field or method do, but does have Do\)"
+ y.Dont() // ERROR "y\.Dont undefined \(type \*HasAMethod has no field or method Dont\)"
+ (*y).Dont() // ERROR "\(\*y\)\.Dont undefined \(type HasAMethod has no field or method Dont\)"
+
+ z.Do() // ERROR "z\.Do undefined \(type \*other\.Exported is pointer to interface, not interface\)"
+ z.do() // ERROR "z\.do undefined \(type \*other\.Exported is pointer to interface, not interface\)"
+ (*z).Do()
+ (*z).do() // ERROR "\(\*z\)\.do undefined \(type other.Exported has no field or method do, but does have Do\)"
+ z.Dont() // ERROR "z\.Dont undefined \(type \*other\.Exported is pointer to interface, not interface\)"
+ (*z).Dont() // ERROR "\(\*z\)\.Dont undefined \(type other\.Exported has no field or method Dont\)"
+ z.secret() // ERROR "z\.secret undefined \(type \*other\.Exported is pointer to interface, not interface\)"
+ (*z).secret() // ERROR "\(\*z\)\.secret undefined \(cannot refer to unexported field or method secret\)"
+
+}
+
+func main() {
+}
diff --git a/test/fixedbugs/issue10700.go b/test/fixedbugs/issue10700.go
new file mode 100644
index 0000000..25544ef
--- /dev/null
+++ b/test/fixedbugs/issue10700.go
@@ -0,0 +1,7 @@
+// errorcheckdir
+
+// Copyright 2015 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 ignored
diff --git a/test/interface/embed2.go b/test/interface/embed2.go
index 1636db78..df3e2e4 100644
--- a/test/interface/embed2.go
+++ b/test/interface/embed2.go
@@ -12,20 +12,25 @@
const Value = 1e12
-type Inter interface { M() int64 }
+type Inter interface {
+ M() int64
+}
type T int64
+
func (t T) M() int64 { return int64(t) }
+
var t = T(Value)
var pt = &t
var ti Inter = t
var pti = &ti
-type S struct { Inter }
-var s = S{ ti }
+type S struct{ Inter }
+
+var s = S{ti}
var ps = &s
-type SP struct { *Inter } // ERROR "interface"
+type SP struct{ *Inter } // ERROR "interface"
var i Inter
var pi = &i
@@ -43,25 +48,25 @@
check("t.M()", t.M())
check("pt.M()", pt.M())
check("ti.M()", ti.M())
- check("pti.M()", pti.M()) // ERROR "method"
+ check("pti.M()", pti.M()) // ERROR "pointer to interface, not interface"
check("s.M()", s.M())
check("ps.M()", ps.M())
i = t
check("i = t; i.M()", i.M())
- check("i = t; pi.M()", pi.M()) // ERROR "method"
+ check("i = t; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
i = pt
check("i = pt; i.M()", i.M())
- check("i = pt; pi.M()", pi.M()) // ERROR "method"
+ check("i = pt; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
i = s
check("i = s; i.M()", i.M())
- check("i = s; pi.M()", pi.M()) // ERROR "method"
+ check("i = s; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
i = ps
check("i = ps; i.M()", i.M())
- check("i = ps; pi.M()", pi.M()) // ERROR "method"
+ check("i = ps; pi.M()", pi.M()) // ERROR "pointer to interface, not interface"
if !ok {
println("BUG: interface10")