-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Description
Consider the following program:
void main() async {
late final int x;
await for (x in Stream.fromIterable([1])) {} // Error: 'Can't assign to final'.
print(x); // Error: 'definitely unassigned'.
}
This program is rejected with two compile-time errors by the CFE (DartPad, Based on Flutter 3.12.0-2.0.pre Dart SDK 3.1.0-169.0.dev):
Error compiling to JavaScript:
lib/main.dart:3:14:
Error: Can't assign to the final variable 'x'.
await for (x in Stream.fromIterable([1])) {} // Error: 'Can't assign to final'.
^
lib/main.dart:4:9:
Error: Late variable 'x' without initializer is definitely unassigned.
print(x); // Error: 'definitely unassigned'.
^
Error: Compilation failed.
The first error is fine, we may iterate more than once with the loop, and at the 2nd iteration and up we will assign a value to x
even though it is definitely already assigned. (We could allow this because the loop might run exactly once; but this is hardly a useful treatment of the loop because it doesn't have to be a loop in the first place if it must run exactly once; so the error is indeed fine).
It is also possible that the loop iterates zero times, in which case x
remains unassigned. So print(x)
might fail. However, x
should be considered 'possibly assigned' at print(x)
because it is possible that the loop runs exactly once.
Note that the analyzer does not report any 'definitely unassigned' errors for this program.
Perhaps this is just caused by a kind of recovery where the await-for statement is considered to be a compile-time error, and then it is ignored during analysis of successors in the control flow graph?