Skip to content
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: index out of range while trying to run textDocument/codeAction on entire document #55300

Closed
fsouza opened this issue Sep 21, 2022 · 3 comments
Labels
Documentation FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Milestone

Comments

@fsouza
Copy link
Contributor

fsouza commented Sep 21, 2022

gopls version

Build info
----------
golang.org/x/tools/gopls master
    golang.org/x/tools/gopls@(devel)
    github.com/BurntSushi/toml@v1.2.0 h1:Rt8g24XnyGTyglgET/PRUNlrUeu9F5L+7FilkXfZgs0=
    github.com/google/go-cmp@v0.5.8 h1:e6P7q2lk1O+qJJb4BtCQXlK8vWEO8V1ZeuEdJNOqZyg=
    github.com/sergi/go-diff@v1.1.0 h1:we8PVUC3FE2uYfodKH/nBHMSetSfHDR6scGdBi+erh0=
    golang.org/x/exp@v0.0.0-20220722155223-a9213eeb770e h1:+WEEuIdZHnUeJJmEUjyYC2gfUMj69yZXw17EnHg/otA=
    golang.org/x/exp/typeparams@v0.0.0-20220722155223-a9213eeb770e h1:7Xs2YCOpMlNqSQSmrrnhlzBXIE/bpMecZplbLePTJvE=
    golang.org/x/mod@v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
    golang.org/x/sync@v0.0.0-20220722155255-886fb9371eb4 h1:uVc8UZUe6tr40fFVnUP5Oj+veunVezqYl9z7DYw9xzw=
    golang.org/x/sys@v0.0.0-20220808155132-1c4a2a72c664 h1:v1W7bwXHsnLLloWYTVEdvGvA7BHMeBYsPcF0GLDxIRs=
    golang.org/x/text@v0.3.7 h1:olpwvP2KacW1ZWvsR7uQhoyTYvKAupfQrRGBFM352Gk=
    golang.org/x/tools@v0.1.13-0.20220810174125-0ad49fdeb955 => ../
    golang.org/x/vuln@v0.0.0-20220919155316-41b1fc70d0a6 h1:tQFrcJZ95V1wiLLPoAIaEuEVXJ7JkhbZI4Hws7Fx69c=
    honnef.co/go/tools@v0.3.3 h1:oDx7VAwstgpYpb3wv0oxiZlxY+foCpRAwY7Vk6XpAgA=
    mvdan.cc/gofumpt@v0.3.1 h1:avhhrOmv0IuvQVK7fvwV91oFSGAk5/6Po8GXTzICeu8=
    mvdan.cc/xurls/v2@v2.4.0 h1:tzxjVAj+wSBmDcF6zBB7/myTy3gX9xvi8Tyr28AuQgc=
go: devel go1.20-d11c58eedb Wed Sep 21 01:56:24 2022 +0000

go env

% go env
GO111MODULE=""
GOARCH="arm64"
GOBIN="/Users/fsouza/bin"
GOCACHE="/Users/fsouza/Library/Caches/go-build"
GOENV="/Users/fsouza/Library/Application Support/go/env"
GOEXE=""
GOEXPERIMENT=""
GOFLAGS="-modcacherw"
GOHOSTARCH="arm64"
GOHOSTOS="darwin"
GOINSECURE=""
GOMODCACHE="/Users/fsouza/.cache/go/path/pkg/mod"
GONOPROXY=""
GONOSUMDB=""
GOOS="darwin"
GOPATH="/Users/fsouza/.cache/go/path"
GOPRIVATE=""
GOPROXY="https://proxy.golang.org,direct"
GOROOT="/Users/fsouza/.cache/go/sdk/gotip"
GOSUMDB="sum.golang.org"
GOTMPDIR=""
GOTOOLDIR="/Users/fsouza/.cache/go/sdk/gotip/pkg/tool/darwin_arm64"
GOVCS=""
GOVERSION="devel go1.20-d11c58eedb Wed Sep 21 01:56:24 2022 +0000"
GCCGO="gccgo"
AR="ar"
CC="clang"
CXX="clang++"
CGO_ENABLED="1"
GOMOD="/Users/fsouza/Projects/os/p/fake-gcs-server/go.mod"
GOWORK=""
CGO_CFLAGS="-g -O2"
CGO_CPPFLAGS=""
CGO_CXXFLAGS="-g -O2"
CGO_FFLAGS="-g -O2"
CGO_LDFLAGS="-g -O2"
PKG_CONFIG="pkg-config"
GOGCCFLAGS="-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -fdebug-prefix-map=/var/folders/rz/8d0l4yp51sd3jh9f34x7pkg80000gn/T/go-build3810227374=/tmp/go-build -gno-record-gcc-switches -fno-common"

