golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.94k stars 17.66k forks source link

x/tools/gopls: 'implementations' doesn't work with generics #59224

Open adonovan opened 1 year ago

adonovan commented 1 year ago

Even some of the most basic scenarios of 'implementations' are not working at all with generics, for example when the concrete and interface types are both generalized over [T any] and are defined within the same file:

xtools$ cat d/d.go 
package d

type Collection[T any] interface {
    Push(T) error
    Pop() (*T, bool)
}

type C[T any] struct{}

func (C[T]) Push(t T) error { return nil }

func (C[T]) Pop() (*T, bool) {
    var t T
    return &t, true
}

var _ Collection[int] = C[int]{}

xtools$ go run ./gopls implementation ./d/d.go:#120  # within "Push" concrete method identifier
xtools$

This is not a recent regression:

xtools$ ./gopls-v0.11.0 implementation ./d/d.go:#120  
xtools$

A similar lack of results is obtained by querying the Push abstract method, or the Collection interface, or the C concrete type.

(This test case was a further reduction of the one described in https://youtrack.jetbrains.com/issue/GO-12702/Go-to-Declaration-Implementation-not-available-for-generics-interfaces, referenced by https://github.com/golang/vscode-go/issues/2711.)

linjunhao1997 commented 1 year ago

I think this is urgently needed

fangjh13 commented 1 year ago

I would like to know how the progress is going, it's really needed.

adonovan commented 1 year ago

I would like to know how the progress is going, it's really needed.

No progress, sorry. Haven't even designed the algorithm yet. But let's make it a priority for 0.13.

ajsqr commented 9 months ago

Hello, is a fix for this planned in the upcoming release ?

Solverj commented 9 months ago

I'm also currently googling / gpting / searching, atm I have to make tests on a struct to verify that I've created structs according to generic interface in neovim.

adonovan commented 9 months ago

Hello, is a fix for this planned in the upcoming release ?

Unfortunately no, but likely the following one.

HarishHary commented 3 months ago

Hello any progress on this one?

adonovan commented 3 months ago

Still no progress yet, sorry.

The problem is a little trickier than it may appear because of the design of the index (database) used to radically optimize gopls v0.15. The indexed design means that the problem of testing implements(T, I), where I is an interface, cannot be done by making queries on the type-checker data structures for T and I since we no longer have them. Instead, the problem is mapped onto the domain of sets of strings, each representing a single method, so that the query becomes a string subset test. This works well for non-generic methods, which can each be mapped to a special string called a fingerprint; but we have not yet had time to develop a theory for fingerprinting generic methods, so they would need to fall back to using the type-checker, undoing the benefits of the gopls v0.15 redesign. Of course there are various short-cuts we could apply for common and simple cases, but our current focus is on better support for refactoring, so unfortunately this is not going to happen in the next several months.