Description
[New status Apr 2022, eernstg: This issue has been lingering for years; it is now more likely than not that we will change the specification to make the existing behavior the specified behavior. I closed the subissues; we can easily create new ones if we change our minds.]
Cf. the discussion in #34497, the October 2017 language team decision described here which was integrated into the language specification as part of CL 51323 has not been implemented everywhere.
Said decision has the following contents: When an ordinary method invocation i of the form e.m(arguments)
is such that m
is a getter, the evaluation of i proceeds by evaluating e
to an object o
, then invoking the getter o.m
to an object f
, and then evaluating f(arguments)
.
In other words, the evaluation order is strictly left-to-right, including the getter invocation. The old rules specified that the argument list should be evaluated first, and then the getter should be invoked.
Surely, this change request could have been communicated better. However, at this point I believe the way ahead is to adjust the implementations such that they support the left-to-right evaluation order which was specified and intended.
Here is an example:
import "package:expect/expect.dart";
int i = 0;
void f() => i *= 2;
class A {
void Function(void) get m {
++i;
return (_) {};
}
}
main() {
A().m(f());
Expect.equals(i, 2);
}
This currently fails on the following trybots (I just used the standard selection of trybots), illustrating that dart2js as well as the vm needs adjustments: dart2js-minified-strong-linux-x64-d8-try, dart2js-strong-hostasserts-linux-ia32-d8-try, dart2js-strong-linux-x64-chrome-try, vm-kernel-linux-product-x64-try, vm-kernel-linux-release-simdbc64-try, vm-kernel-linux-release-x64-try.
I've chosen 'type-enhancement' for this issue, because it is concerned with the implementation of a specification change.