Skip to content

Commit cad2df3

Browse files
committed
[Concurrency] Downgrade non-Sendable type captures to warnings if closure is in @preconcurrency context
The original check examined only the immediate closure, but it's possible that the closure happens to be in a preconcurrency context which also requires a downgrade. Resolves: rdar://148996589
1 parent 716ef96 commit cad2df3

File tree

3 files changed

+58
-2
lines changed

3 files changed

+58
-2
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2924,8 +2924,10 @@ namespace {
29242924
auto *explicitClosure = dyn_cast_or_null<ClosureExpr>(closure);
29252925

29262926
bool preconcurrency = false;
2927-
if (explicitClosure) {
2928-
preconcurrency = explicitClosure->isIsolatedByPreconcurrency();
2927+
if (closure) {
2928+
preconcurrency =
2929+
getActorIsolationOfContext(closure, getClosureActorIsolation)
2930+
.preconcurrency();
29292931
}
29302932

29312933
for (const auto &capture : localFunc.getCaptureInfo().getCaptures()) {

test/Concurrency/sendable_checking_captures_swift6.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,3 +50,31 @@ do {
5050
}
5151
}
5252
}
53+
54+
func use(_ closure: @autoclosure () -> Any) {
55+
}
56+
57+
do {
58+
class C {
59+
@preconcurrency static func f(_: @escaping @Sendable () -> Void) {}
60+
}
61+
62+
class SelfCapture { // expected-note 5 {{class 'SelfCapture' does not conform to the 'Sendable' protocol}}
63+
func fooDirect() {
64+
C.f {
65+
use(self)
66+
// expected-warning@-1 {{capture of 'self' with non-sendable type 'SelfCapture' in a '@Sendable' closure}}
67+
// expected-warning@-2 {{implicit capture of 'self' requires that 'SelfCapture' conforms to 'Sendable'}}
68+
}
69+
}
70+
71+
func fooThroughClosure() {
72+
C.f {
73+
{ use(self) }()
74+
// expected-warning@-1 {{capture of 'self' with non-sendable type 'SelfCapture' in a '@Sendable' closure}}
75+
// expected-warning@-2 {{capture of 'self' with non-sendable type 'SelfCapture' in an isolated closure}}
76+
// expected-warning@-3 {{implicit capture of 'self' requires that 'SelfCapture' conforms to 'Sendable'}}
77+
}
78+
}
79+
}
80+
}

test/Concurrency/sendable_objc_attr_in_type_context_swift6.swift

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,10 @@ void doSomethingConcurrently(__attribute__((noescape)) void SWIFT_SENDABLE (^blo
8686
-(void) testWithCompletion: (void (^)(void)) completion;
8787
@end
8888

89+
@interface TestSelfCapture : NSObject
90+
+ (void)doWithCompletion:(void(^)(void)) completion;
91+
@end
92+
8993
#pragma clang assume_nonnull end
9094

9195
//--- main.swift
@@ -219,3 +223,25 @@ extension TestDR {
219223
@_dynamicReplacement(for: test(completion:))
220224
func __replaceObjCFunc(_: @escaping () -> Void) {} // Ok
221225
}
226+
227+
class SelfCapture { // expected-note 5 {{class 'SelfCapture' does not conform to the 'Sendable' protocol}}
228+
static func use(_ closure: @autoclosure () -> Any) {
229+
}
230+
231+
func testDirect() {
232+
TestSelfCapture.do {
233+
Self.use(self)
234+
// expected-warning@-1 {{capture of 'self' with non-sendable type 'SelfCapture' in a '@Sendable' closure}}
235+
// expected-warning@-2 {{implicit capture of 'self' requires that 'SelfCapture' conforms to 'Sendable'}}
236+
}
237+
}
238+
239+
func testThroughClosure() {
240+
TestSelfCapture.do {
241+
let _ = { Self.use(self) }()
242+
// expected-warning@-1 {{capture of 'self' with non-sendable type 'SelfCapture' in a '@Sendable' closure}}
243+
// expected-warning@-2 {{capture of 'self' with non-sendable type 'SelfCapture' in an isolated closure}}
244+
// expected-warning@-3 {{implicit capture of 'self' requires that 'SelfCapture' conforms to 'Sendable'}}
245+
}
246+
}
247+
}

0 commit comments

Comments
 (0)