Skip to content

Commit 1401510

Browse files
authored
Merge pull request #76707 from DougGregor/sendable-conformance-evolution-old-deployment
Use "resilient conformance" logic for deciding protocol dependencies involving Sendable
2 parents 6d78955 + 624570d commit 1401510

File tree

3 files changed

+44
-7
lines changed

3 files changed

+44
-7
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -959,8 +959,13 @@ namespace {
959959

960960
/// Return true if the witness table requires runtime instantiation to
961961
/// handle resiliently-added requirements with default implementations.
962+
///
963+
/// If disableOptimizations is true, skip optimizations that treat
964+
/// formally-resilient conformances as non-resilient.
962965
bool IRGenModule::isResilientConformance(
963-
const NormalProtocolConformance *conformance) {
966+
const NormalProtocolConformance *conformance,
967+
bool disableOptimizations
968+
) {
964969
// If the protocol is not resilient, the conformance is not resilient
965970
// either.
966971
bool shouldTreatProtocolNonResilient =
@@ -992,16 +997,18 @@ bool IRGenModule::isResilientConformance(
992997
// This is an optimization -- a conformance of a non-generic type cannot
993998
// resiliently become dependent.
994999
if (!conformance->getDeclContext()->isGenericContext() &&
995-
conformanceModule == conformance->getProtocol()->getParentModule())
1000+
conformanceModule == conformance->getProtocol()->getParentModule() &&
1001+
!disableOptimizations)
9961002
return false;
9971003

9981004
// We have a resilient conformance.
9991005
return true;
10001006
}
10011007

1002-
bool IRGenModule::isResilientConformance(const RootProtocolConformance *root) {
1008+
bool IRGenModule::isResilientConformance(const RootProtocolConformance *root,
1009+
bool disableOptimizations) {
10031010
if (auto normal = dyn_cast<NormalProtocolConformance>(root))
1004-
return isResilientConformance(normal);
1011+
return isResilientConformance(normal, disableOptimizations);
10051012
// Self-conformances never require this.
10061013
return false;
10071014
}
@@ -1185,7 +1192,9 @@ bool IRGenModule::isDependentConformance(
11851192
const RootProtocolConformance *conformance) {
11861193
llvm::SmallPtrSet<const NormalProtocolConformance *, 4> visited;
11871194
return ::isDependentConformance(
1188-
*this, conformance, conformance->getProtocol()->isResilient(), visited);
1195+
*this, conformance,
1196+
isResilientConformance(conformance, /*disableOptimizations=*/true),
1197+
visited);
11891198
}
11901199

11911200
static llvm::Value *

lib/IRGen/IRGenModule.h

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1119,8 +1119,10 @@ class IRGenModule {
11191119

11201120
TypeExpansionContext getMaximalTypeExpansionContext() const;
11211121

1122-
bool isResilientConformance(const NormalProtocolConformance *conformance);
1123-
bool isResilientConformance(const RootProtocolConformance *root);
1122+
bool isResilientConformance(const NormalProtocolConformance *conformance,
1123+
bool disableOptimizations = false);
1124+
bool isResilientConformance(const RootProtocolConformance *root,
1125+
bool disableOptimizations = false);
11241126
bool isDependentConformance(const RootProtocolConformance *conformance);
11251127

11261128
Alignment getCappedAlignment(Alignment alignment);

test/IRGen/protocol_resilience_sendable.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,37 @@
66
// RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos14.0 | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-BEFORE
77
// RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos15.0 | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-AFTER
88

9+
// RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos14.0 -enable-library-evolution | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-BEFORE
10+
// RUN: %target-swift-frontend -I %t -emit-ir %s -target %target-cpu-apple-macos15.0 -enable-library-evolution | %FileCheck %s -DINT=i%target-ptrsize -check-prefix=CHECK-USAGE -check-prefix=CHECK-USAGE-AFTER
11+
912
// REQUIRES: OS=macosx
1013

1114
import resilient_protocol
1215
import non_resilient_protocol
1316

17+
// CHECK-USAGE: @"$s28protocol_resilience_sendable9LocalTypeVAA0D11SubProtocolAAWP" = hidden constant [3 x ptr] [
18+
// CHECK-USAGE-SAME: ptr @"$s28protocol_resilience_sendable9LocalTypeVAA0D11SubProtocolAAMc",
19+
// CHECK-USAGE-SAME: ptr @"$s28protocol_resilience_sendable9LocalTypeVAA0D8ProtocolAAWP",
20+
// CHECK-USAGE-SAME: ptr @"$s28protocol_resilience_sendable9LocalTypeVAA0D11SubProtocolA2aDP9subMethodyyFTW"
21+
public protocol LocalProtocol: Sendable {
22+
func method()
23+
}
24+
25+
protocol LocalSubProtocol: Sendable, LocalProtocol {
26+
func subMethod()
27+
}
28+
29+
struct LocalType: Sendable, LocalSubProtocol {
30+
func method() { }
31+
func subMethod() { }
32+
}
33+
34+
func acceptLocalProtocol<T: LocalProtocol>(_: T.Type) { }
35+
func testLocalType() {
36+
acceptLocalProtocol(LocalType.self)
37+
}
38+
39+
1440
func acceptResilientSendableBase<T: ResilientSendableBase>(_: T.Type) { }
1541

1642
// CHECK-USAGE: define{{.*}}swiftcc void @"$s28protocol_resilience_sendable25passResilientSendableBaseyyF"()

0 commit comments

Comments
 (0)