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.25k stars 1.58k forks source link

Misleading error message with generator function return type #35921

Closed eernstg closed 5 years ago

eernstg commented 5 years ago

Consider the following program:

abstract class Foo<X> extends Iterable<X> {}
Foo<int> foo() sync* { yield 1; }

main() => foo();

With dart, dartanalyzer, and dart2js from commit 0a7dcf17eb5f2450480527d6ad1e201fb47f1e36, we get the following error (with slightly different formatting):

Error: Functions marked 'sync*' must have a return type assignable to 'Iterable'

But Foo<T> is assignable to Iterable<T> for all T (and thus also Iterable<dynamic>, if that's the meaning of assignable to 'Iterable'), so the error message has an implication which is just not true.

Of course, the actual Iterable which is returned is provided by the platform, so any attempt to specify a return type such that Iterable<T> is a proper superinterface will cause a dynamic failure, so the program "won't work" anyway.

A similar thing occurs when the function is async*, with Stream.

We could change the language specification to say that these return types must be supertypes of Iterable<Null> resp. Stream<Null>, and then change the error messages from all tools accordingly.

@lrhn, @leafpetersen, do you see any reason why we would not change the language specification in this manner?

(If we take this course then we can change this issue to be a meta-issue for tool changes later on; for now I'll mark it as area-specification).

eernstg commented 5 years ago

Closing: As of today, the language specification requires the return type of a generator to be a supertype of Iterable<T>/Stream<T> for some T.