Skip to content

Relax @retroactive check to allow same-package declarations #73512

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
Jul 3, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 9 additions & 3 deletions lib/AST/ProtocolConformance.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -185,16 +185,22 @@ 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;
}

auto conformingTypeDecl =
ConformingType->getNominalOrBoundGenericNominal();
if (conformingTypeDecl) {
auto conformingTypeModule = conformingTypeDecl->getParentModule();
if (extensionModule->
isSameModuleLookingThroughOverlays(conformingTypeModule)) {
if (isSameRetroactiveContext(extensionModule, conformingTypeModule)) {
return false;
}
}
Expand Down
43 changes: 43 additions & 0 deletions test/Sema/extension_retroactive_conformances_package.swift
Original file line number Diff line number Diff line change
@@ -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 {}