@@ -7787,31 +7787,50 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
77877787 if (auto var = dyn_cast<VarDecl>(D)) {
77887788 // stored properties have limitations as to when they can be nonisolated.
77897789 auto type = var->getTypeInContext ();
7790- if (var->hasStorage ()) {
7790+ if (var->hasStorage () || var->hasAttachedPropertyWrapper () ||
7791+ var->getAttrs ().hasAttribute <LazyAttr>()) {
77917792 {
77927793 // A stored property can be 'nonisolated' if it is a 'Sendable' member
77937794 // of a 'Sendable' value type.
7795+ // The above rule does not apply to lazy properties and properties with
7796+ // property wrappers, because backing storage is a stored
7797+ // 'var' that is part of the internal state of the actor which could
7798+ // only be accessed in actor's isolation context.
77947799 bool canBeNonisolated = false ;
77957800 if (auto nominal = dc->getSelfStructDecl ()) {
7796- if (nominal->getDeclaredTypeInContext ()->isSendableType () &&
7801+ if (var->hasStorage () &&
7802+ nominal->getDeclaredTypeInContext ()->isSendableType () &&
77977803 !var->isStatic () && type->isSendableType ()) {
77987804 canBeNonisolated = true ;
77997805 }
78007806 }
78017807
7802- // Additionally, a stored property of a non-'Sendable' type can be
7803- // explicitly marked 'nonisolated'.
7804- if (auto parentDecl = dc->getDeclaredTypeInContext ())
7805- if (!parentDecl->isSendableType ()) {
7806- canBeNonisolated = true ;
7807- }
7808+ // Additionally, a stored property of a non-'Sendable' type can be
7809+ // explicitly marked 'nonisolated'.
7810+ if (auto parentDecl = dc->getDeclaredTypeInContext ())
7811+ if (!parentDecl->isSendableType ()) {
7812+ canBeNonisolated = true ;
7813+ }
78087814
78097815 // Otherwise, this stored property has to be qualified as 'unsafe'.
78107816 if (var->supportsMutation () && !attr->isUnsafe () && !canBeNonisolated) {
7811- diagnoseAndRemoveAttr (attr, diag::nonisolated_mutable_storage)
7817+ if (var->hasAttachedPropertyWrapper ()) {
7818+ diagnoseAndRemoveAttr (attr, diag::nonisolated_mutable_storage)
7819+ .warnUntilSwiftVersionIf (attr->isImplicit (), 6 )
78127820 .fixItInsertAfter (attr->getRange ().End , " (unsafe)" );
7813- var->diagnose (diag::nonisolated_mutable_storage_note, var);
7814- return ;
7821+ return ;
7822+ } else if (var->getAttrs ().hasAttribute <LazyAttr>()) {
7823+ diagnoseAndRemoveAttr (attr, diag::nonisolated_mutable_storage)
7824+ .warnUntilSwiftVersion (6 )
7825+ .fixItInsertAfter (attr->getRange ().End , " (unsafe)" );
7826+ return ;
7827+ } else {
7828+ diagnoseAndRemoveAttr (attr, diag::nonisolated_mutable_storage)
7829+ .fixItInsertAfter (attr->getRange ().End , " (unsafe)" );
7830+ if (var->hasStorage ())
7831+ var->diagnose (diag::nonisolated_mutable_storage_note, var);
7832+ return ;
7833+ }
78157834 }
78167835
78177836 // 'nonisolated' without '(unsafe)' is not allowed on non-Sendable
@@ -7877,22 +7896,6 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
78777896 }
78787897 }
78797898
7880- // Using 'nonisolated' with lazy properties and wrapped properties is
7881- // unsupported, because backing storage is a stored 'var' that is part
7882- // of the internal state of the actor which could only be accessed in
7883- // actor's isolation context.
7884- if (var->hasAttachedPropertyWrapper ()) {
7885- diagnoseAndRemoveAttr (attr, diag::nonisolated_wrapped_property)
7886- .warnUntilSwiftVersionIf (attr->isImplicit (), 6 );
7887- return ;
7888- }
7889-
7890- if (var->getAttrs ().hasAttribute <LazyAttr>()) {
7891- diagnose (attr->getLocation (), diag::nonisolated_lazy)
7892- .warnUntilSwiftVersion (6 );
7893- return ;
7894- }
7895-
78967899 // nonisolated can not be applied to local properties unless qualified as
78977900 // 'unsafe'.
78987901 if (dc->isLocalContext () && !attr->isUnsafe ()) {
0 commit comments