Skip to content

Commit 49c1692

Browse files
committed
swift-module-digester: diagnose type witness type changes when checking ABI stability.
1 parent e7c2bf0 commit 49c1692

File tree

9 files changed

+44
-2
lines changed

9 files changed

+44
-2
lines changed

include/swift/AST/DiagnosticsModuleDiffer.def

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,8 @@ ERROR(func_self_access_change,none,"%0 has self access kind changing from %1 to
9090

9191
ERROR(param_ownership_change,none,"%0 has %1 changing from %2 to %3", (StringRef, StringRef, StringRef, StringRef))
9292

93+
ERROR(type_witness_change,none,"%0 has type witness type for %1 changing from %2 to %3", (StringRef, StringRef, StringRef, StringRef))
94+
9395
#ifndef DIAG_NO_UNDEF
9496
# if defined(DIAG)
9597
# undef DIAG

test/api-digester/Inputs/cake1.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,11 @@ public class FinalFuncContainer {
150150
public func NewFinalFunc() {}
151151
public final func NoLongerFinalFunc() {}
152152
}
153+
154+
public protocol AssociatedTypesProtocol {
155+
associatedtype T
156+
}
157+
158+
public class TChangesFromIntToString: AssociatedTypesProtocol {
159+
public typealias T = Int
160+
}

test/api-digester/Inputs/cake2.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,3 +161,11 @@ public class FinalFuncContainer {
161161
public final func NewFinalFunc() {}
162162
public func NoLongerFinalFunc() {}
163163
}
164+
165+
public protocol AssociatedTypesProtocol {
166+
associatedtype T
167+
}
168+
169+
public class TChangesFromIntToString: AssociatedTypesProtocol {
170+
public typealias T = String
171+
}

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ cake1: Struct Somestruct2 has been renamed to Struct NSSomestruct2
2727

2828
/* Type Changes */
2929
cake1: AssociatedType AssociatedTypePro.T3 has default type change from C1 to C6
30+
cake1: Class TChangesFromIntToString has type witness type for AssociatedTypesProtocol.T changing from Int to String
3031
cake1: Constructor S1.init(_:) has parameter 0 type change from Int to Double
3132
cake1: Func C1.foo2(_:) has parameter 0 type change from Int to () -> ()
3233
cake1: Func C7.foo(_:_:) has removed default argument from parameter 0

test/api-digester/Outputs/Cake.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ cake1: Func C7.foo(_:_:) has removed default argument from parameter 0
3232
cake1: Func C7.foo(_:_:) has removed default argument from parameter 1
3333
cake1: Func ownershipChange(_:_:) has parameter 0 changing from InOut to Default
3434
cake1: Func ownershipChange(_:_:) has parameter 1 changing from Shared to Owned
35+
cake1: TypeAlias TChangesFromIntToString.T has underlying type change from Int to String
3536

3637
/* Decl Attribute changes */
3738
cake1: Func C1.foo1() is now not static

tools/swift-api-digester/ModuleAnalyzerNodes.cpp

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -326,7 +326,7 @@ StringRef SDKNodeType::getParamValueOwnership() const {
326326

327327
StringRef SDKNodeType::getTypeRoleDescription() const {
328328
assert(isTopLevelType());
329-
auto P = cast<SDKNodeDecl>(getParent());
329+
auto P = getParent();
330330
switch(P->getKind()) {
331331
case SDKNodeKind::Root:
332332
case SDKNodeKind::TypeNominal:
@@ -335,7 +335,6 @@ StringRef SDKNodeType::getTypeRoleDescription() const {
335335
case SDKNodeKind::DeclType:
336336
case SDKNodeKind::DeclOperator:
337337
case SDKNodeKind::Conformance:
338-
case SDKNodeKind::TypeWitness:
339338
llvm_unreachable("Type Parent is wrong");
340339
case SDKNodeKind::DeclFunction:
341340
case SDKNodeKind::DeclConstructor:
@@ -350,6 +349,8 @@ StringRef SDKNodeType::getTypeRoleDescription() const {
350349
return "underlying";
351350
case SDKNodeKind::DeclAssociatedType:
352351
return "default";
352+
case SDKNodeKind::TypeWitness:
353+
return "type witness type";
353354
}
354355
}
355356

@@ -440,6 +441,11 @@ SDKNodeType *SDKNodeTypeWitness::getUnderlyingType() const {
440441
return getOnlyChild()->getAs<SDKNodeType>();
441442
}
442443

444+
StringRef SDKNodeTypeWitness::getWitnessedTypeName() const {
445+
return Ctx.buffer((llvm::Twine(getParent()->getAs<SDKNodeConformance>()->
446+
getName()) + "." + getName()).str());
447+
}
448+
443449
Optional<SDKNodeDeclType*> SDKNodeDeclType::getSuperclass() const {
444450
if (SuperclassUsr.empty())
445451
return None;

tools/swift-api-digester/ModuleAnalyzerNodes.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -499,6 +499,7 @@ class SDKNodeConformance: public SDKNode {
499499
class SDKNodeTypeWitness: public SDKNode {
500500
public:
501501
SDKNodeTypeWitness(SDKNodeInitInfo Info);
502+
StringRef getWitnessedTypeName() const;
502503
SDKNodeType *getUnderlyingType() const;
503504
static bool classof(const SDKNode *N);
504505
};

tools/swift-api-digester/ModuleDiagsConsumer.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ static StringRef getCategoryName(uint32_t ID) {
4949
case LocalDiagID::decl_type_change:
5050
case LocalDiagID::func_type_escaping_changed:
5151
case LocalDiagID::param_ownership_change:
52+
case LocalDiagID::type_witness_change:
5253
return "/* Type Changes */";
5354
case LocalDiagID::raw_type_change:
5455
return "/* RawRepresentable Changes */";

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -859,7 +859,21 @@ void swift::ide::api::SDKNodeType::diagnose(SDKNode *Right) {
859859
if (!RT || !shouldDiagnoseType(this))
860860
return;
861861
assert(isTopLevelType());
862+
863+
// Diagnose type witness changes when diagnosing ABI breakages.
864+
if (auto *Wit = dyn_cast<SDKNodeTypeWitness>(getParent())) {
865+
auto *Conform = Wit->getParent()->getAs<SDKNodeConformance>();
866+
if (Ctx.checkingABI() && getPrintedName() != RT->getPrintedName()) {
867+
Diags.diagnose(SourceLoc(), diag::type_witness_change,
868+
Conform->getNominalTypeDecl()->getScreenInfo(),
869+
Wit->getWitnessedTypeName(),
870+
getPrintedName(), RT->getPrintedName());
871+
}
872+
return;
873+
}
874+
862875
StringRef Descriptor = getTypeRoleDescription();
876+
assert(isa<SDKNodeDecl>(getParent()));
863877
auto LParent = cast<SDKNodeDecl>(getParent());
864878
assert(LParent->getKind() == RT->getParent()->getAs<SDKNodeDecl>()->getKind());
865879

0 commit comments

Comments
 (0)