What did you do?

Invoke textDocument/codeAction passing a range that covers the entire file
(following the spec for
range
,
which means that the end position is exclusive). Here's what the range I'm
sending looks like (in JSON-ish):

{
  ... other fields
  "range": {
    "start": {
      "line": 0,
      "character": 0
    },
    "end": {
      "line": $N,
      "character": 0
    }
  }
}

Where $N = number of lines in the file.

For full reproduction steps, see "Editor & Settings" below.

What did you expect to see?

The list of code actions available in the entire file.

What did you see instead?

gopls panics with an index out of range. Since this is a panic, the stacktrace
isn't available in the logs for gopls, but I'm able to get the process output
from my editor's logs:

[ERROR][2022-09-21 09:02:06] .../vim/lsp/rpc.lua:733    "rpc"   "/Users/fsouza/.cache/nvim/langservers/bin/gopls"  "stderr"        "panic: runtime error: index out of range [2] with length 2\n\ngoroutine 8707 [running]:\ngolang.org/x/tools/gopls/internal/lsp/source.adjustRangeForCommentsAndWhiteSpace({0x140038d9380?, 0x69?, 0x1?}, 0x140038d9380, {0x14001dea000, 0xbc7, 0x140000f4640?}, 0x1400370b400)\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/source/extract.go:704 +0x3e0\ngolang.org/x/tools/gopls/internal/lsp/source.CanExtractFunction(0x140038d9380, {0x140038d9380, 0x92e342, 0x92eef2}, {0x14001dea000, 0xbc7, 0xbc8"
[ERROR][2022-09-21 09:02:06] .../vim/lsp/rpc.lua:733    "rpc"   "/Users/fsouza/.cache/nvim/langservers/bin/gopls"  "stderr"        "}, 0x102f5bfe4?)\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/source/extract.go:984 +0xc4\ngolang.org/x/tools/gopls/internal/lsp.extractionFixes({0x1034480e0, 0x1400d856440}, {0x103453b18?, 0x140038e2640?}, {0x103408780?, 0x0?}, {0x140069ec9c0, 0x3a}, {{0x0?, 0x0?}, ...})\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/code_action.go:301 +0x180\ngolang.org/x/tools/gopls/internal/lsp.(*Server).codeAction(0x1400d8b4180?, {0x1034480e0, 0x1400d856440}, 0x1400d8b4180)\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/code_action.go:196 +0x13c4\ngolang.org/x/tools/gopls/internal/lsp.(*Server).CodeAction(0x14000138210?, {0x1034480e0?, 0x1400d856440?}, 0x1032e84c0?)\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/server_gen.go:16 +0x24\ngolang.org/x/tools/gopls/internal/lsp/protocol.serverDispatch({0x1034480e0, 0x1400d856440}, {0x1034571a8, 0x140004f2360}, 0x1400d66e750, {0x103448498, 0x1400d8562c0})\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/protocol/tsserver.go:239 +0x18cc\ngolang.org/x/tools/gopls/internal/lsp/protocol.ServerHandler.func1({0x1034480e0, 0x1400d856440}, 0x1400d66e750, {0x103448498, 0x1400d8562c0})\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/protocol/protocol.go:157 +0x6c\ngolang.org/x/tools/gopls/internal/lsp/lsprpc.handshaker.func1({0x1034480e0, 0x1400d856440}, 0x1400d66e750, {0x103448498?, 0x1400d8562c0?})\n\t/Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/lsprpc/lsprpc.go:515 +0x768\ngolang.org/x/tools/internal/jsonrpc2.MustReplyHandler.func1({0x1034480e0, 0x1400d856440}, 0x1400d5bd128, {0x103448498?, 0x1400d8562c0?})\n\t/Users/fsouza/.cache/nvim/langservers/tools/internal/jsonrpc2/handler.go:35 +0xf0\ngolang.org/x/tools/internal/jsonrpc2.AsyncHandler.func1.2()\n\t/Users/fsouza/.cache/nvim/langservers/tools/internal/jsonrpc2/handler.go:103 +0x90\ncreated by golang.org/x/tools/internal/jsonrpc2.AsyncHandler.func1\n\t/Users/fsouza/.cache/nvim/langservers/tools/internal/jsonrpc2/handler.go:100 +0x1dc\n"

