Function expression should be evaluated before arguments
Author: nevkontakteCreated Feb 25, 2024Updated Feb 25, 2024
Labelsbug
Consider the following snippet:
package main
var ok = false
func f() func(int, int) {
ok = true
return func(int, int) {}
}
func g() (int, int) {
if !ok {
panic("Bad order!")
}
return 0, 0
}
func main() {
f()(g())
}In it, the f()(g()) should be equivalent to:
funExpr := f()
a, b := g()
funExpr(a, b)However, in GopherJS it is:
a, b := g()
funExpr := f()
funExpr(a, b)https://gopherjs.github.io/playground/#/FMGNfOX9RA
https://go.dev/play/p/DGqo4zOvkUM
The bug is here: https://github.com/gopherjs/gopherjs/blob/e76f82360ff049505deaa7d42af04f5d67bf565b/compiler/utils.go#L119. When a function argument is another function's returned tuple, the inner function is broken out into a separate statement that's evaluated too early. To avoid that we can use ES6 spread operator and avoid a separate statement.
Source: gopherjs/gopherjs