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

Implementation for @unknown default #14382

Merged
merged 11 commits into from Apr 10, 2018
Merged

Conversation

jrose-apple
Copy link
Contributor

@jrose-apple jrose-apple commented Feb 3, 2018

Part of the revised SE-0192, building on top of #11961. The first PR is big enough that I'd like to land this part separately afterwards.

Still to do: write some SIL tests to make sure unknown case is properly getting treated like default. (done!)

@jrose-apple
Copy link
Contributor Author

(yes, I know it needs rebasing)

@jrose-apple
Copy link
Contributor Author

Rebased on top of the new implementation of frozen enums! (already in-tree)

@CodaFi, I'm sorry to subject you to such a diff, but I welcome your SpaceEngine wisdom once again.

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test compiler performance

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test source compatibility

@swift-ci
Copy link
Collaborator

Build failed
Swift Test OS X Platform
Git Sha - ef52640f5f8d070bd78ed81291af6039a1f82644

@swift-ci
Copy link
Collaborator

Build failed
Swift Test Linux Platform
Git Sha - ef52640f5f8d070bd78ed81291af6039a1f82644

@jrose-apple
Copy link
Contributor Author

Oops, the very last change I did is wrong.

@swift-ci
Copy link
Collaborator

Build comment file:

Summary for master full

Unexpected test results, excluded stats for Core, ChattoAdditions, CoreStore, SourceKittenFramework, StencilSwiftKit, SwifterSwift, AMScrollingNavbar, ProcedureKit, GRDB, JSQDataSourcesKit, AsyncNinja, ReactiveCocoa, IBAnimatable, ObjectMapper, Cub

No regressions above thresholds

Debug

debug brief

Regressed (0)
name old new delta delta_pct
Improved (1)
name old new delta delta_pct
time.swift-driver.wall 1908.5s 1665.4s -243.1s -12.74% ✅
Unchanged (delta < 1.0% or delta < 100.0ms) (1)
name old new delta delta_pct
LLVM.NumLLVMBytesOutput 1,025,072,916 1,025,074,461 1,545 0.0%

debug detailed

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (23)
name old new delta delta_pct
AST.NumImportedExternalDefinitions 1,242,855 1,242,855 0 0.0%
AST.NumLoadedModules 309,207 309,207 0 0.0%
AST.NumTotalClangImportedEntities 4,191,577 4,191,577 0 0.0%
AST.NumUsedConformances 142,789 142,789 0 0.0%
IRModule.NumIRBasicBlocks 2,916,835 2,916,835 0 0.0%
IRModule.NumIRFunctions 1,522,896 1,522,896 0 0.0%
IRModule.NumIRGlobals 1,461,573 1,461,573 0 0.0%
IRModule.NumIRInsts 33,601,803 33,601,803 0 0.0%
IRModule.NumIRValueSymbols 2,645,099 2,645,099 0 0.0%
LLVM.NumLLVMBytesOutput 1,025,072,916 1,025,074,461 1,545 0.0%
SILModule.NumSILGenFunctions 864,781 864,781 0 0.0%
SILModule.NumSILOptFunctions 1,340,980 1,340,980 0 0.0%
Sema.NumConformancesDeserialized 5,568,965 5,568,965 0 0.0%
Sema.NumConstraintScopes 8,977,823 8,977,823 0 0.0%
Sema.NumDeclsDeserialized 46,574,871 46,574,871 0 0.0%
Sema.NumDeclsValidated 1,743,937 1,743,937 0 0.0%
Sema.NumFunctionsTypechecked 791,483 791,483 0 0.0%
Sema.NumGenericSignatureBuilders 1,449,101 1,449,101 0 0.0%
Sema.NumLazyGenericEnvironments 9,422,484 9,422,484 0 0.0%
Sema.NumLazyGenericEnvironmentsLoaded 835,511 835,511 0 0.0%
Sema.NumLazyIterableDeclContexts 7,375,579 7,375,579 0 0.0%
Sema.NumTypesDeserialized 49,233,177 49,233,177 0 0.0%
Sema.NumTypesValidated 5,069,010 5,069,010 0 0.0%

Debug-opt

debug-opt brief

Regressed (0)
name old new delta delta_pct
Improved (1)
name old new delta delta_pct
time.swift-driver.wall 3452.0s 2921.4s -530.6s -15.37% ✅
Unchanged (delta < 1.0% or delta < 100.0ms) (1)
name old new delta delta_pct
LLVM.NumLLVMBytesOutput 970,106,776 970,086,201 -20,575 -0.0%

