Skip to content

Commit a90e591

Browse files
committed
[ClangImporter] Wrap compositions with Sendable protocol into existentials
Resolves: #65730
1 parent 10541ef commit a90e591

5 files changed

+34
-5
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1916,7 +1916,13 @@ class GetSendableType :
19161916
auto composition =
19171917
ProtocolCompositionType::get(ctx, members, inverses, explicitAnyObject);
19181918

1919-
return { composition, true };
1919+
// If we started from a protocol or a composition we should already
1920+
// be in an existential context. Otherwise we'd have to wrap a new
1921+
// composition into an existential.
1922+
if (isa<ProtocolType>(ty) || isa<ProtocolCompositionType>(ty))
1923+
return {composition, true};
1924+
1925+
return {ExistentialType::get(composition), true};
19201926
}
19211927

19221928
/// Visitor action: Recurse into the children of this type and try to add

test/Concurrency/sendable_objc_attr_in_type_context_swift5.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void doSomethingConcurrently(__attribute__((noescape)) void SWIFT_SENDABLE (^blo
5858
@end
5959

6060
@protocol InnerSendableTypes
61+
-(void) testComposition:(SWIFT_SENDABLE MyValue *)composition;
6162
-(void) test:(NSDictionary<NSString *, SWIFT_SENDABLE id> *)options;
6263
-(void) testWithCallback:(NSString *)name handler:(MAIN_ACTOR void (^)(NSDictionary<NSString *, SWIFT_SENDABLE id> *, NSError * _Nullable))handler;
6364
@end
@@ -109,6 +110,10 @@ func test_sendable_attr_in_type_context(test: Test) {
109110
}
110111

111112
class TestConformanceWithStripping : InnerSendableTypes {
113+
func testComposition(_: MyValue) {
114+
// expected-warning@-1 {{sendability of function types in instance method 'testComposition' does not match requirement in protocol 'InnerSendableTypes'; this is an error in the Swift 6 language mode}}
115+
}
116+
112117
func test(_ options: [String: Any]) {
113118
// expected-warning@-1 {{sendability of function types in instance method 'test' does not match requirement in protocol 'InnerSendableTypes'; this is an error in the Swift 6 language mode}}
114119
}
@@ -119,6 +124,9 @@ class TestConformanceWithStripping : InnerSendableTypes {
119124
}
120125

121126
class TestConformanceWithoutStripping : InnerSendableTypes {
127+
func testComposition(_: any MyValue & Sendable) { // Ok
128+
}
129+
122130
func test(_ options: [String: any Sendable]) { // Ok
123131
}
124132

test/Concurrency/sendable_objc_attr_in_type_context_swift5_strict.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ void doSomethingConcurrently(__attribute__((noescape)) void SWIFT_SENDABLE (^blo
5959
@end
6060

6161
@protocol InnerSendableTypes
62+
-(void) testComposition:(SWIFT_SENDABLE MyValue *)composition;
6263
-(void) test:(NSDictionary<NSString *, SWIFT_SENDABLE id> *)options;
6364
-(void) testWithCallback:(NSString *)name handler:(MAIN_ACTOR void (^)(NSDictionary<NSString *, SWIFT_SENDABLE id> *, NSError * _Nullable))handler;
6465
@end
@@ -116,6 +117,10 @@ func test_sendable_attr_in_type_context(test: Test) {
116117
class TestConformanceWithStripping : InnerSendableTypes {
117118
// expected-error@-1 {{type 'TestConformanceWithStripping' does not conform to protocol 'InnerSendableTypes'}}
118119

120+
func testComposition(_: MyValue) {
121+
// expected-note@-1 {{candidate has non-matching type '(MyValue) -> ()'}}
122+
}
123+
119124
func test(_ options: [String: Any]) {
120125
// expected-note@-1 {{candidate has non-matching type '([String : Any]) -> ()'}}
121126
}
@@ -126,6 +131,9 @@ class TestConformanceWithStripping : InnerSendableTypes {
126131
}
127132

128133
class TestConformanceWithoutStripping : InnerSendableTypes {
134+
func testComposition(_: MyValue & Sendable) { // Ok
135+
}
136+
129137
func test(_ options: [String: any Sendable]) { // Ok
130138
}
131139

test/Concurrency/sendable_objc_attr_in_type_context_swift6.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,7 @@ void doSomethingConcurrently(__attribute__((noescape)) void SWIFT_SENDABLE (^blo
5858
@end
5959

6060
@protocol InnerSendableTypes
61+
-(void) testComposition:(SWIFT_SENDABLE MyValue *)composition;
6162
-(void) test:(NSDictionary<NSString *, SWIFT_SENDABLE id> *)options;
6263
-(void) testWithCallback:(NSString *)name handler:(MAIN_ACTOR void (^)(NSDictionary<NSString *, SWIFT_SENDABLE id> *, NSError * _Nullable))handler;
6364
@end
@@ -115,6 +116,10 @@ func test_sendable_attr_in_type_context(test: Test) {
115116
class TestConformanceWithStripping : InnerSendableTypes {
116117
// expected-error@-1 {{type 'TestConformanceWithStripping' does not conform to protocol 'InnerSendableTypes'}}
117118

119+
func testComposition(_: MyValue) {
120+
// expected-note@-1 {{candidate has non-matching type '(MyValue) -> ()'}}
121+
}
122+
118123
func test(_ options: [String: Any]) {
119124
// expected-note@-1 {{candidate has non-matching type '([String : Any]) -> ()'}}
120125
}
@@ -125,6 +130,9 @@ class TestConformanceWithStripping : InnerSendableTypes {
125130
}
126131

127132
class TestConformanceWithoutStripping : InnerSendableTypes {
133+
func testComposition(_: any MyValue & Sendable) { // Ok
134+
}
135+
128136
func test(_ options: [String: any Sendable]) { // Ok
129137
}
130138

test/IDE/print_clang_objc_async.swift

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,13 +129,12 @@ import _Concurrency
129129
// CHECK-LABEL: class NXSender :
130130
// CHECK: func sendAny(_ obj: any Sendable) -> any Sendable
131131
// CHECK: func sendOptionalAny(_ obj: (any Sendable)?) -> (any Sendable)?
132-
// FIXME(https://github.com/apple/swift/issues/65730): Compositions not wrappped in existentials
133-
// CHECK: func sendSendable(_ sendable: SendableClass & Sendable) -> SendableClass & Sendable
134-
// CHECK: func sendSendableSubclasses(_ sendableSubclass: NonSendableClass & Sendable) -> NonSendableClass & Sendable
132+
// CHECK: func sendSendable(_ sendable: any SendableClass & Sendable) -> any SendableClass & Sendable
133+
// CHECK: func sendSendableSubclasses(_ sendableSubclass: any NonSendableClass & Sendable) -> any NonSendableClass & Sendable
135134
// CHECK: func sendProto(_ obj: any LabellyProtocol & Sendable) -> any LabellyProtocol & Sendable
136135
// CHECK: func sendProtos(_ obj: any LabellyProtocol & ObjCClub & Sendable) -> any LabellyProtocol & ObjCClub & Sendable
137136
// CHECK: func sendAnyArray(_ array: [any Sendable]) -> [any Sendable]
138-
// CHECK: func sendGeneric(_ generic: GenericObject<SendableClass> & Sendable) -> GenericObject<SendableClass> & Sendable
137+
// CHECK: func sendGeneric(_ generic: any GenericObject<SendableClass> & Sendable) -> any GenericObject<SendableClass> & Sendable
139138
// CHECK: func sendPtr(_ val: UnsafeMutableRawPointer) -> UnsafeMutableRawPointer
140139
// CHECK: func sendStringArray(_ obj: [String]) -> [String]
141140
// CHECK: func sendAnyTypedef(_ obj: any Sendable) -> any Sendable

0 commit comments

Comments
 (0)