dart-lang / sdk

The Dart SDK, including the VM, JS and Wasm compilers, analysis, core libraries, and more.
https://dart.dev
BSD 3-Clause "New" or "Revised" License
10.2k stars 1.57k forks source link

Poor recovery when using `yield` in a non-generator function #44633

Open bwilkerson opened 3 years ago

bwilkerson commented 3 years ago

Given the following code

Iterable<int> get digits {
  yield [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}

The analyzer produces three diagnostics:

error: The body might complete normally, causing 'null' to be returned, but the return type is a potentially non-nullable type. (body_might_complete_normally at ...)
error: Expected to find ']'. (expected_token at ...)
error: Undefined name 'yield'. (undefined_identifier at ...)

It would be nice if the analyzer could produce a single diagnostic stating that a yield statement is only valid in a generator function.

I believe that in order to do that the parser would need to recognize that the yield is followed by an expression and parse it as a yield statement rather than as an identifier followed by garbage.

It would also require the analyzer to treat the function as if it were a generator for the purpose of flow analysis.

bwilkerson commented 3 years ago

There are a couple of similar cases that ought to be fixed at the same time that I'll just record for posterity.

Iterable<int> get digits {
  yield* [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}

and

Iterable<int> get digits async {
  yield* [0, 1, 2, 3, 4, 5, 6, 7, 8, 9];
}