Skip to content

x/tools/gopls: gopls panics/crashes on inline variable #76144

@bystones

Description

@bystones

gopls version

Build info
----------
golang.org/x/tools/gopls v0.20.0
    golang.org/x/tools/gopls@v0.20.0 h1:fxOYZXKl6IsOTKIh6IgjDbIDHlr5btOtOUkrGOgFDB4=
    github.com/BurntSushi/toml@v1.5.0 h1:W5quZX/G/csjUnuI8SUYlsHs9M38FC7znL0lIO+DvMg=
    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/go-cmp@v0.7.0 h1:wk8382ETsv4JYUZwIsn6YpYiWiBsYLSJiTsyBybVuN8=
    golang.org/x/exp/typeparams@v0.0.0-20250620022241-b7579e27df2b h1:KdrhdYPDUvJTvrDK9gdjfFd6JTk8vA1WJoldYSi0kHo=
    golang.org/x/mod@v0.26.0 h1:EGMPT//Ezu+ylkCijjPc+f4Aih7sZvaAr+O3EHBxvZg=
    golang.org/x/sync@v0.16.0 h1:ycBJEhp9p4vXvUZNszeOq0kGTPghopOL8q0fq3vstxw=
    golang.org/x/sys@v0.34.0 h1:H5Y5sJ2L2JRdyv7ROF1he/lPdvFsd0mJHFw2ThKHxLA=
    golang.org/x/telemetry@v0.0.0-20250710130107-8d8967aff50b h1:DU+gwOBXU+6bO0sEyO7o/NeMlxZxCZEvI7v+J4a1zRQ=
    golang.org/x/text@v0.27.0 h1:4fGWRpyh641NLlecmyl4LOe6yDdfaYNrGb2zdfo4JV4=
    golang.org/x/tools@v0.35.1-0.20250728180453-01a3475a31bc h1:ZRKyKRJl/YEWl9ScZwd6Ua6xSt7DE6tHp1I3ucMroGM=
    golang.org/x/vuln@v1.1.4 h1:Ju8QsuyhX3Hk8ma3CesTbO8vfJD9EvUBgHvkxHBzj0I=
    honnef.co/go/tools@v0.7.0-0.dev.0.20250523013057-bbc2f4dd71ea h1:fj8r9irJSpolAGUdZBxJIRY3lLc4jH2Dt4lwnWyWwpw=
    mvdan.cc/gofumpt@v0.8.0 h1:nZUCeC2ViFaerTcYKstMmfysj6uhQrA2vJe+2vwGU6k=
    mvdan.cc/xurls/v2@v2.6.0 h1:3NTZpeTxYVWNSokW3MKeyVkz/j7uYXYiMtXRUfmjbgI=
go: go1.24.5

go env

AR='ar'
CC='gcc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='g++'
GCCGO='gccgo'
GO111MODULE=''
GOAMD64='v1'
GOARCH='amd64'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/home/bystones/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/bystones/.config/go/env'
GOEXE=''
GOEXPERIMENT='nodwarf5'
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build2148461368=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/home/bystones/.local/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/bystones/.local/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/usr/lib/go'
GOSUMDB='sum.golang.org'
GOTELEMETRY='on'
GOTELEMETRYDIR='/home/bystones/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/usr/lib/go/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.3 X:nodwarf5'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Use the code action 'Inline variable "human"' in Neovim on the following code:

package main

type A struct {
	Name string
}

func F() map[string]A {
	m := make(map[string]A)

	human := A{
		Name: "foo",
	}
	m["foo"] = human // Action used here from the "n" of the word human.
	return m
}

I attempted to reproduce the problem as a gopls test to rule out that my editor/config is doing something it should not be doing. To do this I appended the following testcase into gopls/internal/test/marker/testdata/codeaction/inline-var.txt and ran the tests:

-- c/c.go --
package main

type A struct {
	Name string
}

func F() map[string]A {
	m := make(map[string]A)

	human := A{
		Name: "foo",
	}
	m["foo"] = human //@codeaction("hu", "refactor.inline.variable", err=re`test`)
	return m
}

Before tests run fine, afterwards they paniced:

$ go test -run Test/codeaction/inline-var.txt
panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x40 pc=0xeaad83]

goroutine 2566 [running]:
golang.org/x/tools/gopls/internal/golang.inlineVariableOne-range1({0xc007fb4090?, 0x9b1965?})
	/tmp/tools/gopls/internal/golang/inline.go:208 +0x203
golang.org/x/tools/go/ast/inspector.Cursor.Preorder.func1(0xc0089cf560)
	/home/bystones/.local/go/pkg/mod/golang.org/x/tools@v0.35.1-0.20250728180453-01a3475a31bc/go/ast/inspector/cursor.go:132 +0xac
golang.org/x/tools/gopls/internal/golang.inlineVariableOne(0xc0089fd020, 0xc007264ea0, 0x10b9, 0x10bb)
	/tmp/tools/gopls/internal/golang/inline.go:194 +0x386
