Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
[ModuleInterface] Preserve SPI information for indirect conformances
rdar://73082943
  • Loading branch information
xymus committed Jan 26, 2021
1 parent f668c59 commit c76269e
Show file tree
Hide file tree
Showing 2 changed files with 15 additions and 1 deletion.
8 changes: 7 additions & 1 deletion lib/Frontend/ModuleInterfaceSupport.cpp
Expand Up @@ -452,6 +452,9 @@ class InheritedProtocolCollector {
inherited->isSpecificProtocol(KnownProtocolKind::Actor))
return TypeWalker::Action::Continue;

if (inherited->isSPI() && !printOptions.PrintSPIs)
return TypeWalker::Action::Continue;

if (isPublicOrUsableFromInline(inherited) &&
conformanceDeclaredInModule(M, nominal, inherited)) {
protocolsToPrint.push_back({inherited, protoAndAvailability.second});
Expand All @@ -466,17 +469,20 @@ class InheritedProtocolCollector {

for (const auto &protoAndAvailability : protocolsToPrint) {
StreamPrinter printer(out);
ProtocolDecl *proto = protoAndAvailability.first;

// FIXME: Shouldn't this be an implicit conversion?
TinyPtrVector<const DeclAttribute *> attrs;
attrs.insert(attrs.end(), protoAndAvailability.second.begin(),
protoAndAvailability.second.end());
auto spiAttributes = proto->getAttrs().getAttributes<SPIAccessControlAttr>();
attrs.insert(attrs.end(), spiAttributes.begin(), spiAttributes.end());
DeclAttributes::print(printer, printOptions, attrs);

printer << "extension ";
nominal->getDeclaredType().print(printer, printOptions);
printer << " : ";

ProtocolDecl *proto = protoAndAvailability.first;
proto->getDeclaredInterfaceType()->print(printer, printOptions);

printer << " {}\n";
Expand Down
8 changes: 8 additions & 0 deletions test/SPI/private_swiftinterface.swift
Expand Up @@ -200,3 +200,11 @@ extension IOIPublicStruct : LocalPublicProto {}
extension PublicType: SPIProto where T: PrivateConstraint {}
// CHECK-PRIVATE: extension {{.*}}.PublicType : {{.*}}.SPIProto where T : _ConstraintThatIsNotPartOfTheAPIOfThisLibrary
// CHECK-PUBLIC-NOT: _ConstraintThatIsNotPartOfTheAPIOfThisLibrary

// Preserve SPI information when printing indirect conformances via
// an internal protocol. rdar://73082943
@_spi(S) public protocol SPIProtocol {}
internal protocol InternalProtocol: SPIProtocol {}
public struct PublicStruct2: InternalProtocol {}
// CHECK-PRIVATE: @_spi(S) extension {{.*}}.PublicStruct2 : {{.*}}.SPIProtocol
// CHECK-PUBLIC-NOT: SPIProtocol

0 comments on commit c76269e

Please sign in to comment.