golang/go

x/tools/gopls: modernize/waitgroup.go can produce invalid code

Closed this issue · 2 comments

gopls version

Build info
----------
golang.org/x/tools/gopls v0.20.0
    golang.org/x/tools/gopls@(devel)
    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='cc'
CGO_CFLAGS='-O2 -g'
CGO_CPPFLAGS=''
CGO_CXXFLAGS='-O2 -g'
CGO_ENABLED='1'
CGO_FFLAGS='-O2 -g'
CGO_LDFLAGS='-O2 -g'
CXX='c++'
GCCGO='gccgo'
GO111MODULE=''
GOARCH='arm64'
GOARM64='v8.0'
GOAUTH='netrc'
GOBIN=''
GOCACHE='/Users/rquitt/Library/Caches/go-build'
GOCACHEPROG=''
GODEBUG=''
GOENV='/Users/rquitt/Library/Application Support/go/env'
GOEXE=''
GOEXPERIMENT=''
GOFIPS140='off'
GOFLAGS=''
GOGCCFLAGS='-fPIC -arch arm64 -pthread -fno-caret-diagnostics -Qunused-arguments -fmessage-length=0 -ffile-prefix-map=/var/folders/dl/fbhwp50s761fhppy9y0r2_0w0000gp/T/go-build2180092075=/tmp/go-build -gno-record-gcc-switches -fno-common'
GOHOSTARCH='arm64'
GOHOSTOS='darwin'
GOINSECURE=''
GOMOD='/dev/null'
GOMODCACHE='/Users/rquitt/go/pkg/mod'
GONOPROXY=''
GONOSUMDB=''
GOOS='darwin'
GOPATH='/Users/rquitt/go'
GOPRIVATE=''
GOPROXY='https://proxy.golang.org,direct'
GOROOT='/opt/homebrew/Cellar/go/1.25.3/libexec'
GOSUMDB='sum.golang.org'
GOTELEMETRY='local'
GOTELEMETRYDIR='/Users/rquitt/Library/Application Support/go/telemetry'
GOTMPDIR=''
GOTOOLCHAIN='auto'
GOTOOLDIR='/opt/homebrew/Cellar/go/1.25.3/libexec/pkg/tool/darwin_arm64'
GOVCS=''
GOVERSION='go1.25.3'
GOWORK=''
PKG_CONFIG='pkg-config'

What did you do?

I ran the modernizer against some code and got some code that didn't work. This is a minimal reproduction:

go run golang.org/x/tools/gopls/internal/analysis/modernize/cmd/modernize@latest -v -fix -test main.go

Before:

package main

import "sync"

type Foo struct {
	wg sync.WaitGroup
}

func (f *Foo) Bar() {
	f.wg.Add(1)
	go func() {
		defer f.wg.Done()
	}()
}

func main() {

}

After:

package main

import "sync"

type Foo struct {
	wg sync.WaitGroup
}

func (f *Foo) Bar() {
	&{f wg}.Go(func() {
	})
}

func main() {

}

What did you see happen?

The waitgroup code no longer compiles

What did you expect to see?

I would expect the code to be something like

	f.wg.Go(func() {
	})

Editor and settings

N/A

Logs

No response

Dup of #74708, now fixed on master.