Skip to content

Commit dffffcd

Browse files
Merge pull request #70135 from sophiapoirier/non-isolated-unsafe-local-variables
[Sema] nonisolated(unsafe) for local variables
2 parents 6442e91 + 18c88e4 commit dffffcd

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
@@ -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

lib/Sema/TypeCheckAttr.cpp

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

lib/Sema/TypeCheckConcurrency.cpp

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

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)