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 @@ -1699,6 +1699,7 @@ bool ActorIsolation::requiresSubstitution() const {
16991699 switch (kind) {
17001700 case ActorInstance:
17011701 case Nonisolated:
1702+ case NonisolatedUnsafe:
17021703 case Unspecified:
17031704 return false ;
17041705
@@ -1713,6 +1714,7 @@ ActorIsolation ActorIsolation::subst(SubstitutionMap subs) const {
17131714 switch (kind) {
17141715 case ActorInstance:
17151716 case Nonisolated:
1717+ case NonisolatedUnsafe:
17161718 case Unspecified:
17171719 return *this ;
17181720
Original file line number Diff line number Diff line change @@ -6816,12 +6816,14 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
68166816 auto dc = D->getDeclContext ();
68176817
68186818 if (auto var = dyn_cast<VarDecl>(D)) {
6819+ const bool isUnsafe =
6820+ attr->isUnsafe () && Ctx.LangOpts .hasFeature (Feature::GlobalConcurrency);
6821+
68196822 // stored properties have limitations as to when they can be nonisolated.
68206823 if (var->hasStorage ()) {
6821- const bool isUnsafeGlobal = attr->isUnsafe () && var->isGlobalStorage ();
6822-
6823- // 'nonisolated' can not be applied to mutable stored properties.
6824- if (var->supportsMutation () && !isUnsafeGlobal) {
6824+ // 'nonisolated' can not be applied to mutable stored properties unless
6825+ // qualified as 'unsafe'.
6826+ if (var->supportsMutation () && !isUnsafe) {
68256827 diagnoseAndRemoveAttr (attr, diag::nonisolated_mutable_storage);
68266828 return ;
68276829 }
@@ -6863,8 +6865,9 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
68636865 return ;
68646866 }
68656867
6866- // nonisolated can not be applied to local properties.
6867- if (dc->isLocalContext ()) {
6868+ // nonisolated can not be applied to local properties unless qualified as
6869+ // 'unsafe'.
6870+ if (dc->isLocalContext () && !isUnsafe) {
68686871 diagnoseAndRemoveAttr (attr, diag::nonisolated_local_var);
68696872 return ;
68706873 }
Original file line number Diff line number Diff line change @@ -2813,6 +2813,12 @@ namespace {
28132813 if (getActorIsolation (value).isActorIsolated ())
28142814 return false ;
28152815
2816+ if (auto attr = value->getAttrs ().getAttribute <NonisolatedAttr>();
2817+ ctx.LangOpts .hasFeature (Feature::GlobalConcurrency) && attr &&
2818+ attr->isUnsafe ()) {
2819+ return false ;
2820+ }
2821+
28162822 ctx.Diags .diagnose (loc, diag::shared_mutable_state_access, value);
28172823 value->diagnose (diag::kind_declared_here, value->getDescriptiveKind ());
28182824 return true ;
@@ -3279,6 +3285,12 @@ namespace {
32793285 }
32803286 }
32813287
3288+ if (auto attr = var->getAttrs ().getAttribute <NonisolatedAttr>();
3289+ ctx.LangOpts .hasFeature (Feature::GlobalConcurrency) && attr &&
3290+ attr->isUnsafe ()) {
3291+ return false ;
3292+ }
3293+
32823294 // Otherwise, we have concurrent access. Complain.
32833295 bool preconcurrencyContext =
32843296 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