Skip to content

Expressions of type void should be allowed in switch expressions #52191

Description

@munificent

The language has some fairly ad hoc rules about where expressions of type void are and aren't allowed. The patterns specification makes no mention of disallowing expressions of type void anywhere so I assumed that, by default, they would be allowed. However:

void printBugsSwitch(int n) => switch (n) {
      0 => print('no bugs'),
      1 => print('one bug'),
      _ => print('$n bugs'),
    };

void printBugsConditional(int n) => n == 0
    ? print('no bugs')
    : n == 1
        ? print('one bug')
        : print('$n bugs');

Currently, this produces on analyzer:

Analyzing temp.dart...                 0.5s

  error • temp.dart:2:12 • This expression has a type of 'void' so its value can't be used. Try checking to see if
          you're using the correct API; there might be a function or call that returns void you didn't expect. Also check type
          parameters and variables which might also be void. • use_of_void_result
  error • temp.dart:3:12 • This expression has a type of 'void' so its value can't be used. Try checking to see if
          you're using the correct API; there might be a function or call that returns void you didn't expect. Also check type
          parameters and variables which might also be void. • use_of_void_result
  error • temp.dart:4:12 • This expression has a type of 'void' so its value can't be used. Try checking to see if
          you're using the correct API; there might be a function or call that returns void you didn't expect. Also check type
          parameters and variables which might also be void. • use_of_void_result

And if you try to run it:

temp.dart:2:12: Error: This expression has type 'void' and can't be used.
      0 => print('no bugs'),
           ^
temp.dart:3:12: Error: This expression has type 'void' and can't be used.
      1 => print('one bug'),
           ^
temp.dart:4:12: Error: This expression has type 'void' and can't be used.
      _ => print('$n bugs'),
           ^

Note that there are no errors in printBugsConditional(), which has similar behavior using conditional expressions. I think switch expressions should behave similarly to conditional expressions.

I'm going to put this in the stable milestone so that triaging folks take a look at it. This is an annoying restriction (at least two users have already noticed it), but I don't know if it's worth trying to cherry pick a fix for it. Since fixing this bug is removing a restriction, it's a non-breaking change that we could do in 3.0.1 or 3.1 if needed. Personally, I would lean towards not trying to cherry pick a fix, but I'm happy to defer to implementers (who know how hard/risky this is to fix) and leads (who know how much risk we want to accept).

Related language issue: dart-lang/language#2907

cc @dart-lang/language-team

Metadata

Metadata

Assignees

No one assigned

    Labels

    P1A high priority bug; for example, a single project is unusable or has many test failureslegacy-area-analyzerUse area-devexp instead.legacy-area-front-endLegacy: Use area-dart-model instead.

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions