Skip to content

Commit fe2dc11

Browse files
committed
[region-isolation] When computing isolation for isolated parameters, use getAnyActor instead of getNominalOrBoundGenericNominal().
This ensures that we can properly compute isolation for generic types that conform to AnyActor. I found this by playing with test cases from the previous commit. We would not find an actor type for the actor instance isolation and would fall back along an incorrect path. rdar://128021548
1 parent 4412fff commit fe2dc11

File tree

4 files changed

+38
-5
lines changed

4 files changed

+38
-5
lines changed

include/swift/SILOptimizer/Utils/PartitionUtils.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -192,7 +192,10 @@ class SILIsolationInfo {
192192
actorInstance(ActorInstance::getForValue(actorInstance)) {
193193
assert((!actorInstance ||
194194
(actorIsolation.getKind() == ActorIsolation::ActorInstance &&
195-
actorInstance->getType().isAnyActor())) &&
195+
actorInstance->getType()
196+
.getASTType()
197+
->lookThroughAllOptionalTypes()
198+
->getAnyActor())) &&
196199
"actorInstance must be an actor if it is non-empty");
197200
}
198201

lib/SILOptimizer/Utils/PartitionUtils.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -113,8 +113,9 @@ SILIsolationInfo SILIsolationInfo::get(SILInstruction *inst) {
113113
auto &self = fas.getSelfArgumentOperand();
114114
if (fas.getArgumentParameterInfo(self).hasOption(
115115
SILParameterInfo::Isolated)) {
116+
CanType astType = self.get()->getType().getASTType();
116117
if (auto *nomDecl =
117-
self.get()->getType().getNominalOrBoundGenericNominal()) {
118+
astType->lookThroughAllOptionalTypes()->getAnyActor()) {
118119
// TODO: We really should be doing this based off of an Operand. Then
119120
// we would get the SILValue() for the first element. Today this can
120121
// only mess up isolation history.
@@ -416,8 +417,8 @@ SILIsolationInfo SILIsolationInfo::get(SILArgument *arg) {
416417
// Before we do anything further, see if we have an isolated parameter. This
417418
// handles isolated self and specifically marked isolated.
418419
if (auto *isolatedArg = fArg->getFunction()->maybeGetIsolatedArgument()) {
419-
if (auto *nomDecl =
420-
isolatedArg->getType().getNominalOrBoundGenericNominal()) {
420+
auto astType = isolatedArg->getType().getASTType();
421+
if (auto *nomDecl = astType->lookThroughAllOptionalTypes()->getAnyActor()) {
421422
return SILIsolationInfo::getActorInstanceIsolated(fArg, isolatedArg,
422423
nomDecl);
423424
}

test/Concurrency/transfernonsendable.swift

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
////////////////////////
1616

1717
/// Classes are always non-sendable, so this is non-sendable
18-
class NonSendableKlass { // expected-complete-note 48{{}}
18+
class NonSendableKlass { // expected-complete-note 49{{}}
1919
// expected-typechecker-only-note @-1 4{{}}
2020
// expected-tns-note @-2 2{{}}
2121
var field: NonSendableKlass? = nil
@@ -1698,3 +1698,16 @@ func differentInstanceTest(_ a: MyActor, _ b: MyActor) async {
16981698
await b.useKlass(x) // expected-tns-note {{access can happen concurrently}}
16991699
// expected-complete-warning @-1 {{passing argument of non-sendable type 'NonSendableKlass' into actor-isolated context may introduce data races}}
17001700
}
1701+
1702+
protocol AssociatedTypeTestProtocol {
1703+
associatedtype A: Actor
1704+
}
1705+
1706+
func associatedTypeTestBasic<T: AssociatedTypeTestProtocol>(_: T, _: isolated T.A) {
1707+
}
1708+
1709+
func associatedTypeTestBasic2<T: AssociatedTypeTestProtocol>(_: T, iso: isolated T.A, x: NonSendableKlass) async {
1710+
await transferToMain(x) // expected-tns-warning {{sending 'x' risks causing data races}}
1711+
// expected-tns-note @-1 {{sending 'iso'-isolated 'x' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and 'iso'-isolated uses}}
1712+
// expected-complete-warning @-2 {{passing argument of non-sendable type 'NonSendableKlass' into main actor-isolated context may introduce data races}}
1713+
}

test/Distributed/distributed_actor_transfernonsendable.swift

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,19 @@ distributed actor MyDistributedActor {
6666
}
6767
}
6868
}
69+
70+
/////////////////////////////////
71+
// MARK: Associated Type Tests //
72+
/////////////////////////////////
73+
74+
protocol AssociatedTypeTestProtocol {
75+
associatedtype A: DistributedActor
76+
}
77+
78+
func associatedTypeTestBasic<T: AssociatedTypeTestProtocol>(_: T, _: isolated T.A) {
79+
}
80+
81+
func associatedTypeTestBasic2<T: AssociatedTypeTestProtocol>(_: T, iso: isolated T.A, x: NonSendableKlass) async {
82+
await transferToMain(x) // expected-error {{sending 'x' risks causing data races}}
83+
// expected-note @-1 {{sending 'iso'-isolated 'x' to main actor-isolated global function 'transferToMain' risks causing data races between main actor-isolated and 'iso'-isolated uses}}
84+
}

0 commit comments

Comments
 (0)