Skip to content

Commit 9581918

Browse files
authored
Merge pull request #31997 from nkcsgexi/exhaustive-enum-check
API checker: only diagnose adding enum cases to exhaustive enums
2 parents d3162e4 + c5730be commit 9581918

File tree

9 files changed

+26
-3
lines changed

9 files changed

+26
-3
lines changed

include/swift/IDE/DigesterEnums.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -132,6 +132,7 @@ KEY_BOOL(HasStorage, hasStorage)
132132
KEY_BOOL(ReqNewWitnessTableEntry, reqNewWitnessTableEntry)
133133
KEY_BOOL(IsABIPlaceholder, isABIPlaceholder)
134134
KEY_BOOL(IsExternal, isExternal)
135+
KEY_BOOL(IsEnumExhaustive, isEnumExhaustive)
135136
KEY_BOOL(HasMissingDesignatedInitializers, hasMissingDesignatedInitializers)
136137
KEY_BOOL(InheritsConvenienceInitializers, inheritsConvenienceInitializers)
137138

test/api-digester/Inputs/cake_baseline/cake.swift

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,9 @@ public struct C6 {}
4040
@frozen
4141
public enum IceKind {}
4242

43+
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
44+
public enum FutureKind {}
45+
4346
public protocol P1 {}
4447

4548
public protocol P2 {}

test/api-digester/Inputs/cake_current/cake.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ public struct C6 {}
4040

4141
public enum IceKind {}
4242

43+
@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *)
44+
public enum FutureKind {
45+
case FineToAdd
46+
}
47+
4348
public protocol P1 {}
4449

4550
public protocol P2 {}

test/api-digester/Outputs/cake-abi.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,7 @@
615615
"usr": "s:4cake6NumberO",
616616
"moduleName": "cake",
617617
"enumRawTypeName": "Int",
618+
"isEnumExhaustive": true,
618619
"conformances": [
619620
{
620621
"kind": "Conformance",

test/api-digester/Outputs/cake.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,7 @@
635635
"usr": "s:4cake6NumberO",
636636
"moduleName": "cake",
637637
"enumRawTypeName": "Int",
638+
"isEnumExhaustive": true,
638639
"conformances": [
639640
{
640641
"kind": "Conformance",

test/api-digester/dump-module.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// REQUIRES: macosx
1+
// REQUIRES: OS=macosx
22
// RUN: %empty-directory(%t.mod)
33
// RUN: %empty-directory(%t.sdk)
44
// RUN: %empty-directory(%t.module-cache)

tools/swift-api-digester/ModuleAnalyzerNodes.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,9 @@ SDKNodeTypeAlias::SDKNodeTypeAlias(SDKNodeInitInfo Info):
126126
SDKNodeDeclType::SDKNodeDeclType(SDKNodeInitInfo Info):
127127
SDKNodeDecl(Info, SDKNodeKind::DeclType), SuperclassUsr(Info.SuperclassUsr),
128128
SuperclassNames(Info.SuperclassNames),
129-
EnumRawTypeName(Info.EnumRawTypeName), IsExternal(Info.IsExternal),
129+
EnumRawTypeName(Info.EnumRawTypeName),
130+
IsExternal(Info.IsExternal),
131+
IsEnumExhaustive(Info.IsEnumExhaustive),
130132
HasMissingDesignatedInitializers(Info.HasMissingDesignatedInitializers),
131133
InheritsConvenienceInitializers(Info.InheritsConvenienceInitializers) {}
132134

@@ -1426,6 +1428,7 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD)
14261428

14271429
// Get enum raw type name if this is an enum.
14281430
if (auto *ED = dyn_cast<EnumDecl>(VD)) {
1431+
IsEnumExhaustive = ED->isFormallyExhaustive(nullptr);
14291432
if (auto RT = ED->getRawType()) {
14301433
if (auto *D = RT->getNominalOrBoundGenericNominal()) {
14311434
EnumRawTypeName = D->getName().str();
@@ -1981,6 +1984,7 @@ void SDKNodeDeclType::jsonize(json::Output &out) {
19811984
output(out, KeyKind::KK_superclassUsr, SuperclassUsr);
19821985
output(out, KeyKind::KK_enumRawTypeName, EnumRawTypeName);
19831986
output(out, KeyKind::KK_isExternal, IsExternal);
1987+
output(out, KeyKind::KK_isEnumExhaustive, IsEnumExhaustive);
19841988
output(out, KeyKind::KK_hasMissingDesignatedInitializers,
19851989
HasMissingDesignatedInitializers);
19861990
output(out, KeyKind::KK_inheritsConvenienceInitializers,

tools/swift-api-digester/ModuleAnalyzerNodes.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -524,6 +524,7 @@ class SDKNodeDeclType: public SDKNodeDecl {
524524
// Check whether the type declaration is pulled from an external module so we
525525
// can incorporate extensions in the interested module.
526526
bool IsExternal;
527+
bool IsEnumExhaustive;
527528
bool HasMissingDesignatedInitializers;
528529
bool InheritsConvenienceInitializers;
529530
public:
@@ -550,6 +551,11 @@ class SDKNodeDeclType: public SDKNodeDecl {
550551
return EnumRawTypeName;
551552
}
552553

554+
bool isEnumExhaustive() const {
555+
assert(isEnum());
556+
return IsEnumExhaustive;
557+
}
558+
553559
bool hasMissingDesignatedInitializers() const {
554560
return HasMissingDesignatedInitializers;
555561
};

tools/swift-api-digester/swift-api-digester.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1216,7 +1216,9 @@ class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass {
12161216
if (!Ctx.checkingABI()) {
12171217
if (auto *Var = dyn_cast<SDKNodeDeclVar>(Right)) {
12181218
if (Var->getDeclKind() == DeclKind::EnumElement) {
1219-
Var->emitDiag(Var->getLoc(), diag::enum_case_added);
1219+
if (Var->getParent()->getAs<SDKNodeDeclType>()->isEnumExhaustive()) {
1220+
Var->emitDiag(Var->getLoc(), diag::enum_case_added);
1221+
}
12201222
}
12211223
}
12221224
}

0 commit comments

Comments
 (0)