debug-opt detailed

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (23)
name old new delta delta_pct
AST.NumImportedExternalDefinitions 1,242,855 1,242,855 0 0.0%
AST.NumLoadedModules 296,242 296,242 0 0.0%
AST.NumTotalClangImportedEntities 4,279,674 4,279,674 0 0.0%
AST.NumUsedConformances 142,789 142,789 0 0.0%
IRModule.NumIRBasicBlocks 3,018,822 3,018,822 0 0.0%
IRModule.NumIRFunctions 1,228,854 1,228,854 0 0.0%
IRModule.NumIRGlobals 1,211,760 1,211,760 0 0.0%
IRModule.NumIRInsts 27,365,935 27,365,935 0 0.0%
IRModule.NumIRValueSymbols 2,217,371 2,217,371 0 0.0%
LLVM.NumLLVMBytesOutput 970,106,776 970,086,201 -20,575 -0.0%
SILModule.NumSILGenFunctions 863,674 863,674 0 0.0%
SILModule.NumSILOptFunctions 1,796,059 1,796,059 0 0.0%
Sema.NumConformancesDeserialized 11,279,671 11,279,671 0 0.0%
Sema.NumConstraintScopes 8,977,823 8,977,823 0 0.0%
Sema.NumDeclsDeserialized 52,771,819 52,771,819 0 0.0%
Sema.NumDeclsValidated 1,743,937 1,743,937 0 0.0%
Sema.NumFunctionsTypechecked 791,483 791,483 0 0.0%
Sema.NumGenericSignatureBuilders 1,494,359 1,494,359 0 0.0%
Sema.NumLazyGenericEnvironments 10,421,732 10,421,732 0 0.0%
Sema.NumLazyGenericEnvironmentsLoaded 852,533 852,533 0 0.0%
Sema.NumLazyIterableDeclContexts 7,742,132 7,742,132 0 0.0%
Sema.NumTypesDeserialized 56,971,546 56,971,546 0 0.0%
Sema.NumTypesValidated 5,069,010 5,069,010 0 0.0%

Wmo-onone

wmo-onone brief

Regressed (0)
name old new delta delta_pct
Improved (1)
name old new delta delta_pct
time.swift-driver.wall 1638.4s 1413.2s -225.1s -13.74% ✅
Unchanged (delta < 1.0% or delta < 100.0ms) (1)
name old new delta delta_pct
LLVM.NumLLVMBytesOutput 932,188,781 932,052,089 -136,692 -0.01%

wmo-onone detailed

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (23)
name old new delta delta_pct
AST.NumImportedExternalDefinitions 163,941 163,828 -113 -0.07%
AST.NumLoadedModules 10,898 10,888 -10 -0.09%
AST.NumTotalClangImportedEntities 537,014 536,637 -377 -0.07%
AST.NumUsedConformances 145,002 144,932 -70 -0.05%
IRModule.NumIRBasicBlocks 2,331,211 2,330,240 -971 -0.04%
IRModule.NumIRFunctions 1,403,833 1,403,328 -505 -0.04%
IRModule.NumIRGlobals 1,294,755 1,294,316 -439 -0.03%
IRModule.NumIRInsts 30,697,193 30,688,845 -8,348 -0.03%
IRModule.NumIRValueSymbols 2,422,725 2,421,876 -849 -0.04%
LLVM.NumLLVMBytesOutput 932,188,781 932,052,089 -136,692 -0.01%
SILModule.NumSILGenFunctions 519,580 519,435 -145 -0.03%
SILModule.NumSILOptFunctions 603,263 603,021 -242 -0.04%
Sema.NumConformancesDeserialized 1,430,057 1,429,226 -831 -0.06%
Sema.NumConstraintScopes 8,505,156 8,502,826 -2,330 -0.03%
Sema.NumDeclsDeserialized 4,797,630 4,793,898 -3,732 -0.08%
Sema.NumDeclsValidated 784,700 784,542 -158 -0.02%
Sema.NumFunctionsTypechecked 294,264 294,168 -96 -0.03%
Sema.NumGenericSignatureBuilders 168,519 168,442 -77 -0.05%
Sema.NumLazyGenericEnvironments 825,769 825,137 -632 -0.08%
Sema.NumLazyGenericEnvironmentsLoaded 98,776 98,719 -57 -0.06%
Sema.NumLazyIterableDeclContexts 510,627 510,212 -415 -0.08%
Sema.NumTypesDeserialized 4,980,067 4,976,258 -3,809 -0.08%
Sema.NumTypesValidated 1,397,996 1,397,908 -88 -0.01%

Release

release brief

Regressed (0)
name old new delta delta_pct
Improved (1)
name old new delta delta_pct
time.swift-driver.wall 4209.4s 3379.8s -829.6s -19.71% ✅
Unchanged (delta < 1.0% or delta < 100.0ms) (1)
name old new delta delta_pct
LLVM.NumLLVMBytesOutput 971,855,012 971,719,389 -135,623 -0.01%

release detailed

