Merge pull request #83110 from swiftlang/jepa-release

[6.2] Sema: Make `@concurrent` not imply `async` on closures
This commit is contained in:
Anthony Latsis
2025-07-17 16:44:44 +01:00
committed by GitHub
5 changed files with 96 additions and 23 deletions

View File

@@ -1438,17 +1438,11 @@ FunctionType::ExtInfo ClosureEffectsRequest::evaluate(
if (!body)
return ASTExtInfoBuilder().withSendable(sendable).build();
// `@concurrent` attribute is only valid on asynchronous function types.
bool asyncFromAttr = false;
if (expr->getAttrs().hasAttribute<ConcurrentAttr>()) {
asyncFromAttr = true;
}
auto throwFinder = FindInnerThrows(expr);
body->walk(throwFinder);
return ASTExtInfoBuilder()
.withThrows(throwFinder.foundThrow(), /*FIXME:*/Type())
.withAsync(asyncFromAttr || bool(findAsyncNode(expr)))
.withAsync(bool(findAsyncNode(expr)))
.withSendable(sendable)
.build();
}

View File

@@ -305,6 +305,11 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
}
}
// Performs checks on a closure.
if (auto *closure = dyn_cast<ClosureExpr>(E)) {
checkClosure(closure);
}
// Specially diagnose some checked casts that are illegal.
if (auto cast = dyn_cast<CheckedCastExpr>(E)) {
checkCheckedCastExpr(cast);
@@ -1459,6 +1464,33 @@ static void diagSyntacticUseRestrictions(const Expr *E, const DeclContext *DC,
}
}
}
void checkClosure(ClosureExpr *closure) {
if (closure->isImplicit()) {
return;
}
auto attr = closure->getAttrs().getAttribute<ConcurrentAttr>();
if (!attr) {
return;
}
if (closure->getAsyncLoc().isValid()) {
return;
}
if (closure->getType()->castTo<AnyFunctionType>()->isAsync()) {
return;
}
// `@concurrent` is not allowed on synchronous closures, but this is
// likely to change, so diagnose this here, post solution application,
// instead of introducing an "implies `async`" inference rule that won't
// make sense in the nearish future.
Ctx.Diags.diagnose(attr->getLocation(),
diag::execution_behavior_only_on_async_closure, attr);
attr->setInvalid();
}
};
DiagnoseWalker Walker(DC, isExprStmt);

View File

@@ -8243,16 +8243,6 @@ public:
}
void checkExecutionBehaviorAttribute(DeclAttribute *attr) {
// execution behavior attribute implies `async`.
if (closure->hasExplicitResultType() &&
closure->getAsyncLoc().isInvalid()) {
ctx.Diags
.diagnose(attr->getLocation(),
diag::execution_behavior_only_on_async_closure, attr)
.fixItRemove(attr->getRangeWithAt());
attr->setInvalid();
}
if (auto actorType = getExplicitGlobalActor(closure)) {
ctx.Diags
.diagnose(