golang.org/x/tools/gopls/internal/golang.ApplyFix.singleFile.func6({0xc007264ea0?, 0xc008a8a640?}, 0xc0089e6da0?, 0xc0080728c0?, 0xdc16b1?, 0x0?, 0x47fefa?)
	/tmp/tools/gopls/internal/golang/fix.go:49 +0x24
golang.org/x/tools/gopls/internal/golang.ApplyFix({0x1667848, 0xc008a8a640}, {0xc0089e6da0, 0xf}, 0xc00055c7e0, {0x166edc0, 0xc007203380}, {{0xc, 0xc}, {0xc, ...}})
	/tmp/tools/gopls/internal/golang/fix.go:127 +0x6fc
golang.org/x/tools/gopls/internal/server.(*commandHandler).ApplyFix.func1({0x1667848, 0xc008a8a640}, {0xc00055c7e0?, {0x166edc0?, 0xc007203380?}, 0x0?})
	/tmp/tools/gopls/internal/server/command.go:430 +0x86
golang.org/x/tools/gopls/internal/server.(*commandHandler).run.func2()
	/tmp/tools/gopls/internal/server/command.go:390 +0x87
golang.org/x/tools/gopls/internal/server.(*commandHandler).run(0xc008a8c610, {0x1667810, 0xc008a992c0}, {0x0, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}, ...}, ...)
	/tmp/tools/gopls/internal/server/command.go:421 +0x583
golang.org/x/tools/gopls/internal/server.(*commandHandler).ApplyFix(0xc008a8c610, {0x1667810, 0xc008a992c0}, {{0xc0089e6da0, 0xf}, {{0xc008233b30, 0x42}, {{0xc, 0xc}, {0xc, ...}}}, ...})
	/tmp/tools/gopls/internal/server/command.go:426 +0x1a5
golang.org/x/tools/gopls/internal/protocol/command.Dispatch({0x1667810, 0xc008a992c0}, 0xc008a8ef80, {0x1681da8, 0xc008a8c610})
	/tmp/tools/gopls/internal/protocol/command/command_gen.go:151 +0xaa2
golang.org/x/tools/gopls/internal/server.(*server).ResolveCodeAction(0xc00722e000, {0x1667810?, 0xc008a991d0?}, 0xc0089cf500)
	/tmp/tools/gopls/internal/server/code_action.go:256 +0x1b9
golang.org/x/tools/gopls/internal/protocol.serverDispatch({0x1667810, 0xc008a991d0}, {0x1688810, 0xc00722e000}, 0xc008a99200, {0x1667cb8, 0xc008a8eec0})
	/tmp/tools/gopls/internal/protocol/tsserver.go:216 +0xcda
golang.org/x/tools/gopls/internal/lsprpc.(*StreamServer).ServeStream.ServerHandler.func4({0x1667810, 0xc008a991d0}, 0xc008a99200, {0x1667cb8, 0xc008a8eec0})
	/tmp/tools/gopls/internal/protocol/protocol.go:159 +0x85
golang.org/x/tools/gopls/internal/lsprpc.(*StreamServer).ServeStream.handshaker.func5({0x1667810, 0xc008a991d0}, 0xc008a99200, {0x1667cb8, 0xc008a8eec0})
	/tmp/tools/gopls/internal/lsprpc/lsprpc.go:575 +0x909
golang.org/x/tools/gopls/internal/protocol.Handlers.MustReplyHandler.func1({0x1667810, 0xc008a991d0}, 0xc008a89380, {0x1667cb8, 0xc008a8eec0})
	/home/bystones/.local/go/pkg/mod/golang.org/x/tools@v0.35.1-0.20250728180453-01a3475a31bc/internal/jsonrpc2/handler.go:35 +0xc6
golang.org/x/tools/gopls/internal/protocol.Handlers.AsyncHandler.func2.2()
	/home/bystones/.local/go/pkg/mod/golang.org/x/tools@v0.35.1-0.20250728180453-01a3475a31bc/internal/jsonrpc2/handler.go:104 +0x96
created by golang.org/x/tools/gopls/internal/protocol.Handlers.AsyncHandler.func2 in goroutine 125
	/home/bystones/.local/go/pkg/mod/golang.org/x/tools@v0.35.1-0.20250728180453-01a3475a31bc/internal/jsonrpc2/handler.go:101 +0x22f
exit status 2
FAIL	golang.org/x/tools/gopls/internal/test/marker	0.466s

What did you see happen?

Client gopls quit with exit code 2 and signal 0. Check log for errors: /home/bystones/.local/state/nvim/lsp.log

What did you expect to see?

No crash/panic.

Editor and settings

Neovim

Logs

No response

Metadata

Metadata

Assignees

Labels

BugReportIssues describing a possible bug in the Go implementation.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