-
Notifications
You must be signed in to change notification settings - Fork 213
Flow analysis could handle final variables with assignments better #1721
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Comments
@renatoathaydes FYI |
Related to, maybe identical, #1536 |
@stereotype441 the bool f(bool b) {
final num a; // (1)
a = 2;
bool Function() g;
if (a is int) { // (5)
g = () => a.isEven; // (6)
} else {
g = () => false;
}
return g();
} |
Well as long as we're playing code golf, I'll join in 😁 void f(bool b) {
final num a;
a = 2;
if (a is int) {
final g = () => a.isEven; // error: isEven isn't defined for num
}
} |
@Levi-Lesches Haha, challenge accepted! How about: f(){final Object a;a=2;a is int?()=>-a:0;} More seriously, @renatoathaydes is right, the |
That issue shows that people expect even non-final local variables to work in such cases because that's safe (if the variable is not re-assigned anywhere). I wrote a comment in that issue showing how that works in Kotlin (basically using the concept from Java of effectively final). @Levi-Lesches exactly, even the other if was unecessary. But the point was that Dart behaves particularly badly because it distinguishes between: final num a;
a = 1; and final num a = 1; |
It's an even better point if we can treat final num a;
if (b) {
... // Do arbitrary stuff, just nothing about `a`.
a = 0;
... // Do arbitrary stuff, just nothing about `a`.
} else {
... // Do arbitrary stuff, just nothing about `a`.
a = 0.5;
... // Do arbitrary stuff, just nothing about `a`.
} and final num a = b ? 0 : 0.5; as equivalent, with respect to promotions of |
The fields `isFinal` and `isLate` are moved to the `Var` class. This should allow greater flexibility when experimenting with possible changes in promotion behavior for final and late variables. Bug: dart-lang/language#1721 Change-Id: I3a328566b4a55244ca76c41da6e362066118d283 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/217261 Reviewed-by: Konstantin Shcheglov <[email protected]> Commit-Queue: Paul Berry <[email protected]>
… for final vars. Tests for the issue dart-lang/language#1721. Promotions should happen for final variables because they are assigned and won't be re-assigned by the time they're evaluated. In a conservative join, promotions should not be cancelled for final variables. Bug: dart-lang/language#1721 Change-Id: Ibf29f42052a054424f7cef1075d1f67203f62c06 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390340 Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
Promotions should happen for final variables because they are assigned and won't be re-assigned by the time they're evaluated. In a conservative join, promotions should not be cancelled for final variables. Language tests made in https://dart-review.googlesource.com/c/sdk/+/390340. Bug: dart-lang/language#1721 Change-Id: I7bb577a694ddb5572a28884de70bd8c5b68e3c25 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390803 Reviewed-by: Chloe Stefantsova <[email protected]> Reviewed-by: Paul Berry <[email protected]> Commit-Queue: Kallen Tu <[email protected]>
dart-lang/sdk@47d5502 addresses this behaviour (although, currently under the |
Consider the following code (adapted from discussion in #1247):
This has an error at the line marked (6):
The getter 'isEven' isn't defined for the type 'num'.
If the lines from (1) to (4) are replaced with:
then no error occurs.
What's happening is that flow analysis sees the assignments to
a
on lines (2) and (3), and conservatively assumes that they could happen at any time, including between the time of the test at (5) and the usage at (6). So it disables promotion. But this is nonsense, becausea
is a final variable, therefore at the time of the test on line (5), it is guaranteed to be already assigned (otherwise line (5) would have had an error), and thus no further assignments to it can occur. So it should be safe to promote.It should be safe to alter flow analysis so that assignments do not defeat promotion if the variable assigned to is final. This will work even for
late final
variables, because such variables are still guaranteed not to be assigned to more than once (the only difference is that the checking is done at runtime rather than statically).The text was updated successfully, but these errors were encountered: