Skip to content

Inferring void for a toplevel is strange #34171

Closed
@MichaelRFairhurst

Description

@MichaelRFairhurst

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?

@eernstg @leafpetersen

Metadata

Metadata

Assignees

No one assigned

    Labels

    area-languageDart language related items (some items might be better tracked at github.com/dart-lang/language).

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions