Skip to content

Commit d541190

Browse files
committed
[silgen] Refactor out how we compute the actor isolation for a SILFunction so we can reuse it in other contexts.
I also want to extend it and did not want to have to copy/paste this code into multiple places. The small test tweak occurs since I changed the initializer SILGen emission code to set the declref field of SILFunctions to the actual decl ref which we did not before. So we got a more specific diagnostic.
1 parent ebcab8f commit d541190

File tree

3 files changed

+26
-23
lines changed

3 files changed

+26
-23
lines changed

lib/SILGen/SILGen.cpp

Lines changed: 24 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -731,6 +731,25 @@ static bool isEmittedOnDemand(SILModule &M, SILDeclRef constant) {
731731
return false;
732732
}
733733

734+
static ActorIsolation getActorIsolationForFunction(SILFunction &fn) {
735+
if (auto constant = fn.getDeclRef()) {
736+
if (constant.kind == SILDeclRef::Kind::Deallocator) {
737+
// Deallocating destructor is always nonisolated. Isolation of the deinit
738+
// applies only to isolated deallocator and destroyer.
739+
return ActorIsolation::forNonisolated(false);
740+
}
741+
742+
// If we have actor isolation for our constant, put the isolation onto the
743+
// function. If the isolation is unspecified, we do not return it.
744+
if (auto isolation =
745+
getActorIsolationOfContext(constant.getInnermostDeclContext()))
746+
return isolation;
747+
}
748+
749+
// Otherwise, return for unspecified.
750+
return ActorIsolation::forUnspecified();
751+
}
752+
734753
SILFunction *SILGenModule::getFunction(SILDeclRef constant,
735754
ForDefinition_t forDefinition) {
736755
// If we already emitted the function, return it.
@@ -756,16 +775,8 @@ SILFunction *SILGenModule::getFunction(SILDeclRef constant,
756775
return IGM.getFunction(constant, NotForDefinition);
757776
});
758777

759-
if (constant.kind == SILDeclRef::Kind::Deallocator) {
760-
// Deallocating destructor is always nonisolated.
761-
// Isolation of the deinit applies only to isolated deallocator and
762-
// destroyer.
763-
F->setActorIsolation(ActorIsolation::forNonisolated(false));
764-
} else {
765-
// If we have global actor isolation for our constant, put the isolation onto
766-
// the function.
767-
F->setActorIsolation(getActorIsolationOfContext(constant.getInnermostDeclContext()));
768-
}
778+
F->setDeclRef(constant);
779+
F->setActorIsolation(getActorIsolationForFunction(*F));
769780

770781
assert(F && "SILFunction should have been defined");
771782

@@ -1254,23 +1265,15 @@ void SILGenModule::preEmitFunction(SILDeclRef constant, SILFunction *F,
12541265
F->setGenericEnvironment(genericEnv, capturedEnvs, forwardingSubs);
12551266
}
12561267

1257-
if (constant.kind == SILDeclRef::Kind::Deallocator) {
1258-
// Deallocating destructor is always nonisolated.
1259-
// Isolation of the deinit applies only to isolated deallocator and
1260-
// destroyer.
1261-
F->setActorIsolation(ActorIsolation::forNonisolated(false));
1262-
} else {
1263-
// If we have global actor isolation for our constant, put the isolation
1264-
// onto the function.
1265-
F->setActorIsolation(getActorIsolationOfContext(constant.getInnermostDeclContext()));
1266-
}
1267-
12681268
// Create a debug scope for the function using astNode as source location.
12691269
F->setDebugScope(new (M) SILDebugScope(Loc, F));
12701270

12711271
// Initialize F with the constant we created for it.
12721272
F->setDeclRef(constant);
12731273

1274+
// Set our actor isolation.
1275+
F->setActorIsolation(getActorIsolationForFunction(*F));
1276+
12741277
LLVM_DEBUG(llvm::dbgs() << "lowering ";
12751278
F->printName(llvm::dbgs());
12761279
llvm::dbgs() << " : ";

test/Concurrency/transfernonsendable.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1763,7 +1763,7 @@ extension MyActor {
17631763
_ = sc
17641764

17651765
Task { // expected-tns-warning {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
1766-
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument risks causing races in between local and caller code}}
1766+
// expected-tns-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to initializer 'init(priority:operation:)' risks causing races in between local and caller code}}
17671767
_ = sc
17681768
}
17691769

test/Concurrency/transfernonsendable_typed_errors.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ extension MyActor {
6060
_ = sc
6161

6262
Task { // expected-error {{sending value of non-Sendable type '() async -> ()' risks causing data races}}
63-
// expected-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument risks causing races in between local and caller code}}
63+
// expected-note @-1 {{Passing value of non-Sendable type '() async -> ()' as a 'sending' argument to initializer 'init(priority:operation:)' risks causing races in between local and caller code}}
6464
_ = sc
6565
}
6666

0 commit comments

Comments
 (0)