-
Notifications
You must be signed in to change notification settings - Fork 214
Flow analysis does not specify treatment of local variables in function literal bodies #1247
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
The current behavior is actually more subtle than this. It depends whether an assignment to f() {
Object v = 0;
bool Function() g;
if (v is int) {
g = () => v.isEven; // ERROR: v has type `Object`
}
v = 'bad';
print(g());
} However, if there is no assignment to f() {
Object v = 0;
bool Function() g;
if (v is int) {
g = () => v.isEven; // OK
}
print(g());
} You're right that this is not specified. I believe we need a clause in the
We need a similar rule for local (named) function declaration statements and for late variable initializers, both of which behave similar to function expressions. (*Edit: added the text "within the body of any local functions" in response to #1247 (comment)) |
I believe the current implementation for final local variables is mistaken and does not match the description given by @stereotype441 . Take this example: main() {
final num a;
a = 1;
if (a is int) {
final isEven = a.isEven;
return (i) => i == a.isEven;
}
} According to this sentence:
The above code should fail on line However, within the scope of the This can only be a mistake. |
@renatoathaydes wrote:
Actually, the promotion which is being cancelled is the promotion of the local variable in the nested function. You do get an error in line 6 ( The reason why the promotion is lost is that the nested function can be executed anywhere (we don't try to detect statically where that function object goes, so any construct that runs unknown code, including basically any method call, could potentially run that function). But the promotion in line 5 ( |
@renatoathaydes wrote:
You're right. The mistake was in my sentence "If it does, then promotion is cancelled." I should have said "If it does, then promotion is cancelled within the body of any local functions". I've corrected my comment above (#1247 (comment)). I believe that with this correction, my description is now consistent with what the implementation does, and with @eernstg's explanation from #1247 (comment). |
But do you really think it makes sense for the promotion to happen on line 5 but not on line 6? Could |
That lambda on line 6 is instantiated at a time when the value of local variable IMO it won't matter whether you pass the lambda reference to a million places , calls it a million more: |
Here is an example which shows that it is not sound to assume that bool f(num a) {
bool Function() g;
if (a is int) {
g = () => a.isEven;
} else {
g = () => false;
}
a = 1.5;
return g();
} The point is that The fact that the variable is final in the original example makes it reasonable to say that it won't stop being an @stereotype441, do you think it would be possible to improve on the analysis for that kind of final local variables? |
This is a different case completely. |
There must be a simple way to find out that:
The first one is trivial. The second one: the compiler already knows at any point if the variable has been assigned at a certain location, otherwise it would allow invalid code to be compiled. |
@renatoathaydes You're right. I'm filing a separate issue to track this. |
@renatoathaydes @eernstg since this issue is about the spec being an incomplete description of what was implemented, and the issue Renato raised is a suggested improvement to what was implemented, I think we should track them separately. I've filed #1721 to track Renato's issue. |
Thanks @stereotype441 , really appreciate it. |
Uh oh!
There was an error while loading. Please reload this page.
Having looked around in flow-analysis.md, I think the following is not covered:
A local variable
v
declared in a functionf
which is evaluated in the body of a function literall
in the body off
is considered to have its declared type (even in the case wherev
has been promoted at the location wherel
occurs andv
is never demoted).(The case where
v
is assigned inl
is covered: it is then writeCaptured, and promotion never applies.)@stereotype441, do you agree that this is not covered today, and the rule could be approximately as stated above?
The text was updated successfully, but these errors were encountered: