@@ -7787,31 +7787,50 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
7787
7787
if (auto var = dyn_cast<VarDecl>(D)) {
7788
7788
// stored properties have limitations as to when they can be nonisolated.
7789
7789
auto type = var->getTypeInContext ();
7790
- if (var->hasStorage ()) {
7790
+ if (var->hasStorage () || var->hasAttachedPropertyWrapper () ||
7791
+ var->getAttrs ().hasAttribute <LazyAttr>()) {
7791
7792
{
7792
7793
// A stored property can be 'nonisolated' if it is a 'Sendable' member
7793
7794
// 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.
7794
7799
bool canBeNonisolated = false ;
7795
7800
if (auto nominal = dc->getSelfStructDecl ()) {
7796
- if (nominal->getDeclaredTypeInContext ()->isSendableType () &&
7801
+ if (var->hasStorage () &&
7802
+ nominal->getDeclaredTypeInContext ()->isSendableType () &&
7797
7803
!var->isStatic () && type->isSendableType ()) {
7798
7804
canBeNonisolated = true ;
7799
7805
}
7800
7806
}
7801
7807
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
+ }
7808
7814
7809
7815
// Otherwise, this stored property has to be qualified as 'unsafe'.
7810
7816
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 )
7812
7820
.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
+ }
7815
7834
}
7816
7835
7817
7836
// 'nonisolated' without '(unsafe)' is not allowed on non-Sendable
@@ -7877,22 +7896,6 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
7877
7896
}
7878
7897
}
7879
7898
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
-
7896
7899
// nonisolated can not be applied to local properties unless qualified as
7897
7900
// 'unsafe'.
7898
7901
if (dc->isLocalContext () && !attr->isUnsafe ()) {
0 commit comments