Skip to content

Commit d73b907

Browse files
committed
[Distributed] Avoid redundant conformance to DistributedActor in interface files
Forgetting to handle DistributedActor next to Actor strikes again: Actors are special that their conformance is implicit and needs not be printed in swift interface files. an actor's Actor conformance was filtered out, however the same logic needs to be applied to DistributedActor, as otherwise there can be redundant conformance errors when validating module interface files. Resolves rdar://160252579
1 parent d8393c4 commit d73b907

File tree

3 files changed

+36
-4
lines changed

3 files changed

+36
-4
lines changed

lib/AST/ProtocolConformance.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1267,7 +1267,7 @@ void NominalTypeDecl::prepareConformanceTable() const {
12671267
}
12681268
}
12691269

1270-
// Actor classes conform to the actor protocol.
1270+
// Actor classes conform to the appropriate actor protocol.
12711271
if (auto classDecl = dyn_cast<ClassDecl>(mutableThis)) {
12721272
if (classDecl->isDistributedActor()) {
12731273
addSynthesized(ctx.getProtocol(KnownProtocolKind::DistributedActor));

lib/Frontend/ModuleInterfaceSupport.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -688,10 +688,13 @@ class InheritedProtocolCollector {
688688
if (!printOptions.shouldPrint(nominal))
689689
return;
690690

691-
/// is this nominal specifically an 'actor'?
691+
/// is this nominal specifically an 'actor' or 'distributed actor'?
692692
bool actorClass = false;
693-
if (auto klass = dyn_cast<ClassDecl>(nominal))
693+
bool distributedActorClass = false;
694+
if (auto klass = dyn_cast<ClassDecl>(nominal)) {
694695
actorClass = klass->isActor();
696+
distributedActorClass = klass->isDistributedActor();
697+
}
695698

696699
SmallPtrSet<ProtocolDecl *, 16> handledProtocols;
697700

@@ -727,7 +730,10 @@ class InheritedProtocolCollector {
727730
// it is only valid to conform to Actor on an 'actor' decl,
728731
// not extensions of that 'actor'.
729732
if (actorClass &&
730-
inherited->isSpecificProtocol(KnownProtocolKind::Actor))
733+
inherited->isSpecificProtocol(KnownProtocolKind::Actor))
734+
return TypeWalker::Action::SkipNode;
735+
if (distributedActorClass &&
736+
inherited->isSpecificProtocol(KnownProtocolKind::DistributedActor))
731737
return TypeWalker::Action::SkipNode;
732738

733739
// Do not synthesize an extension to print a conformance to an
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// RUN: %empty-directory(%t)
2+
3+
// RUN: %target-swift-emit-module-interface(%t/TestResilient.swiftinterface) %s -module-name TestResilient
4+
// RUN: %target-swift-typecheck-module-from-interface(%t/TestResilient.swiftinterface) -module-name TestResilient
5+
// RUN: %FileCheck %s --dump-input=always < %t/TestResilient.swiftinterface
6+
7+
// RUN: %target-swift-frontend -compile-module-from-interface -swift-version 5 %t/TestResilient.swiftinterface -o %t/TestResilient.swiftmodule
8+
// RUN: %target-swift-frontend -emit-module -o /dev/null -merge-modules -swift-version 5 -emit-module-interface-path - %t/TestResilient.swiftmodule -module-name TestResilient | %FileCheck %s
9+
10+
import Distributed
11+
12+
// Note that tat while an actor is implicitly conforming to Actor, we don't need to print this in interfaces
13+
// as it would cause 'redundant conformance of ... to (Distributed)Actor' issues.
14+
15+
public actor Example {}
16+
17+
// CHECK-NOT: extension TestResilient.Example : _Concurrency.Actor {}
18+
19+
public distributed actor DistributedExample {
20+
public typealias ActorSystem = LocalTestingDistributedActorSystem
21+
distributed func example() {}
22+
}
23+
24+
// CHECK: distributed public actor DistributedExample {
25+
26+
// CHECK-NOT: extension TestResilient.DistributedExample : Distributed.DistributedActor {}

0 commit comments

Comments
 (0)