Skip to content

Commit 9c673a5

Browse files
authored
Merge pull request #19466 from nkcsgexi/assoiciated-type-diag
swift-module-digester: diagnose removing default associated type as API breakage.
2 parents 57b8247 + 565fd91 commit 9c673a5

File tree

13 files changed

+143
-1
lines changed

13 files changed

+143
-1
lines changed

include/swift/AST/DiagnosticsModuleDiffer.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,8 @@ ERROR(conformance_removed,none,"%0 has removed %select{conformance to|inherited
6262

6363
ERROR(conformance_added,none,"%0 has added inherited protocol %1", (StringRef, StringRef))
6464

65+
ERROR(default_associated_type_removed,none,"%0 has removed default type %1", (StringRef, StringRef))
66+
6567
#ifndef DIAG_NO_UNDEF
6668
# if defined(DIAG)
6769
# undef DIAG

include/swift/IDE/DigesterEnums.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ NODE_KIND(DeclGetter, Getter)
4545
NODE_KIND(DeclSetter, Setter)
4646
NODE_KIND(DeclVar, Var)
4747
NODE_KIND(DeclTypeAlias, TypeAlias)
48+
NODE_KIND(DeclAssociatedType, AssociatedType)
4849

4950
NODE_ANNOTATION(Added)
5051
NODE_ANNOTATION(Removed)

test/api-digester/Inputs/cake.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -49,4 +49,9 @@ public struct fixedLayoutStruct {
4949
var c = 3
5050
}
5151

52-
extension Int: P1 { public func bar() {} }
52+
extension Int: P1 { public func bar() {} }
53+
54+
public protocol ProWithAssociatedType {
55+
associatedtype A
56+
associatedtype B = Int
57+
}

test/api-digester/Inputs/cake1.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,3 +69,9 @@ public class C7 {
6969
public protocol P3: P2, P1 {}
7070

7171
extension fixedLayoutStruct: P1 {}
72+
73+
public protocol AssociatedTypePro {
74+
associatedtype T1 = Int
75+
associatedtype T2
76+
associatedtype T3 = C1
77+
}

test/api-digester/Inputs/cake2.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,3 +76,9 @@ public protocol P3: P1, P4 {}
7676
public protocol P4 {}
7777

7878
extension fixedLayoutStruct: P2 {}
79+
80+
public protocol AssociatedTypePro {
81+
associatedtype T1
82+
associatedtype T2
83+
associatedtype T3 = C6
84+
}

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
1717
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
1818

1919
/* Type Changes */
20+
cake1: AssociatedType AssociatedTypePro.T3 has default type change from C1 to C6
2021
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
2122
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
2223
cake1: Func C7.foo(_:_:) has removed default argument from parameter 0
@@ -47,3 +48,6 @@ cake2: Var fixedLayoutStruct.lazy_d.storage is added to a non-resilient type
4748
cake1: Protocol P3 has added inherited protocol P4
4849
cake1: Protocol P3 has removed inherited protocol P2
4950
cake1: Struct fixedLayoutStruct has removed conformance to P1
51+
52+
/* Protocol Requirement Change */
53+
cake1: AssociatedType AssociatedTypePro.T1 has removed default type Int

test/api-digester/Outputs/Cake.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ cake1: Func S1.foo5(x:y:) has been renamed to Func S1.foo5(x:y:z:)
1717
cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
1818

1919
/* Type Changes */
20+
cake1: AssociatedType AssociatedTypePro.T3 has default type change from C1 to C6
2021
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
2122
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
2223
cake1: Func C7.foo(_:_:) has removed default argument from parameter 0
@@ -33,3 +34,6 @@ cake1: Var C1.CIIns2 changes from strong to weak
3334
cake1: Protocol P3 has added inherited protocol P4
3435
cake1: Protocol P3 has removed inherited protocol P2
3536
cake1: Struct fixedLayoutStruct has removed conformance to P1
37+
38+
/* Protocol Requirement Change */
39+
cake1: AssociatedType AssociatedTypePro.T1 has removed default type Int

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

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,6 +963,43 @@
963963
}
964964
]
965965
},
966+
{
967+
"kind": "TypeDecl",
968+
"name": "ProWithAssociatedType",
969+
"printedName": "ProWithAssociatedType",
970+
"declKind": "Protocol",
971+
"usr": "s:4cake21ProWithAssociatedTypeP",
972+
"location": "",
973+
"moduleName": "cake",
974+
"children": [
975+
{
976+
"kind": "AssociatedType",
977+
"name": "A",
978+
"printedName": "A",
979+
"declKind": "AssociatedType",
980+
"usr": "s:4cake21ProWithAssociatedTypeP1AQa",
981+
"location": "",
982+
"moduleName": "cake"
983+
},
984+
{
985+
"kind": "AssociatedType",
986+
"name": "B",
987+
"printedName": "B",
988+
"declKind": "AssociatedType",
989+
"usr": "s:4cake21ProWithAssociatedTypeP1BQa",
990+
"location": "",
991+
"moduleName": "cake",
992+
"children": [
993+
{
994+
"kind": "TypeNominal",
995+
"name": "Int",
996+
"printedName": "Int",
997+
"usr": "s:Si"
998+
}
999+
]
1000+
}
1001+
]
1002+
},
9661003
{
9671004
"kind": "TypeDecl",
9681005
"name": "Int",

test/api-digester/Outputs/cake.json

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -839,6 +839,43 @@
839839
}
840840
]
841841
},
842+
{
843+
"kind": "TypeDecl",
844+
"name": "ProWithAssociatedType",
845+
"printedName": "ProWithAssociatedType",
846+
"declKind": "Protocol",
847+
"usr": "s:4cake21ProWithAssociatedTypeP",
848+
"location": "",
849+
"moduleName": "cake",
850+
"children": [
851+
{
852+
"kind": "AssociatedType",
853+
"name": "A",
854+
"printedName": "A",
855+
"declKind": "AssociatedType",
856+
"usr": "s:4cake21ProWithAssociatedTypeP1AQa",
857+
"location": "",
858+
"moduleName": "cake"
859+
},
860+
{
861+
"kind": "AssociatedType",
862+
"name": "B",
863+
"printedName": "B",
864+
"declKind": "AssociatedType",
865+
"usr": "s:4cake21ProWithAssociatedTypeP1BQa",
866+
"location": "",
867+
"moduleName": "cake",
868+
"children": [
869+
{
870+
"kind": "TypeNominal",
871+
"name": "Int",
872+
"printedName": "Int",
873+
"usr": "s:Si"
874+
}
875+
]
876+
}
877+
]
878+
},
842879
{
843880
"kind": "TypeDecl",
844881
"name": "Int",

tools/swift-api-digester/ModuleAnalyzerNodes.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -130,6 +130,9 @@ SDKNodeDeclGetter::SDKNodeDeclGetter(SDKNodeInitInfo Info):
130130
SDKNodeDeclSetter::SDKNodeDeclSetter(SDKNodeInitInfo Info):
131131
SDKNodeDeclAbstractFunc(Info, SDKNodeKind::DeclSetter) {}
132132

133+
SDKNodeDeclAssociatedType::SDKNodeDeclAssociatedType(SDKNodeInitInfo Info):
134+
SDKNodeDecl(Info, SDKNodeKind::DeclAssociatedType) {};
135+
133136
StringRef SDKNodeDecl::getHeaderName() const {
134137
if (Location.empty())
135138
return StringRef();
@@ -348,6 +351,7 @@ bool SDKNodeDecl::classof(const SDKNode *N) {
348351
case SDKNodeKind::DeclTypeAlias:
349352
case SDKNodeKind::DeclType:
350353
case SDKNodeKind::DeclVar:
354+
case SDKNodeKind::DeclAssociatedType:
351355
return true;
352356
case SDKNodeKind::Root:
353357
case SDKNodeKind::TypeNominal:
@@ -731,6 +735,7 @@ bool SDKNode::operator==(const SDKNode &Other) const {
731735
}
732736
LLVM_FALLTHROUGH;
733737
}
738+
case SDKNodeKind::DeclAssociatedType:
734739
case SDKNodeKind::DeclTypeAlias: {
735740
auto Left = this->getAs<SDKNodeDecl>();
736741
auto Right = (&Other)->getAs<SDKNodeDecl>();
@@ -1250,6 +1255,16 @@ static SDKNode *constructTypeAliasNode(SDKContext &Ctx,TypeAliasDecl *TAD) {
12501255
return Alias;
12511256
}
12521257

1258+
static SDKNode *constructAssociatedTypeNode(SDKContext &Ctx,
1259+
AssociatedTypeDecl *ATD) {
1260+
auto Asso = SDKNodeInitInfo(Ctx, ATD).
1261+
createSDKNode(SDKNodeKind::DeclAssociatedType);
1262+
if (auto DT = ATD->getDefaultDefinitionType()) {
1263+
Asso->addChild(constructTypeNode(Ctx, DT));
1264+
}
1265+
return Asso;
1266+
}
1267+
12531268
static void addMembersToRoot(SDKContext &Ctx, SDKNode *Root,
12541269
IterableDeclContext *Context,
12551270
std::set<ExtensionDecl*> &HandledExts) {
@@ -1268,6 +1283,8 @@ static void addMembersToRoot(SDKContext &Ctx, SDKNode *Root,
12681283
Root->addChild(constructVarNode(Ctx, EED));
12691284
} else if (auto NTD = dyn_cast<NominalTypeDecl>(Member)) {
12701285
Root->addChild(constructTypeDeclNode(Ctx, NTD, HandledExts));
1286+
} else if (auto ATD = dyn_cast<AssociatedTypeDecl>(Member)) {
1287+
Root->addChild(constructAssociatedTypeNode(Ctx, ATD));
12711288
}
12721289
}
12731290
}

tools/swift-api-digester/ModuleAnalyzerNodes.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -440,6 +440,15 @@ class SDKNodeDeclTypeAlias : public SDKNodeDecl {
440440
static bool classof(const SDKNode *N);
441441
};
442442

443+
class SDKNodeDeclAssociatedType: public SDKNodeDecl {
444+
public:
445+
SDKNodeDeclAssociatedType(SDKNodeInitInfo Info);
446+
const SDKNodeType* getDefault() const {
447+
return getChildrenCount() ? getOnlyChild()->getAs<SDKNodeType>(): nullptr;
448+
}
449+
static bool classof(const SDKNode *N);
450+
};
451+
443452
class SDKNodeDeclVar : public SDKNodeDecl {
444453
Optional<unsigned> FixedBinaryOrder;
445454
public:

tools/swift-api-digester/ModuleDiagsConsumer.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,8 @@ static StringRef getCategoryName(uint32_t ID) {
5454
case LocalDiagID::conformance_added:
5555
case LocalDiagID::conformance_removed:
5656
return "/* Protocol Conformance Change */";
57+
case LocalDiagID::default_associated_type_removed:
58+
return "/* Protocol Requirement Change */";
5759
default:
5860
return StringRef();
5961
}

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

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -817,6 +817,13 @@ class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass {
817817
case NodeMatchReason::Removed:
818818
assert(!Right);
819819
Left->annotate(NodeAnnotation::Removed);
820+
if (auto *LT = dyn_cast<SDKNodeType>(Left)) {
821+
if (auto *AT = dyn_cast<SDKNodeDeclAssociatedType>(LT->getParent())) {
822+
Ctx.getDiags().diagnose(SourceLoc(),
823+
diag::default_associated_type_removed,
824+
AT->getScreenInfo(), LT->getPrintedName());
825+
}
826+
}
820827
return;
821828
case NodeMatchReason::FuncToProperty:
822829
case NodeMatchReason::ModernizeEnum:
@@ -860,6 +867,7 @@ class PrunePass : public MatchedNodeListener, public SDKTreeDiffPass {
860867
break;
861868
}
862869

870+
case SDKNodeKind::DeclAssociatedType:
863871
case SDKNodeKind::DeclFunction:
864872
case SDKNodeKind::DeclSetter:
865873
case SDKNodeKind::DeclGetter:
@@ -1732,6 +1740,10 @@ void DiagnosisEmitter::visitType(SDKNodeType *Node) {
17321740
Diags.diagnose(SourceLoc(), diag::decl_type_change, Parent->getScreenInfo(),
17331741
Descriptor, Node->getPrintedName(), Count->getPrintedName());
17341742
break;
1743+
case SDKNodeKind::DeclAssociatedType:
1744+
Diags.diagnose(SourceLoc(), diag::decl_type_change, Parent->getScreenInfo(),
1745+
"default", Node->getPrintedName(), Count->getPrintedName());
1746+
break;
17351747
default:
17361748
break;
17371749
}

0 commit comments

Comments
 (0)