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

Type Promotion For If-Case Statements #3505

Open
mcmah309 opened this issue Dec 8, 2023 · 3 comments
Open

Type Promotion For If-Case Statements #3505

mcmah309 opened this issue Dec 8, 2023 · 3 comments
Labels
feature Proposed language feature that solves one or more problems patterns Issues related to pattern matching.

Comments

@mcmah309
Copy link

mcmah309 commented Dec 8, 2023

For sealed types with two implementations, Dart should be able to promote the type based on if-case statements, like it does with switch statements. Example given

sealed class Result<S,F> {}

final class Ok<S,F> implements Result<S,F>{
  final S ok;
  
  const Ok(this.ok);
}

final class Err<S,F> implements Result<S,F>{
  final F err;

  const Err(this.err);
}

Result<int,String> okResult() => Ok(1);

This works

Result<int,String> main(){
  Result<int,String> result = okResult();
  switch(result){
    case Err():
      return result;
    case Ok():
  }
  int s = result.ok; // type promotion works
 return Ok(s+1);
}

But this does not

Result<int,String> main(){
  Result<int,String> result = okResult();
  if(result case Err()){
    return result;
  }
  int s = result.ok; // type promotion does not work here
  return Ok(s + 1);
}
@mcmah309 mcmah309 added the feature Proposed language feature that solves one or more problems label Dec 8, 2023
@mcmah309
Copy link
Author

mcmah309 commented Mar 5, 2024

@eernstg based on our current chat here dart-lang/sdk#55104 , I assume the reason this works in the first instance is because specifying all cases of the sealed class triggers exhaustiveness analysis. While this is not currently done for if case statements?

@eernstg
Copy link
Member

eernstg commented Mar 5, 2024

Right, if-case chains do not have an exhaustiveness property, no attempt is made to detect any such thing.

I don't think we're going to have it either. @stereotype441, WDYT?

@lrhn
Copy link
Member

lrhn commented Mar 6, 2024

Agree, we do not try to handle exhaustiveness with if except for union types, where we know that there are precisely two immediate subtypes.

We could do the same for sealed types with two immediate subclasses, but that's a feature which feels partial if it stops working at three subclasses.

We could aim to solve the general problem: Given a sealed type with subtypes T1...Tn, can we treat it as a union type T1|...|Tn and have type checks elimintate some parts of it.
(But then we run into the case of T4 being another sealed type, and wanting to eliminate that one subclass at a time. Possibly doable, likely not trivial.)

@munificent munificent added the patterns Issues related to pattern matching. label Mar 8, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
feature Proposed language feature that solves one or more problems patterns Issues related to pattern matching.
Projects
None yet
Development

No branches or pull requests

4 participants