import 'dart:async';
FutureOr<Iterable<int>> f() sync* {
yield 'Hello!' as dynamic;
}
void main() {
var iterable = f();
if (iterable is Future<Object?>) return;
int i = iterable.first;
print(i); // 'Hello!' is not an `int`.
}
The main idea in the correction is that the element type of a generator function uses a reduction step where the given return type is simplified to an Iterable<T> for some T (for a sync* function body) or a Stream<T> for some T (for an async* body), and the element type is then extracted from that Iterable<T> / Stream<T>.
Thanks to @lrhn for spotting this issue and reporting it here.
The specification of the element type of a generator has just been updated accordingly, cf. https://github.com/dart-lang/language/pull/3218.
The old rule gave rise to a soundness issue:
The main idea in the correction is that the element type of a generator function uses a reduction step where the given return type is simplified to an
Iterable<T>
for someT
(for async*
function body) or aStream<T>
for someT
(for anasync*
body), and the element type is then extracted from thatIterable<T>
/Stream<T>
.Subtasks:
53053
53054