1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
|
// RUN: %target-swift-emit-silgen -disable-availability-checking -parse-as-library %s | %FileCheck %s
// RUN: %target-run-simple-swift( -Xfrontend -disable-availability-checking -parse-as-library)
// REQUIRES: executable_test
// REQUIRES: concurrency
// REQUIRES: distributed
// rdar://76038845
// UNSUPPORTED: use_os_stdlib
// UNSUPPORTED: back_deployment_runtime
import Distributed
distributed actor Philosopher {
distributed func think() {
}
// CHECK: sil hidden [ossa] @$s28distributed_actor_self_calls11PhilosopherC10stopEatingyyF : $@convention(method) (@sil_isolated @guaranteed Philosopher) -> () {
func stopEating() { // NOTE: marking this async solves the issue; we find the async context then
self.think()
// Confirm we're calling the function directly, rather than the distributed thunk
// Calling the thunk would crash, because it is async (and throws), and as we're not in an async function
// trying to get the async context to call the async thunk would fail here.
//
// CHECK: // function_ref Philosopher.think()
// CHECK-NEXT: [[E:%[0-9]+]] = function_ref @$s28distributed_actor_self_calls11PhilosopherC5thinkyyF : $@convention(method) (@sil_isolated @guaranteed Philosopher) -> ()
}
}
// ==== Fake Transport ---------------------------------------------------------
struct ActorAddress: Sendable, Hashable, Codable {
let address: String
init(parse address : String) {
self.address = address
}
}
struct FakeActorSystem: DistributedActorSystem {
typealias ActorID = ActorAddress
typealias InvocationDecoder = FakeInvocationDecoder
typealias InvocationEncoder = FakeInvocationEncoder
typealias SerializationRequirement = Codable
typealias ResultHandler = FakeResultHandler
func resolve<Act>(id: ActorID, as actorType: Act.Type) throws -> Act?
where Act: DistributedActor,
Act.ID == ActorID {
return nil
}
func assignID<Act>(_ actorType: Act.Type) -> ActorID
where Act: DistributedActor {
ActorAddress(parse: "")
}
func actorReady<Act>(_ actor: Act)
where Act: DistributedActor {
print("\(#function):\(actor)")
}
func resignID(_ id: ActorID) {}
func makeInvocationEncoder() -> InvocationEncoder {
.init()
}
func remoteCall<Act, Err, Res>(
on actor: Act,
target: RemoteCallTarget,
invocation invocationEncoder: inout InvocationEncoder,
throwing: Err.Type,
returning: Res.Type
) async throws -> Res
where Act: DistributedActor,
Act.ID == ActorID,
Err: Error,
Res: SerializationRequirement {
fatalError("Not implemented")
}
func remoteCallVoid<Act, Err>(
on actor: Act,
target: RemoteCallTarget,
invocation invocationEncoder: inout InvocationEncoder,
throwing: Err.Type
) async throws
where Act: DistributedActor,
Act.ID == ActorID,
Err: Error {
fatalError("Not implemented")
}
}
// === Sending / encoding -------------------------------------------------
struct FakeInvocationEncoder: DistributedTargetInvocationEncoder {
typealias SerializationRequirement = Codable
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
mutating func recordArgument<Value: SerializationRequirement>(_ argument: RemoteCallArgument<Value>) throws {}
mutating func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws {}
mutating func recordErrorType<E: Error>(_ type: E.Type) throws {}
mutating func doneRecording() throws {}
}
// === Receiving / decoding -------------------------------------------------
class FakeInvocationDecoder : DistributedTargetInvocationDecoder {
typealias SerializationRequirement = Codable
func decodeGenericSubstitutions() throws -> [Any.Type] { [] }
func decodeNextArgument<Argument: SerializationRequirement>() throws -> Argument { fatalError() }
func decodeReturnType() throws -> Any.Type? { nil }
func decodeErrorType() throws -> Any.Type? { nil }
}
public struct FakeResultHandler: DistributedTargetInvocationResultHandler {
public typealias SerializationRequirement = Codable
public func onReturn<Success: SerializationRequirement>(value: Success) async throws {
fatalError("Not implemented: \(#function)")
}
public func onReturnVoid() async throws {
fatalError("Not implemented: \(#function)")
}
public func onThrow<Err: Error>(error: Err) async throws {
fatalError("Not implemented: \(#function)")
}
}
typealias DefaultDistributedActorSystem = FakeActorSystem
// ==== Execute ----------------------------------------------------------------
func test(system: FakeActorSystem) async {
_ = Philosopher(actorSystem: system)
}
@main struct Main {
static func main() async {
await test(system: FakeActorSystem())
}
}
|