In order to make it easier to read, I've also expanded the two lines above. This is the output from gopls:

panic: runtime error: index out of range [2] with length 2

goroutine 8707 [running]:
golang.org/x/tools/gopls/internal/lsp/source.adjustRangeForCommentsAndWhiteSpace({0x140038d9380?, 0x69?, 0x1?}, 0x140038d9380, {0x14001dea000, 0xbc7, 0x140000f4640?}, 0x1400370b400)
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/source/extract.go:704 +0x3e0
golang.org/x/tools/gopls/internal/lsp/source.CanExtractFunction(0x140038d9380, {0x140038d9380, 0x92e342, 0x92eef2}, {0x14001dea000, 0xbc7, 0xbc8}, 0x102f5bfe4?)
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/source/extract.go:984 +0xc4
golang.org/x/tools/gopls/internal/lsp.extractionFixes({0x1034480e0, 0x1400d856440}, {0x103453b18?, 0x140038e2640?}, {0x103408780?, 0x0?}, {0x140069ec9c0, 0x3a}, {{0x0?, 0x0?}, ...})
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/code_action.go:301 +0x180
golang.org/x/tools/gopls/internal/lsp.(*Server).codeAction(0x1400d8b4180?, {0x1034480e0, 0x1400d856440}, 0x1400d8b4180)
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/code_action.go:196 +0x13c4
golang.org/x/tools/gopls/internal/lsp.(*Server).CodeAction(0x14000138210?, {0x1034480e0?, 0x1400d856440?}, 0x1032e84c0?)
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/server_gen.go:16 +0x24
golang.org/x/tools/gopls/internal/lsp/protocol.serverDispatch({0x1034480e0, 0x1400d856440}, {0x1034571a8, 0x140004f2360}, 0x1400d66e750, {0x103448498, 0x1400d8562c0})
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/protocol/tsserver.go:239 +0x18cc
golang.org/x/tools/gopls/internal/lsp/protocol.ServerHandler.func1({0x1034480e0, 0x1400d856440}, 0x1400d66e750, {0x103448498, 0x1400d8562c0})
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/protocol/protocol.go:157 +0x6c
golang.org/x/tools/gopls/internal/lsp/lsprpc.handshaker.func1({0x1034480e0, 0x1400d856440}, 0x1400d66e750, {0x103448498?, 0x1400d8562c0?})
        /Users/fsouza/.cache/nvim/langservers/tools/gopls/internal/lsp/lsprpc/lsprpc.go:515 +0x768
