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 @@ -1624,6 +1624,7 @@ bool ActorIsolation::requiresSubstitution() const {
16241624 switch (kind) {
16251625 case ActorInstance:
16261626 case Nonisolated:
1627+ case NonisolatedUnsafe:
16271628 case Unspecified:
16281629 return false ;
16291630
@@ -1638,6 +1639,7 @@ ActorIsolation ActorIsolation::subst(SubstitutionMap subs) const {
16381639 switch (kind) {
16391640 case ActorInstance:
16401641 case Nonisolated:
1642+ case NonisolatedUnsafe:
16411643 case Unspecified:
16421644 return *this ;
16431645
Original file line number Diff line number Diff line change @@ -6594,12 +6594,14 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
65946594 auto dc = D->getDeclContext ();
65956595
65966596 if (auto var = dyn_cast<VarDecl>(D)) {
6597+ const bool isUnsafe =
6598+ attr->isUnsafe () && Ctx.LangOpts .hasFeature (Feature::GlobalConcurrency);
6599+
65976600 // stored properties have limitations as to when they can be nonisolated.
65986601 if (var->hasStorage ()) {
6599- const bool isUnsafeGlobal = attr->isUnsafe () && var->isGlobalStorage ();
6600-
6601- // 'nonisolated' can not be applied to mutable stored properties.
6602- if (var->supportsMutation () && !isUnsafeGlobal) {
6602+ // 'nonisolated' can not be applied to mutable stored properties unless
6603+ // qualified as 'unsafe'.
6604+ if (var->supportsMutation () && !isUnsafe) {
66036605 diagnoseAndRemoveAttr (attr, diag::nonisolated_mutable_storage);
66046606 return ;
66056607 }
@@ -6641,8 +6643,9 @@ void AttributeChecker::visitNonisolatedAttr(NonisolatedAttr *attr) {
66416643 return ;
66426644 }
66436645
6644- // nonisolated can not be applied to local properties.
6645- if (dc->isLocalContext ()) {
6646+ // nonisolated can not be applied to local properties unless qualified as
6647+ // 'unsafe'.
6648+ if (dc->isLocalContext () && !isUnsafe) {
66466649 diagnoseAndRemoveAttr (attr, diag::nonisolated_local_var);
66476650 return ;
66486651 }
Original file line number Diff line number Diff line change @@ -2812,6 +2812,12 @@ namespace {
28122812 if (getActorIsolation (value).isActorIsolated ())
28132813 return false ;
28142814
2815+ if (auto attr = value->getAttrs ().getAttribute <NonisolatedAttr>();
2816+ ctx.LangOpts .hasFeature (Feature::GlobalConcurrency) && attr &&
2817+ attr->isUnsafe ()) {
2818+ return false ;
2819+ }
2820+
28152821 ctx.Diags .diagnose (loc, diag::shared_mutable_state_access, value);
28162822 value->diagnose (diag::kind_declared_here, value->getDescriptiveKind ());
28172823 return true ;
@@ -3275,6 +3281,12 @@ namespace {
32753281 }
32763282 }
32773283
3284+ if (auto attr = var->getAttrs ().getAttribute <NonisolatedAttr>();
3285+ ctx.LangOpts .hasFeature (Feature::GlobalConcurrency) && attr &&
3286+ attr->isUnsafe ()) {
3287+ return false ;
3288+ }
3289+
32783290 // Otherwise, we have concurrent access. Complain.
32793291 bool preconcurrencyContext =
32803292 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