Skip to content

Commit 65f09cc

Browse files
authored
Merge pull request #39708 from kavon/actor-init-fixes
2 parents 37de862 + 5888e72 commit 65f09cc

18 files changed

+539
-110
lines changed

include/swift/AST/ActorIsolation.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -106,6 +106,8 @@ class ActorIsolation {
106106
operator Kind() const { return getKind(); }
107107

108108
bool isUnspecified() const { return kind == Unspecified; }
109+
110+
bool isIndependent() const { return kind == Independent; }
109111

110112
NominalTypeDecl *getActor() const {
111113
assert(getKind() == ActorInstance || getKind() == DistributedActorInstance);

include/swift/AST/DiagnosticsSIL.def

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -168,14 +168,12 @@ ERROR(variable_defer_use_uninit,none,
168168
ERROR(self_closure_use_uninit,none,
169169
"'self' captured by a closure before all members were initialized", ())
170170

171-
/// false == sync; true == global-actor isolated
172-
ERROR(self_use_actor_init,none,
173-
"this use of actor 'self' %select{can only|cannot}0 appear in "
174-
"%select{an async|a global-actor isolated}0 initializer",
175-
(bool))
176-
ERROR(self_disallowed_actor_init,none,
177-
"actor 'self' %select{can only|cannot}0 %1 from "
178-
"%select{an async|a global-actor isolated}0 initializer",
171+
ERROR(self_disallowed_nonisolated_actor_init,none,
172+
"%select{|this use of }0actor 'self' cannot %2 %select{from|in}0 "
173+
"%select{a non-isolated, designated|a global-actor isolated}1 initializer",
174+
(bool, bool, StringRef))
175+
ERROR(self_disallowed_plain_actor_init,none,
176+
"%select{|this use of }0actor 'self' can only %1 %select{from|in}0 an async initializer",
179177
(bool, StringRef))
180178
NOTE(actor_convenience_init,none,
181179
"convenience initializers allow non-isolated use of 'self' once "

include/swift/AST/DiagnosticsSema.def

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4611,6 +4611,12 @@ ERROR(nonisolated_mutable_storage,none,
46114611
ERROR(nonisolated_local_var,none,
46124612
"'nonisolated' can not be applied to local variables",
46134613
())
4614+
ERROR(nonisolated_actor_sync_init,none,
4615+
"'nonisolated' on an actor's synchronous initializer is invalid",
4616+
())
4617+
ERROR(nonisolated_actor_convenience_init,none,
4618+
"'nonisolated' on an actor's convenience initializer is redundant",
4619+
())
46144620

46154621
ERROR(actor_instance_property_wrapper,none,
46164622
"%0 property in property wrapper type %1 cannot be isolated to "

lib/AST/ASTContext.cpp

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2936,7 +2936,6 @@ AnyFunctionType::Param swift::computeSelfParam(AbstractFunctionDecl *AFD,
29362936
bool isStatic = false;
29372937
SelfAccessKind selfAccess = SelfAccessKind::NonMutating;
29382938
bool isDynamicSelf = false;
2939-
bool isIsolated = false;
29402939

29412940
if (auto *FD = dyn_cast<FuncDecl>(AFD)) {
29422941
isStatic = FD->isStatic();
@@ -2954,10 +2953,6 @@ AnyFunctionType::Param swift::computeSelfParam(AbstractFunctionDecl *AFD,
29542953
else if (wantDynamicSelf && FD->hasDynamicSelfResult())
29552954
isDynamicSelf = true;
29562955

2957-
// If this is a non-static method within an actor, the 'self' parameter
2958-
// is isolated if this declaration is isolated.
2959-
isIsolated = evaluateOrDefault(
2960-
Ctx.evaluator, HasIsolatedSelfRequest{AFD}, false);
29612956
} else if (auto *CD = dyn_cast<ConstructorDecl>(AFD)) {
29622957
if (isInitializingCtor) {
29632958
// initializing constructors of value types always have an implicitly
@@ -3014,6 +3009,10 @@ AnyFunctionType::Param swift::computeSelfParam(AbstractFunctionDecl *AFD,
30143009
if (isStatic)
30153010
return AnyFunctionType::Param(MetatypeType::get(selfTy, Ctx));
30163011

3012+
// `self` is isolated if typechecker says the function is isolated to it.
3013+
bool isIsolated =
3014+
evaluateOrDefault(Ctx.evaluator, HasIsolatedSelfRequest{AFD}, false);
3015+
30173016
auto flags = ParameterTypeFlags().withIsolated(isIsolated);
30183017
switch (selfAccess) {
30193018
case SelfAccessKind::Consuming:

lib/SILGen/SILGenConstructor.cpp

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -681,6 +681,8 @@ void SILGenFunction::emitConstructorPrologActorHop(
681681
}
682682
}
683683

684+
// MARK: class constructor
685+
684686
void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
685687
MagicFunctionName = SILGenModule::getMagicFunctionName(ctor);
686688

@@ -784,9 +786,8 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
784786
}
785787

786788
// Distributed actor initializers implicitly initialize their transport and id
787-
if (isDesignatedDistActorInit) {
789+
if (isDesignatedDistActorInit)
788790
emitDistActorImplicitPropertyInits(ctor, selfArg);
789-
}
790791

791792
// Prepare the end of initializer location.
792793
SILLocation endOfInitLoc = RegularLocation(ctor);
@@ -818,12 +819,6 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
818819
failureExitBB = createBasicBlock();
819820
failureExitArg = failureExitBB->createPhiArgument(
820821
resultLowering.getLoweredType(), OwnershipKind::Owned);
821-
822-
// For an async distributed actor init, we must `resignIdentity` before
823-
// the clean-ups are triggered in this failure block.
824-
if (isDesignatedDistActorInit && ctor->hasAsync()) {
825-
emitResignIdentityCall(loc, selfClassDecl, selfArg);
826-
}
827822

828823
Cleanups.emitCleanupsForReturn(ctor, IsForUnwind);
829824
SILValue nilResult =
@@ -878,9 +873,6 @@ void SILGenFunction::emitClassConstructorInitializer(ConstructorDecl *ctor) {
878873

879874
// For distributed actors, their synchronous initializers invoke "actor ready"
880875
// at the very end, just before returning on a successful initialization.
881-
// There is no need for injecting `resignIdentity` calls in such inits,
882-
// even if they are failable or throwing, because we will never call
883-
// `actorReady` at a point before the init can exit abnormally.
884876
if (isDesignatedDistActorInit && !ctor->hasAsync()) {
885877
RegularLocation loc(ctor);
886878
loc.markAutoGenerated();

lib/SILGen/SILGenDistributed.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,35 @@ static void emitIdentityInit(SILGenFunction &SGF, ConstructorDecl *ctor,
178178
initializeProperty(SGF, loc, borrowedSelfArg.getValue(), var, temp);
179179
}
180180

181+
namespace {
182+
/// Cleanup to resign the identity of a distributed actor if an abnormal exit happens.
183+
class ResignIdentity : public Cleanup {
184+
ClassDecl *actorDecl;
185+
SILValue self;
186+
public:
187+
ResignIdentity(ClassDecl *actorDecl, SILValue self)
188+
: actorDecl(actorDecl), self(self) {
189+
assert(actorDecl->isDistributedActor());
190+
}
191+
192+
void emit(SILGenFunction &SGF, CleanupLocation l, ForUnwind_t forUnwind) override {
193+
if (forUnwind == IsForUnwind) {
194+
l.markAutoGenerated();
195+
SGF.emitResignIdentityCall(l, actorDecl,
196+
ManagedValue::forUnmanaged(self));
197+
}
198+
}
199+
200+
void dump(SILGenFunction &SGF) const override {
201+
#ifndef NDEBUG
202+
llvm::errs() << "ResignIdentity "
203+
<< "State:" << getState() << " "
204+
<< "Self: " << self << "\n";
205+
#endif
206+
}
207+
};
208+
} // end anonymous namespace
209+
181210
void SILGenFunction::emitDistActorImplicitPropertyInits(
182211
ConstructorDecl *ctor, ManagedValue selfArg) {
183212
// Only designated initializers should perform this initialization.
@@ -189,6 +218,10 @@ void SILGenFunction::emitDistActorImplicitPropertyInits(
189218
selfArg = selfArg.borrow(*this, loc);
190219
emitTransportInit(*this, ctor, loc, selfArg);
191220
emitIdentityInit(*this, ctor, loc, selfArg);
221+
222+
// register a clean-up to resign the identity upon abnormal exit
223+
auto *actorDecl = cast<ClassDecl>(ctor->getParent()->getAsDecl());
224+
Cleanups.pushCleanup<ResignIdentity>(actorDecl, selfArg.getValue());
192225
}
193226

194227
void SILGenFunction::emitDistributedActorReady(

0 commit comments

Comments
 (0)