Skip to content

Commit 90ccc75

Browse files
committed
[Concurrency] Do not allow accessing actor-isolated superclass properties
from nonisolated subclass initializers.
1 parent a6d078b commit 90ccc75

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
@@ -1512,6 +1512,15 @@ static bool isStoredProperty(ValueDecl const *member) {
15121512
return false;
15131513
}
15141514

1515+
static bool isNonInheritedStorage(ValueDecl const *member,
1516+
DeclContext const *useDC) {
1517+
auto *nominal = useDC->getParent()->getSelfNominalTypeDecl();
1518+
if (!nominal)
1519+
return false;
1520+
1521+
return isStoredProperty(member) && member->getDeclContext() == nominal;
1522+
}
1523+
15151524
/// Based on the former escaping-use restriction, which was replaced by
15161525
/// flow-isolation. We need this to support backwards compatability in the
15171526
/// type-checker for programs prior to Swift 6.
@@ -1727,7 +1736,7 @@ static bool checkedByFlowIsolation(DeclContext const *refCxt,
17271736
return false;
17281737

17291738
// Stored properties are definitely OK.
1730-
if (isStoredProperty(member))
1739+
if (isNonInheritedStorage(member, fnDecl))
17311740
return true;
17321741

17331742
return false;
@@ -5659,7 +5668,7 @@ ActorReferenceResult ActorReferenceResult::forReference(
56595668
// FIXME: At the very least, we should consistently use
56605669
// isActorInitOrDeInitContext here, but it only wants to think about actors.
56615670
if (actorInstance && actorInstance->isSelf() &&
5662-
isStoredProperty(declRef.getDecl()) &&
5671+
isNonInheritedStorage(declRef.getDecl(), fromDC) &&
56635672
declIsolation.isGlobalActor() &&
56645673
(isa<ConstructorDecl>(fromDC) || isa<DestructorDecl>(fromDC)))
56655674
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)