Skip to content

Commit 44557a4

Browse files
sophiapoirierhborla
authored andcommitted
[Sema] nonisolated(unsafe) for local variables
(cherry picked from commit 18c88e4)
1 parent d7d6188 commit 44557a4

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

lib/Sema/TypeCheckAttr.cpp

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

lib/Sema/TypeCheckConcurrency.cpp

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

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)