golang.org/x/tools/internal/jsonrpc2.MustReplyHandler.func1({0x1034480e0, 0x1400d856440}, 0x1400d5bd128, {0x103448498?, 0x1400d8562c0?})
        /Users/fsouza/.cache/nvim/langservers/tools/internal/jsonrpc2/handler.go:35 +0xf0
golang.org/x/tools/internal/jsonrpc2.AsyncHandler.func1.2()
        /Users/fsouza/.cache/nvim/langservers/tools/internal/jsonrpc2/handler.go:103 +0x90
created by golang.org/x/tools/internal/jsonrpc2.AsyncHandler.func1
        /Users/fsouza/.cache/nvim/langservers/tools/internal/jsonrpc2/handler.go:100 +0x1dc

This is a regression and I was able to bisect it to this commit:

fdf581fdab091d9dd12425be67e59db67a2ad501 is the first bad commit
commit fdf581fdab091d9dd12425be67e59db67a2ad501
Author: Suzy Mueller <suzmue@golang.org>
Date:   Thu Sep 23 19:52:37 2021 -0600

    internal/lsp: allow extract func ranges to begin/end with comments

    CanExtract strips of the whitespace on either end of the range in
    order to get an exact range to extract to function. We can do the
    same thing for comments by moving adjusting the range if the start
    or end positions contain the position.

    Updates golang/go#37170
    Fixes golang/go#54816

    Change-Id: I3508c822434400f084a273730380c89611803e97
    Reviewed-on: https://go-review.googlesource.com/c/tools/+/351989
    Reviewed-by: Robert Findley <rfindley@google.com>
    gopls-CI: kokoro <noreply+kokoro@google.com>
    Run-TryBot: Suzy Mueller <suzmue@golang.org>
    TryBot-Result: Gopher Robot <gobot@golang.org>

 gopls/internal/lsp/source/extract.go               | 94 +++++++++++++++-------
 .../extract_function/extract_basic_comment.go      | 10 ++-
 .../extract_basic_comment.go.golden                | 46 ++++++++++-
 gopls/internal/lsp/testdata/summary.txt.golden     |  2 +-
 .../lsp/testdata/summary_go1.18.txt.golden         |  2 +-
 5 files changed, 115 insertions(+), 39 deletions(-)

Editor and settings

This is neovim. It can be reproduced with just gopls installed. Minimal
reproducer in neovim:
https://gist.github.com/fsouza/01bf91accbce744ae528bad2472c79f3

How to reproduce in neovim with the config file above, using some Go repo (I
tested with fake-gcs-server, but
I suspect that any project/file will do):

nvim -u minimal_init.lua
:e main.go
:lua document_code_action()

Logs

Logs from gopls: https://gist.github.com/fsouza/ecc217ae4f2bbdc4dbcf2033c6b34581

Logs from the editor (includes the process stderr with the crash at the very end): https://gist.github.com/fsouza/9700b8daa4658fb226440fbedf1dbff5

@gopherbot gopherbot added Tools This label describes issues relating to any tools in the x/tools repository. gopls Issues related to the Go language server, gopls. labels Sep 21, 2022
@gopherbot gopherbot added this to the Unreleased milestone Sep 21, 2022
@findleyr
Copy link
Contributor

Thank you for the detailed report. I believe this is a dupe of #55271, which was just closed.

@findleyr findleyr closed this as not planned Won't fix, can't repro, duplicate, stale Sep 21, 2022
@fsouza
Copy link
Contributor Author

fsouza commented Sep 21, 2022

Thank you for the detailed report. I believe this is a dupe of #55271, which was just closed.

Oh thanks for the quick fix and apologies for the dup!

@findleyr
Copy link
Contributor

No need to apologize! Your report was very thoughtful and appreciated. We just happened to have caught this yesterday.

@golang golang locked and limited conversation to collaborators Sep 21, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Documentation FrozenDueToAge gopls Issues related to the Go language server, gopls. Tools This label describes issues relating to any tools in the x/tools repository.
Projects
None yet
Development

No branches or pull requests

3 participants