Skip to content

Commit def1cca

Browse files
committed
Don't print extensions to conform to protocols that aren't printed
Try a little harder to avoid printing empty extensions by seeing if any of the inherited protocols are actually going to be printed. Previously this just made things a little prettier, but with implementation-only imports it's a correctness issue, since there may be extensions of implementation-only types that do in fact conform to non-public protocols. rdar://problem/50748072
1 parent c622f6b commit def1cca

File tree

3 files changed

+23
-9
lines changed

3 files changed

+23
-9
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1618,7 +1618,9 @@ bool ShouldPrintChecker::shouldPrint(const Decl *D,
16181618
auto Ext = cast<ExtensionDecl>(D);
16191619
// If the extension doesn't add protocols or has no members that we should
16201620
// print then skip printing it.
1621-
if (Ext->getLocalProtocols().empty()) {
1621+
SmallVector<TypeLoc, 8> ProtocolsToPrint;
1622+
getInheritedForPrinting(Ext, Options, ProtocolsToPrint);
1623+
if (ProtocolsToPrint.empty()) {
16221624
bool HasMemberToPrint = false;
16231625
for (auto Member : Ext->getMembers()) {
16241626
if (shouldPrint(Member, Options)) {

lib/Frontend/ParseableInterfaceSupport.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -417,17 +417,17 @@ bool swift::emitParseableInterface(raw_ostream &out,
417417
SmallVector<Decl *, 16> topLevelDecls;
418418
M->getTopLevelDecls(topLevelDecls);
419419
for (const Decl *D : topLevelDecls) {
420+
InheritedProtocolCollector::collectProtocols(inheritedProtocolMap, D);
421+
420422
if (!D->shouldPrintInContext(printOptions) ||
421-
!printOptions.CurrentPrintabilityChecker->shouldPrint(D, printOptions)){
423+
!printOptions.shouldPrint(D)) {
422424
InheritedProtocolCollector::collectSkippedConditionalConformances(
423425
inheritedProtocolMap, D);
424426
continue;
425427
}
426428

427429
D->print(out, printOptions);
428430
out << "\n";
429-
430-
InheritedProtocolCollector::collectProtocols(inheritedProtocolMap, D);
431431
}
432432

433433
// Print dummy extensions for any protocols that were indirectly conformed to.

test/ParseableInterface/conformances.swift

Lines changed: 17 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public struct B2: PublicBaseProto, PrivateSubProto {}
5252
// CHECK-END: extension conformances.B3 : conformances.PublicBaseProto {}
5353
public struct B3: PublicBaseProto & PrivateSubProto {}
5454
// CHECK: public struct B4 : PublicBaseProto {
55-
// CHECK: extension B4 {
55+
// NEGATIVE-NOT: extension B4 {
5656
// NEGATIVE-NOT: extension conformances.B4
5757
public struct B4: PublicBaseProto {}
5858
extension B4: PrivateSubProto {}
@@ -62,15 +62,15 @@ extension B4: PrivateSubProto {}
6262
public struct B5: PrivateSubProto {}
6363
extension B5: PublicBaseProto {}
6464
// CHECK: public struct B6 {
65-
// CHECK: extension B6 {
65+
// NEGATIVE-NOT: extension B6 {
6666
// CHECK: extension B6 : PublicBaseProto {
6767
// NEGATIVE-NOT: extension conformances.B6
6868
public struct B6 {}
6969
extension B6: PrivateSubProto {}
7070
extension B6: PublicBaseProto {}
7171
// CHECK: public struct B7 {
7272
// CHECK: extension B7 : PublicBaseProto {
73-
// CHECK: extension B7 {
73+
// NEGATIVE-NOT: extension B7 {
7474
// NEGATIVE-NOT: extension conformances.B7
7575
public struct B7 {}
7676
extension B7: PublicBaseProto {}
@@ -107,7 +107,7 @@ public struct C1: PrivateSubProto, AnotherPrivateSubProto {}
107107
// CHECK-END: extension conformances.C2 : conformances.PublicBaseProto {}
108108
public struct C2: PrivateSubProto & AnotherPrivateSubProto {}
109109
// CHECK: public struct C3 {
110-
// CHECK: extension C3 {
110+
// NEGATIVE-NOT: extension C3 {
111111
// CHECK-END: extension conformances.C3 : conformances.PublicBaseProto {}
112112
public struct C3: PrivateSubProto {}
113113
extension C3: AnotherPrivateSubProto {}
@@ -135,7 +135,7 @@ public struct D4: APublicSubProto & PrivateSubProto {}
135135
public struct D5: PrivateSubProto {}
136136
extension D5: PublicSubProto {}
137137
// CHECK: public struct D6 : PublicSubProto {
138-
// CHECK: extension D6 {
138+
// NEGATIVE-NOT: extension D6 {
139139
// NEGATIVE-NOT: extension conformances.D6
140140
public struct D6: PublicSubProto {}
141141
extension D6: PrivateSubProto {}
@@ -212,6 +212,18 @@ extension VeryNewMacProto: PrivateSubProto {}
212212
// CHECK-END: @available(OSX, introduced: 10.98)
213213
// CHECK-END-NEXT: extension conformances.VeryNewMacProto : conformances.PublicBaseProto {}
214214

215+
public struct PrivateProtoConformer {}
216+
extension PrivateProtoConformer : PrivateProto {
217+
public var member: Int { return 0 }
218+
}
219+
// CHECK: public struct PrivateProtoConformer {
220+
// CHECK: extension PrivateProtoConformer {
221+
// CHECK-NEXT: public var member: Int {
222+
// CHECK-NEXT: get
223+
// CHECK-NEXT: }
224+
// CHECK-NEXT: {{^}$}}
225+
// NEGATIVE-NOT: extension conformances.PrivateProtoConformer
226+
215227
// NEGATIVE-NOT: extension {{(Swift.)?}}Bool{{.+}}Hashable
216228
// NEGATIVE-NOT: extension {{(Swift.)?}}Bool{{.+}}Equatable
217229

0 commit comments

Comments
 (0)