Skip to content

Commit 7cadb0b

Browse files
committed
Sema: Downgrade actor convenience initializer diagnostic to a warning in interfaces.
The `convenience` keyword is not accepted on actor initializers because the compiler infers this status automatically and actors cannot be subclassed. However, internally the compiler still computes whether an actor init is a convenience init and this implicit status has been leaking through accidentally in printed `.swiftinterface` files. This was noticed because in Swift 6 the presence of the keyword is diagnosed as an error, making `.swiftinterface` files unparseable for modules containing actors with convenience inits. For Swift 6, I'm just going to suppress the error in `.swiftinterface` files regardless of language mode. In future releases of the compiler, though, it can stop printing the `convenience` keyword on these inits altogether, though. Resolves rdar://130857256.
1 parent a13c1dc commit 7cadb0b

File tree

2 files changed

+27
-3
lines changed

2 files changed

+27
-3
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -379,8 +379,9 @@ static bool doesAccessorNeedDynamicAttribute(AccessorDecl *accessor) {
379379
CtorInitializerKind
380380
InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
381381
auto &diags = decl->getASTContext().Diags;
382+
auto dc = decl->getDeclContext();
382383

383-
if (auto nominal = decl->getDeclContext()->getSelfNominalTypeDecl()) {
384+
if (auto nominal = dc->getSelfNominalTypeDecl()) {
384385

385386
// Convenience inits are only allowed on classes and in extensions thereof.
386387
if (auto convenAttr = decl->getAttrs().getAttribute<ConvenienceAttr>()) {
@@ -390,6 +391,7 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
390391
diags.diagnose(decl->getLoc(),
391392
diag::no_convenience_keyword_init, "actors")
392393
.fixItRemove(convenAttr->getLocation())
394+
.warnInSwiftInterface(dc)
393395
.warnUntilSwiftVersion(6);
394396

395397
} else { // not an actor
@@ -447,7 +449,7 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
447449
// (or the same file) to add vtable entries, we can re-evaluate this
448450
// restriction.
449451
if (!decl->isSynthesized() &&
450-
isa<ExtensionDecl>(decl->getDeclContext()->getImplementedObjCContext()) &&
452+
isa<ExtensionDecl>(dc->getImplementedObjCContext()) &&
451453
!(decl->getAttrs().hasAttribute<DynamicReplacementAttr>())) {
452454

453455
if (classDcl->getForeignClassKind() == ClassDecl::ForeignKind::CFType) {
@@ -476,7 +478,7 @@ InitKindRequest::evaluate(Evaluator &evaluator, ConstructorDecl *decl) const {
476478
} // end of Nominal context
477479

478480
// initializers in protocol extensions must be convenience inits
479-
if (decl->getDeclContext()->getExtendedProtocolDecl()) {
481+
if (dc->getExtendedProtocolDecl()) {
480482
return CtorInitializerKind::Convenience;
481483
}
482484

test/ModuleInterface/actor_init.swift

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -module-name Library
4+
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -module-name Library
5+
// RUN: %FileCheck %s --check-prefixes=CHECK < %t/Library.swiftinterface
6+
7+
// Re-verify with -swift-version 6
8+
// RUN: %target-swift-emit-module-interface(%t/Library.swiftinterface) %s -swift-version 6 -module-name Library
9+
// RUN: %target-swift-typecheck-module-from-interface(%t/Library.swiftinterface) -module-name Library
10+
// RUN: %FileCheck %s --check-prefixes=CHECK < %t/Library.swiftinterface
11+
12+
// CHECK-LABEL: public actor TestActor {
13+
@available(SwiftStdlib 5.5, *)
14+
public actor TestActor {
15+
// FIXME: The convenience keyword should be omitted (rdar://130926278)
16+
// CHECK: public convenience init(convenience: Swift.Int)
17+
public init(convenience: Int) {
18+
self.init()
19+
}
20+
// CHECK: public init()
21+
public init() {}
22+
}

0 commit comments

Comments
 (0)