diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp index ef50870285047..844edf81fddcc 100644 --- a/lib/AST/ProtocolConformance.cpp +++ b/lib/AST/ProtocolConformance.cpp @@ -184,7 +184,14 @@ usesDefaultDefinition(AssociatedTypeDecl *requirement) const { bool ProtocolConformance::isRetroactive() const { auto extensionModule = getDeclContext()->getParentModule(); auto protocolModule = getProtocol()->getParentModule(); - if (extensionModule->isSameModuleLookingThroughOverlays(protocolModule)) { + + auto isSameRetroactiveContext = + [](ModuleDecl *moduleA, ModuleDecl *moduleB) -> bool { + return moduleA->isSameModuleLookingThroughOverlays(moduleB) || + moduleA->inSamePackage(moduleB); + }; + + if (isSameRetroactiveContext(extensionModule, protocolModule)) { return false; } @@ -192,8 +199,7 @@ bool ProtocolConformance::isRetroactive() const { ConformingType->getNominalOrBoundGenericNominal(); if (conformingTypeDecl) { auto conformingTypeModule = conformingTypeDecl->getParentModule(); - if (extensionModule-> - isSameModuleLookingThroughOverlays(conformingTypeModule)) { + if (isSameRetroactiveContext(extensionModule, conformingTypeModule)) { return false; } } diff --git a/test/Sema/extension_retroactive_conformances_package.swift b/test/Sema/extension_retroactive_conformances_package.swift new file mode 100644 index 0000000000000..456b48bd93936 --- /dev/null +++ b/test/Sema/extension_retroactive_conformances_package.swift @@ -0,0 +1,43 @@ +// RUN: %empty-directory(%t) +// RUN: split-file %s %t + +// RUN: %target-swift-frontend -swift-version 5 %t/Library.swift -emit-module -module-name Library -o %t -package-name Library +// RUN: %target-swift-frontend -swift-version 5 %t/OtherLibrary.swift -emit-module -module-name OtherLibrary -o %t -package-name Library +// RUN: %target-swift-frontend -typecheck %t/Client.swift -module-name Client -verify -swift-version 5 -I %t -package-name Library + +//--- Library.swift + +public class LibraryClass {} +public protocol LibraryProtocol {} +package class PackageLibraryClass {} +package protocol PackageLibraryProtocol {} + +//--- OtherLibrary.swift + +public class OtherLibraryClass {} +public protocol OtherLibraryProtocol {} +package class PackageOtherLibraryClass {} +package protocol PackageOtherLibraryProtocol {} + +//--- Client.swift + +public import Library +public import OtherLibrary + +// These are all fine because all 3 of these modules are in the same package. + +extension LibraryClass: LibraryProtocol {} +extension OtherLibraryClass: LibraryProtocol {} +extension LibraryClass: OtherLibraryProtocol {} + +extension PackageLibraryClass: LibraryProtocol {} +extension PackageOtherLibraryClass: LibraryProtocol {} +extension PackageLibraryClass: OtherLibraryProtocol {} + +extension LibraryClass: PackageLibraryProtocol {} +extension OtherLibraryClass: PackageLibraryProtocol {} +extension LibraryClass: PackageOtherLibraryProtocol {} + +extension PackageLibraryClass: PackageLibraryProtocol {} +extension PackageOtherLibraryClass: PackageLibraryProtocol {} +extension PackageLibraryClass: PackageOtherLibraryProtocol {} \ No newline at end of file