Skip to content

Commit c4a4b0d

Browse files
authored
Merge pull request #20058 from nkcsgexi/type-witness-diag
2 parents a4a8537 + 8c0495f commit c4a4b0d

File tree

9 files changed

+45
-15
lines changed

9 files changed

+45
-15
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 & 10 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

@@ -376,14 +377,6 @@ StringRef SDKNodeDecl::getScreenInfo() const {
376377
return Ctx.buffer(OS.str());
377378
}
378379

379-
bool SDKNodeDecl::isSDKPrivate() const {
380-
if (getName().startswith("__"))
381-
return true;
382-
if (auto *PD = dyn_cast<SDKNodeDecl>(getParent()))
383-
return PD->isSDKPrivate();
384-
return false;
385-
}
386-
387380
void SDKNodeDecl::printFullyQualifiedName(llvm::raw_ostream &OS) const {
388381
std::vector<NodePtr> Parent;
389382
for (auto *P = getParent(); isa<SDKNodeDecl>(P); P = P->getParent())
@@ -440,6 +433,11 @@ SDKNodeType *SDKNodeTypeWitness::getUnderlyingType() const {
440433
return getOnlyChild()->getAs<SDKNodeType>();
441434
}
442435

436+
StringRef SDKNodeTypeWitness::getWitnessedTypeName() const {
437+
return Ctx.buffer((llvm::Twine(getParent()->getAs<SDKNodeConformance>()->
438+
getName()) + "." + getName()).str());
439+
}
440+
443441
Optional<SDKNodeDeclType*> SDKNodeDeclType::getSuperclass() const {
444442
if (SuperclassUsr.empty())
445443
return None;

tools/swift-api-digester/ModuleAnalyzerNodes.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -320,7 +320,6 @@ class SDKNodeDecl: public SDKNode {
320320
DeclKind getDeclKind() const { return DKind; }
321321
void printFullyQualifiedName(llvm::raw_ostream &OS) const;
322322
StringRef getFullyQualifiedName() const;
323-
bool isSDKPrivate() const;
324323
bool isDeprecated() const { return IsDeprecated; };
325324
bool isProtocolRequirement() const { return IsProtocolReq; }
326325
bool hasDeclAttribute(DeclAttrKind DAKind) const;
@@ -499,6 +498,7 @@ class SDKNodeConformance: public SDKNode {
499498
class SDKNodeTypeWitness: public SDKNode {
500499
public:
501500
SDKNodeTypeWitness(SDKNodeInitInfo Info);
501+
StringRef getWitnessedTypeName() const;
502502
SDKNodeType *getUnderlyingType() const;
503503
static bool classof(const SDKNode *N);
504504
};

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: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -848,8 +848,7 @@ void swift::ide::api::SDKNodeDeclVar::diagnose(SDKNode *Right) {
848848
}
849849

850850
static bool shouldDiagnoseType(SDKNodeType *T) {
851-
return T->isTopLevelType() &&
852-
!cast<SDKNodeDecl>(T->getParent())->isSDKPrivate();
851+
return T->isTopLevelType();
853852
}
854853

855854
void swift::ide::api::SDKNodeType::diagnose(SDKNode *Right) {
@@ -859,7 +858,21 @@ void swift::ide::api::SDKNodeType::diagnose(SDKNode *Right) {
859858
if (!RT || !shouldDiagnoseType(this))
860859
return;
861860
assert(isTopLevelType());
861+
862+
// Diagnose type witness changes when diagnosing ABI breakages.
863+
if (auto *Wit = dyn_cast<SDKNodeTypeWitness>(getParent())) {
864+
auto *Conform = Wit->getParent()->getAs<SDKNodeConformance>();
865+
if (Ctx.checkingABI() && getPrintedName() != RT->getPrintedName()) {
866+
Diags.diagnose(SourceLoc(), diag::type_witness_change,
867+
Conform->getNominalTypeDecl()->getScreenInfo(),
868+
Wit->getWitnessedTypeName(),
869+
getPrintedName(), RT->getPrintedName());
870+
}
871+
return;
872+
}
873+
862874
StringRef Descriptor = getTypeRoleDescription();
875+
assert(isa<SDKNodeDecl>(getParent()));
863876
auto LParent = cast<SDKNodeDecl>(getParent());
864877
assert(LParent->getKind() == RT->getParent()->getAs<SDKNodeDecl>()->getKind());
865878

@@ -1900,8 +1913,6 @@ void DiagnosisEmitter::handle(const SDKNodeDecl *Node, NodeAnnotation Anno) {
19001913
}
19011914

19021915
void DiagnosisEmitter::visitDecl(SDKNodeDecl *Node) {
1903-
if (Node->isSDKPrivate())
1904-
return;
19051916
std::vector<NodeAnnotation> Scratch;
19061917
for (auto Anno : Node->getAnnotations(Scratch))
19071918
handle(Node, Anno);

0 commit comments

Comments
 (0)