Skip to content

Commit 570eedb

Browse files
committed
[ConstraintSystem] Update closure inference to support @execution(...) attribute
- Update `ClosureEffectsRequest` to make sure that closure is marked as `async` when `@execution(...)` attribute is present. - Update `inferClosureType` to set isolation based on an explicit `@execution(...)` attribute attached to a closure.
1 parent e9fd369 commit 570eedb

File tree

3 files changed

+27
-0
lines changed

3 files changed

+27
-0
lines changed

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2542,6 +2542,16 @@ namespace {
25422542
return FunctionTypeIsolation::forGlobalActor(actorType);
25432543
}
25442544

2545+
if (auto *execution =
2546+
closure->getAttrs().getAttribute<ExecutionAttr>()) {
2547+
switch (execution->getBehavior()) {
2548+
case ExecutionKind::Caller:
2549+
return FunctionTypeIsolation::forNonIsolatedCaller();
2550+
case ExecutionKind::Concurrent:
2551+
return FunctionTypeIsolation::forNonIsolated();
2552+
}
2553+
}
2554+
25452555
return FunctionTypeIsolation::forNonIsolated();
25462556
}();
25472557
extInfo = extInfo.withIsolation(isolation);

lib/Sema/ConstraintSystem.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1400,6 +1400,12 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
14001400
bool throws = expr->getThrowsLoc().isValid();
14011401
bool async = expr->getAsyncLoc().isValid();
14021402
bool sendable = expr->getAttrs().hasAttribute<SendableAttr>();
1403+
1404+
// `@execution(...)` attribute is only valid on asynchronous function types.
1405+
if (expr->getAttrs().hasAttribute<ExecutionAttr>()) {
1406+
async = true;
1407+
}
1408+
14031409
if (throws || async) {
14041410
return ASTExtInfoBuilder()
14051411
.withThrows(throws, /*FIXME:*/Type())

test/Concurrency/attr_execution_conversions.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,6 +82,17 @@ do {
8282
// expected-error@-1 {{cannot convert value of type '(@execution(caller) () async -> ()).Type' to expected argument type '(@isolated(any) () async -> Void).Type'}}
8383
}
8484

85+
do {
86+
let _: () -> Void = { @execution(concurrent) in
87+
// expected-error@-1 {{invalid conversion from 'async' function of type '() async -> Void' to synchronous function type '() -> Void'}}
88+
}
89+
90+
func test(_: () -> Void) {}
91+
92+
test { @execution(caller) in
93+
// expected-error@-1 {{cannot pass function of type '@execution(caller) () async -> ()' to parameter expecting synchronous function type}}
94+
}
95+
}
8596

8697
// Converting to `@execution(caller)` function
8798
class NonSendable {}

0 commit comments

Comments
 (0)