Skip to content

Non-optimal recovery and error message for case in switch expression. #51886

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
lrhn opened this issue Mar 29, 2023 · 2 comments
Closed

Non-optimal recovery and error message for case in switch expression. #51886

lrhn opened this issue Mar 29, 2023 · 2 comments
Assignees
Labels
front-end-fasta legacy-area-front-end Legacy: Use area-dart-model instead. type-enhancement A request for a change that isn't a bug

Comments

@lrhn
Copy link
Member

lrhn commented Mar 29, 2023

I wrote the "obvious"

void main() {
  var map = {"X": 4};
  var o = switch (map) {
    case {"x": var a} => a,
    case {...} => 0
  };
  print(o);
}

and got the non-obvious error message:

error - swr.dart:4:5 - 'case' can't be used as an identifier because
          it's a keyword. Try renaming this to be an identifier that
          isn't a keyword. - expected_identifier_but_got_keyword

That's not the most actionable error message. We could assume that the user thought case was needed for switch expressions (or forgot removing it when switching from switch statement to switch expression), and tell them to remove the case.

In general, switch expressions differ from switch statements. We should recognize switch statements syntax in switch expressions, and suggest changing it to the correct syntax.

var o = switch (map) {
  case {"X": var a}: a;
  case {...}: 0;
}

gives the following errors:

  error - swr.dart:4:5 - 'case' can't be used as an identifier because
          it's a keyword. Try renaming this to be an identifier that
          isn't a keyword. - expected_identifier_but_got_keyword
  error - swr.dart:4:5 - The expression of a constant pattern must be a
          valid constant. Try making the expression a valid constant. -
          constant_pattern_with_non_constant_expression
  error - swr.dart:4:5 - Undefined name 'case'. Try correcting the name
          to one that is defined, or defining the name. -
          undefined_identifier
  error - swr.dart:4:10 - Expected to find '=>'. - expected_token
  error - swr.dart:4:16 - Expected an identifier. - missing_identifier
  error - swr.dart:4:16 - Expected to find '}'. - expected_token
  error - swr.dart:4:23 - Expected to find '}'. - expected_token

(And the switch being non-exhaustive on top, a derived error which should probably be suppressed if you cannot parse the cases.)

I'd prefer an error message like:

  error - swr.dart:4:5 - the 'case' keyword is not needed or allowed in switch expression cases.
           - case_keyword_in_switch_expression
  error - swr.dart:4:22 - Expected to find '=>'. - expected_token
  error - swr.dart:4:25 - Expected to find ','. - expected_token
  error - swr.dart:4:5 - the 'case' keyword is not needed or allowed in switch expression cases.
           - case_keyword_in_switch_expression
  error - swr.dart:5:15 - Expected to find '=>'. - expected_token
  error - swr.dart:5:18 - Expected to find ','. - expected_token

This would tell me what to change, and recover from finding : and ; where => and , are expected.


Maybe it also applies the other direction, using switch expression syntax in a switch statement:

void main() {                                                          
  var map = {"X": 4};                                                  
  switch (map) {                                                       
    {"x": var a} => return a,                                          
    {...} => return 0                                                  
  };                                                                   
}   

yields the errors:

Analyzing swe.dart...

  error - swe.dart:4:5 - Expected to find 'case'. - expected_token
   info - swe.dart:6:4 - Unnecessary empty statement. Try removing the empty statement or restructuring the code. - empty_statements

2 issues found.

which isn't particularly enlightening (the "expected to find case" is correct, the recovery isn't great).
After adding just the case keywords, I get:

Analyzing swe.dart...

  error - swe.dart:4:23 - Expected an identifier. - missing_identifier
  error - swe.dart:4:23 - Expected to find ':'. - expected_token
  error - swe.dart:4:23 - Expected to find ';'. - expected_token
  error - swe.dart:4:33 - A value of type 'int' can't be returned from the function 'main' because it has a return type of 'void'. - return_of_invalid_type
  error - swe.dart:4:33 - Expected to find ';'. - expected_token
  error - swe.dart:4:34 - Expected an identifier. - missing_identifier
  error - swe.dart:4:34 - Unexpected text ','. Try removing the text. - unexpected_token
  error - swe.dart:5:16 - Expected an identifier. - missing_identifier
  error - swe.dart:5:16 - Expected to find ':'. - expected_token
  error - swe.dart:5:16 - Expected to find ';'. - expected_token
  error - swe.dart:5:26 - A value of type 'int' can't be returned from the function 'main' because it has a return type of 'void'. - return_of_invalid_type
  error - swe.dart:5:26 - Expected to find ';'. - expected_token
   info - swe.dart:6:4 - Unnecessary empty statement. Try removing the empty statement or restructuring the code. - empty_statements

13 issues found.

That suggests using ; instead of ,, but the => is just misunderstood somehow.

@lrhn lrhn added type-enhancement A request for a change that isn't a bug front-end-fasta legacy-area-front-end Legacy: Use area-dart-model instead. front-end-fasta-recovery labels Mar 29, 2023
@johnniwinther
Copy link
Member

cc @stereotype441

@bwilkerson
Copy link
Member

@jensjoha

@stereotype441 stereotype441 self-assigned this Apr 4, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
front-end-fasta legacy-area-front-end Legacy: Use area-dart-model instead. type-enhancement A request for a change that isn't a bug
Projects
None yet
Development

No branches or pull requests

4 participants