diff --git a/lib/AST/ProtocolConformance.cpp b/lib/AST/ProtocolConformance.cpp index 9fdff392a9ee0..f6d072a88478a 100644 --- a/lib/AST/ProtocolConformance.cpp +++ b/lib/AST/ProtocolConformance.cpp @@ -1267,7 +1267,7 @@ void NominalTypeDecl::prepareConformanceTable() const { } } - // Actor classes conform to the actor protocol. + // Actor classes conform to the appropriate actor protocol. if (auto classDecl = dyn_cast(mutableThis)) { if (classDecl->isDistributedActor()) { addSynthesized(ctx.getProtocol(KnownProtocolKind::DistributedActor)); diff --git a/lib/Frontend/ModuleInterfaceSupport.cpp b/lib/Frontend/ModuleInterfaceSupport.cpp index 229e7f031e343..1f5238ccb8a01 100644 --- a/lib/Frontend/ModuleInterfaceSupport.cpp +++ b/lib/Frontend/ModuleInterfaceSupport.cpp @@ -688,10 +688,11 @@ class InheritedProtocolCollector { if (!printOptions.shouldPrint(nominal)) return; - /// is this nominal specifically an 'actor'? - bool actorClass = false; - if (auto klass = dyn_cast(nominal)) - actorClass = klass->isActor(); + /// is this nominal specifically an 'actor' or 'distributed actor'? + bool anyActorClass = false; + if (auto klass = dyn_cast(nominal)) { + anyActorClass = klass->isAnyActor(); + } SmallPtrSet handledProtocols; @@ -726,9 +727,11 @@ class InheritedProtocolCollector { // There is a special restriction on the Actor protocol in that // it is only valid to conform to Actor on an 'actor' decl, // not extensions of that 'actor'. - if (actorClass && - inherited->isSpecificProtocol(KnownProtocolKind::Actor)) - return TypeWalker::Action::SkipNode; + if (anyActorClass) { + if (inherited->isSpecificProtocol(KnownProtocolKind::Actor) || + inherited->isSpecificProtocol(KnownProtocolKind::DistributedActor)) + return TypeWalker::Action::SkipNode; + } // Do not synthesize an extension to print a conformance to an // invertible protocol, as their conformances are always re-inferred diff --git a/test/ModuleInterface/distributed-actor.swift b/test/ModuleInterface/distributed-actor.swift index 2edb8c2efbe15..1d8c73c73096e 100644 --- a/test/ModuleInterface/distributed-actor.swift +++ b/test/ModuleInterface/distributed-actor.swift @@ -73,9 +73,6 @@ public distributed actor DAG where ActorSystem: DistributedActorSys // CHECK: } } -// CHECK-NOT: #if compiler(>=5.3) && $Actors -// CHECK: @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) -// CHECK-NEXT:extension Library.DA : Distributed.DistributedActor {} // CHECK-NOT: #if compiler(>=5.3) && $Actors // CHECK: @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) // CHECK-NEXT:extension Library.DA : Swift.Encodable {} @@ -83,10 +80,6 @@ public distributed actor DAG where ActorSystem: DistributedActorSys // CHECK: @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *) // CHECK-NEXT:extension Library.DA : Swift.Decodable {} -// CHECK-NOT: #if compiler(>=5.3) && $Actors -// CHECK: @available(macOS 15.0, iOS 18.0, watchOS 11.0, tvOS 18.0, visionOS 2.0, *) -// CHECK-NEXT: extension Library.DAG : Distributed.DistributedActor {} - //--- Client.swift import Distributed diff --git a/test/ModuleInterface/distributed_no_redundant_conformance.swift b/test/ModuleInterface/distributed_no_redundant_conformance.swift new file mode 100644 index 0000000000000..88b88bc5c1f0d --- /dev/null +++ b/test/ModuleInterface/distributed_no_redundant_conformance.swift @@ -0,0 +1,23 @@ +// RUN: %empty-directory(%t) + +// RUN: %target-swift-emit-module-interface(%t/TestResilient.swiftinterface) %s -module-name TestResilient +// RUN: %target-swift-typecheck-module-from-interface(%t/TestResilient.swiftinterface) -module-name TestResilient +// RUN: %FileCheck %s < %t/TestResilient.swiftinterface + +import Distributed + +// Note that tat while an actor is implicitly conforming to Actor, we don't need to print this in interfaces +// as it would cause 'redundant conformance of ... to (Distributed)Actor' issues. + +public actor Example {} + +// CHECK-NOT: extension TestResilient.Example : _Concurrency.Actor {} + +public distributed actor DistributedExample { + public typealias ActorSystem = LocalTestingDistributedActorSystem + distributed func example() {} +} + +// CHECK: distributed public actor DistributedExample { + +// CHECK-NOT: extension TestResilient.DistributedExample : Distributed.DistributedActor {}