File tree Expand file tree Collapse file tree 4 files changed +32
-6
lines changed Expand file tree Collapse file tree 4 files changed +32
-6
lines changed Original file line number Diff line number Diff line change @@ -1722,6 +1722,7 @@ bool ActorIsolation::requiresSubstitution() const {
17221722 switch (kind) {
17231723 case ActorInstance:
17241724 case Nonisolated:
1725+ case NonisolatedUnsafe:
17251726 case Unspecified:
17261727 return false ;
17271728
@@ -1736,6 +1737,7 @@ ActorIsolation ActorIsolation::subst(SubstitutionMap subs) const {
17361737 switch (kind) {
17371738 case ActorInstance:
17381739 case Nonisolated:
1740+ case NonisolatedUnsafe:
17391741 case Unspecified:
17401742 return *this ;
17411743
Original file line number Diff line number Diff line change @@ -6830,12 +6830,14 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
68306830 auto dc = D->getDeclContext ();
68316831
68326832 if (auto var = dyn_cast<VarDecl>(D)) {
6833+ const bool isUnsafe =
6834+ attr->isUnsafe () && Ctx.LangOpts .hasFeature (Feature::GlobalConcurrency);
6835+
68336836 // stored properties have limitations as to when they can be nonisolated.
68346837 if (var->hasStorage ()) {
6835- const bool isUnsafeGlobal = attr->isUnsafe () && var->isGlobalStorage ();
6836-
6837- // 'nonisolated' can not be applied to mutable stored properties.
6838- if (var->supportsMutation () && !isUnsafeGlobal) {
6838+ // 'nonisolated' can not be applied to mutable stored properties unless
6839+ // qualified as 'unsafe'.
6840+ if (var->supportsMutation () && !isUnsafe) {
68396841 diagnoseAndRemoveAttr (attr, diag::nonisolated_mutable_storage);
68406842 return ;
68416843 }
@@ -6878,8 +6880,9 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
68786880 return ;
68796881 }
68806882
6881- // nonisolated can not be applied to local properties.
6882- if (dc->isLocalContext ()) {
6883+ // nonisolated can not be applied to local properties unless qualified as
6884+ // 'unsafe'.
6885+ if (dc->isLocalContext () && !isUnsafe) {
68836886 diagnoseAndRemoveAttr (attr, diag::nonisolated_local_var);
68846887 return ;
68856888 }
Original file line number Diff line number Diff line change @@ -2833,6 +2833,12 @@ namespace {
28332833 if (getActorIsolation (value).isActorIsolated ())
28342834 return false ;
28352835
2836+ if (auto attr = value->getAttrs ().getAttribute <NonisolatedAttr>();
2837+ ctx.LangOpts .hasFeature (Feature::GlobalConcurrency) && attr &&
2838+ attr->isUnsafe ()) {
2839+ return false ;
2840+ }
2841+
28362842 ctx.Diags .diagnose (loc, diag::shared_mutable_state_access, value);
28372843 value->diagnose (diag::kind_declared_here, value->getDescriptiveKind ());
28382844 return true ;
@@ -3299,6 +3305,12 @@ namespace {
32993305 }
33003306 }
33013307
3308+ if (auto attr = var->getAttrs ().getAttribute <NonisolatedAttr>();
3309+ ctx.LangOpts .hasFeature (Feature::GlobalConcurrency) && attr &&
3310+ attr->isUnsafe ()) {
3311+ return false ;
3312+ }
3313+
33023314 // Otherwise, we have concurrent access. Complain.
33033315 bool preconcurrencyContext =
33043316 getActorIsolationOfContext (
Original file line number Diff line number Diff line change @@ -75,3 +75,12 @@ func f() {
7575 print ( TestStatics . immutableInferredSendable)
7676 print ( TestStatics . mutable) // expected-warning{{reference to static property 'mutable' is not concurrency-safe because it involves shared mutable state}}
7777}
78+
79+ func testLocalNonisolatedUnsafe( ) async {
80+ nonisolated ( unsafe) var value = 1
81+ let task = Task {
82+ value = 2
83+ return value
84+ }
85+ print ( await task. value)
86+ }
You can’t perform that action at this time.
0 commit comments