Skip to content

Commit 18c88e4

Browse files
committed
[Sema] nonisolated(unsafe) for local variables
1 parent bd4ee46 commit 18c88e4

File tree

4 files changed

+32
-6
lines changed

4 files changed

+32
-6
lines changed

lib/AST/TypeCheckRequests.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff 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

lib/Sema/TypeCheckAttr.cpp

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff 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
}

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff 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(

test/Concurrency/experimental_feature_strictconcurrency.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff 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+
}

0 commit comments

Comments
 (0)