Skip to content

Commit c5444a8

Browse files
committed
swift-module-digester: diagnose optional protocol requirement changes.
1 parent 3dfe615 commit c5444a8

File tree

8 files changed

+35
-2
lines changed

8 files changed

+35
-2
lines changed

include/swift/AST/DiagnosticsModuleDiffer.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,8 @@ ERROR(super_class_changed,none,"%0 has changed its super class from %1 to %2", (
7474

7575
ERROR(nominal_type_kind_changed,none,"%0 has been changed to a %1", (StringRef, StringRef))
7676

77+
ERROR(optional_req_changed,none,"%0 is %select{now|no longer}1 an optional requirement", (StringRef, bool))
78+
7779
#ifndef DIAG_NO_UNDEF
7880
# if defined(DIAG)
7981
# undef DIAG

test/api-digester/Inputs/cake1.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,4 +102,12 @@ public class SuperClassChange: C7 {}
102102

103103
public class GenericClass<T> {}
104104

105-
public class SubGenericClass: GenericClass<P1> {}
105+
public class SubGenericClass: GenericClass<P1> {}
106+
107+
@objc
108+
public protocol ObjCProtocol {
109+
@objc
110+
optional func removeOptional()
111+
@objc
112+
func addOptional()
113+
}

test/api-digester/Inputs/cake2.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -113,3 +113,11 @@ public class SuperClassChange: C8 {}
113113
public class GenericClass<T> {}
114114

115115
public class SubGenericClass: GenericClass<P2> {}
116+
117+
@objc
118+
public protocol ObjCProtocol {
119+
@objc
120+
func removeOptional()
121+
@objc
122+
optional func addOptional()
123+
}

test/api-digester/Outputs/Cake-abi.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,8 @@ cake2: Var fixedLayoutStruct.c is added to a non-resilient type
5353
cake2: Var fixedLayoutStruct.lazy_d.storage is added to a non-resilient type
5454

5555
/* Conformance changes */
56+
cake1: Func ObjCProtocol.addOptional() is now an optional requirement
57+
cake1: Func ObjCProtocol.removeOptional() is no longer an optional requirement
5658
cake1: Protocol P3 has added inherited protocol P4
5759
cake1: Protocol P3 has removed inherited protocol P2
5860
cake1: Struct fixedLayoutStruct has removed conformance to P1

test/api-digester/Outputs/Cake.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ cake1: Var C1.CIIns1 changes from weak to strong
3838
cake1: Var C1.CIIns2 changes from strong to weak
3939

4040
/* Conformance changes */
41+
cake1: Func ObjCProtocol.removeOptional() is no longer an optional requirement
4142
cake1: Protocol P3 has added inherited protocol P4
4243
cake1: Protocol P3 has removed inherited protocol P2
4344
cake1: Struct fixedLayoutStruct has removed conformance to P1

tools/swift-api-digester/ModuleAnalyzerNodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -317,6 +317,7 @@ class SDKNodeDecl: public SDKNode {
317317
bool isImplicit() const { return IsImplicit; };
318318
bool isStatic() const { return IsStatic; };
319319
bool isOverriding() const { return IsOverriding; };
320+
bool isOptional() const { return hasDeclAttribute(DeclAttrKind::DAK_Optional); }
320321
StringRef getGenericSignature() const { return GenericSig; }
321322
StringRef getScreenInfo() const;
322323
virtual void jsonize(json::Output &Out) override;

tools/swift-api-digester/ModuleDiagsConsumer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ static StringRef getCategoryName(uint32_t ID) {
5555
return "/* Fixed-layout Type Changes */";
5656
case LocalDiagID::conformance_added:
5757
case LocalDiagID::conformance_removed:
58+
case LocalDiagID::optional_req_changed:
5859
return "/* Protocol Conformance Change */";
5960
case LocalDiagID::default_associated_type_removed:
6061
case LocalDiagID::protocol_req_added:

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -775,7 +775,17 @@ static void detectDeclChange(NodePtr L, NodePtr R, SDKContext &Ctx) {
775775
Diags.diagnose(SourceLoc(), diag::generic_sig_change, LD->getScreenInfo(),
776776
LD->getGenericSignature(), RD->getGenericSignature());
777777
}
778-
778+
if (LD->isOptional() != RD->isOptional()) {
779+
if (Ctx.checkingABI()) {
780+
// Both adding/removing optional is ABI-breaking.
781+
Diags.diagnose(SourceLoc(), diag::optional_req_changed,
782+
LD->getScreenInfo(), LD->isOptional());
783+
} else if (LD->isOptional()) {
784+
// Removing optional is source-breaking.
785+
Diags.diagnose(SourceLoc(), diag::optional_req_changed,
786+
LD->getScreenInfo(), LD->isOptional());
787+
}
788+
}
779789
if (auto *LDT = dyn_cast<SDKNodeDeclType>(L)) {
780790
if (auto *RDT = dyn_cast<SDKNodeDeclType>(R)) {
781791
diagnoseNominalTypeDeclChange(LDT, RDT);

0 commit comments

Comments
 (0)