@@ -253,6 +253,81 @@ class AttributeChecker : public AttributeVisitor<AttributeChecker> {
253
253
}
254
254
255
255
public:
256
+ void visitExecutionAttr(ExecutionAttr *attr) {
257
+ auto *F = dyn_cast<FuncDecl>(D);
258
+ if (!F)
259
+ return;
260
+
261
+ if (!F->hasAsync()) {
262
+ diagnoseAndRemoveAttr(attr, diag::attr_execution_concurrent_only_on_async,
263
+ F);
264
+ return;
265
+ }
266
+
267
+ switch (attr->getBehavior()) {
268
+ case ExecutionKind::Concurrent: {
269
+ // 'concurrent' doesn't work with explicit `nonisolated`
270
+ if (F->hasExplicitIsolationAttribute()) {
271
+ if (F->getAttrs().hasAttribute<NonisolatedAttr>()) {
272
+ diagnoseAndRemoveAttr(
273
+ attr,
274
+ diag::attr_execution_concurrent_incompatible_with_nonisolated, F);
275
+ return;
276
+ }
277
+ }
278
+
279
+ auto parameters = F->getParameters();
280
+ if (!parameters)
281
+ return;
282
+
283
+ for (auto *P : *parameters) {
284
+ auto *repr = P->getTypeRepr();
285
+ if (!repr)
286
+ continue;
287
+
288
+ // isolated parameters affect isolation of the function itself
289
+ if (isa<IsolatedTypeRepr>(repr)) {
290
+ diagnoseAndRemoveAttr(
291
+ attr,
292
+ diag::attr_execution_concurrent_incompatible_isolated_parameter,
293
+ F, P);
294
+ return;
295
+ }
296
+
297
+ if (auto *attrType = dyn_cast<AttributedTypeRepr>(repr)) {
298
+ if (attrType->has(TypeAttrKind::Isolated)) {
299
+ diagnoseAndRemoveAttr(
300
+ attr,
301
+ diag::
302
+ attr_execution_concurrent_incompatible_dynamically_isolated_parameter,
303
+ F, P);
304
+ return;
305
+ }
306
+ }
307
+ }
308
+
309
+ // We need isolation check here because global actor isolation
310
+ // could be inferred.
311
+
312
+ auto isolation = getActorIsolation(F);
313
+ if (isolation.isGlobalActor()) {
314
+ diagnoseAndRemoveAttr(
315
+ attr,
316
+ diag::attr_execution_concurrent_incompatible_with_global_actor, F,
317
+ isolation.getGlobalActor());
318
+ return;
319
+ }
320
+
321
+ break;
322
+ }
323
+
324
+ case ExecutionKind::Caller: {
325
+ // no restrictions for now.
326
+ break;
327
+ }
328
+ }
329
+ }
330
+
256
331
void visitABIAttr(ABIAttr *attr) {
257
332
Decl *AD = attr->abiDecl;
258
333
if (isa<VarDecl>(D) && isa<PatternBindingDecl>(AD)) {
0 commit comments