Skip to content

Commit 2537602

Browse files
committed
IRGen: keep emitting protocol witness table symbols for refactored protocols
When Protocol P and Struct S are in a same module and S conforms to P, the protocol witness table is emitted directly as a symbol. If we move P to a lower-level module, the protocol witness table symbol isn't emitted, breaking users' existing executable as a result. This change checks whether the protocol used to be defined in the same module and marks it as non-resilient if so. The compiler will continue emitting witness table as symbols to maintain cross-module ABI stability.
1 parent 93a83d3 commit 2537602

File tree

3 files changed

+17
-4
lines changed

3 files changed

+17
-4
lines changed

lib/AST/Decl.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3535,7 +3535,11 @@ bool NominalTypeDecl::isResilient(ModuleDecl *M,
35353535
case ResilienceExpansion::Minimal:
35363536
return isResilient();
35373537
case ResilienceExpansion::Maximal:
3538-
return M != getModuleContext() && isResilient();
3538+
// We consider this decl belongs to the module either it's currently
3539+
// defined in this module or it's originally defined in this module, which
3540+
// is specified by @_originallyDefinedIn
3541+
return M != getModuleContext() &&
3542+
M->getName().str() != getAlternateModuleName() && isResilient();
35393543
}
35403544
llvm_unreachable("bad resilience expansion");
35413545
}

lib/IRGen/GenProto.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -828,6 +828,15 @@ bool IRGenModule::isResilientConformance(
828828
conformanceModule == conformance->getProtocol()->getParentModule())
829829
return false;
830830

831+
// If the protocol WAS from the current module (@_originallyDefinedIn), we
832+
// consider the conformance non-resilient, because we used to consider it
833+
// non-resilient before the symbol moved. This is to ensure ABI stability
834+
// across module boundaries.
835+
if (conformanceModule == getSwiftModule() &&
836+
conformanceModule->getName().str() ==
837+
conformance->getProtocol()->getAlternateModuleName())
838+
return false;
839+
831840
// If the protocol and the conformance are in the same module and the
832841
// conforming type is not generic, they're not resilient.
833842
//

test/attr/attr_originally_definedin_backward_compatibility.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
// RUN: mkdir -p %t/SDK/Frameworks/HighLevel.framework/Modules/HighLevel.swiftmodule
1212
// RUN: %target-build-swift-dylib(%t/SDK/Frameworks/HighLevel.framework/HighLevel) -module-name HighLevel -emit-module \
1313
// RUN: -emit-module-path %t/SDK/Frameworks/HighLevel.framework/Modules/HighLevel.swiftmodule/%module-target-triple.swiftmodule \
14-
// RUN: %S/Inputs/SymbolMove/HighLevelOriginal.swift -Xlinker -install_name -Xlinker @rpath/HighLevel.framework/HighLevel
14+
// RUN: %S/Inputs/SymbolMove/HighLevelOriginal.swift -Xlinker -install_name -Xlinker @rpath/HighLevel.framework/HighLevel -enable-library-evolution
1515

1616
// --- Build an executable using the original high level framework
1717
// RUN: %target-build-swift -emit-executable %s -g -o %t/HighlevelRunner -F %t/SDK/Frameworks/ -framework HighLevel \
@@ -24,13 +24,13 @@
2424
// RUN: mkdir -p %t/SDK/Frameworks/LowLevel.framework/Modules/LowLevel.swiftmodule
2525
// RUN: %target-build-swift-dylib(%t/SDK/Frameworks/LowLevel.framework/LowLevel) -module-name LowLevel -emit-module \
2626
// RUN: -emit-module-path %t/SDK/Frameworks/LowLevel.framework/Modules/LowLevel.swiftmodule/%module-target-triple.swiftmodule \
27-
// RUN: %S/Inputs/SymbolMove/LowLevel.swift -Xlinker -install_name -Xlinker @rpath/LowLevel.framework/LowLevel
27+
// RUN: %S/Inputs/SymbolMove/LowLevel.swift -Xlinker -install_name -Xlinker @rpath/LowLevel.framework/LowLevel -enable-library-evolution
2828

2929
// --- Build high level framework.
3030
// RUN: mkdir -p %t/SDK/Frameworks/HighLevel.framework/Modules/HighLevel.swiftmodule
3131
// RUN: %target-build-swift-dylib(%t/SDK/Frameworks/HighLevel.framework/HighLevel) -module-name HighLevel -emit-module \
3232
// RUN: -emit-module-path %t/SDK/Frameworks/HighLevel.framework/Modules/HighLevel.swiftmodule/%module-target-triple.swiftmodule \
33-
// RUN: %S/Inputs/SymbolMove/HighLevel.swift -F %t/SDK/Frameworks -Xlinker -reexport_framework -Xlinker LowLevel
33+
// RUN: %S/Inputs/SymbolMove/HighLevel.swift -F %t/SDK/Frameworks -Xlinker -reexport_framework -Xlinker LowLevel -enable-library-evolution
3434

3535
// --- Run the executable
3636
// RUN: %t/HighlevelRunner | %FileCheck %s -check-prefix=AFTER_MOVE

0 commit comments

Comments
 (0)