Go version
go version go1.25.1 darwin/amd64
Output of go env
in your module/workspace:
N/A
What did you do?
I ran modernize (commit 0b1eed09a34f5a1e0a5c237bc9771eb036b35319) on the following program (playground), which outputs 10:
package main
import "fmt"
func main() {
var i int
defer func() { fmt.Println(i) }()
for i = 0; i < 10; i++ {
// deliberately empty
}
}
What did you see happen?
REDACTED.go:8:6: for loop can be modernized using range over int
Fix suggested:
Replace for loop with range 10
i.e.
func main() {
var i int
defer func() { fmt.Println(i) }()
- for i = 0; i < 10; i++ {
+ for i = range 10 {
// deliberately empty
}
}
What did you expect to see?
No suggested change, or at least not that one. The semantics of the resulting program are indeed different from the original program's: whereas the original program prints 10, the resulting program (playground) prints 9:
package main
import "fmt"
func main() {
var i int
defer func() { fmt.Println(i) }()
for i = range 10 {
// deliberately empty
}
}
Comment From: gabyhelp
Related Issues
- x/tools/gopls: modernize's rangeint check is too aggressive #74295 (closed)
- x/tools/gopls/internal/analysis/modernize: rangeint: transformation unsound when loop body has effects on iterated array #72917 (closed)
- x/tools/gopls/internal/analysis/modernize: rangeint: transformation unsound when loop variable is defined outside loop #73009 (closed)
- x/tools/gopls/internal/analysis/modernize: replacing non-equivalent code #73073 (closed)
- x/tools/gopls/internal/analysis/modernize: range over int rule doesn't consider potential slice appends #73022 (closed)
- x/tools/gopls/internal/analysis/modernize: rangeint generates correct but not idiomatic transformation #71725 (closed)
- x/tools/gopls/internal/analysis/modernize: rangeint should be silent when RHS of 'i \< limit' depends on loop var #72726 (closed)
- x/tools/gopls/internal/analyze/modernize: rangeint: transformation introduces invalid type #73037 (closed)
- gopls/modernize: "for i = range n {}" fix is wrong if there are later uses of i #71952 (closed)
- x/tools/gopls/internal/analysis/modernize: rangeint produces invalid syntax due to use of types.RelativeTo #74687
(Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.)
Comment From: adonovan
Argh, this is closely related to #71952 (fixed by https://go.dev/cl/652496), but it looks like defer is the distinguishing feature here. I wish I had seen this a week ago--I would have added a slide on it to my gophercon talk!
Comment From: jub0bs
@adonovan Sorry! Bad timing. I remember independently observing #71952 in VS Code a few months ago, intended to report it but forgot to. I finally remembered to do so yesterday, was pleased to discover that #71952 had been fixed, and thought of using defer
. 😈
I couldn't attend GopherCon, but thanks for sharing your talk.
Comment From: thediveo
I would have added a slide on it to my gophercon talk!
I especially lAIke the Elephant in the Room. Reading issues here turns up interesting and highly instructive Gopher details.