Description
This works:
int foo(int x) {
int? y;
if (x == 10) y = x;
if (y == null) return -1;
return y; // y is correctly promoted to be non-nullable, due to null check above.
}
But this doesn't work:
int foo(int x) {
int? y;
final bar = () {
if (x == 10) y = x;
};
bar();
if (y == null) return -1;
return y; // y is not promoted, and is still nullable. Compile error.
}
I think this is happening because in the second case, bar
is a closure, which is implemented internally by creating an anonymous class and storing x
and y
as fields on the class. So since class fields can't be type promoted, y
is still int?
at the end of foo
. This is a very confusing behavior, since many users wouldn't realize that bar
is actually a class.
My understanding is that class fields can't be promoted in this way because elsewhere in the code someone might write a subclass that overrides the getter to return null on the second access. However, in this case the class is anonymous, so can't be subclassed. So I think this instance could be safely special cased by allowing promotion for fields of anonymous classes.