Skip to content

Commit ae71175

Browse files
authored
Merge pull request #75769 from DougGregor/deployment-gate-nondependent-marker-conformances
Deployment-gate treatment of protocols without witness tables as never-dependent
2 parents 906efcb + b81f23e commit ae71175

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
@@ -39,6 +39,7 @@
3939
#include "swift/AST/PrettyStackTrace.h"
4040
#include "swift/AST/SubstitutionMap.h"
4141
#include "swift/Basic/Assertions.h"
42+
#include "swift/Basic/Platform.h"
4243
#include "swift/ClangImporter/ClangModule.h"
4344
#include "swift/IRGen/Linking.h"
4445
#include "swift/SIL/SILDeclRef.h"
@@ -1032,6 +1033,29 @@ static bool isSynthesizedNonUnique(const RootProtocolConformance *conformance) {
10321033
return false;
10331034
}
10341035

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

10661090
auto assocProtocol = req.getProtocolDecl();
1067-
if (!Lowering::TypeConverter::protocolRequiresWitnessTable(assocProtocol))
1091+
if (!protocolCanHaveDependentConformance(assocProtocol))
10681092
continue;
10691093

10701094
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)