diff --git a/include/swift/IDE/DigesterEnums.def b/include/swift/IDE/DigesterEnums.def index d00a337f4eb21..415db666c919d 100644 --- a/include/swift/IDE/DigesterEnums.def +++ b/include/swift/IDE/DigesterEnums.def @@ -132,6 +132,7 @@ KEY_BOOL(HasStorage, hasStorage) KEY_BOOL(ReqNewWitnessTableEntry, reqNewWitnessTableEntry) KEY_BOOL(IsABIPlaceholder, isABIPlaceholder) KEY_BOOL(IsExternal, isExternal) +KEY_BOOL(IsEnumExhaustive, isEnumExhaustive) KEY_BOOL(HasMissingDesignatedInitializers, hasMissingDesignatedInitializers) KEY_BOOL(InheritsConvenienceInitializers, inheritsConvenienceInitializers) diff --git a/test/api-digester/Inputs/cake_baseline/cake.swift b/test/api-digester/Inputs/cake_baseline/cake.swift index 8ac2884bca90a..63604ca8c1553 100644 --- a/test/api-digester/Inputs/cake_baseline/cake.swift +++ b/test/api-digester/Inputs/cake_baseline/cake.swift @@ -40,6 +40,9 @@ public struct C6 {} @frozen public enum IceKind {} +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public enum FutureKind {} + public protocol P1 {} public protocol P2 {} diff --git a/test/api-digester/Inputs/cake_current/cake.swift b/test/api-digester/Inputs/cake_current/cake.swift index 353c8c632a748..f6c3d365a404b 100644 --- a/test/api-digester/Inputs/cake_current/cake.swift +++ b/test/api-digester/Inputs/cake_current/cake.swift @@ -40,6 +40,11 @@ public struct C6 {} public enum IceKind {} +@available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) +public enum FutureKind { + case FineToAdd +} + public protocol P1 {} public protocol P2 {} diff --git a/test/api-digester/Outputs/cake-abi.json b/test/api-digester/Outputs/cake-abi.json index a6f9baf090553..baf48c95925bf 100644 --- a/test/api-digester/Outputs/cake-abi.json +++ b/test/api-digester/Outputs/cake-abi.json @@ -615,6 +615,7 @@ "usr": "s:4cake6NumberO", "moduleName": "cake", "enumRawTypeName": "Int", + "isEnumExhaustive": true, "conformances": [ { "kind": "Conformance", diff --git a/test/api-digester/Outputs/cake.json b/test/api-digester/Outputs/cake.json index 13fd939c1e866..8a487febb665b 100644 --- a/test/api-digester/Outputs/cake.json +++ b/test/api-digester/Outputs/cake.json @@ -635,6 +635,7 @@ "usr": "s:4cake6NumberO", "moduleName": "cake", "enumRawTypeName": "Int", + "isEnumExhaustive": true, "conformances": [ { "kind": "Conformance", diff --git a/test/api-digester/dump-module.swift b/test/api-digester/dump-module.swift index c0bdcb213a869..79955afcf567e 100644 --- a/test/api-digester/dump-module.swift +++ b/test/api-digester/dump-module.swift @@ -1,4 +1,4 @@ -// REQUIRES: macosx +// REQUIRES: OS=macosx // RUN: %empty-directory(%t.mod) // RUN: %empty-directory(%t.sdk) // RUN: %empty-directory(%t.module-cache) diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp index 84ecd79fb78ef..66d1112058750 100644 --- a/tools/swift-api-digester/ModuleAnalyzerNodes.cpp +++ b/tools/swift-api-digester/ModuleAnalyzerNodes.cpp @@ -126,7 +126,9 @@ SDKNodeTypeAlias::SDKNodeTypeAlias(SDKNodeInitInfo Info): SDKNodeDeclType::SDKNodeDeclType(SDKNodeInitInfo Info): SDKNodeDecl(Info, SDKNodeKind::DeclType), SuperclassUsr(Info.SuperclassUsr), SuperclassNames(Info.SuperclassNames), - EnumRawTypeName(Info.EnumRawTypeName), IsExternal(Info.IsExternal), + EnumRawTypeName(Info.EnumRawTypeName), + IsExternal(Info.IsExternal), + IsEnumExhaustive(Info.IsEnumExhaustive), HasMissingDesignatedInitializers(Info.HasMissingDesignatedInitializers), InheritsConvenienceInitializers(Info.InheritsConvenienceInitializers) {} @@ -1426,6 +1428,7 @@ SDKNodeInitInfo::SDKNodeInitInfo(SDKContext &Ctx, ValueDecl *VD) // Get enum raw type name if this is an enum. if (auto *ED = dyn_cast(VD)) { + IsEnumExhaustive = ED->isFormallyExhaustive(nullptr); if (auto RT = ED->getRawType()) { if (auto *D = RT->getNominalOrBoundGenericNominal()) { EnumRawTypeName = D->getName().str(); @@ -1981,6 +1984,7 @@ void SDKNodeDeclType::jsonize(json::Output &out) { output(out, KeyKind::KK_superclassUsr, SuperclassUsr); output(out, KeyKind::KK_enumRawTypeName, EnumRawTypeName); output(out, KeyKind::KK_isExternal, IsExternal); + output(out, KeyKind::KK_isEnumExhaustive, IsEnumExhaustive); output(out, KeyKind::KK_hasMissingDesignatedInitializers, HasMissingDesignatedInitializers); output(out, KeyKind::KK_inheritsConvenienceInitializers, diff --git a/tools/swift-api-digester/ModuleAnalyzerNodes.h b/tools/swift-api-digester/ModuleAnalyzerNodes.h index db19837d46ebc..b1426059dce51 100644 --- a/tools/swift-api-digester/ModuleAnalyzerNodes.h +++ b/tools/swift-api-digester/ModuleAnalyzerNodes.h @@ -524,6 +524,7 @@ class SDKNodeDeclType: public SDKNodeDecl { // Check whether the type declaration is pulled from an external module so we // can incorporate extensions in the interested module. bool IsExternal; + bool IsEnumExhaustive; bool HasMissingDesignatedInitializers; bool InheritsConvenienceInitializers; public: @@ -550,6 +551,11 @@ class SDKNodeDeclType: public SDKNodeDecl { return EnumRawTypeName; } + bool isEnumExhaustive() const { + assert(isEnum()); + return IsEnumExhaustive; + } + bool hasMissingDesignatedInitializers() const { return HasMissingDesignatedInitializers; }; diff --git a/tools/swift-api-digester/swift-api-digester.cpp b/tools/swift-api-digester/swift-api-digester.cpp index 72b216defaa15..b8ab15e72a9d2 100644 --- a/tools/swift-api-digester/swift-api-digester.cpp +++ b/tools/swift-api-digester/swift-api-digester.cpp @@ -1216,7 +1216,9 @@ class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass { if (!Ctx.checkingABI()) { if (auto *Var = dyn_cast(Right)) { if (Var->getDeclKind() == DeclKind::EnumElement) { - Var->emitDiag(Var->getLoc(), diag::enum_case_added); + if (Var->getParent()->getAs()->isEnumExhaustive()) { + Var->emitDiag(Var->getLoc(), diag::enum_case_added); + } } } }