Description
This is a downside of allowing void-to-void assignment that I don't think we fully considered.
void f() {}
void main() {
var x = f(); // no error
x.y; // Error
}
This is not very good locality for the error here. It is extremely unlikely that the user meant the first line. For instance, I ran into this when testing if List.removeWhere()
returned an Iterable
of the removed items, or int count, or just void. I did not get any errors for assigning it to a variable, which I thought ruled out the last case.
final items = list.removeWhere(...); // no error! Must not return void! So I thought to myself.
In fact, it gets worse. In the first example, y
gets highlighted instead of the x
on the second line! (or x.y
for that matter).
This makes sense for f().y
, but in this example, the highlight + bad locatily + error message combine poorly, and it looks like x
is of some type that has some member y
of type void, and then you are sitting there wondering how that would be possible (a void getter?) and why that would be a problem (to get a void getter?). So the real problem is not obvious.
This could probably be covered as part of void_checks in the linter, but should it be? Should it maybe instead be a rule in the language spec, that a variable cannot have the type void inferred?