Skip to content

Commit 0505bcd

Browse files
committed
[CSApply] Don't inject global actor into closure type if it's marked as @concurrent
When the attribute is specified explicitly passing a `@concurrent` closure to a global actor-isolated parameter or contextual type should result in a conversion and closure itself should be nonisolated. Resolves: rdar://151797372
1 parent 98c3993 commit 0505bcd

File tree

2 files changed

+16
-4
lines changed

2 files changed

+16
-4
lines changed

lib/Sema/CSApply.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7731,11 +7731,13 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
77317731
}
77327732

77337733
// If we have a ClosureExpr, then we can safely propagate a global actor
7734-
// to the closure without invalidating prior analysis.
7734+
// to the closure if it's not explicitly marked as `@concurrent` without
7735+
// invalidating prior analysis.
77357736
fromEI = fromFunc->getExtInfo();
7736-
if (toEI.getGlobalActor() && !fromEI.getGlobalActor()) {
7737-
auto newFromFuncType = fromFunc->withExtInfo(
7738-
fromEI.withGlobalActor(toEI.getGlobalActor()));
7737+
if (toEI.getGlobalActor() && !fromEI.getGlobalActor() &&
7738+
!isClosureMarkedAsConcurrent(expr)) {
7739+
auto newFromFuncType =
7740+
fromFunc->withExtInfo(fromEI.withGlobalActor(toEI.getGlobalActor()));
77397741
if (applyTypeToClosureExpr(cs, expr, newFromFuncType)) {
77407742
fromFunc = newFromFuncType->castTo<FunctionType>();
77417743

test/Concurrency/attr_execution/conversions_silgen.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -462,3 +462,13 @@ func testNoIsolationTransfer() {
462462
// CHECK: hop_to_executor [[GENERIC_EXECUTOR]]
463463
testErasure { @concurrent in }
464464
}
465+
466+
func testClosuresDontAssumeGlobalActorWithMarkedAsConcurrent() {
467+
func test(_ fn: @MainActor () async -> Void) {}
468+
469+
// CHECK-LABEL: sil private [ossa] @$s21attr_execution_silgen55testClosuresDontAssumeGlobalActorWithMarkedAsConcurrentyyFyyYaYbXEfU_
470+
// CHECK: [[GENERIC_EXECUTOR:%.*]] = enum $Optional<Builtin.Executor>, #Optional.none!enumelt
471+
// CHECK-NEXT: hop_to_executor [[GENERIC_EXECUTOR]]
472+
test { @Sendable @concurrent in
473+
}
474+
}

0 commit comments

Comments
 (0)