Regressed (0)
name old new delta delta_pct
Improved (0)
name old new delta delta_pct
Unchanged (delta < 1.0% or delta < 100.0ms) (23)
name old new delta delta_pct
AST.NumImportedExternalDefinitions 282,450 282,446 -4 -0.0%
AST.NumLoadedModules 38,362 38,356 -6 -0.02%
AST.NumTotalClangImportedEntities 901,249 901,207 -42 -0.0%
AST.NumUsedConformances 147,811 147,731 -80 -0.05%
IRModule.NumIRBasicBlocks 2,651,487 2,650,243 -1,244 -0.05%
IRModule.NumIRFunctions 1,259,700 1,259,279 -421 -0.03%
IRModule.NumIRGlobals 1,294,849 1,294,492 -357 -0.03%
IRModule.NumIRInsts 25,840,630 25,831,473 -9,157 -0.04%
IRModule.NumIRValueSymbols 2,314,334 2,313,587 -747 -0.03%
LLVM.NumLLVMBytesOutput 971,855,012 971,719,389 -135,623 -0.01%
SILModule.NumSILGenFunctions 535,005 534,859 -146 -0.03%
SILModule.NumSILOptFunctions 868,730 868,105 -625 -0.07%
Sema.NumConformancesDeserialized 3,352,322 3,349,701 -2,621 -0.08%
Sema.NumConstraintScopes 8,686,330 8,683,988 -2,342 -0.03%
Sema.NumDeclsDeserialized 8,783,235 8,777,480 -5,755 -0.07%
Sema.NumDeclsValidated 840,497 840,258 -239 -0.03%
Sema.NumFunctionsTypechecked 349,217 349,163 -54 -0.02%
Sema.NumGenericSignatureBuilders 295,569 295,482 -87 -0.03%
Sema.NumLazyGenericEnvironments 1,557,312 1,556,305 -1,007 -0.06%
Sema.NumLazyGenericEnvironmentsLoaded 155,839 155,772 -67 -0.04%
Sema.NumLazyIterableDeclContexts 1,108,811 1,108,319 -492 -0.04%
Sema.NumTypesDeserialized 9,817,988 9,811,836 -6,152 -0.06%
Sema.NumTypesValidated 1,676,437 1,676,143 -294 -0.02%

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

@swift-ci
Copy link
Collaborator

Build failed
Swift Test OS X Platform
Git Sha - ef52640f5f8d070bd78ed81291af6039a1f82644

@swift-ci
Copy link
Collaborator

Build failed
Swift Test Linux Platform
Git Sha - ef52640f5f8d070bd78ed81291af6039a1f82644

@jrose-apple
Copy link
Contributor Author

This fails on Linux, and I can reproduce the failure, but I have no idea why. It's emitting the fix-its in a different order, but I don't see anything that should be non-deterministic or implementation-defined.

@jrose-apple
Copy link
Contributor Author

…should have known it'd be the std::sort.

@swift-ci Please test

@swift-ci
Copy link
Collaborator

Build failed
Swift Test OS X Platform
Git Sha - 60b4ef70444587eb17e37bdb6ed76183ec4988f9

@swift-ci
Copy link
Collaborator

Build failed
Swift Test Linux Platform
Git Sha - 60b4ef70444587eb17e37bdb6ed76183ec4988f9

