In this code, the inferred return type of the lambda is Null. We had agreed last year that when void as a type argument landed, we would change this to void.
void main() {
var a = () {};
int b = a;
}
@lrhn Do you agree with this (I believe this was your request)? If so, I will file issues to get this implemented.
Definitely agree.
The function expression (){} contains no return with an expression, so it should be considered a void-returning function when inferring its return type from the body.
I think it would make sense to infer return type void when there is no type-from-context or when the type-from-context specifies a return type of void, but it is well-defined (and may be convenient, who knows) to _allow_ for inference of return type Null when that is the specified return type in the type-from-context.
This may be essentially the same thing as allowing a function with return type Null to reach the end of its body (without explicitly returning), but that would make sense to allow as well.
Even though we could, we shouldn't allow the return type Null to be inferred in the case where the type-from-context specifies any other (nullable) type—say, a String is expected—because that's too bug prone.
This isn't going to land for Dart 2 unfortunately.
@leafpetersen does this mean this is not planned for the future as well?
@zoechi I'm not in principle opposed, but it's hard to see this being worth the cost of a future breaking change. We allow () {} to be given the type void Function(), so it's just in the upwards inference case that there's a noticeable difference.
@leafpetersen I was just wondering if you closed this issue by accident because the comment seemed to indicate this is just postponed.
I do not have a strong opinion about this feature.
Got it, yes. I'm trying to cut down on the number of lingering "maybe, possibly, someday" issues we have sitting around for years.
Excuse me, what the frick, why it is still returning null? :C
void main() {
var a = () {};
a(); // ""() → Null a"
}
(DartSDK 2.3.1)
It is quite obvious for me, that lambda with no specified return type should return nothing, void. Not null. =
For the reasons given above: It would be a breaking change to make it void Function() because there is existing code relying on it being Null Function().
We can change it, but we'll have to migrate all that code, and the cost/benefit ratio for this particular change meant that it didn't make it into the larger Dart 2.0 breaking change.
One thing remains, though: We would probably be able to change the inferred type of a function literal with a block body and no returns to have return type void based on the context type:
void main() {
void Function() f = () {};
print(f.runtimeType); // Prints '() => Null', would be '() => void'.
}
We'd need to check that there are indeed no migration issues in doing this. @lrhn, do you see any? It would be helpful in the cases where a T function() is expected and a type test is performed: The Null Function() would be allowed to masquerade as a T Function() for any T (even with NNBD: for any nullable T), which could be seen as an unnecessary source of bugs.
@leafpetersen, are you against keeping this issue alive, even if it isn't on a shortlist?