Skip to content

Commit f72b8e5

Browse files
committed
[Clang importer] Infer @_downgrade_exhaustivity_check for new-to-2017 enum elements in Swift 3.
In Swift 3 mode, infer @_downgrade_exhaustivity_check for any enum elements that were introduced in the 2017 SDKs (macOS 10.13, iOS 11.0, tvOS 11.0, watchOS 4.0). This is a stop-gap until we get "open" enums, but serves an important source-compatibility use case. Fixes rdar://problem/32824207. (cherry picked from commit f855d2f)
1 parent 4065cdd commit f72b8e5

File tree

4 files changed

+82
-0
lines changed

4 files changed

+82
-0
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7016,6 +7016,41 @@ void ClangImporter::Implementation::importAttributes(
70167016
PlatformAgnostic, /*Implicit=*/false);
70177017

70187018
MappedDecl->getAttrs().add(AvAttr);
7019+
7020+
// For enum cases introduced in the 2017 SDKs, add
7021+
// @_downgrade_exhaustivity_check in Swift 3.
7022+
if (C.LangOpts.isSwiftVersion3() && isa<EnumElementDecl>(MappedDecl)) {
7023+
bool downgradeExhaustivity = false;
7024+
switch (*platformK) {
7025+
case PlatformKind::OSX:
7026+
case PlatformKind::OSXApplicationExtension:
7027+
downgradeExhaustivity = (introduced.getMajor() == 10 &&
7028+
introduced.getMinor() &&
7029+
*introduced.getMinor() == 13);
7030+
break;
7031+
7032+
case PlatformKind::iOS:
7033+
case PlatformKind::iOSApplicationExtension:
7034+
case PlatformKind::tvOS:
7035+
case PlatformKind::tvOSApplicationExtension:
7036+
downgradeExhaustivity = (introduced.getMajor() == 11);
7037+
break;
7038+
7039+
case PlatformKind::watchOS:
7040+
case PlatformKind::watchOSApplicationExtension:
7041+
downgradeExhaustivity = (introduced.getMajor() == 4);
7042+
break;
7043+
7044+
case PlatformKind::none:
7045+
break;
7046+
}
7047+
7048+
if (downgradeExhaustivity) {
7049+
auto attr =
7050+
new (C) DowngradeExhaustivityCheckAttr(/*isImplicit=*/true);
7051+
MappedDecl->getAttrs().add(attr);
7052+
}
7053+
}
70197054
}
70207055
}
70217056

test/ClangImporter/Inputs/custom-modules/AvailabilityExtras.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
@import Foundation;
2+
13
void unavail1(void) __attribute__((unavailable("first")));
24
void unavail1(void);
35
void unavail1(void);
@@ -84,3 +86,10 @@ struct NSSwiftUnavailableStruct {
8486
} __attribute__((availability(swift, unavailable)));
8587

8688
void unavailableWithOS() __attribute__((availability(ios, deprecated=8.0))) __attribute__((availability(swift, unavailable))) __attribute__((availability(macosx, deprecated=10.10))) ;
89+
90+
typedef NS_ENUM(NSInteger, NSEnumAddedCasesIn2017) {
91+
NSEnumAddedCasesIn2017ExistingCaseOne,
92+
NSEnumAddedCasesIn2017ExistingCaseTwo,
93+
NSEnumAddedCasesIn2017ExistingCaseThree,
94+
NSEnumAddedCasesIn2017NewCaseOne __attribute__((availability(macosx,introduced=10.13))) __attribute__((availability(ios,introduced=11.0))) __attribute__((availability(tvos,introduced=11.0))) __attribute__((availability(watchos,introduced=4.0)))
95+
};
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -I %S/Inputs/custom-modules -swift-version 4 -target x86_64-apple-macosx10.13 %s
2+
3+
// REQUIRES: OS=macosx
4+
// REQUIRES: objc_interop
5+
6+
import Foundation
7+
import AvailabilityExtras
8+
9+
func exhaustiveSwitch(e: NSEnumAddedCasesIn2017) {
10+
switch e { // expected-error{{switch must be exhaustive}}
11+
// expected-note@-1{{add missing case: '.newCaseOne'}}
12+
case .existingCaseOne:
13+
return
14+
case .existingCaseTwo:
15+
return
16+
case .existingCaseThree:
17+
return
18+
}
19+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify -I %S/Inputs/custom-modules -swift-version 3 -target x86_64-apple-macosx10.13 %s
2+
3+
// REQUIRES: OS=macosx
4+
// REQUIRES: objc_interop
5+
6+
import Foundation
7+
import AvailabilityExtras
8+
9+
func exhaustiveSwitch(e: NSEnumAddedCasesIn2017) {
10+
switch e { // expected-warning{{switch must be exhaustive}}
11+
// expected-note@-1{{add missing case: '.newCaseOne'}}
12+
case .existingCaseOne:
13+
return
14+
case .existingCaseTwo:
15+
return
16+
case .existingCaseThree:
17+
return
18+
}
19+
}

0 commit comments

Comments
 (0)