-
Notifications
You must be signed in to change notification settings - Fork 17.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
x/tools/gopls: cannot find refs to function type #62366
Comments
@notrobpike can you clarify what you meant by "the method that the type alias references"? |
sorry, i did misspeak. there is no alias here. And yes, I did expect to find However, please consider this slightly updated version. package main
import (
"context"
"fmt"
)
type cmdable func(ctx context.Context, arg string) string
type client struct {
cmdable
fn func(ctx context.Context, arg string) string
}
func (c *client) init() {
c.cmdable = c.Process
c.fn = c.Process
}
func (c *client) Process(ctx context.Context, arg string) string {
return arg
}
func (c cmdable) DoIt(ctx context.Context, arg string) string {
return c(ctx, arg) // really?!?
}
func main() {
var c client
c.init()
c.fn(context.Background(), "wtf")
fmt.Println(c.DoIt(context.Background(), "wtf"))
} At L31, "Find all References" to If I highlight the receiver |
If I hover over the Name It's a field name in the context of
On the other hand,
Should Find all References on I agree that embedding makes things so confusing in this case. However, I don't know how to express this Go-specific unique feature within LSP designed for general languages. Finally, the receiver name |
I agree, in your example, Find all References should NOT return the assignment in c.init()! So perhaps likewise highlighting cmdable in c.Doit() shouldn't locate that assignment either. I guess I muddied the waters a little there. The function call c() in c.Doit() is known to be a function call. So eg, gopls properly identifies if the arguments are wrong. And so just like how Find all References on c.fn() in main() locates the assignment, Find all References on c() in c.Doit() should locate the assignment. I agree that Yes this is hella confusing. This is not a contrived example for the sake of opening a bug. The popular library go-redis uses this construction, since v7 I believe. The second commit of this PR. Because gopls cannot find the function c.Process(), it's difficult to follow a call tree. eg, start at a command in You can Go to Type Definition on any method, that will take you to the function type declaration. Then you do Find all References, which gives you a bazillion hits (at least for |
I think there may be two separate issues here:
|
I think we should treat an Implementations request on any 'func' type without methods, or on any value of such a type, as a request for all the address-taken functions that are assignable to that type. (A request on a named func type with methods should continue to be treated only as an interface query to avoid ambiguity; the informed user can always issue an Implementations query from the func portion of Computing address-taken functions is a little tricky. If we assume (like unusedparams) that every exported function is potentially address-taken, then we'll get a lot of spurious matches. Perhaps that's ok, because there are always going to be tons of spurious matches for common signatures like If we conduct a workspace-wide search for address-taking operations (e.g. So, a rough plan:
Should we return the position of each function declaration (e.g. |
What version of Go are you using (
go version
)?Does this issue reproduce with the latest release?
What operating system and processor architecture are you using (
go env
)?go env
OutputWhat did you do?
I tried to use vscode to "find all references", "find all implementations", "go to definition" of an function type alias embedded in a struct. vscode is unable to find it. vscode uses
gopls
so I believe it isgopls
that is at fault.What did you expect to see?
I expected to be taken to the method that the type alias references.
What did you see instead?
"go to definition" took me to the method that the function alias was itself part of (where it was being called from).
Load the following program into vscode. right click on the commented function call and try to find what actually would get called.
The text was updated successfully, but these errors were encountered: