diff --git a/gopls/internal/golang/implementation.go b/gopls/internal/golang/implementation.go
index 49963e5..220ba0a 100644
--- a/gopls/internal/golang/implementation.go
+++ b/gopls/internal/golang/implementation.go
@@ -548,11 +548,23 @@
for method := range ymset.Methods() {
ym := method.Obj().(*types.Func)
+ // Ignore generic methods, for safety.
+ // This is probably unnecessary since they cannot
+ // appear in a true interface type.
+ // (They can appear in a constraint interface type,
+ // but we shouldn't be called in that case.)
+ if ym.Signature().TypeParams().Len() > 0 {
+ continue
+ }
+
xobj, _, _ := types.LookupFieldOrMethod(x, false, ym.Pkg(), ym.Name())
xm, ok := xobj.(*types.Func)
if !ok {
return false // x lacks a method of y
}
+ if xm.Signature().TypeParams().Len() > 0 {
+ return false // generic methods do not satisfy interface methods
+ }
if !unify(xm.Signature(), ym.Signature(), nil) {
return false // signatures do not match
}
diff --git a/gopls/internal/test/marker/testdata/implementation/genericmethods.txt b/gopls/internal/test/marker/testdata/implementation/genericmethods.txt
index 28f9dca..e3dd66c 100644
--- a/gopls/internal/test/marker/testdata/implementation/genericmethods.txt
+++ b/gopls/internal/test/marker/testdata/implementation/genericmethods.txt
@@ -1,6 +1,9 @@
Test of 'implementation' query on generic methods, which don't
participate in interface satisfaction.
+Test same-package and cross-package cases,
+since they use different logic.
+
-- flags --
-min_go=go1.27
@@ -15,6 +18,10 @@
func (C) F[T any](T) {} //@ implementation("F")
+type I interface {
+ F(int)
+}
+
-- b/a.go --
package a