mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[ParseableInterface] Don't print conformances from other modules (#20657)
...even if they're depended on by protocols we conform to.
This commit is contained in:
@@ -17,6 +17,7 @@
|
||||
#include "swift/AST/ExistentialLayout.h"
|
||||
#include "swift/AST/FileSystem.h"
|
||||
#include "swift/AST/Module.h"
|
||||
#include "swift/AST/ProtocolConformance.h"
|
||||
#include "swift/Frontend/Frontend.h"
|
||||
#include "swift/Frontend/ParseableInterfaceSupport.h"
|
||||
#include "swift/Frontend/PrintingDiagnosticConsumer.h"
|
||||
@@ -657,12 +658,26 @@ public:
|
||||
// No recursion here because extensions are never nested.
|
||||
}
|
||||
|
||||
/// Returns true if the conformance of \p nominal to \p proto is declared in
|
||||
/// module \p M.
|
||||
static bool conformanceDeclaredInModule(ModuleDecl *M,
|
||||
const NominalTypeDecl *nominal,
|
||||
ProtocolDecl *proto) {
|
||||
SmallVector<ProtocolConformance *, 4> conformances;
|
||||
nominal->lookupConformance(M, proto, conformances);
|
||||
return llvm::all_of(conformances,
|
||||
[M](const ProtocolConformance *conformance) -> bool {
|
||||
return M == conformance->getDeclContext()->getParentModule();
|
||||
});
|
||||
}
|
||||
|
||||
/// If there were any public protocols that need to be printed (i.e. they
|
||||
/// weren't conformed to explicitly or inherited by another printed protocol),
|
||||
/// do so now by printing a dummy extension on \p nominal to \p out.
|
||||
void
|
||||
printSynthesizedExtensionIfNeeded(raw_ostream &out,
|
||||
const PrintOptions &printOptions,
|
||||
ModuleDecl *M,
|
||||
const NominalTypeDecl *nominal) const {
|
||||
if (ExtraProtocols.empty())
|
||||
return;
|
||||
@@ -688,10 +703,13 @@ public:
|
||||
[&](ProtocolDecl *inherited) -> TypeWalker::Action {
|
||||
if (!handledProtocols.insert(inherited).second)
|
||||
return TypeWalker::Action::SkipChildren;
|
||||
if (isPublicOrUsableFromInline(inherited)) {
|
||||
|
||||
if (isPublicOrUsableFromInline(inherited) &&
|
||||
conformanceDeclaredInModule(M, nominal, inherited)) {
|
||||
protocolsToPrint.push_back(inherited);
|
||||
return TypeWalker::Action::SkipChildren;
|
||||
}
|
||||
|
||||
return TypeWalker::Action::Continue;
|
||||
});
|
||||
}
|
||||
@@ -775,7 +793,7 @@ bool swift::emitParseableInterface(raw_ostream &out,
|
||||
for (const auto &nominalAndCollector : inheritedProtocolMap) {
|
||||
const NominalTypeDecl *nominal = nominalAndCollector.first;
|
||||
const InheritedProtocolCollector &collector = nominalAndCollector.second;
|
||||
collector.printSynthesizedExtensionIfNeeded(out, printOptions, nominal);
|
||||
collector.printSynthesizedExtensionIfNeeded(out, printOptions, M, nominal);
|
||||
needDummyProtocolDeclaration |=
|
||||
collector.printInaccessibleConformanceExtensionIfNeeded(out,
|
||||
printOptions,
|
||||
|
||||
@@ -167,6 +167,7 @@ extension MultiGeneric: PublicProto where U: PrivateProto {}
|
||||
// CHECK: public struct MultiGeneric<T, U, V> {
|
||||
// CHECK-END: extension conformances.MultiGeneric : PublicProto where T : _ConstraintThatIsNotPartOfTheAPIOfThisLibrary {}
|
||||
|
||||
|
||||
internal struct InternalImpl_BAD: PrivateSubProto {}
|
||||
internal struct InternalImplConstrained_BAD<T> {}
|
||||
extension InternalImplConstrained_BAD: PublicProto where T: PublicProto {}
|
||||
@@ -182,5 +183,12 @@ extension WrapperForInternal.InternalImplConstrained_BAD: PublicProto where T: P
|
||||
extension WrapperForInternal.InternalImplConstrained2_BAD: PublicProto where T: PrivateProto {}
|
||||
|
||||
|
||||
internal protocol ExtraHashable: Hashable {}
|
||||
extension Bool: ExtraHashable {}
|
||||
|
||||
// NEGATIVE-NOT: extension {{(Swift.)?}}Bool{{.+}}Hashable
|
||||
// NEGATIVE-NOT: extension {{(Swift.)?}}Bool{{.+}}Equatable
|
||||
|
||||
|
||||
// CHECK-END: @usableFromInline
|
||||
// CHECK-END-NEXT: internal protocol _ConstraintThatIsNotPartOfTheAPIOfThisLibrary {}
|
||||
|
||||
Reference in New Issue
Block a user