Skip to content

Commit 627e4f0

Browse files
committed
Properly print protocols that inherit marker protocols under $MarkerProtocol
1 parent aa139a1 commit 627e4f0

File tree

3 files changed

+55
-20
lines changed

3 files changed

+55
-20
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 41 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2409,21 +2409,10 @@ static bool usesFeatureAsyncAwait(Decl *decl) {
24092409
}
24102410

24112411
static bool usesFeatureMarkerProtocol(Decl *decl) {
2412-
if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
2413-
if (proto->isMarkerProtocol())
2414-
return true;
2415-
}
2416-
2417-
if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
2418-
for (const auto &req: ext->getGenericRequirements()) {
2419-
if (req.getKind() == RequirementKind::Conformance &&
2420-
req.getSecondType()->castTo<ProtocolType>()->getDecl()
2421-
->isMarkerProtocol())
2422-
return true;
2423-
}
2424-
2425-
for (const auto &inherited : ext->getInherited()) {
2426-
if (auto inheritedType = inherited.getType()) {
2412+
// Check an inheritance clause for a marker protocol.
2413+
auto checkInherited = [&](ArrayRef<TypeLoc> inherited) -> bool {
2414+
for (const auto &inheritedEntry : inherited) {
2415+
if (auto inheritedType = inheritedEntry.getType()) {
24272416
if (inheritedType->isExistentialType()) {
24282417
auto layout = inheritedType->getExistentialLayout();
24292418
for (ProtocolType *protoTy : layout.getProtocols()) {
@@ -2433,6 +2422,39 @@ static bool usesFeatureMarkerProtocol(Decl *decl) {
24332422
}
24342423
}
24352424
}
2425+
2426+
return false;
2427+
};
2428+
2429+
// Check generic requirements for a marker protocol.
2430+
auto checkRequirements = [&](ArrayRef<Requirement> requirements) -> bool {
2431+
for (const auto &req: requirements) {
2432+
if (req.getKind() == RequirementKind::Conformance &&
2433+
req.getSecondType()->castTo<ProtocolType>()->getDecl()
2434+
->isMarkerProtocol())
2435+
return true;
2436+
}
2437+
2438+
return false;
2439+
};
2440+
2441+
if (auto proto = dyn_cast<ProtocolDecl>(decl)) {
2442+
if (proto->isMarkerProtocol())
2443+
return true;
2444+
2445+
if (checkInherited(proto->getInherited()))
2446+
return true;
2447+
2448+
if (checkRequirements(proto->getRequirementSignature()))
2449+
return true;
2450+
}
2451+
2452+
if (auto ext = dyn_cast<ExtensionDecl>(decl)) {
2453+
if (checkRequirements(ext->getGenericRequirements()))
2454+
return true;
2455+
2456+
if (checkInherited(ext->getInherited()))
2457+
return true;
24362458
}
24372459

24382460
return false;
@@ -5377,9 +5399,10 @@ swift::getInheritedForPrinting(const Decl *decl, const PrintOptions &options,
53775399
return true;
53785400

53795401
if (auto PD = dyn_cast<ProtocolDecl>(NTD)) {
5380-
// Marker protocols are unprintable on nominal types, but they're
5381-
// okay on extension declarations.
5382-
if (PD->isMarkerProtocol() && !isa<ExtensionDecl>(decl))
5402+
// Marker protocols are unprintable on concrete types, but they're
5403+
// okay on extension declarations and protocols.
5404+
if (PD->isMarkerProtocol() && !isa<ExtensionDecl>(decl) &&
5405+
!isa<ProtocolDecl>(decl))
53835406
return true;
53845407
}
53855408
}

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -252,8 +252,8 @@ class InheritedProtocolCollector {
252252
if (!isPublicOrUsableFromInline(type))
253253
return false;
254254

255-
// Extensions can print marker protocols.
256-
if (isa<ExtensionDecl>(D))
255+
// Extensions and protocols can print marker protocols.
256+
if (isa<ExtensionDecl>(D) || isa<ProtocolDecl>(D))
257257
return true;
258258

259259
ExistentialLayout layout = type->getExistentialLayout();

test/ModuleInterface/features.swift

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,18 @@ public func globalAsync() async { }
3131
// CHECK-NEXT: public protocol MP
3232
@_marker public protocol MP { }
3333

34+
// CHECK: #if compiler(>=5.3) && $MarkerProtocol
35+
// CHECK-NEXT: @_marker public protocol MP2 : FeatureTest.MP {
36+
// CHECK-NEXT: }
37+
// CHECK-NEXT: #endif
38+
@_marker public protocol MP2: MP { }
39+
40+
// CHECK: #if compiler(>=5.3) && $MarkerProtocol
41+
// CHECK-NEXT: public protocol MP3
42+
// CHECK-NEXT: }
43+
public protocol MP3: MP { }
44+
// CHECK-NEXT: #endif
45+
3446
// CHECK: class OldSchool {
3547
public class OldSchool: MP {
3648
// CHECK: #if compiler(>=5.3) && $AsyncAwait

0 commit comments

Comments
 (0)