Skip to content

Commit e8b97c1

Browse files
committed
fix cycle in determining synthesized initializer kind
When synthesizing the initializer for an actor, we'd sometimes hit a cycle when that initializer needs to chain to NSObject.init. The cycle only happens because we ask if the initializer we're trying to synthesize is a convenience init, in a scenario which only applies to non-final classes. Since all actors are effectively "final" classes, it's valid to workaround the cycle by only asking that initializer question for non-final classes, thus breaking the cycle.
1 parent b473046 commit e8b97c1

File tree

2 files changed

+10
-2
lines changed

2 files changed

+10
-2
lines changed

lib/AST/ASTContext.cpp

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3066,10 +3066,14 @@ AnyFunctionType::Param swift::computeSelfParam(AbstractFunctionDecl *AFD,
30663066
}
30673067

30683068
// Convenience initializers have a dynamic 'self' in '-swift-version 5'.
3069+
//
3070+
// NOTE: it's important that we check if it's a convenience init only after
3071+
// confirming it's not semantically final, or else there can be a request
3072+
// evaluator cycle to determine the init kind for actors, which are final.
30693073
if (Ctx.isSwiftVersionAtLeast(5)) {
3070-
if (wantDynamicSelf && CD->isConvenienceInit())
3074+
if (wantDynamicSelf)
30713075
if (auto *classDecl = selfTy->getClassOrBoundGenericClass())
3072-
if (!classDecl->isSemanticallyFinal())
3076+
if (!classDecl->isSemanticallyFinal() && CD->isConvenienceInit())
30733077
isDynamicSelf = true;
30743078
}
30753079
} else if (isa<DestructorDecl>(AFD)) {

test/Concurrency/actor_isolation_objc.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,3 +55,7 @@ actor Dril: NSObject {
5555
return true
5656
}
5757
}
58+
59+
60+
// makes sure the synthesized init's delegation kind is determined correctly.
61+
actor Pumpkin: NSObject {}

0 commit comments

Comments
 (0)