Skip to content
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

No analysis error when switch case can never match #56338

Open
DanTup opened this issue Jul 29, 2024 · 7 comments
Open

No analysis error when switch case can never match #56338

DanTup opened this issue Jul 29, 2024 · 7 comments
Labels
area-devexp Developer experience items (DevTools, IDEs, analysis server, completions, refactorings, ...). devexp-warning Issues with the analyzer's Warning codes P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)

Comments

@DanTup
Copy link
Collaborator

DanTup commented Jul 29, 2024

While debugging Dart-Code/Dart-Code#5202 I was surprised to find that there are no analysis errors when a switch case has an unrelated type to what's being tested:

void f(int a, String b) {
  switch ((a, b)) {
    case (1, _):
      break;
    case 'Foo': // This can never occur
      break;
  }
}

Could/should there be an error in this case? Unless I'm missing something, it seems like this is probably always a bug in the users code?

@dart-github-bot
Copy link
Collaborator

Summary: The analyzer currently doesn't flag switch cases with incompatible types, even when they can never match the switch expression. This could lead to unexpected behavior and potential bugs.

@dart-github-bot dart-github-bot added area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. triage-automation See https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot. type-bug Incorrect behavior (everything from a crash to more subtle misbehavior) labels Jul 29, 2024
@bwilkerson
Copy link
Member

@eernstg

@Yash05080
Copy link

yes this seems to be a bug, as it is not in the input format we mentioned

@Yash05080
Copy link

can we instead update the code for switch case such that

  1. if the case value is of any type that is mentioned then perform the task on all the available/possible such case
  2. if the case value is not of any type mentioned then show error

basically treat it like how we treat a nested switch , when 2 or more conditions satisfy then that specific condition and if only one condition is mentioned then perform task as that one condition(or all the asked condition in the switch case) is satisfied

@lrhn
Copy link
Member

lrhn commented Jul 31, 2024

Could/should there be an error in this case?

Not an error, but there could probably be a warning from the analyzer.

@lrhn lrhn removed the triage-automation See https://github.com/dart-lang/ecosystem/tree/main/pkgs/sdk_triage_bot. label Jul 31, 2024
@bwilkerson bwilkerson added P3 A lower priority bug or feature request devexp-warning Issues with the analyzer's Warning codes labels Aug 1, 2024
@eernstg
Copy link
Member

eernstg commented Aug 5, 2024

I think it's worth noting that we have only a few situations where it is statically known that a given type T has an empty intersection with some other type S (which means that case S(): will definitely be unreachable when the scrutinee has static type T).

The general instance of this situation includes the following:

class A {}
class B {} // Unrelated to `A`.

void f(A a) {
  switch (a) {
    case B(): // This _can_ occur.
      break;
  }
}

class AB extends A implements B {}

void main() {
  f(AB());
}

So it isn't sufficient that the two types are unrelated, we must actually know (somehow) that they are disjoint, that is, they don't have any non-empty common subtypes (Never is a common subtype of any pair of types, but it is empty, so we can't ever encounter an instance of that type).

To handle disjointness of types, this could get us started:

  • Some platform types do not have any denotable subtypes (e.g., int, String), so they don't have a non-empty common subtype with any type that isn't one of their supertypes.
  • An enumerated type (enum E {}) and any type which isn't the same type or a supertype do not have any non-empty common subtypes.
  • A class or mixin class with the modifier final can only have a non-empty common subtype S with other types unless S is declared in the same library; we could check that and recognize disjointness in some cases.
  • A function type does not have any non-empty common subtype with any non-function type other than Function, Object, and top types.
  • A record type R has non-empty common subtypes with a record type R2 with the same shape, iff each component type of R has a non-empty common subtype with the same component of R2. R has non-empty common subtypes with Record, Object, and top types. R has no non-empty common subtypes with any other type.

Surely there will be more cases where we can determine that no non-empty common subtypes exist, but it could be useful to recognize a smaller set now and add more general cases later on, when we notice them.

@bwilkerson bwilkerson added area-devexp Developer experience items (DevTools, IDEs, analysis server, completions, refactorings, ...). and removed area-analyzer Use area-analyzer for Dart analyzer issues, including the analysis server and code completion. labels Feb 27, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-devexp Developer experience items (DevTools, IDEs, analysis server, completions, refactorings, ...). devexp-warning Issues with the analyzer's Warning codes P3 A lower priority bug or feature request type-bug Incorrect behavior (everything from a crash to more subtle misbehavior)
Projects
None yet
Development

No branches or pull requests

7 participants