@@ -78,13 +78,22 @@ namespace {
Type,
Constructor,
Disjunct,
BooleanConstant
BooleanConstant,
UnknownCase,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You wound up making this a space kind anyway? For those that want context, we discussed this in private. The idea then was that you could traverse the pattern space to look for these - like we're already doing to find downgradable spaces - rather than using a subtraction and flattening them out.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah, heh, I forgot about that conversation. I think I threw out most of those ideas (mistakenly?) once we decided unknown could match patterns containing non-frozen enums as well. Do you still think I should keep "future cases" out of the space kinds?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The space traversal for downgradable patterns looks into nested patterns as well - unless I'm not quite understanding you here. I haven't kept up with the Swift Evolution discussion around this all that well.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'll take a look tomorrow. Given that the user side of unknown had to be handled specially anyway, what I think you're saying might make more sense.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

…yeah, I'm not sure this is going to work. I can't figure out how to deal with this example that way:

/*non-frozen*/ public enum Test {
  case a, b, c
}

@inlinable public func consume(_ x: Test) {
  switch x {
  case .a, .b: break
  }
}

In this case the compiler should suggest adding both case .c and unknown. If you decompose the Test space, you lose the non-frozen-ness, but if you don't decompose you can't subtract out the a and b cases.

I think the other way worked when the only thing that could match future cases was irrefutable patterns, and so the suggestion for the above example could just be default. But now that we have to distinguish these situations I think an Unknown space does make sense.

@jrose-apple
Copy link
Contributor Author

@swift-ci Please smoke test

@jrose-apple
Copy link
Contributor Author

@swift-ci Please smoke test

@@ -440,7 +493,8 @@ namespace {
PAIRCASE (SpaceKind::Type, SpaceKind::Disjunct):
PAIRCASE (SpaceKind::Constructor, SpaceKind::Disjunct):
PAIRCASE (SpaceKind::Disjunct, SpaceKind::Disjunct):
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::Disjunct): {
PAIRCASE (SpaceKind::BooleanConstant, SpaceKind::Disjunct):
PAIRCASE (SpaceKind::UnknownCase, SpaceKind::Disjunct): {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just a note: It looks to me like these two blocks (where disjunction is on the either side) could be refactored to be a single block since intersection operation supposed to be commutative (at least from the comment).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, I'd kinda like to do that for all the symmetrical ones. I didn't change that structure in this PR, though.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Makes sense, just wanted to point it out!

Get these simple changes out of the way first. No functionality change.
Copy link
Member

@xedin xedin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great, @jrose-apple! I think it makes sense to have Unknown as a type of space and check for it only after initial exhaustiveness check.

This is our first statement attribute, made more complicated by the
fact that a 'case'/'default' isn't really a normal statement. I've
chosen /not/ to implement a general statement attribute logic like we
have for types and decls at this time, but I did get the compiler
parsing arbitrary attributes before 'case' and 'default'. As a bonus,
we now treat all cases within functions as being switch-like rather
than enum-like, which is better for recovery when not in a switch.
The first half of Sema support for '@unknown'. The other part is
handling when the user /does/ write '@unknown', which results in
/other/ things being downgraded to warnings.

The diagnostics here are still pretty minimal; they should explain
what's going on with '@unknown' to someone who hasn't read the Swift 5
release notes.
The other half of '@unknown' in Sema. Again, the diagnostics here
could be improved; rather than a generic "switch must be exhaustive",
it could say something about unknown case handling known cases.

One interesting detail here: '@unknown' is only supposed to match
/fully/ missing cases. If a case is /partly/ accounted for, not
handling the rest is still an error, even if an unknown case is
present.

This only works with switches over single enum values, not values that
contain an enum with unknown cases. That's coming in a later commit.
(It was easier to get this part working first.)
We still model the enums as non-exhaustive so that someone /can/
handle unknown cases, which may be important for imported enums. But
we won't diagnose a problem if the only missing case is '@unknown'.
That is, when matching non-frozen enums at non-top-level positions:

    switch (nonFrozenEnum1, nonFrozenEnum2) {
    case (.singleKnownCase1, .singleKnownCase2): ...
    unknown: ...
    }

...it's sufficient to use '@unknown' to match

  (.singleKnownCase1, .someFutureCase2)
  (.someFutureCase1, .singleKnownCase2)
  (.someFutureCase1, .someFutureCase2)
If a client wants to defend themselves against new cases in libraries
they use, or even in their own code, they're allowed to.
- Combine the common logic for editor mode and non-editor mode.
- Do a better job minimizing fix-its.
- If '@unknown' is the only missing case, put `fatalError()` in the
  Xcode placeholder, since that's what the compiler would have done.
- Must be a single pattern
- Must be last in the switch
- Must not have a 'where' clause
- Must specifically be the "any" pattern if using 'case'

We may lift some of these restrictions in the future, but that would
need a new proposal.
@jrose-apple jrose-apple changed the title [WIP] Implementation for unknown case Implementation for @unknown case _ Apr 6, 2018
@jrose-apple jrose-apple changed the title Implementation for @unknown case _ Implementation for @unknown default Apr 6, 2018
@jrose-apple
Copy link
Contributor Author

Okay, final version is ready. None of the space engine stuff changed in any interesting ways, but it may be worth looking over the rest of it again, @xedin.

@swift-ci Please test

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test source compatibility

@swift-ci
Copy link
Collaborator

swift-ci commented Apr 6, 2018

Build failed
Swift Test OS X Platform
Git Sha - 6ee50b2ec66682e4ea4662c4009cf14519ccc9b2

@swift-ci
Copy link
Collaborator

swift-ci commented Apr 6, 2018

Build failed
Swift Test Linux Platform
Git Sha - 6ee50b2ec66682e4ea4662c4009cf14519ccc9b2

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test source compatibility

@jrose-apple
Copy link
Contributor Author

@swift-ci Please test

@jrose-apple jrose-apple merged commit 6d30272 into apple:master Apr 10, 2018
@jrose-apple jrose-apple deleted the unknown-case branch April 10, 2018 18:19
children=[
Child('UnknownKeyword', kind='Token'),
Child('Colon', kind='ColonToken'),
]),
Copy link
Member

@rintaro rintaro Apr 11, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This SwitchUnknownLabel is not used. Can I remove this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Whoops, I thought I took it out already. Yes, sorry!

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.

None yet

5 participants