Skip to content

Commit 1406b28

Browse files
committed
[Concurrency] Consider the upcoming feature flags in the originating module when
applying `@Sendable` inference for global-actor-isolated function types. Otherwise, for libraries that do not enable `GlobalActorIsolatedTypesUsability`, clients that do will encounter mangling mismatches for any library APIs that have global-actor-isolated function types that are not explicitly `@Sendable`.
1 parent 9c868f8 commit 1406b28

8 files changed

+18
-19
lines changed

lib/AST/Type.cpp

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3894,11 +3894,6 @@ Type AnyFunctionType::getThrownError() const {
38943894
}
38953895

38963896
bool AnyFunctionType::isSendable() const {
3897-
auto &ctx = getASTContext();
3898-
if (ctx.LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability)) {
3899-
// Global-actor-isolated function types are implicitly Sendable.
3900-
return getExtInfo().isSendable() || getIsolation().isGlobalActor();
3901-
}
39023897
return getExtInfo().isSendable();
39033898
}
39043899

lib/ClangImporter/ImportType.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,8 +1695,7 @@ void swift::getConcurrencyAttrs(ASTContext &SwiftContext,
16951695
findSwiftAttributes(type, [&](const clang::SwiftAttrAttr *attr) {
16961696
if (isMainActorAttr(attr)) {
16971697
isMainActor = true;
1698-
isNonSendable = importKind == ImportTypeKind::Parameter ||
1699-
importKind == ImportTypeKind::CompletionHandlerParameter;
1698+
isSendable = true; // MainActor implies Sendable
17001699
} else if (attr->getAttribute() == "@Sendable")
17011700
isSendable = true;
17021701
else if (attr->getAttribute() == "@_nonSendable")

lib/Sema/CSGen.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,6 +2587,10 @@ namespace {
25872587
return FunctionTypeIsolation::forNonIsolated();
25882588
}();
25892589
extInfo = extInfo.withIsolation(isolation);
2590+
if (isolation.isGlobalActor() &&
2591+
CS.getASTContext().LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability)) {
2592+
extInfo = extInfo.withSendable();
2593+
}
25902594

25912595
auto *fnTy = FunctionType::get(closureParams, resultTy, extInfo);
25922596
return CS.replaceInferableTypesWithTypeVars(

lib/Sema/TypeCheckType.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3920,6 +3920,10 @@ NeverNullType TypeResolver::resolveASTFunctionType(
39203920
globalActorAttr->setInvalid();
39213921
} else {
39223922
isolation = FunctionTypeIsolation::forGlobalActor(globalActor);
3923+
3924+
// This inference is currently gated because `@Sendable` impacts mangling.
3925+
if (ctx.LangOpts.hasFeature(Feature::GlobalActorIsolatedTypesUsability))
3926+
sendable = true;
39233927
}
39243928
}
39253929

test/Concurrency/predates_concurrency_swift6.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,29 +25,29 @@ struct X {
2525

2626
func testInAsync(x: X) async {
2727
let _: Int = unsafelySendableClosure // expected-error{{type '@Sendable (@Sendable () -> Void) -> ()'}}
28-
let _: Int = unsafelyMainActorClosure // expected-error{{type '@Sendable (@MainActor () -> Void) -> ()'}}
28+
let _: Int = unsafelyMainActorClosure // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
2929
let _: Int = unsafelyDoEverythingClosure // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
3030
let _: Int = x.unsafelyDoEverythingClosure // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
3131
let _: Int = X.unsafelyDoEverythingClosure // expected-error{{type '@Sendable (X) -> @Sendable (@MainActor @Sendable () -> Void) -> ()'}}
3232
let _: Int = (X.unsafelyDoEverythingClosure)(x) // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
3333

3434
let _: Int = x.sendableVar // expected-error{{type '@Sendable () -> Void'}}
35-
let _: Int = x.mainActorVar // expected-error{{type '@MainActor () -> Void'}}
35+
let _: Int = x.mainActorVar // expected-error{{type '@MainActor @Sendable () -> Void'}}
3636

3737
let _: Int = x[{ onMainActor() }] // expected-error{{type '@Sendable () -> Void'}}
3838
let _: Int = X[statically: { onMainActor() }] // expected-error{{type '@Sendable () -> Void'}}
3939
}
4040

4141
func testElsewhere(x: X) {
4242
let _: Int = unsafelySendableClosure // expected-error{{type '@Sendable (@Sendable () -> Void) -> ()'}}
43-
let _: Int = unsafelyMainActorClosure // expected-error{{type '@Sendable (@MainActor () -> Void) -> ()'}}
43+
let _: Int = unsafelyMainActorClosure // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
4444
let _: Int = unsafelyDoEverythingClosure // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
4545
let _: Int = x.unsafelyDoEverythingClosure // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
4646
let _: Int = X.unsafelyDoEverythingClosure // expected-error{{type '@Sendable (X) -> @Sendable (@MainActor @Sendable () -> Void) -> ()'}}
4747
let _: Int = (X.unsafelyDoEverythingClosure)(x) // expected-error{{type '@Sendable (@MainActor @Sendable () -> Void) -> ()'}}
4848

4949
let _: Int = x.sendableVar // expected-error{{type '@Sendable () -> Void'}}
50-
let _: Int = x.mainActorVar // expected-error{{type '@MainActor () -> Void'}}
50+
let _: Int = x.mainActorVar // expected-error{{type '@MainActor @Sendable () -> Void'}}
5151

5252
let _: Int = x[{ onMainActor() }] // expected-error{{type '@Sendable () -> Void'}}
5353
let _: Int = X[statically: { onMainActor() }] // expected-error{{type '@Sendable () -> Void'}}

test/Concurrency/sendable_objc_attr_in_type_context_swift6.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -125,7 +125,7 @@ class TestConformanceWithStripping : InnerSendableTypes {
125125
}
126126

127127
func test(withCallback name: String, handler: @escaping @MainActor ([String : Any], (any Error)?) -> Void) {
128-
// expected-note@-1 {{candidate has non-matching type '(String, @escaping @MainActor ([String : Any], (any Error)?) -> Void) -> ()'}}
128+
// expected-note@-1 {{candidate has non-matching type '(String, @escaping @MainActor @Sendable ([String : Any], (any Error)?) -> Void) -> ()'}}
129129
}
130130
}
131131

test/Concurrency/transfernonsendable_global_actor_sending.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func useValue<T>(_ t: T) {}
2626
let ns = NonSendableKlass()
2727

2828
// Will be resolved once @MainActor is @Sendable
29-
Task.fakeInit { @MainActor in // expected-error {{main actor-isolated value of type '@MainActor () async -> ()' passed as a strongly transferred parameter}}
29+
Task.fakeInit { @MainActor in // expected-error {{main actor-isolated value of type '@MainActor @Sendable () async -> ()' passed as a strongly transferred parameter}}
3030
print(ns)
3131
}
3232

test/Concurrency/transfernonsendable_sending_params.swift

Lines changed: 3 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -358,20 +358,17 @@ func testTransferOtherParamTuple(_ x: sending Klass, y: (Klass, Klass)) async {
358358
func fakeInitOutside(operation: sending @escaping () async -> ()) {}
359359

360360
func taskIsolatedOutsideError(_ x: @escaping @MainActor () async -> ()) {
361-
fakeInitOutside(operation: x) // expected-warning {{sending 'x' risks causing data races}}
362-
// expected-note @-1 {{task-isolated 'x' is passed as a 'sending' parameter; Uses in callee may race with later task-isolated uses}}
361+
fakeInitOutside(operation: x) // okay; x is @Sendable
363362
}
364363

365364
@MainActor func actorIsolatedOutsideError(_ x: @escaping @MainActor () async -> ()) {
366-
fakeInitOutside(operation: x) // expected-warning {{sending 'x' risks causing data races}}
367-
// expected-note @-1 {{main actor-isolated 'x' is passed as a 'sending' parameter; Uses in callee may race with later main actor-isolated uses}}
365+
fakeInitOutside(operation: x) // okay; x is @Sendable
368366
}
369367

370368
func taskIsolatedInsideError(_ x: @escaping @MainActor () async -> ()) {
371369
func fakeInit(operation: sending @escaping () async -> ()) {}
372370

373-
fakeInit(operation: x) // expected-warning {{sending 'x' risks causing data races}}
374-
// expected-note @-1 {{task-isolated 'x' is passed as a 'sending' parameter; Uses in callee may race with later task-isolated uses}}
371+
fakeInit(operation: x) // okay; x is @Sendable
375372
}
376373

377374
@MainActor func actorIsolatedInsideError(_ x: @escaping @MainActor () async -> ()) {

0 commit comments

Comments
 (0)