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