-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Open
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.ToolsThis label describes issues relating to any tools in the x/tools repository.This label describes issues relating to any tools in the x/tools repository.
Milestone
Description
The slicescontains modernizer rewrites a for/range loop with an equality check into slices.ContainsFunc (or slices.Contains), but this changes how many times the needle expression is evaluated. In the original loop, the needle is evaluated once per iteration (until break). With slices.ContainsFunc, the needle is hoisted and evaluated once before iteration.
Before (go fix):
package main
import "fmt"
func main() {
n := 0
f := func() int { n++; return 3 }
s := []int{1, 2, 3}
found := false
for _, elem := range s {
if elem == f() {
found = true
break
}
}
_ = found
fmt.Println(n)
}Output: 3 (f() called once per iteration: elem=1 vs 1, elem=2 vs 2, elem=3 vs 3 — match, break)
After (GOTOOLCHAIN=go1.26.0 go fix):
package main
import (
"fmt"
"slices"
)
func main() {
n := 0
f := func() int { n++; return 3 }
s := []int{1, 2, 3}
found := slices.Contains(s, f())
_ = found
fmt.Println(n)
}Output: 1 (f() called once before iteration, needle=3 used for all comparisons)
The modernizer should not apply the transformation when the needle expression has side effects.
CC @adonovan
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
BugReportIssues describing a possible bug in the Go implementation.Issues describing a possible bug in the Go implementation.NeedsInvestigationSomeone must examine and confirm this is a valid issue and not a duplicate of an existing one.Someone must examine and confirm this is a valid issue and not a duplicate of an existing one.ToolsThis label describes issues relating to any tools in the x/tools repository.This label describes issues relating to any tools in the x/tools repository.