Skip to content

Commit e9fd369

Browse files
committed
[Sema] Allow use of @execution(...) attribute on closures
1 parent 80050bb commit e9fd369

File tree

3 files changed

+60
-0
lines changed

3 files changed

+60
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8343,6 +8343,10 @@ ERROR(attr_execution_only_on_async,none,
83438343
"cannot use '@execution' on non-async %kind0",
83448344
(ValueDecl *))
83458345

8346+
ERROR(attr_execution_only_on_async_closure,none,
8347+
"cannot use '@execution' on non-async closure",
8348+
())
8349+
83468350
ERROR(attr_execution_type_attr_only_on_async,none,
83478351
"cannot use '@execution' on non-async function type",
83488352
())

lib/Sema/TypeCheckAttr.cpp

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8222,6 +8222,44 @@ class ClosureAttributeChecker
82228222
// Nothing else to check.
82238223
}
82248224

8225+
void visitExecutionAttr(ExecutionAttr *attr) {
8226+
if (!ctx.LangOpts.hasFeature(Feature::ExecutionAttribute)) {
8227+
visitDeclAttribute(attr);
8228+
return;
8229+
}
8230+
8231+
// `@execution(...)` implies `async`.
8232+
if (closure->hasExplicitResultType() &&
8233+
closure->getAsyncLoc().isInvalid()) {
8234+
ctx.Diags
8235+
.diagnose(attr->getLocation(),
8236+
diag::attr_execution_only_on_async_closure)
8237+
.fixItRemove(attr->getRangeWithAt());
8238+
attr->setInvalid();
8239+
}
8240+
8241+
if (auto actorType = getExplicitGlobalActor(closure)) {
8242+
ctx.Diags
8243+
.diagnose(
8244+
attr->getLocation(),
8245+
diag::attr_execution_type_attr_incompatible_with_global_isolation,
8246+
actorType)
8247+
.fixItRemove(attr->getRangeWithAt());
8248+
attr->setInvalid();
8249+
}
8250+
8251+
if (auto *paramList = closure->getParameters()) {
8252+
if (llvm::any_of(*paramList, [](auto *P) { return P->isIsolated(); })) {
8253+
ctx.Diags
8254+
.diagnose(
8255+
attr->getLocation(),
8256+
diag::attr_execution_type_attr_incompatible_with_isolated_param)
8257+
.fixItRemove(attr->getRangeWithAt());
8258+
attr->setInvalid();
8259+
}
8260+
}
8261+
}
8262+
82258263
void visitNonisolatedAttr(NonisolatedAttr *attr) {
82268264
if (attr->isUnsafe() ||
82278265
!ctx.LangOpts.hasFeature(Feature::ClosureIsolation)) {

test/attr/attr_execution.swift

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,3 +75,21 @@ struct InfersMainActor : P {
7575
struct IsolatedType {
7676
@execution(concurrent) func test() async {}
7777
}
78+
79+
_ = { @execution(caller) in // Ok
80+
}
81+
82+
_ = { @execution(concurrent) in // Ok
83+
}
84+
85+
_ = { @MainActor @execution(concurrent) in
86+
// expected-error@-1 {{cannot use '@execution' because function type is isolated to a global actor 'MainActor'}}
87+
}
88+
89+
_ = { @execution(concurrent) () -> Int in
90+
// expected-error@-1 {{'@execution' on non-async closure}}
91+
}
92+
93+
_ = { @execution(caller) (x: isolated (any Actor)?) in
94+
// expected-error@-1 {{cannot use '@execution' together with an isolated parameter}}
95+
}

0 commit comments

Comments
 (0)