-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Open
Labels
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 minmax modernizer rewrites if/else patterns into calls to min/max, but this changes evaluation semantics when the arguments have side effects. In the if/else form, only one branch executes; with max(a, b), both arguments are always evaluated.
Before (go fix):
package main
import "fmt"
func main() {
n := 0
f := func() int { n++; return n }
x := f()
if x < f() {
x = f()
}
fmt.Println(x)
}Output: 3 (f called 3 times: once for initial x=1, once for comparison yielding 2, once in the branch yielding x=3)
After (GOTOOLCHAIN=go1.26.0 go fix):
package main
import "fmt"
func main() {
n := 0
f := func() int { n++; return n }
x := max(f(), f())
fmt.Println(x)
}Output: 2 (f called only twice: max(1, 2) = 2)
The original code calls f() three times (initial assignment, comparison, and branch), while the modernized code calls f() only twice. The modernizer should not apply the transformation when the expressions being compared have side effects.
CC @adonovan
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
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.