Skip to content

Commit c7da857

Browse files
authored
Merge pull request #75770 from DougGregor/deployment-gate-nondependent-marker-conformances-6.0
[6.0] Deployment-gate treatment of protocols without witness tables as never-dependent
2 parents 7de7134 + 53d5254 commit c7da857

File tree

3 files changed

+62
-2
lines changed

3 files changed

+62
-2
lines changed

lib/IRGen/GenProto.cpp

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
#include "swift/AST/PackConformance.h"
3939
#include "swift/AST/PrettyStackTrace.h"
4040
#include "swift/AST/SubstitutionMap.h"
41+
#include "swift/Basic/Platform.h"
4142
#include "swift/ClangImporter/ClangModule.h"
4243
#include "swift/IRGen/Linking.h"
4344
#include "swift/SIL/SILDeclRef.h"
@@ -1028,6 +1029,29 @@ static bool isSynthesizedNonUnique(const RootProtocolConformance *conformance) {
10281029
return false;
10291030
}
10301031

1032+
/// Determine whether a protocol can ever have a dependent conformance.
1033+
static bool protocolCanHaveDependentConformance(ProtocolDecl *proto) {
1034+
// Objective-C protocols have never been able to have a dependent conformance.
1035+
if (proto->isObjC())
1036+
return false;
1037+
1038+
// Prior to Swift 6.0, only Objective-C protocols were never able to have
1039+
// a dependent conformance. This is overly pessimistic when the protocol
1040+
// is a marker protocol (since they don't have requirements), but we must
1041+
// retain backward compatibility with binaries built for earlier deployment
1042+
// targets that concluded that these protocols might involve dependent
1043+
// conformances.
1044+
ASTContext &ctx = proto->getASTContext();
1045+
if (auto runtimeCompatVersion = getSwiftRuntimeCompatibilityVersionForTarget(
1046+
ctx.LangOpts.Target)) {
1047+
if (runtimeCompatVersion < llvm::VersionTuple(6, 0) &&
1048+
proto->isSpecificProtocol(KnownProtocolKind::Sendable))
1049+
return true;
1050+
}
1051+
1052+
return Lowering::TypeConverter::protocolRequiresWitnessTable(proto);
1053+
}
1054+
10311055
static bool isDependentConformance(
10321056
IRGenModule &IGM,
10331057
const RootProtocolConformance *rootConformance,
@@ -1060,7 +1084,7 @@ static bool isDependentConformance(
10601084
continue;
10611085

10621086
auto assocProtocol = req.getProtocolDecl();
1063-
if (!Lowering::TypeConverter::protocolRequiresWitnessTable(assocProtocol))
1087+
if (!protocolCanHaveDependentConformance(assocProtocol))
10641088
continue;
10651089

10661090
auto assocConformance =
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-frontend -emit-module -enable-library-evolution -emit-module-path=%t/resilient_protocol.swiftmodule -module-name=resilient_protocol %S/../Inputs/resilient_protocol.swift
4+
5+
// 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
6+
// 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
7+
8+
// REQUIRES: OS=macosx
9+
10+
import resilient_protocol
11+
12+
func acceptResilientSendableBase<T: ResilientSendableBase>(_: T.Type) { }
13+
14+
// CHECK-USAGE: define{{.*}}swiftcc void @"$s28protocol_resilience_sendable25passResilientSendableBaseyyF"()
15+
func passResilientSendableBase() {
16+
// CHECK-USAGE-NOT: ret
17+
// CHECK-USAGE: [[METATYPE:%.*]] = extractvalue
18+
// CHECK-USAGE-BEFORE: [[WITNESS_TABLE:%.*]] = call ptr @"$s18resilient_protocol27ConformsToResilientSendableVAcA0eF4BaseAAWl"()
19+
// CHECK-USAGE-BEFORE-NEXT: call swiftcc void @"$s28protocol_resilience_sendable27acceptResilientSendableBaseyyxm010resilient_A00efG0RzlF"(ptr [[METATYPE]], ptr [[METATYPE]], ptr [[WITNESS_TABLE]])
20+
// CHECK-USAGE-AFTER-NEXT: call swiftcc void @"$s28protocol_resilience_sendable27acceptResilientSendableBaseyyxm010resilient_A00efG0RzlF"(ptr [[METATYPE]], ptr [[METATYPE]], ptr @"$s18resilient_protocol27ConformsToResilientSendableVAA0eF4BaseAAWP")
21+
acceptResilientSendableBase(ConformsToResilientSendable.self)
22+
}

test/Inputs/resilient_protocol.swift

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,4 +43,18 @@ public protocol ResilientSelfDefault : ResilientBaseProtocol {
4343

4444
@_fixed_layout public protocol OtherFrozenProtocol {
4545
func protocolMethod()
46-
}
46+
}
47+
48+
public protocol ResilientSendableBase: Sendable {
49+
func f()
50+
}
51+
52+
public protocol ResilientSendable: ResilientSendableBase {
53+
func g()
54+
}
55+
56+
57+
public struct ConformsToResilientSendable: ResilientSendable {
58+
public func f() { }
59+
public func g() { }
60+
}

0 commit comments

Comments
 (0)