Skip to content

Commit f58d609

Browse files
committed
[Distributed][Macro] handle same type requirement
1 parent b7ff16b commit f58d609

File tree

4 files changed

+85
-32
lines changed

4 files changed

+85
-32
lines changed

lib/Macros/Sources/SwiftMacros/DistributedProtocolMacro.swift

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import SwiftSyntaxBuilder
1919
/// - `distributed actor $MyDistributedActor<ActorSystem>: $MyDistributedActor, _DistributedActorStub where ...`
2020
/// - `extension MyDistributedActor where Self: _DistributedActorStub {}`
2121
public struct DistributedProtocolMacro: ExtensionMacro, PeerMacro {
22+
23+
/// Introduce the `extension MyDistributedActor` which contains default
24+
/// implementations of the protocol's requirements.
2225
public static func expansion(
2326
of node: AttributeSyntax,
2427
attachedTo declaration: some DeclGroupSyntax,
@@ -66,8 +69,34 @@ public struct DistributedProtocolMacro: ExtensionMacro, PeerMacro {
6669
}
6770

6871
// FIXME must detect this off the protocol
69-
let serializationRequirementType =
70-
"Codable"
72+
let serializationRequirementType: String = "Codable"
73+
let specificActorSystemRequirement: TypeSyntax?
74+
75+
for req in proto.genericWhereClause?.requirements ?? [] {
76+
print("req.requirement: \(req.requirement)")
77+
switch req.requirement {
78+
case .conformanceRequirement(let conformanceReq):
79+
print("conf: \(conformanceReq)")
80+
81+
case .sameTypeRequirement(let sameTypeReq):
82+
print("same type: \(sameTypeReq)")
83+
if sameTypeReq.leftType.trimmedDescription == "ActorSystem" {
84+
let specificActorSystemRequirement = sameTypeReq.rightType.trimmed
85+
86+
return [
87+
"""
88+
distributed actor $\(proto.name.trimmed): \(proto.name.trimmed),
89+
Distributed._DistributedActorStub
90+
{
91+
typealias ActorSystem = \(specificActorSystemRequirement)
92+
}
93+
"""
94+
]
95+
}
96+
case .layoutRequirement(let layoutReq):
97+
print("layout: \(layoutReq)")
98+
}
99+
}
71100

72101
let stubActorDecl: DeclSyntax =
73102
"""

stdlib/public/Distributed/DistributedMacros.swift

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,17 @@
1515
import Swift
1616
import _Concurrency
1717

18-
#if $Macros
18+
// Macros are disabled when Swift is built without swift-syntax.
19+
#if $Macros && hasAttribute(attached)
1920

21+
/// Enables the attached to protocol to be resolved as remote distributed
22+
/// actor reference.
23+
///
24+
/// ### Requirements
25+
///
26+
/// The attached to type must be a protocol that refines the `DistributedActor`
27+
/// protocol. It must either specify a concrete `ActorSystem` or constrain it
28+
/// in such way that the system's `SerializationRequirement` is statically known.
2029
@attached(peer, names: prefixed(`$`)) // provides $Greeter concrete stub type
2130
@attached(extension, names: arbitrary) // provides extension for Greeter & _DistributedActorStub
2231
public macro _DistributedProtocol() =
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// REQUIRES: swift_swift_parser, asserts
2+
//
3+
// UNSUPPORTED: back_deploy_concurrency
4+
// REQUIRES: concurrency
5+
// REQUIRES: distributed
6+
//
7+
// RUN: %empty-directory(%t)
8+
// RUN: %empty-directory(%t-scratch)
9+
10+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift
11+
// RUN: %target-swift-frontend -typecheck -verify -disable-availability-checking -plugin-path %swift-plugin-dir -parse-as-library -I %t %S/../Inputs/FakeDistributedActorSystems.swift -dump-macro-expansions %s -dump-macro-expansions 2>&1 | %FileCheck %s --dump-input=always
12+
13+
import Distributed
14+
15+
@_DistributedProtocol
16+
protocol Greeter: DistributedActor where ActorSystem == FakeActorSystem {
17+
distributed func greet(name: String) -> String
18+
}
19+
20+
// @_DistributedProtocol ->
21+
22+
// CHECK: distributed actor $Greeter: Greeter,
23+
// CHECK-NEXT: Distributed._DistributedActorStub
24+
// CHECK-NEXT: {
25+
// CHECK-NEXT: typealias ActorSystem = FakeActorSystem
26+
// CHECK-NEXT: }
27+
28+
// CHECK: extension Greeter where Self: Distributed._DistributedActorStub {
29+
// CHECK-NEXT: distributed func greet(name: String) -> String {
30+
// CHECK-NEXT: if #available (SwiftStdlib 6.0, *) {
31+
// CHECK-NEXT: Distributed._distributedStubFatalError()
32+
// CHECK-NEXT: } else {
33+
// CHECK-NEXT: fatalError()
34+
// CHECK-NEXT: }
35+
// CHECK-NEXT: }
36+
// CHECK-NEXT: }

test/Distributed/Runtime/distributed_actor_remoteCall_protocol_method.swift

Lines changed: 8 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,9 @@
11
// RUN: %empty-directory(%t)
2-
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift
3-
// RUN: %target-build-swift -module-name main -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out
2+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift -plugin-path %swift-plugin-dir
3+
// RUN: %target-build-swift -module-name main -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -plugin-path %swift-plugin-dir -o %t/a.out
44
// RUN: %target-codesign %t/a.out
55
// RUN: %target-run %t/a.out | %FileCheck %s --color --dump-input=always
66

7-
// UNSUPPORTED: OS=windows-msvc
8-
97
// REQUIRES: executable_test
108
// REQUIRES: concurrency
119
// REQUIRES: distributed
@@ -14,6 +12,9 @@
1412
// UNSUPPORTED: use_os_stdlib
1513
// UNSUPPORTED: back_deployment_runtime
1614

15+
// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574
16+
// UNSUPPORTED: OS=windows-msvc
17+
1718
// FIXME(distributed): pending rework of distributed protocol target mangling
1819
// XFAIL: *
1920

@@ -22,34 +23,11 @@ import FakeDistributedActorSystems
2223

2324
// ==== Known actor system -----------------------------------------------------
2425

25-
// @DistributedRemotelyJustViaProxyAccessible
26+
@_DistributedProtocol
2627
protocol GreeterDefinedSystemProtocol: DistributedActor where ActorSystem == FakeRoundtripActorSystem {
2728
distributed func greet() -> String
2829
}
2930

30-
// start of @Proxy output =======
31-
extension GreeterDefinedSystemProtocol where Self == GreeterDefinedSystemProtocol_Stub {
32-
static func resolve(
33-
id: ID, using system: ActorSystem
34-
) throws -> any GreeterDefinedSystemProtocol {
35-
print("\(Self.self).\(#function) -> return \(GreeterDefinedSystemProtocol_Stub.self)")
36-
37-
return try GreeterDefinedSystemProtocol_Stub.resolve(id: id, using: system)
38-
}
39-
}
40-
41-
distributed actor GreeterDefinedSystemProtocol_Stub: GreeterDefinedSystemProtocol {
42-
typealias ActorSystem = FakeRoundtripActorSystem
43-
init(actorSystem: ActorSystem) {
44-
self.actorSystem = actorSystem
45-
}
46-
47-
distributed func greet() -> String {
48-
fatalError("Stub implementation")
49-
}
50-
}
51-
// end of @Proxy output =======
52-
5331
/// A concrete implementation done on the "server" side of a non-symmetric application
5432
distributed actor GreeterImpl: GreeterDefinedSystemProtocol {
5533
typealias ActorSystem = FakeRoundtripActorSystem
@@ -70,7 +48,8 @@ distributed actor GreeterImpl: GreeterDefinedSystemProtocol {
7048
print("local call greeting: \(realGreeting)")
7149
// CHECK: local call greeting: [IMPL]:Hello from GreeterImpl
7250

73-
let proxy: any GreeterDefinedSystemProtocol = try .resolve(id: real.id, using: roundtripSystem)
51+
let proxy: any GreeterDefinedSystemProtocol =
52+
try $GreeterDefinedSystemProtocol.resolve(id: real.id, using: roundtripSystem)
7453
let greeting = try await proxy.greet()
7554
// CHECK: >> remoteCall: on:main.GreeterDefinedSystemProtocol_Stub, target:greet(), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String
7655
// CHECK: > execute distributed target: greet(), identifier: $s4main28GreeterDefinedSystemProtocolP5greetSSyFTE

0 commit comments

Comments
 (0)