dart-lang / dart-lang/language
Spec is unclear about scoping of variables declared in `for` loops
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
Consider the following code:
```dart
void f(int x) {
for (int y = x, x = 0; x < 10; x++) {
print(x);
}
}
main() {
f(0);
}
```
The front end rejects this code with the error:
```
file:///usr/local/google/home/paulberry/tmp/test.dart:2:19: Error: Can't declare 'x' because it was already used in this scope.
for (int y = x, x = 0; x < 10; x++) {
^
file:///usr/local/google/home/paulberry/tmp/test.dart:2:16: Context: Previous use of 'x'.
for (int y = x, x = 0; x < 10; x++) {
```
whereas the analyzer accepts the code without complaint.
It appears that the front end's rule is: the scope of all declarations appearing in the initializer part of the for-loop is the entire for-loop, therefore in the code above, the `x` in `y = x` refers to the `x` declared by `x = 0`; thus this is a use-before-declaration (and hence an error). Whereas the analyzer's rule appears to be: the scope of all declarations appearing in the initializer part of the for-loop is from the declaration onward to the end of the for-loop; therefore the scope of the declaration `x = 0` does not cover the previous declaration `y = x`.
I looked at the spec to see which behavior is correct, and could not find clear guidance. The section "statements - for" says nothing about the scope of the declarations in the loop.
Note that the spec isn't clear about the scoping of variables declared in for-in loops either, but fortunately the front end and the analyzer agree: the scope of a variable declared in a for-in loop is just the body of the loop; it does not cover the iterable. So for example this code is accepted by both the front end and the analyzer:
```dart
void f(List x) {
for (int x in x) {
print(x);
}
}
void main() {
f([1, 2, 3]);
}
```
Contributor guide
Assessment
This issue has not been assessed yet.