Skip to content

Commit 68971bf

Browse files
committed
Merge remote-tracking branch 'origin/main' into rebranch
2 parents e3a98f8 + 515d203 commit 68971bf

File tree

4 files changed

+54
-10
lines changed

4 files changed

+54
-10
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1414,11 +1414,6 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
14141414
bool async = expr->getAsyncLoc().isValid();
14151415
bool sendable = expr->getAttrs().hasAttribute<SendableAttr>();
14161416

1417-
// `@concurrent` attribute is only valid on asynchronous function types.
1418-
if (expr->getAttrs().hasAttribute<ConcurrentAttr>()) {
1419-
async = true;
1420-
}
1421-
14221417
if (throws || async) {
14231418
return ASTExtInfoBuilder()
14241419
.withThrows(throws, /*FIXME:*/Type())
@@ -1432,11 +1427,17 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
14321427
if (!body)
14331428
return ASTExtInfoBuilder().withSendable(sendable).build();
14341429

1430+
// `@concurrent` attribute is only valid on asynchronous function types.
1431+
bool asyncFromAttr = false;
1432+
if (expr->getAttrs().hasAttribute<ConcurrentAttr>()) {
1433+
asyncFromAttr = true;
1434+
}
1435+
14351436
auto throwFinder = FindInnerThrows(expr);
14361437
body->walk(throwFinder);
14371438
return ASTExtInfoBuilder()
14381439
.withThrows(throwFinder.foundThrow(), /*FIXME:*/Type())
1439-
.withAsync(bool(findAsyncNode(expr)))
1440+
.withAsync(asyncFromAttr || bool(findAsyncNode(expr)))
14401441
.withSendable(sendable)
14411442
.build();
14421443
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4781,13 +4781,18 @@ ActorIsolation ActorIsolationChecker::determineClosureIsolation(
47814781

47824782
case ActorIsolation::ActorInstance: {
47834783
if (checkIsolatedCapture) {
4784+
if (auto param = closure->getCaptureInfo().getIsolatedParamCapture())
4785+
return ActorIsolation::forActorInstanceCapture(param);
4786+
47844787
auto *explicitClosure = dyn_cast<ClosureExpr>(closure);
47854788
// @_inheritActorContext(always) forces the isolation capture.
4786-
if (explicitClosure && explicitClosure->alwaysInheritsActorContext())
4789+
if (explicitClosure && explicitClosure->alwaysInheritsActorContext()) {
4790+
if (parentIsolation.isActorInstanceIsolated()) {
4791+
if (auto *param = parentIsolation.getActorInstance())
4792+
return ActorIsolation::forActorInstanceCapture(param);
4793+
}
47874794
return parentIsolation;
4788-
4789-
if (auto param = closure->getCaptureInfo().getIsolatedParamCapture())
4790-
return ActorIsolation::forActorInstanceCapture(param);
4795+
}
47914796
} else {
47924797
// If we don't have capture information during code completion, assume
47934798
// that the closure captures the `isolated` parameter from the parent

test/SILGen/hop_to_executor.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ func testGlobalActorFuncValue(_ fn: @RedActor () -> Void) async {
325325

326326
func acceptAsyncSendableClosureInheriting<T>(@_inheritActorContext _: @Sendable () async -> T) { }
327327
func acceptAsyncSendableClosureAlwaysInheriting<T>(@_inheritActorContext(always) _: @Sendable () async -> T) { }
328+
func acceptAsyncSendableClosureAlwaysInheritingErased<T>(@_inheritActorContext(always) _: sending @isolated(any) () async -> T) { }
328329

329330
extension MyActor {
330331
func synchronous() { }
@@ -385,6 +386,22 @@ func testIsolatedParameterWithInheritActorContext(_ isolation: isolated (any Act
385386
}
386387
}
387388

389+
// CHECK-LABEL: sil hidden [ossa] @$s4test0a17IsolatedParamWithB3AnyyyScA_pYiF
390+
// CHECK: [[CLOSURE_REF:%.*]] = function_ref @$s4test0a17IsolatedParamWithB3AnyyyScA_pYiFyyYaXEfU_
391+
// CHECK-NEXT: [[ISOLATION_COPY_1:%.*]] = copy_value %0 : $any Actor
392+
// CHECK-NEXT: [[ISOLATION_COPY_2:%.*]] = copy_value [[ISOLATION_COPY_1]] : $any Actor
393+
// CHECK-NEXT: [[DYNAMIC_ISOLATION:%.*]] = enum $Optional<any Actor>, #Optional.some!enumelt, [[ISOLATION_COPY_2]] : $any Actor
394+
// CHECK-NEXT: [[CLOSURE_WITH_APPLIED_ISOLATION:%.*]] = partial_apply [callee_guaranteed] [isolated_any] [[CLOSURE_REF]]([[DYNAMIC_ISOLATION]], [[ISOLATION_COPY_1]])
395+
func testIsolatedParamWithIsolatedAny(_ isolation: isolated any Actor) {
396+
// CHECK-LABEL: sil private [ossa] @$s4test0a17IsolatedParamWithB3AnyyyScA_pYiFyyYaXEfU_
397+
// CHECK: bb0(%0 : $*(), [[DYNAMIC_ISOLATION:%[0-9]+]] : @guaranteed $Optional<any Actor>, [[CAPTURED_ISOLATION:%[0-9]+]] : @closureCapture @guaranteed $any Actor):
398+
// CHECK: [[COPY:%[0-9]+]] = copy_value [[CAPTURED_ISOLATION]] : $any Actor
399+
// CHECK-NEXT: [[BORROW:%[0-9]+]] = begin_borrow [[COPY]] : $any Actor
400+
// CHECK-NEXT: hop_to_executor [[BORROW]] : $any Actor
401+
acceptAsyncSendableClosureAlwaysInheritingErased {
402+
}
403+
}
404+
388405
func acceptAsyncClosure(_: () async -> Void) { }
389406
func acceptAsyncClosure2<T>(_: (T) async -> T) { }
390407

test/attr/execution_behavior_attrs.swift

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,3 +137,24 @@ _ = { @MainActor @concurrent in
137137
_ = { @concurrent () -> Int in
138138
// expected-error@-1 {{@concurrent on non-async closure}}
139139
}
140+
141+
// Make sure that explicit use of `@concurrent` doesn't interfere with inference of `throws` from the body.
142+
do {
143+
func acceptsThrowing(_ body: () async throws -> Void) async {
144+
}
145+
146+
struct Invocation {
147+
func throwingFn() async throws {
148+
}
149+
}
150+
151+
func test(invocation: Invocation) async {
152+
await acceptsThrowing({ @concurrent in try await invocation.throwingFn() }) // Ok
153+
await acceptsThrowing({ @concurrent [invocation] in try await invocation.throwingFn() }) // Ok
154+
155+
await acceptsThrowing({ @concurrent in // Ok
156+
_ = 42
157+
try await invocation.throwingFn()
158+
})
159+
}
160+
}

0 commit comments

Comments
 (0)