golang / go

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

x/tools/gopls: References: "KeyOf(%s)={} yet %s is a method" bug in expandMethodSearch when a field and method conflict (via telemetry) #68817

Closed adonovan closed 2 months ago

adonovan commented 2 months ago

This stack WrwN7A was reported by telemetry:

gopls/bug
golang.org/x/tools/gopls/internal/util/bug.report:+35
golang.org/x/tools/gopls/internal/util/bug.Errorf:+2
golang.org/x/tools/gopls/internal/golang.expandMethodSearch:+4
golang.org/x/tools/gopls/internal/golang.ordinaryReferences:+137
golang.org/x/tools/gopls/internal/golang.references:+14
golang.org/x/tools/gopls/internal/golang.References:+1
golang.org/x/tools/gopls/internal/server.(*server).References:+18
golang.org/x/tools/gopls/internal/protocol.serverDispatch:+478
golang.org/x/tools/gopls/internal/lsprpc.(*streamServer).ServeStream.ServerHandler.func3:+5
golang.org/x/tools/gopls/internal/lsprpc.(*streamServer).ServeStream.handshaker.func4:+52
golang.org/x/tools/gopls/internal/protocol.Handlers.MustReplyHandler.func1:+2
golang.org/x/tools/gopls/internal/protocol.Handlers.AsyncHandler.func2.2:+3
runtime.goexit:+0
golang.org/x/tools/gopls@v0.16.1 go1.22.4 darwin/arm64 vscode (1)

Issue created by golang.org/x/tools/gopls/internal/telemetry/cmd/stacks.

gabyhelp commented 2 months ago

Related Issues and Documentation

(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)

adonovan commented 2 months ago

So KeyOf(recv) returns hasMethods = false. This means methodSetInfo returned Mask=0. The Mask has at least one bit set if the loop executes at all, so NewMethodSet(EnsurePointer(t)) must indeed be empty. How can the method set of a type be empty if the query started from a method of that type? Hmm... what if there are two methods, or a field and a method, that conflict?

$ cat a.go
package p

type E struct { X int }
func (E) X() {} // offset #45 is "X"

$ gopls references ./a.go:#45
gopls: KeyOf(*golang.org/x/tools.E)={} yet func (golang.org/x/tools.E).X() is a method
exit status 2

Bingo.

adonovan commented 2 months ago

Dup of https://github.com/golang/go/issues/67978.

gopherbot commented 2 months ago

Change https://go.dev/cl/605015 mentions this issue: gopls/internal/golang: downgrade assertion in methodsets index