Skip to content

x/tools/gopls: completion of receiver types depends on where in the file the type is defined #81658

Open

Description

@rothelius

gopls version

Details
Build info
----------
golang.org/x/tools/gopls v0.23.0
    golang.org/x/tools/gopls@v0.23.0 h1:Dn6mf9WXu9iLnTftDDMb9wV0c6Se7PjzEMqP0LEe08Y=
    github.com/BurntSushi/toml@v1.6.0 h1:dRaEfpa2VI55EwlIW72hMRHdWouJeRF7TPYhI+AUQjk=
    github.com/fatih/camelcase@v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
    github.com/fatih/gomodifytags@v1.17.1-0.20250423142747-f3939df9aa3c h1:dDSgAjoOMp8da3egfz0t2S+t8RGOpEmEXZubcGuc0Bg=
    github.com/fatih/structtag@v1.2.0 h1:/OdNE99OxoI/PqaW/SuSK9uxxT3f/tcSZgon/ssNSx4=
    github.com/fsnotify/fsnotify@v1.9.0 h1:2Ml+OJNzbYCTzsxtv8vKSFD9PbJjmhYF14k/jKC7S9k=
    github.com/google/jsonschema-go@v0.4.3 h1:/DBOLZTfDow7pe2GmaJNhltueGTtDKICi8V8p+DQPd0=
    github.com/modelcontextprotocol/go-sdk@v1.6.0 h1:PPLS3kn7WtOEnR+Af4X5H96SG0qSab8R/ZQT/HkhPkY=
    github.com/segmentio/asm@v1.2.1 h1:DTNbBqs57ioxAD4PrArqftgypG4/qNpXoJx8TVXxPR0=
    github.com/segmentio/encoding@v0.5.4 h1:OW1VRern8Nw6ITAtwSZ7Idrl3MXCFwXHPgqESYfvNt0=
    github.com/yosida95/uritemplate/v3@v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
    golang.org/x/exp/typeparams@v0.0.0-20260611194520-c48552f49976 h1:GTD/WuaexTazIG/SxLOz4rEKZPDVilmVVC2nz4xhwfE=
    golang.org/x/mod@v0.37.0 h1:vF1DjpVEshcIqoEaauuHebaLk1O1forxjxBaVn884JQ=
    golang.org/x/oauth2@v0.36.0 h1:peZ/1z27fi9hUOFCAZaHyrpWG5lwe0RJEEEeH0ThlIs=
    golang.org/x/sync@v0.21.0 h1:HLII4xRRTtCRkxYp4HNFF0Js/Og6q2i++KXbg0gHCwM=
    golang.org/x/sys@v0.46.0 h1:noSf2Fq6F8DBgS+LysIkx7rIExoNHJsxOAtPp4rthXw=
    golang.org/x/telemetry@v0.0.0-20260625142307-59b4966ccb57 h1:nwGZBCt+FnXUrGsj5vjzAsEmkcaFvd82BbOjECiFYZc=
    golang.org/x/text@v0.38.0 h1:sXmwo9DwP3OK9EZ7PqAdaooSGozfl/3a6/xJcbzPRhE=
    golang.org/x/tools@v0.47.1-0.20260707181000-a299dadba899 h1:5O28oLQxJ1jif5UNdi9OULXCd4g3rsy3xkECh96fnf8=
    golang.org/x/vuln@v1.4.0 h1:FpmTZiV4PyqY3lFfuCkz1JftEXb/+8M2NEkjJM5TF4g=
    honnef.co/go/tools@v0.8.0-rc.1 h1:wqMm2kjcEXMOr+6yau+pdKqJKe6l2N1aKPkpini+Kzk=
    mvdan.cc/gofumpt@v0.10.0 h1:yGGpRS2pBN2OQIi7b21IXknJna7faPkFaVfHLrN6Euo=
    mvdan.cc/xurls/v2@v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
go: go1.27.1-X:simd

go env

Details
AR='ar'
CC='clang'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='clang++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN='/Users/fabian/go/bin'
GOCACHE='/Users/fabian/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/fabian/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT='simd'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch x86_64 -m64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/rn/nygjm47n5wj_4pxy3096pwkr0000gn/T/go-build2259973909=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='amd64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/Users/fabian/go/src/gsp/go.mod'
GOMODCACHE='/Users/fabian/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPACKAGESDRIVER=''
GOPATH='/Users/fabian/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/local/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/fabian/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/local/go/pkg/tool/darwin_amd64'
GOVCS=''
GOVERSION='go1.27.1'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Tried to complete the type name of the receiver for a new method:

type SomeType1 int 

func (st Some)

type SomeType2 int 

What did you see happen?

Only SomeType1 was offered as a suggestion:
SomeType2 missing
SomeType2, being defined later in the same file, was missing from the suggestions.

What did you expect to see?

I expected SomeType2 to be suggested as well, as type and method declarations can come in any order.

I'm guessing it has to do with the file not being valid code from the incomplete method declaration down, since both types are suggested given:

type SomeType1 int 

func (st Some) foo() {}

type SomeType2 int 

Hopefully gopls can be made slightly more robust in this regard! 😃

Editor and settings

VSCode settings.json
{
    "workbench.preferredHighContrastColorTheme": "Shades of Purple",
    "go.inlayHints.constantValues": true,
    "editor.maxTokenizationLineLength": 200000,    
    "javascript.format.semicolons": "remove",
    "go.toolsManagement.autoUpdate": true,
    "chat.disableAIFeatures": true,
    "go.experiments": {
        "testExplorer": true
    },
    "editor.unicodeHighlight.allowedCharacters": {
        "σ": true
    },
    "editor.inlayHints.maximumLength": 0,
    "go.inlayHints.functionTypeParameters": true,
    "go.coverOnSingleTest": true,
    "go.coverOnSingleTestFile": true,
    "go.editorContextMenuCommands": {
        "fillStruct": true,
        "testFile": true,
        "testPackage": true,
        "compilerDetails": true
    },
    "go.inlayHints.ignoredError": true,
}

Logs

No response

Activity

  1. added
    goplsIssues related to the Go language server, gopls.
    ToolsThis label describes issues relating to any tools in the x/tools repository.
    on Sep 22, 2026
  2. added this to the Unreleased milestone on Sep 22, 2026
  3. h9jiang commented on Oct 1, 2026

    @h9jiang
    Member

    I can not promise this is the root cause, but I remember, the problem is the parser where the parser failed to identify the the symbol after the broken place func (st Some). So the parser / type checker did not realize there is another symbol down below.

    I remember there was a idea proposed if the parser can parse the file from top to bottom (until failure) and then parse from bottom to top (until failure). So the type checker can capture anything before the failure point and after and hence can offer the best type checked information for functionalities like completion. (But it is possible that we won't be able to get to this in near future.)

    I probably need to sit down and look at the case you are mentioning here to verify whether the reason is actually the root cause, and maybe there is a easier way to fix this by manually insert a {} in gopls memory. If there is a easy version, then we maybe able to do it as a quick fix.

    +Needs Investigation.

  4. added
    NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.
    on Oct 1, 2026
  5. self-assigned this
    on Oct 1, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.ToolsThis label describes issues relating to any tools in the x/tools repository.goplsIssues related to the Go language server, gopls.

Type

No type

Projects

No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions