Skip to content

x/tools/gopls: Extract Function: shouldReturn appears at wrong index of ReturnStmt.Results #75527

@fatanugraha

Description

@fatanugraha

gopls version

golang.org/x/tools/gopls v0.0.0-20250917170932-b71b35e896b5+dirty
golang.org/x/tools/gopls@v0.0.0-20250917170932-b71b35e896b5+dirty
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=
github.com/google/jsonschema-go@v0.2.3 h1:dkP3B96OtZKKFvdrUSaDkL+YDx8Uw9uC4Y+eukpCnmM=
github.com/modelcontextprotocol/go-sdk@v0.5.0 h1:WXRHx/4l5LF5MZboeIJYn7PMFCrMNduGGVapYWFgrF8=
github.com/yosida95/uritemplate/v3@v3.0.2 h1:Ed3Oyj9yrmi9087+NczuL5BwkIc4wvTb5zIM+UJPGz4=
golang.org/x/exp/typeparams@v0.0.0-20250819193227-8b4c13bb791b h1:GU1ttDuJS89SePnuEsEuLj7dMMFP2JkGsDV1Z51iDXo=
golang.org/x/mod@v0.28.0 h1:gQBtGhjxykdjY9YhZpSlZIsbnaE2+PgjfLWUQTnoZ1U=
golang.org/x/sync@v0.17.0 h1:l60nONMj9l5drqw6jlhIELNv9I0A4OFgRsG9k2oT9Ug=
golang.org/x/sys@v0.36.0 h1:KVRy2GtZBrk1cBYA7MKu5bEZFxQk4NIDV6RLVcC8o0k=
golang.org/x/telemetry@v0.0.0-20250908211612-aef8a434d053 h1:dHQOQddU4YHS5gY33/6klKjq7Gp3WwMyOXGNp5nzRj8=
golang.org/x/text@v0.29.0 h1:1neNs90w9YzJ9BocxfsQNHKuAT4pkghyXc4nhZ6sJvk=
golang.org/x/tools@v0.36.0 => ../
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.25.0

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='/home/fata/.local/share/mise/installs/go/1.24.6/bin'
GOCACHE='/home/fata/.cache/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/home/fata/.config/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -m64 -pthread -Wl,--no-gc-sections -fmessage-length=0 -ffile-prefix-map=/tmp/go-build1253172891=/tmp/go-build -gno-record-gcc-switches'
GOHOSTARCH='amd64'
GOHOSTOS='linux'
GOINSECURE=''
GOMOD='/home/fata/tools/gopls/go.mod'
GOMODCACHE='/home/fata/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='linux'
GOPATH='/home/fata/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/home/fata/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.0.linux-amd64'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/home/fata/.config/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/home/fata/go/pkg/mod/golang.org/toolchain@v0.0.1-go1.25.0.linux-amd64/pkg/tool/linux_amd64'
GOVCS=''
GOVERSION='go1.25.0'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

Extract function generates incorrect code when the selection has nested return

func doSomething() string {
	// selection starts -> run extract function code action
	y := 10
	if true {
		return "hi"
	}
	// selection ends

	return fmt.Sprintf("%d", y)
}

What did you see happen?

func doSomething() string {
	// selection starts
	y, s, shouldReturn := newFunction()
	if shouldReturn {
		return s
	}
	// selection ends

	return fmt.Sprintf("%d", y)
}

func newFunction() (int, string, bool) {
	y := 10
	if true {
		return 0, true, "hi"
	}
	return y, "", false
}

notice that the shouldReturn bool value is misplaced for the nested return while the non-nested one is correct

What did you expect to see?

func doSomething() string {
	// selection starts
	y, s, shouldReturn := newFunction()
	if shouldReturn {
		return s
	}
	// selection ends

	return fmt.Sprintf("%d", y)
}

func newFunction() (int, string, bool) {
	y := 10
	if true {
		return 0, "hi", true
	}
	return y, "", false
}

Editor and settings

VSCode

settings.json

    // go
    "go.formatTool": "gofumpt"

Logs

Info - 9:44:56 PM] 2025/09/18 21:44:56 Created View (#1)
directory=/home/fata/tools
view_type="GoMod"
root_dir="file:///home/fata/tools"
go_version="go version go1.24.6 linux/amd64"
build_flags=[]
env={GOOS:linux GOARCH:amd64 GOCACHE:/home/fata/.cache/go-build GOMODCACHE:/home/fata/go/pkg/mod GOPATH:/home/fata/go GOPRIVATE: GOFLAGS: GO111MODULE: GOTOOLCHAIN:auto GOROOT:/home/fata/.local/share/mise/installs/go/1.24.6 GoVersion:24 GoVersionOutput:go version go1.24.6 linux/amd64
ExplicitGOWORK: EffectiveGOPACKAGESDRIVER:}
env_overlay=[]

Request to stop language server - manual (enabled: true)[Info - 9:44:57 PM] 2025/09/18 21:44:57 Created View (#1)
directory=/home/fata/tools
view_type="GoMod"
root_dir="file:///home/fata/tools"
go_version="go version go1.24.6 linux/amd64"
build_flags=[]
env={GOOS:linux GOARCH:amd64 GOCACHE:/home/fata/.cache/go-build GOMODCACHE:/home/fata/go/pkg/mod GOPATH:/home/fata/go GOPRIVATE: GOFLAGS: GO111MODULE: GOTOOLCHAIN:auto GOROOT:/home/fata/.local/share/mise/installs/go/1.24.6 GoVersion:24 GoVersionOutput:go version go1.24.6 linux/amd64
ExplicitGOWORK: EffectiveGOPACKAGESDRIVER:}
env_overlay=[]

[Info - 9:44:58 PM] 2025/09/18 21:44:58 go/packages.Load #1
view_id="1"
snapshot=0
directory=/home/fata/tools
query=[/home/fata/tools/... builtin]
packages=527
duration=1.360005048s

[Info - 9:44:58 PM] 2025/09/18 21:44:58 go/packages.Load #1
view_id="1"
snapshot=0
directory=/home/fata/tools
query=[/home/fata/tools/... builtin]
packages=527
duration=1.807376264s

Metadata

Metadata

Assignees

No one assigned

    Labels

    BugReportIssues describing a possible bug in the Go implementation.RefactoringIssues related to refactoring toolsToolsThis 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