Dart version and OS
I saw the following Analyzer problem on the Gitter channel and I thought it was something which should be reported:
// Type of t1 are Analyzed to be: Iterable<Null>
var t1 = [1].map((value) {
// info: The type of the function literal can't be inferred because the literal has a block as its body
return value.toString();
});
// works
// Type of t2 are Analyzed to be: Iterable<String>
var t2 = [1].map((value) => value.toString());
main() {
// Type of t3 are Analyzed to be: Iterable<String>
var t3 = [1].map((value) {
// works
return value.toString();
});
// works
// Type of t4 are Analyzed to be: Iterable<String>
var t4 = [1].map((value) => value.toString()); // works
print(t1.toList()); // works
print(t2.toList()); // works
print(t3.toList()); // works
print(t4.toList()); // works
}
I don't think it makes sense that the type system works different in this situation just because we are on a global context (t1) instead of a context of a method (t3).
Also, the code are running just fine both on VM and Dartpad so it seems to be the Analyzer which have some kind of a problem here.
An analysis result of Iterable<Null> seems highly curious. I'd have expected Iterable<dynamic> since an Iterable<Null> will almost certainly fail at run-time when the body fails to return null.
The CFE type of t1 is Iterable<String>, so it's obviously possible to do the type analysis here, and it's Iterable<Null> for the analyzer, as stated. (The type is visible in the error message if you write t1 = <String>[];).
@julemand101 wrote:
I don't think it makes sense that the type system works different
In general, there is a significant difference between global type inference and local type inference: Local declarations are strictly ordered (names declared earlier in the text, not later, can be used: var x = 42; var y = x + 1; is ok, but not var y = x + 1; var x = 42;). In contrast, top-level declarations can refer to each other, independently of their textual order.
This means that the complexity of global type inference is higher, and that's probably the reason why the situation is flagged as "too hard", when map needs a type argument, and the function literal needs a signature, and its return type must be computed based on potentially multiple return statements that may themselves give rise to type inference.
Finally, I agree that inferring the type Iterable<Null> for t1 looks like a bug in the analyzer (and it would allow dependent code to have errors: Iterable<int> it = t1; would be OK).
@stereotype441, does this look like a known issue in the analyzer? I don't see anything similar with this search.
Yes, this is a known issue (#34503).
Closing as duplicate of #34503.
Most helpful comment
Yes, this is a known issue (#34503).