aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorRobert Griesemer <gri@golang.org>2022-10-04 18:40:38 -0700
committerGopher Robot <gobot@golang.org>2022-10-12 23:03:51 +0000
commit79d0d330a9340d9e3ccb331660eb74f30e2edd01 (patch)
treeff8e4c8315567d03c67436c2ccfbd0ba7f62cea3 /src
parent19095e109d0ae037828c519dda0af307b8a01813 (diff)
downloadgo-79d0d330a9340d9e3ccb331660eb74f30e2edd01.tar.xz
go/types, types2: better error if there's a field with the name of a missing method
Fixes #51025. Change-Id: I469a705e7da059e7ac0b12b05beb9ed5d3617396 Reviewed-on: https://go-review.googlesource.com/c/go/+/438856 Reviewed-by: Robert Griesemer <gri@google.com> Auto-Submit: Robert Griesemer <gri@google.com> Reviewed-by: Robert Findley <rfindley@google.com> TryBot-Result: Gopher Robot <gobot@golang.org> Run-TryBot: Robert Griesemer <gri@google.com>
Diffstat (limited to 'src')
-rw-r--r--src/cmd/compile/internal/types2/lookup.go5
-rw-r--r--src/go/types/lookup.go5
-rw-r--r--src/internal/types/testdata/fixedbugs/issue51025.go38
3 files changed, 48 insertions, 0 deletions
diff --git a/src/cmd/compile/internal/types2/lookup.go b/src/cmd/compile/internal/types2/lookup.go
index 860535cf49..5f76752086 100644
--- a/src/cmd/compile/internal/types2/lookup.go
+++ b/src/cmd/compile/internal/types2/lookup.go
@@ -395,6 +395,11 @@ func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
return "(" + check.interfacePtrError(T) + ")"
}
+ obj, _, _ := lookupFieldOrMethod(V, true /* auto-deref */, m.pkg, m.name, false)
+ if fld, _ := obj.(*Var); fld != nil {
+ return check.sprintf("(%s.%s is a field, not a method)", V, fld.Name())
+ }
+
return check.sprintf("(missing %s)", mname)
}
diff --git a/src/go/types/lookup.go b/src/go/types/lookup.go
index 43fd8d9947..9e0a06aedb 100644
--- a/src/go/types/lookup.go
+++ b/src/go/types/lookup.go
@@ -395,6 +395,11 @@ func (check *Checker) missingMethodCause(V, T Type, m, alt *Func) string {
return "(" + check.interfacePtrError(T) + ")"
}
+ obj, _, _ := lookupFieldOrMethod(V, true /* auto-deref */, m.pkg, m.name, false)
+ if fld, _ := obj.(*Var); fld != nil {
+ return check.sprintf("(%s.%s is a field, not a method)", V, fld.Name())
+ }
+
return check.sprintf("(missing %s)", mname)
}
diff --git a/src/internal/types/testdata/fixedbugs/issue51025.go b/src/internal/types/testdata/fixedbugs/issue51025.go
new file mode 100644
index 0000000000..207b06e84b
--- /dev/null
+++ b/src/internal/types/testdata/fixedbugs/issue51025.go
@@ -0,0 +1,38 @@
+// 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
+
+var _ interface{ m() } = struct /* ERROR m is a field, not a method */ {
+ m func()
+}{}
+
+var _ interface{ m() } = & /* ERROR m is a field, not a method */ struct {
+ m func()
+}{}
+
+var _ interface{ M() } = struct /* ERROR missing method M */ {
+ m func()
+}{}
+
+var _ interface{ M() } = & /* ERROR missing method M */ struct {
+ m func()
+}{}
+
+// test case from issue
+type I interface{ m() }
+type T struct{ m func() }
+type M struct{}
+
+func (M) m() {}
+
+func _() {
+ var t T
+ var m M
+ var i I
+
+ i = m
+ i = t // ERROR m is a field, not a method
+ _ = i
+}