mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
This code was not consulting SILFunctionConventions, so it was passing things indirect when they are not in sil-opaque-values. This fixes callers as well to ensure they pass arguments and results correctly in both modes.
285 lines
10 KiB
Swift
285 lines
10 KiB
Swift
// RUN: %target-run-simple-swift( -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
|
|
// RUN: %target-run-simple-swift(-Xfrontend -enable-sil-opaque-values -target %target-swift-5.7-abi-triple -parse-as-library) | %FileCheck %s
|
|
|
|
// REQUIRES: executable_test
|
|
// REQUIRES: concurrency
|
|
// REQUIRES: distributed
|
|
|
|
// UNSUPPORTED: use_os_stdlib
|
|
// UNSUPPORTED: back_deployment_runtime
|
|
|
|
import Distributed
|
|
|
|
distributed actor DA: CustomStringConvertible {
|
|
typealias ActorSystem = FakeActorSystem
|
|
|
|
nonisolated var description: String {
|
|
"DA(\(self.id))"
|
|
}
|
|
}
|
|
|
|
// ==== Fake Transport ---------------------------------------------------------
|
|
|
|
struct ActorAddress: Hashable, Sendable, Codable {
|
|
let address: String
|
|
init(parse address : String) {
|
|
self.address = address
|
|
}
|
|
|
|
// Explicit implementations to make our TestEncoder/Decoder simpler
|
|
init(from decoder: Decoder) throws {
|
|
let container = try decoder.singleValueContainer()
|
|
self.address = try container.decode(String.self)
|
|
print("decode ActorAddress -> \(self)")
|
|
}
|
|
|
|
func encode(to encoder: Encoder) throws {
|
|
print("encode \(self)")
|
|
var container = encoder.singleValueContainer()
|
|
try container.encode(self.address)
|
|
}
|
|
}
|
|
|
|
final class FakeActorSystem: DistributedActorSystem {
|
|
typealias ActorID = ActorAddress
|
|
typealias InvocationDecoder = FakeInvocation
|
|
typealias InvocationEncoder = FakeInvocation
|
|
typealias SerializationRequirement = Codable
|
|
typealias ResultHandler = FakeResultHandler
|
|
|
|
func resolve<Act>(id: ActorID, as actorType: Act.Type) throws -> Act?
|
|
where Act: DistributedActor,
|
|
Act.ID == ActorID {
|
|
print("resolve type:\(actorType), address:\(id)")
|
|
return nil
|
|
}
|
|
|
|
func assignID<Act>(_ actorType: Act.Type) -> ActorID
|
|
where Act: DistributedActor, Act.ID == ActorID {
|
|
let address = ActorAddress(parse: "xxx")
|
|
print("assign type:\(actorType), address:\(address)")
|
|
return address
|
|
}
|
|
|
|
func actorReady<Act>(_ actor: Act)
|
|
where Act: DistributedActor,
|
|
Act.ID == ActorID {
|
|
print("ready actor:\(actor), address:\(actor.id)")
|
|
}
|
|
|
|
func resignID(_ id: ActorID) {
|
|
print("resign address:\(id)")
|
|
}
|
|
|
|
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: \(#function)")
|
|
}
|
|
|
|
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: \(#function)")
|
|
}
|
|
|
|
}
|
|
|
|
final class FakeInvocation: DistributedTargetInvocationEncoder, DistributedTargetInvocationDecoder {
|
|
typealias SerializationRequirement = Codable
|
|
|
|
func recordGenericSubstitution<T>(_ type: T.Type) throws {}
|
|
func recordArgument<Value: SerializationRequirement>(_ argument: RemoteCallArgument<Value>) throws {}
|
|
func recordReturnType<R: SerializationRequirement>(_ type: R.Type) throws {}
|
|
func recordErrorType<E: Error>(_ type: E.Type) throws {}
|
|
func doneRecording() throws {}
|
|
|
|
// === Receiving / decoding -------------------------------------------------
|
|
|
|
func decodeGenericSubstitutions() throws -> [Any.Type] { [] }
|
|
func decodeNextArgument<Argument: SerializationRequirement>() throws -> Argument { fatalError() }
|
|
func decodeReturnType() throws -> Any.Type? { nil }
|
|
func decodeErrorType() throws -> Any.Type? { nil }
|
|
}
|
|
|
|
@available(SwiftStdlib 5.5, *)
|
|
typealias DefaultDistributedActorSystem = FakeActorSystem
|
|
|
|
// ==== Test Coding ------------------------------------------------------------
|
|
|
|
class TestEncoder: Encoder {
|
|
var codingPath: [CodingKey]
|
|
var userInfo: [CodingUserInfoKey: Any]
|
|
|
|
var data: String? = nil
|
|
|
|
init(system: FakeActorSystem) {
|
|
self.codingPath = []
|
|
self.userInfo = [.actorSystemKey: system]
|
|
}
|
|
|
|
func container<Key>(keyedBy type: Key.Type) -> KeyedEncodingContainer<Key> {
|
|
fatalError("Not implemented: \(#function)")
|
|
}
|
|
|
|
func unkeyedContainer() -> UnkeyedEncodingContainer {
|
|
fatalError("Not implemented: \(#function)")
|
|
}
|
|
|
|
func singleValueContainer() -> SingleValueEncodingContainer {
|
|
TestSingleValueEncodingContainer(parent: self)
|
|
}
|
|
|
|
class TestSingleValueEncodingContainer: SingleValueEncodingContainer {
|
|
let parent: TestEncoder
|
|
init(parent: TestEncoder) {
|
|
self.parent = parent
|
|
}
|
|
|
|
var codingPath: [CodingKey] = []
|
|
|
|
func encodeNil() throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: Bool) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: String) throws {
|
|
|
|
}
|
|
func encode(_ value: Double) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: Float) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: Int) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: Int8) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: Int16) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: Int32) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: Int64) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: UInt) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: UInt8) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: UInt16) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: UInt32) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode(_ value: UInt64) throws { fatalError("Not implemented: \(#function)") }
|
|
func encode<T: Encodable>(_ value: T) throws {
|
|
print("encode: \(value)")
|
|
if let address = value as? ActorAddress {
|
|
self.parent.data = address.address
|
|
}
|
|
}
|
|
}
|
|
|
|
func encode<Act: DistributedActor>(_ actor: Act) throws -> String where Act.ID: Codable {
|
|
try actor.encode(to: self)
|
|
return self.data!
|
|
}
|
|
}
|
|
|
|
@available(SwiftStdlib 5.5, *)
|
|
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)")
|
|
}
|
|
}
|
|
|
|
class TestDecoder: Decoder {
|
|
let encoder: TestEncoder
|
|
let data: String
|
|
|
|
init(encoder: TestEncoder, system: FakeActorSystem, data: String) {
|
|
self.encoder = encoder
|
|
self.userInfo = [.actorSystemKey: system]
|
|
self.data = data
|
|
}
|
|
|
|
var codingPath: [CodingKey] = []
|
|
var userInfo: [CodingUserInfoKey : Any]
|
|
|
|
func container<Key>(keyedBy type: Key.Type) throws -> KeyedDecodingContainer<Key> where Key : CodingKey {
|
|
fatalError("Not implemented: \(#function)")
|
|
}
|
|
func unkeyedContainer() throws -> UnkeyedDecodingContainer {
|
|
fatalError("Not implemented: \(#function)")
|
|
}
|
|
func singleValueContainer() throws -> SingleValueDecodingContainer {
|
|
TestSingleValueDecodingContainer(parent: self)
|
|
}
|
|
|
|
class TestSingleValueDecodingContainer: SingleValueDecodingContainer {
|
|
let parent: TestDecoder
|
|
init(parent: TestDecoder) {
|
|
self.parent = parent
|
|
}
|
|
|
|
var codingPath: [CodingKey] = []
|
|
func decodeNil() -> Bool { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: Bool.Type) throws -> Bool { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: String.Type) throws -> String {
|
|
print("decode String -> \(self.parent.data)")
|
|
return self.parent.data
|
|
}
|
|
func decode(_ type: Double.Type) throws -> Double { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: Float.Type) throws -> Float { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: Int.Type) throws -> Int { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: Int8.Type) throws -> Int8 { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: Int16.Type) throws -> Int16 { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: Int32.Type) throws -> Int32 { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: Int64.Type) throws -> Int64 { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: UInt.Type) throws -> UInt { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: UInt8.Type) throws -> UInt8 { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: UInt16.Type) throws -> UInt16 { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: UInt32.Type) throws -> UInt32 { fatalError("Not implemented: \(#function)") }
|
|
func decode(_ type: UInt64.Type) throws -> UInt64 { fatalError("Not implemented: \(#function)") }
|
|
func decode<T>(_ type: T.Type) throws -> T where T : Decodable { fatalError("Not implemented: \(#function)") }
|
|
}
|
|
}
|
|
|
|
// ==== Execute ----------------------------------------------------------------
|
|
|
|
func test() {
|
|
let system = DefaultDistributedActorSystem()
|
|
|
|
// CHECK: assign type:DA, address:ActorAddress(address: "xxx")
|
|
// CHECK: ready actor:DA(ActorAddress(address: "xxx"))
|
|
let da = DA(actorSystem: system)
|
|
|
|
// CHECK: encode: ActorAddress(address: "xxx")
|
|
let encoder = TestEncoder(system: system)
|
|
let data = try! encoder.encode(da)
|
|
|
|
// CHECK: decode String -> xxx
|
|
// CHECK: decode ActorAddress -> ActorAddress(address: "xxx")
|
|
let da2 = try! DA(from: TestDecoder(encoder: encoder, system: system, data: data))
|
|
|
|
// CHECK: decoded da2: DA(ActorAddress(address: "xxx"))
|
|
print("decoded da2: \(da2)")
|
|
}
|
|
|
|
@main struct Main {
|
|
static func main() async {
|
|
test()
|
|
}
|
|
}
|