@@ -373,6 +373,15 @@ GlobalActorAttributeRequest::evaluate(
373
373
if (decl->getDeclContext ()->getParentSourceFile () == nullptr )
374
374
return result;
375
375
376
+ auto isStoredInstancePropertyOfStruct = [](VarDecl *var) {
377
+ if (var->isStatic () || !var->isOrdinaryStoredProperty ())
378
+ return false ;
379
+
380
+ auto *nominal = var->getDeclContext ()->getSelfNominalTypeDecl ();
381
+ return isa_and_nonnull<StructDecl>(nominal) &&
382
+ !isWrappedValueOfPropWrapper (var);
383
+ };
384
+
376
385
auto globalActorAttr = result->first ;
377
386
if (auto nominal = dyn_cast<NominalTypeDecl>(decl)) {
378
387
// Nominal types are okay...
@@ -406,25 +415,53 @@ GlobalActorAttributeRequest::evaluate(
406
415
}
407
416
408
417
// ... and not if it's the instance storage of a struct
409
- if (!var->isStatic () && var->isOrdinaryStoredProperty ()) {
410
- if (auto *nominal = var->getDeclContext ()->getSelfNominalTypeDecl ()) {
411
- if (isa<StructDecl>(nominal) && !isWrappedValueOfPropWrapper (var)) {
412
-
413
- var->diagnose (diag::global_actor_on_storage_of_value_type,
414
- var->getName ())
415
- .highlight (globalActorAttr->getRangeWithAt ())
416
- .warnUntilSwiftVersion (6 );
417
-
418
- // In Swift 6, once the diag above is an error, it is disallowed.
419
- if (var->getASTContext ().isSwiftVersionAtLeast (6 ))
420
- return llvm::None;
421
- }
422
- }
418
+ if (isStoredInstancePropertyOfStruct (var)) {
419
+ var->diagnose (diag::global_actor_on_storage_of_value_type,
420
+ var->getName ())
421
+ .highlight (globalActorAttr->getRangeWithAt ())
422
+ .warnUntilSwiftVersion (6 );
423
+
424
+ // In Swift 6, once the diag above is an error, it is disallowed.
425
+ if (var->getASTContext ().isSwiftVersionAtLeast (6 ))
426
+ return llvm::None;
423
427
}
424
428
}
425
429
} else if (isa<ExtensionDecl>(decl)) {
426
430
// Extensions are okay.
427
431
} else if (isa<ConstructorDecl>(decl) || isa<FuncDecl>(decl)) {
432
+ // None of the accessors/addressors besides a getter are allowed
433
+ // to have a global actor attribute.
434
+ if (auto *accessor = dyn_cast<AccessorDecl>(decl)) {
435
+ if (!accessor->isGetter ()) {
436
+ decl->diagnose (diag::global_actor_disallowed,
437
+ decl->getDescriptiveKind ())
438
+ .fixItRemove (globalActorAttr->getRangeWithAt ());
439
+
440
+ auto *storage = accessor->getStorage ();
441
+ // Let's suggest to move the attribute to the storage if
442
+ // this is an accessor/addressor of a property of subscript.
443
+ if (storage->getDeclContext ()->isTypeContext ()) {
444
+ // If enclosing declaration has a global actor,
445
+ // skip the suggestion.
446
+ if (storage->getGlobalActorAttr ())
447
+ return llvm::None;
448
+
449
+ // Global actor attribute cannot be applied to
450
+ // an instance stored property of a struct.
451
+ if (auto *var = dyn_cast<VarDecl>(storage)) {
452
+ if (isStoredInstancePropertyOfStruct (var))
453
+ return llvm::None;
454
+ }
455
+
456
+ decl->diagnose (diag::move_global_actor_attr_to_storage_decl, storage)
457
+ .fixItInsert (
458
+ storage->getAttributeInsertionLoc (/* forModifier=*/ false ),
459
+ llvm::Twine (" @" , result->second ->getNameStr ()).str ());
460
+ }
461
+
462
+ return llvm::None;
463
+ }
464
+ }
428
465
// Functions are okay.
429
466
} else {
430
467
// Everything else is disallowed.
0 commit comments