Skip to content

[Typechecker] Allow matching an enum case against an optional enum without '?' #22486

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

Merged
merged 8 commits into from
Mar 4, 2019
Merged

[Typechecker] Allow matching an enum case against an optional enum without '?' #22486

merged 8 commits into from
Mar 4, 2019

Conversation

theblixguy
Copy link
Collaborator

This PR lifts a restriction on switching over enum cases when the enum is an Optional. Previously, if the enum was optional, you had to use the ? operator to switch over the cases, otherwise an error diagnostic was emitted telling the user that the case does not exist in the enum.

Now, the compiler will synthesise a OptionalSomePattern to match a case without a trailing ?.

Example:

enum Foo {
  case one
  case two
}

let foo: Foo? = .one

switch foo {
  case .one: print("one") // Ok
  case .two?: print("two") // Ok
  default: print("default")
}

Resolves SR-7799.
Resolves rdar://problem/41494702

@theblixguy
Copy link
Collaborator Author

cc @jrose-apple @xedin @jckarter

@slavapestov
Copy link
Contributor

Is this considered a bug fix and not a language change? I guess it makes sense that the behavior is more consistent with non-enum patterns now.

Can you add a test that it SILGens correctly too?

@slavapestov
Copy link
Contributor

@swift-ci Please test

@slavapestov
Copy link
Contributor

@swift-ci Please test source compatibility

@theblixguy
Copy link
Collaborator Author

theblixguy commented Feb 9, 2019

@slavapestov I have added a SILGen test.

Seems like the build stopped running on the CI, it says "Jenkins is going to shut down". Nevermind, the test passed.

@CodaFi
Copy link
Contributor

CodaFi commented Feb 9, 2019

Let me start by saying I am strongly against changes that add implicit conversions into the semantics of pattern matching. I believe this is a language change that needs to go through Swift Evolution, and is not a bug fix. I have articulated this in a reply to the author of the bug report on Swift Evolution in the past.

@CodaFi
Copy link
Contributor

CodaFi commented Feb 9, 2019

Also, please make sure that this is well-defined and included in the test suite for this patch:

enum Foo {
  case one
  case two
}

let foo: Foo?? = .one

switch foo {
  case .none: // To which `none` does this bind?
  default: print("default")
}

@theblixguy
Copy link
Collaborator Author

theblixguy commented Feb 11, 2019

Thanks @CodaFi, I have updated the tests. @jckarter said in the same thread that this is actually a bug and it should compile (hence the PR), but if it's decided that this isn't a bug, then I am happy to pitch it and take it through Swift Evolution.

@jckarter
Copy link
Contributor

I consider this a bug fix because it is inconsistent that the implicit conversion in fact works via an expr pattern unless you have a pattern node in the expression. That seems inconsistent to me. As a rule of thumb, a pattern should match values whose expression form looks like the pattern with the _ and let x blanks filled in. I'm not against discussing this in evolution, but it seems like the current half-working state is clearly a bug to me.

@jrose-apple
Copy link
Contributor

I'll say the implementation looks good to me, but it'd be worth re-getting approval from the core team that this should be considered a bug fix, especially in light of @CodaFi's concerns.

@theblixguy
Copy link
Collaborator Author

theblixguy commented Feb 11, 2019

Tagging core team members: @DougGregor @rjmccall @dabrahams @lattner @airspeedswift @tkremenek

@jckarter
Copy link
Contributor

@swift-ci Please test

@jckarter
Copy link
Contributor

@swift-ci Please test source compatibility

@jckarter
Copy link
Contributor

The Core Team has decided that this is a bug fix.

@jckarter
Copy link
Contributor

@swift-ci Please test

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - e8b5f1e

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - e8b5f1e

Suyash Srijan added 2 commits February 28, 2019 17:36
…onality and use lookThroughAllOptionalTypes on it to peel off all levels of optionality if the type is a nested optional
@rjmccall
Copy link
Contributor

@swift-ci Please test.

@swift-ci
Copy link
Contributor

Build failed
Swift Test Linux Platform
Git Sha - 407c38e

@rjmccall
Copy link
Contributor

@swift-ci Please test OS X.

@swift-ci
Copy link
Contributor

Build failed
Swift Test OS X Platform
Git Sha - 407c38e

@rjmccall
Copy link
Contributor

Yeesh, that took a long time to kick off.

@theblixguy
Copy link
Collaborator Author

Looks like the tests have passed smoothly 🎉

@jckarter jckarter merged commit 7011f32 into swiftlang:master Mar 4, 2019
@jckarter
Copy link
Contributor

jckarter commented Mar 4, 2019

Thanks @theblixguy!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

8 participants