Skip to content

Commit f15f1a8

Browse files
committed
[Concurrency] Do not allow accessing actor-isolated superclass properties
from nonisolated subclass initializers. (cherry picked from commit 90ccc75)
1 parent 4d68b70 commit f15f1a8

File tree

2 files changed

+39
-2
lines changed

2 files changed

+39
-2
lines changed

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,15 @@ static bool isStoredProperty(ValueDecl const *member) {
15161516
return false;
15171517
}
15181518

1519+
static bool isNonInheritedStorage(ValueDecl const *member,
1520+
DeclContext const *useDC) {
1521+
auto *nominal = useDC->getParent()->getSelfNominalTypeDecl();
1522+
if (!nominal)
1523+
return false;
1524+
1525+
return isStoredProperty(member) && member->getDeclContext() == nominal;
1526+
}
1527+
15191528
/// Based on the former escaping-use restriction, which was replaced by
15201529
/// flow-isolation. We need this to support backwards compatability in the
15211530
/// type-checker for programs prior to Swift 6.
@@ -1731,7 +1740,7 @@ static bool checkedByFlowIsolation(DeclContext const *refCxt,
17311740
return false;
17321741

17331742
// Stored properties are definitely OK.
1734-
if (isStoredProperty(member))
1743+
if (isNonInheritedStorage(member, fnDecl))
17351744
return true;
17361745

17371746
return false;
@@ -5663,7 +5672,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
56635672
// FIXME: At the very least, we should consistently use
56645673
// isActorInitOrDeInitContext here, but it only wants to think about actors.
56655674
if (actorInstance && actorInstance->isSelf() &&
5666-
isStoredProperty(declRef.getDecl()) &&
5675+
isNonInheritedStorage(declRef.getDecl(), fromDC) &&
56675676
declIsolation.isGlobalActor() &&
56685677
(isa<ConstructorDecl>(fromDC) || isa<DestructorDecl>(fromDC)))
56695678
return forSameConcurrencyDomain(declIsolation);

test/Concurrency/actor_isolation.swift

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1497,3 +1497,31 @@ extension MyActor {
14971497
}
14981498
}
14991499
}
1500+
1501+
@MainActor
1502+
class SuperWithNonisolatedInit {
1503+
static func isolatedToMainActor() {}
1504+
1505+
// expected-note@+1 2 {{mutation of this property is only permitted within the actor}}
1506+
var x: Int = 0 {
1507+
didSet {
1508+
SuperWithNonisolatedInit.isolatedToMainActor()
1509+
}
1510+
}
1511+
1512+
nonisolated init() {}
1513+
}
1514+
1515+
class OverridesNonsiolatedInit: SuperWithNonisolatedInit {
1516+
override nonisolated init() {
1517+
super.init()
1518+
1519+
// expected-error@+1 {{main actor-isolated property 'x' can not be mutated from a non-isolated context}}
1520+
super.x = 10
1521+
}
1522+
1523+
nonisolated func f() {
1524+
// expected-error@+1 {{main actor-isolated property 'x' can not be mutated from a non-isolated context}}
1525+
super.x = 10
1526+
}
1527+
}

0 commit comments

Comments
 (0)