diff --git a/include/swift/AST/Decl.h b/include/swift/AST/Decl.h index 6910f2b27c710..07d3c2b31f88c 100644 --- a/include/swift/AST/Decl.h +++ b/include/swift/AST/Decl.h @@ -3493,9 +3493,12 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext { /// Find, or potentially synthesize, the implicit 'id' property of this actor. VarDecl *getDistributedActorIDProperty() const; - /// Find the 'RemoteCallTarget.init(_mangledName:)' initializer function + /// Find the 'RemoteCallTarget.init(_:)' initializer function ConstructorDecl* getDistributedRemoteCallTargetInitFunction() const; + /// Find the 'RemoteCallArgument(label:name:value:)' initializer function + ConstructorDecl* getDistributedRemoteCallArgumentInitFunction() const; + /// Collect the set of protocols to which this type should implicitly /// conform, such as AnyObject (for classes). void getImplicitProtocols(SmallVectorImpl &protocols); diff --git a/include/swift/AST/KnownSDKTypes.def b/include/swift/AST/KnownSDKTypes.def index 249fd18b07d82..747f1ad3d6931 100644 --- a/include/swift/AST/KnownSDKTypes.def +++ b/include/swift/AST/KnownSDKTypes.def @@ -49,6 +49,7 @@ KNOWN_SDK_TYPE_DECL(Distributed, DistributedActorSystem, ProtocolDecl, 0) KNOWN_SDK_TYPE_DECL(Distributed, DistributedTargetInvocationEncoder, ProtocolDecl, 0) KNOWN_SDK_TYPE_DECL(Distributed, DistributedTargetInvocationDecoder, ProtocolDecl, 0) KNOWN_SDK_TYPE_DECL(Distributed, RemoteCallTarget, StructDecl, 0) +KNOWN_SDK_TYPE_DECL(Distributed, RemoteCallArgument, StructDecl, 1) // String processing KNOWN_SDK_TYPE_DECL(StringProcessing, Regex, StructDecl, 1) diff --git a/include/swift/AST/TypeCheckRequests.h b/include/swift/AST/TypeCheckRequests.h index 239ca06f00c9a..cfb10f72cdd17 100644 --- a/include/swift/AST/TypeCheckRequests.h +++ b/include/swift/AST/TypeCheckRequests.h @@ -1210,7 +1210,7 @@ class GetDistributedActorSystemPropertyRequest : bool isCached() const { return true; } }; -/// Obtain the constructor of the RemoteCallTarget type. +/// Obtain the constructor of the 'RemoteCallTarget' type. class GetDistributedRemoteCallTargetInitFunctionRequest : public SimpleRequest { +public: + using SimpleRequest::SimpleRequest; + +private: + friend SimpleRequest; + + ConstructorDecl *evaluate(Evaluator &evaluator, + NominalTypeDecl *nominal) const; + +public: + // Caching + bool isCached() const { return true; } +}; + /// Obtain the 'distributed thunk' for the passed-in function. /// /// The thunk is responsible for invoking 'remoteCall' when invoked on a remote diff --git a/include/swift/AST/TypeCheckerTypeIDZone.def b/include/swift/AST/TypeCheckerTypeIDZone.def index 3fd6390dad523..2aa9b7172f3aa 100644 --- a/include/swift/AST/TypeCheckerTypeIDZone.def +++ b/include/swift/AST/TypeCheckerTypeIDZone.def @@ -145,6 +145,9 @@ SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemPropertyRequest, SWIFT_REQUEST(TypeChecker, GetDistributedRemoteCallTargetInitFunctionRequest, ConstructorDecl *(NominalTypeDecl *), Cached, NoLocationInfo) +SWIFT_REQUEST(TypeChecker, GetDistributedRemoteCallArgumentInitFunctionRequest, + ConstructorDecl *(NominalTypeDecl *), + Cached, NoLocationInfo) SWIFT_REQUEST(TypeChecker, GetDistributedActorInvocationDecoderRequest, NominalTypeDecl *(NominalTypeDecl *), Cached, NoLocationInfo) diff --git a/lib/AST/DistributedDecl.cpp b/lib/AST/DistributedDecl.cpp index d3f61b78e8091..d5b6332a63785 100644 --- a/lib/AST/DistributedDecl.cpp +++ b/lib/AST/DistributedDecl.cpp @@ -581,6 +581,11 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordArgument() const auto &C = getASTContext(); auto module = getParentModule(); + auto func = dyn_cast(this); + if (!func) { + return false; + } + // === Check base name if (getBaseIdentifier() != C.Id_recordArgument) { return false; @@ -614,6 +619,12 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordArgument() const return false; } + // --- must be mutating, if it is defined in a struct + if (isa(getDeclContext()) && + !func->isMutating()) { + return false; + } + // --- Check number of generic parameters auto genericParams = getGenericParams(); unsigned int expectedGenericParamNum = 1; @@ -639,56 +650,60 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordArgument() const return false; } - // --- Check parameter: _ argument - auto argumentParam = params->get(0); - if (!argumentParam->getArgumentName().is("")) { - return false; - } - - // === Check generic parameters in detail - // --- Check: Argument: SerializationRequirement GenericTypeParamDecl *ArgumentParam = genericParams->getParams()[0]; - auto sig = getGenericSignature(); - auto requirements = sig.getRequirements(); + // --- Check parameter: _ argument + auto argumentParam = params->get(0); + if (!argumentParam->getArgumentName().empty()) { + return false; + } - if (requirements.size() != expectedRequirementsNum) { - return false; - } + auto argumentTy = argumentParam->getInterfaceType(); + auto argumentInContextTy = mapTypeIntoContext(argumentTy); + if (argumentInContextTy->getAnyNominal() == C.getRemoteCallArgumentDecl()) { + auto argGenericParams = argumentInContextTy->getStructOrBoundGenericStruct() + ->getGenericParams()->getParams(); + if (argGenericParams.size() != 1) { + return false; + } - // --- Check the expected requirements - // --- all the Argument requirements --- - // conforms_to: Argument Decodable - // conforms_to: Argument Encodable - // ... + // the of the RemoteCallArgument + auto remoteCallArgValueGenericTy = + mapTypeIntoContext(argGenericParams[0]->getInterfaceType()) + ->getDesugaredType() + ->getMetatypeInstanceType(); + // expected (the from the recordArgument) + auto expectedGenericParamTy = mapTypeIntoContext( + ArgumentParam->getInterfaceType()->getMetatypeInstanceType()); + + if (!remoteCallArgValueGenericTy->isEqual(expectedGenericParamTy)) { + return false; + } + } else { + return false; + } - auto func = dyn_cast(this); - if (!func) { - return false; - } - auto resultType = func->mapTypeIntoContext(argumentParam->getInterfaceType()) - ->getDesugaredType(); - auto resultParamType = func->mapTypeIntoContext( - ArgumentParam->getInterfaceType()->getMetatypeInstanceType()); - // The result of the function must be the `Res` generic argument. - if (!resultType->isEqual(resultParamType)) { - return false; - } + auto sig = getGenericSignature(); + auto requirements = sig.getRequirements(); - for (auto requirementProto : requirementProtos) { - auto conformance = module->lookupConformance(resultType, requirementProto); - if (conformance.isInvalid()) { + if (requirements.size() != expectedRequirementsNum) { return false; } - } - // === Check result type: Void - if (!func->getResultInterfaceType()->isVoid()) { - return false; - } + // --- Check the expected requirements + // --- all the Argument requirements --- + // e.g. + // conforms_to: Argument Decodable + // conforms_to: Argument Encodable + // ... - return true; + // === Check result type: Void + if (!func->getResultInterfaceType()->isVoid()) { + return false; + } + + return true; } bool @@ -879,8 +894,8 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordErrorType() cons } // --- Check parameter: _ errorType - auto argumentParam = params->get(0); - if (!argumentParam->getArgumentName().is("")) { + auto errorTypeParam = params->get(0); + if (!errorTypeParam->getArgumentName().is("")) { return false; } @@ -1140,6 +1155,14 @@ NominalTypeDecl::getDistributedRemoteCallTargetInitFunction() const { GetDistributedRemoteCallTargetInitFunctionRequest(mutableThis), nullptr); } +ConstructorDecl * +NominalTypeDecl::getDistributedRemoteCallArgumentInitFunction() const { + auto mutableThis = const_cast(this); + return evaluateOrDefault( + getASTContext().evaluator, + GetDistributedRemoteCallArgumentInitFunctionRequest(mutableThis), nullptr); +} + AbstractFunctionDecl *ASTContext::getRemoteCallOnDistributedActorSystem( NominalTypeDecl *actorOrSystem, bool isVoidReturn) const { assert(actorOrSystem && "distributed actor (or system) decl must be provided"); diff --git a/lib/Sema/CodeSynthesisDistributedActor.cpp b/lib/Sema/CodeSynthesisDistributedActor.cpp index 3516f0108a6e4..8fc5cea62a5a9 100644 --- a/lib/Sema/CodeSynthesisDistributedActor.cpp +++ b/lib/Sema/CodeSynthesisDistributedActor.cpp @@ -269,13 +269,67 @@ deriveBodyDistributed_thunk(AbstractFunctionDecl *thunk, void *context) { auto recordArgumentDeclRef = UnresolvedDeclRefExpr::createImplicit( C, recordArgumentDecl->getName()); - auto recordArgArgsList = ArgumentList::forImplicitCallTo( - recordArgumentDeclRef->getName(), + auto argumentName = param->getArgumentName().str(); + LiteralExpr *argumentLabelArg; + if (argumentName.empty()) { + argumentLabelArg = new (C) NilLiteralExpr(sloc, implicit); + } else { + argumentLabelArg = + new (C) StringLiteralExpr(argumentName, SourceRange(), implicit); + } + auto parameterName = param->getParameterName().str(); + + + // --- Prepare the RemoteCallArgument for the argument + auto argumentVarName = C.getIdentifier("_" + parameterName.str()); + StructDecl *RCA = C.getRemoteCallArgumentDecl(); + VarDecl *callArgVar = + new (C) VarDecl(/*isStatic=*/false, VarDecl::Introducer::Let, sloc, + argumentVarName, thunk); + callArgVar->setImplicit(); + callArgVar->setSynthesized(); + + Pattern *callArgPattern = NamedPattern::createImplicit(C, callArgVar); + + auto remoteCallArgumentInitDecl = + RCA->getDistributedRemoteCallArgumentInitFunction(); + auto boundRCAType = BoundGenericType::get( + RCA, Type(), {thunk->mapTypeIntoContext(param->getInterfaceType())}); + auto remoteCallArgumentInitDeclRef = + TypeExpr::createImplicit(boundRCAType, C); + + auto initCallArgArgs = ArgumentList::forImplicitCallTo( + DeclNameRef(remoteCallArgumentInitDecl->getEffectiveFullName()), { - new (C) DeclRefExpr( + // label: + argumentLabelArg, + // name: + new (C) StringLiteralExpr(parameterName, SourceRange(), implicit), + // _ argument: + new (C) DeclRefExpr( ConcreteDeclRef(param), dloc, implicit, AccessSemantics::Ordinary, thunk->mapTypeIntoContext(param->getInterfaceType())) + }, + C); + + auto initCallArgCallExpr = + CallExpr::createImplicit(C, remoteCallArgumentInitDeclRef, initCallArgArgs); + initCallArgCallExpr->setImplicit(); + + auto callArgPB = PatternBindingDecl::createImplicit( + C, StaticSpellingKind::None, callArgPattern, initCallArgCallExpr, thunk); + + remoteBranchStmts.push_back(callArgPB); + remoteBranchStmts.push_back(callArgVar); + + /// --- Pass the argumentRepr to the recordArgument function + auto recordArgArgsList = ArgumentList::forImplicitCallTo( + recordArgumentDeclRef->getName(), + { + new (C) DeclRefExpr( + ConcreteDeclRef(callArgVar), dloc, implicit, + AccessSemantics::Ordinary) }, C); auto tryRecordArgExpr = TryExpr::createImplicit(C, sloc, diff --git a/lib/Sema/TypeCheckDistributed.cpp b/lib/Sema/TypeCheckDistributed.cpp index 9fa49fbde9f88..4a3397baf8062 100644 --- a/lib/Sema/TypeCheckDistributed.cpp +++ b/lib/Sema/TypeCheckDistributed.cpp @@ -305,7 +305,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements( decl->getDescriptiveKind(), decl->getName(), identifier); decl->diagnose(diag::note_distributed_actor_system_conformance_missing_adhoc_requirement, decl->getName(), identifier, - "mutating func recordArgument(_ argument: Argument) throws\n"); + "mutating func recordArgument(_ argument: RemoteCallArgument) throws\n"); anyMissingAdHocRequirements = true; } if (checkAdHocRequirementAccessControl(decl, Proto, recordArgumentDecl)) @@ -731,6 +731,48 @@ GetDistributedRemoteCallTargetInitFunctionRequest::evaluate( return nullptr; } +ConstructorDecl* +GetDistributedRemoteCallArgumentInitFunctionRequest::evaluate( + Evaluator &evaluator, + NominalTypeDecl *nominal) const { + auto &C = nominal->getASTContext(); + + // not via `ensureDistributedModuleLoaded` to avoid generating a warning, + // we won't be emitting the offending decl after all. + if (!C.getLoadedModule(C.Id_Distributed)) + return nullptr; + + if (!nominal->getDeclaredInterfaceType()->isEqual( + C.getRemoteCallArgumentType())) + return nullptr; + + for (auto value : nominal->getMembers()) { + auto ctor = dyn_cast(value); + if (!ctor) + continue; + + auto params = ctor->getParameters(); + if (params->size() != 3) + return nullptr; + + // --- param: label + if (!params->get(0)->getArgumentName().is("label")) + return nullptr; + + // --- param: name + if (!params->get(1)->getArgumentName().is("name")) + return nullptr; + + // --- param: value + if (params->get(2)->getArgumentName() != C.Id_value) + return nullptr; + + return ctor; + } + + return nullptr; +} + NominalTypeDecl * GetDistributedActorInvocationDecoderRequest::evaluate(Evaluator &evaluator, NominalTypeDecl *actor) const { diff --git a/stdlib/public/Distributed/DistributedActorSystem.swift b/stdlib/public/Distributed/DistributedActorSystem.swift index 9519f281b4777..8cff96e4531b1 100644 --- a/stdlib/public/Distributed/DistributedActorSystem.swift +++ b/stdlib/public/Distributed/DistributedActorSystem.swift @@ -12,6 +12,7 @@ import Swift import _Concurrency +/// A distributed actor system @available(SwiftStdlib 5.7, *) public protocol DistributedActorSystem: Sendable { /// The identity used by actors that communicate via this transport @@ -340,7 +341,7 @@ extension DistributedActorSystem { /// The string representation will attempt to pretty print the target identifier, /// however its exact format is not specified and may change in future versions. @available(SwiftStdlib 5.7, *) -public struct RemoteCallTarget: CustomStringConvertible { +public struct RemoteCallTarget: CustomStringConvertible, Hashable { private let _identifier: String public init(_ identifier: String) { @@ -407,6 +408,7 @@ func _executeDistributedTarget( /// Note that the decoding will be provided the specific types that the sending side used to preform the call, /// so decoding can rely on simply invoking e.g. `Codable` (if that is the `SerializationRequirement`) decoding /// entry points on the provided types. +@available(SwiftStdlib 5.7, *) public protocol DistributedTargetInvocationEncoder { associatedtype SerializationRequirement @@ -418,8 +420,9 @@ public protocol DistributedTargetInvocationEncoder { // /// // /// Record an argument of `Argument` type. // /// This will be invoked for every argument of the target, in declaration order. -// mutating func recordArgument(_ argument: Argument) throws - // TODO(distributed): offer recordArgument(label:type:) +// mutating func recordArgument( +// _ argument: DistributedTargetArgument +// ) throws /// Record the error type of the distributed method. /// This method will not be invoked if the target is not throwing. @@ -434,8 +437,51 @@ public protocol DistributedTargetInvocationEncoder { mutating func doneRecording() throws } +/// Represents an argument passed to a distributed call target. +@available(SwiftStdlib 5.7, *) +public struct RemoteCallArgument { + /// The "argument label" of the argument. + /// The label is the name visible name used in external calls made to this + /// target, e.g. for `func hello(label name: String)` it is `label`. + /// + /// If no label is specified (i.e. `func hi(name: String)`), the `label`, + /// value is empty, however `effectiveLabel` is equal to the `name`. + /// + /// In most situations, using `effectiveLabel` is more useful to identify + /// the user-visible name of this argument. + public let label: String? + + /// The effective label of this argument, i.e. if no explicit `label` was set + /// this defaults to the `name`. This reflects the semantics of call sites of + /// function declarations without explicit label definitions in Swift. + public var effectiveLabel: String { + return label ?? name + } + + /// The internal name of parameter this argument is accessible as in the + /// function body. It is not part of the functions API and may change without + /// breaking the target identifier. + /// + /// If the method did not declare an explicit `label`, it is used as the + /// `effectiveLabel`. + public let name: String + + /// The value of the argument being passed to the call. + /// As `RemoteCallArgument` is always used in conjunction with + /// `recordArgument` and populated by the compiler, this Value will generally + /// conform to a distributed actor system's `SerializationRequirement`. + public let value: Value + + public init(label: String?, name: String, value: Value) { + self.label = label + self.name = name + self.value = value + } +} + /// Decoder that must be provided to `executeDistributedTarget` and is used /// by the Swift runtime to decode arguments of the invocation. +@available(SwiftStdlib 5.7, *) public protocol DistributedTargetInvocationDecoder { associatedtype SerializationRequirement diff --git a/stdlib/public/Distributed/LocalTestingDistributedActorSystem.swift b/stdlib/public/Distributed/LocalTestingDistributedActorSystem.swift index 48502dcfdf21e..1de42b0570879 100644 --- a/stdlib/public/Distributed/LocalTestingDistributedActorSystem.swift +++ b/stdlib/public/Distributed/LocalTestingDistributedActorSystem.swift @@ -151,7 +151,7 @@ public struct LocalTestingInvocationEncoder: DistributedTargetInvocationEncoder fatalError("Attempted to call encoder method in a local-only actor system") } - public mutating func recordArgument(_ argument: Argument) throws { + public mutating func recordArgument(_ argument: RemoteCallArgument) throws { fatalError("Attempted to call encoder method in a local-only actor system") } diff --git a/test/Distributed/Inputs/BadDistributedActorSystems.swift b/test/Distributed/Inputs/BadDistributedActorSystems.swift index 8303860f568f9..2cef2ed0a25f9 100644 --- a/test/Distributed/Inputs/BadDistributedActorSystems.swift +++ b/test/Distributed/Inputs/BadDistributedActorSystems.swift @@ -257,8 +257,8 @@ public struct FakeInvocationEncoder : DistributedTargetInvocationEncoder { genericSubs.append(type) } - public mutating func recordArgument(_ argument: Argument) throws { - print(" > encode argument: \(argument)") + public mutating func recordArgument(_ argument: RemoteCallArgument) throws { + print(" > encode argument name:\(argument.effectiveLabel), argument: \(argument.value)") arguments.append(argument) } public mutating func recordErrorType(_ type: E.Type) throws { diff --git a/test/Distributed/Inputs/FakeDistributedActorSystems.swift b/test/Distributed/Inputs/FakeDistributedActorSystems.swift index d9f8611f6e5ad..8e9512e2d0f59 100644 --- a/test/Distributed/Inputs/FakeDistributedActorSystems.swift +++ b/test/Distributed/Inputs/FakeDistributedActorSystems.swift @@ -267,18 +267,22 @@ public struct FakeInvocationEncoder : DistributedTargetInvocationEncoder { genericSubs.append(type) } - public mutating func recordArgument(_ argument: Argument) throws { - print(" > encode argument: \(argument)") - arguments.append(argument) + public mutating func recordArgument( + _ argument: RemoteCallArgument) throws { + print(" > encode argument name:\(argument.label ?? "_"), value: \(argument.value)") + arguments.append(argument.value) } + public mutating func recordErrorType(_ type: E.Type) throws { print(" > encode error type: \(String(reflecting: type))") self.errorType = type } + public mutating func recordReturnType(_ type: R.Type) throws { print(" > encode return type: \(String(reflecting: type))") self.returnType = type } + public mutating func doneRecording() throws { print(" > done recording") } diff --git a/test/Distributed/Inputs/dynamic_replacement_da_decl.swift b/test/Distributed/Inputs/dynamic_replacement_da_decl.swift index 564db85955074..368c45f168a8a 100644 --- a/test/Distributed/Inputs/dynamic_replacement_da_decl.swift +++ b/test/Distributed/Inputs/dynamic_replacement_da_decl.swift @@ -87,7 +87,7 @@ struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} diff --git a/test/Distributed/Runtime/distributed_actor_decode.swift b/test/Distributed/Runtime/distributed_actor_decode.swift index 8f602a35c0d53..a6344d73fb650 100644 --- a/test/Distributed/Runtime/distributed_actor_decode.swift +++ b/test/Distributed/Runtime/distributed_actor_decode.swift @@ -101,11 +101,11 @@ final class FakeActorSystem: DistributedActorSystem { } -class FakeInvocation: DistributedTargetInvocationEncoder, DistributedTargetInvocationDecoder { +final class FakeInvocation: DistributedTargetInvocationEncoder, DistributedTargetInvocationDecoder { typealias SerializationRequirement = Codable func recordGenericSubstitution(_ type: T.Type) throws {} - func recordArgument(_ argument: Argument) throws {} + func recordArgument(_ argument: RemoteCallArgument) throws {} func recordReturnType(_ type: R.Type) throws {} func recordErrorType(_ type: E.Type) throws {} func doneRecording() throws {} diff --git a/test/Distributed/Runtime/distributed_actor_deinit.swift b/test/Distributed/Runtime/distributed_actor_deinit.swift index f32524efd361a..6c7dfbb152f1b 100644 --- a/test/Distributed/Runtime/distributed_actor_deinit.swift +++ b/test/Distributed/Runtime/distributed_actor_deinit.swift @@ -57,8 +57,8 @@ struct ActorAddress: Sendable, Hashable, Codable { final class FakeActorSystem: @unchecked Sendable, DistributedActorSystem { typealias ActorID = ActorAddress typealias SerializationRequirement = Codable - typealias InvocationDecoder = FakeDistributedInvocation - typealias InvocationEncoder = FakeDistributedInvocation + typealias InvocationDecoder = FakeDistributedInvocationEncoder + typealias InvocationEncoder = FakeDistributedInvocationEncoder var n = 0 @@ -119,11 +119,11 @@ final class FakeActorSystem: @unchecked Sendable, DistributedActorSystem { } } -class FakeDistributedInvocation: DistributedTargetInvocationEncoder, DistributedTargetInvocationDecoder { +class FakeDistributedInvocationEncoder: DistributedTargetInvocationEncoder, DistributedTargetInvocationDecoder { typealias SerializationRequirement = Codable func recordGenericSubstitution(_ type: T.Type) throws { } - func recordArgument(_ argument: Argument) throws { } + func recordArgument(_ argument: RemoteCallArgument) throws { } func recordReturnType(_ type: R.Type) throws { } func recordErrorType(_ type: E.Type) throws { } func doneRecording() throws { } diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift index 5c9922d8ac32d..aacd409c422d6 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift @@ -40,7 +40,7 @@ func test() async throws { let r1 = try await ref.generic("Caplin") // CHECK: > encode generic sub: Swift.String - // CHECK: > encode argument: Caplin + // CHECK: > encode argument name:_, value: Caplin // CHECK: > encode return type: Swift.String // CHECK: > done recording // CHECK: >> remoteCall: on:main.Greeter, target:main.Greeter.generic(_:), invocation:FakeInvocationEncoder(genericSubs: [Swift.String], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String @@ -54,9 +54,9 @@ func test() async throws { ) // CHECK: > encode generic sub: Swift.String // CHECK: > encode generic sub: Swift.Int - // CHECK: > encode argument: 2.0 - // CHECK: > encode argument: Caplin - // CHECK: > encode argument: [1, 2, 3] + // CHECK: > encode argument name:strict, value: 2.0 + // CHECK: > encode argument name:_, value: Caplin + // CHECK: > encode argument name:_, value: [1, 2, 3] // CHECK: > encode return type: Swift.String // CHECK: > done recording // CHECK: >> remoteCall: on:main.Greeter, target:main.Greeter.generic2(strict:_:_:), invocation:FakeInvocationEncoder(genericSubs: [Swift.String, Swift.Int], arguments: [2.0, "Caplin", [1, 2, 3]], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift index ae1310ed60d10..fdb1a9a345e88 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take_two.swift @@ -29,6 +29,12 @@ distributed actor Greeter { distributed func take(name: String, int: Int, clazz: SomeClass) { print("take: \(name), int: \(int), clazz: \(clazz)") } + + distributed func params(param p1: String, param p2: Int) -> String { + let message = "params: p1: \(p1), p2: \(p2)" + print(message) + return message + } } func test() async throws { @@ -40,8 +46,10 @@ func test() async throws { try await ref.take(name: "Caplin", int: 1337) // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.take(name:int:), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin", 1337], returnType: nil, errorType: nil), throwing:Swift.Never - // try await ref.take(name: "Caplin", int: 1337, clazz: .init()) // FIXME(distributed): crashes + try await ref.take(name: "Caplin", int: 1337, clazz: .init()) + let r3 = try await ref.params(param: "one", param: 2) + print("r3 = \(r3)") // CHECK: r3 = params: p1: one, p2: 2 } @main struct Main { diff --git a/test/Distributed/Runtime/distributed_actor_init_local.swift b/test/Distributed/Runtime/distributed_actor_init_local.swift index 2dcd74a111b53..39d07005d3bf8 100644 --- a/test/Distributed/Runtime/distributed_actor_init_local.swift +++ b/test/Distributed/Runtime/distributed_actor_init_local.swift @@ -126,7 +126,7 @@ struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall.swift b/test/Distributed/Runtime/distributed_actor_remoteCall.swift index 498560c49ecc7..cdb2054a08998 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall.swift @@ -182,8 +182,8 @@ struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { mutating func recordGenericSubstitution(_ type: T.Type) throws { substitutions.append(type) } - mutating func recordArgument(_ argument: Argument) throws { - arguments.append(argument) + mutating func recordArgument(_ argument: RemoteCallArgument) throws { + arguments.append(argument.value) } mutating func recordErrorType(_ type: E.Type) throws { self.errorType = type @@ -343,8 +343,8 @@ func test() async throws { // CHECK: RETURN: bar var echoInvocation = system.makeInvocationEncoder() - try echoInvocation.recordArgument("Caplin") - try echoInvocation.recordArgument(42) + try echoInvocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: "Caplin")) + try echoInvocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: 42)) try echoInvocation.doneRecording() var echoDecoder = echoInvocation.makeDecoder() @@ -359,7 +359,7 @@ func test() async throws { var generic1Invocation = system.makeInvocationEncoder() try generic1Invocation.recordGenericSubstitution(Int.self) - try generic1Invocation.recordArgument(42) + try generic1Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: 42)) try generic1Invocation.doneRecording() var generic1Decoder = generic1Invocation.makeDecoder() @@ -376,8 +376,8 @@ func test() async throws { try generic2Invocation.recordGenericSubstitution(Int.self) try generic2Invocation.recordGenericSubstitution(String.self) - try generic2Invocation.recordArgument(42) - try generic2Invocation.recordArgument("Ultimate Question!") + try generic2Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: 42)) + try generic2Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: "Ultimate Question!")) try generic2Invocation.doneRecording() var generic2Decoder = generic2Invocation.makeDecoder() @@ -396,9 +396,9 @@ func test() async throws { try generic3Invocation.recordGenericSubstitution(Int.self) try generic3Invocation.recordGenericSubstitution(String.self) try generic3Invocation.recordGenericSubstitution(S.self) - try generic3Invocation.recordArgument(42) - try generic3Invocation.recordArgument(["a", "b", "c"]) - try generic3Invocation.recordArgument(S(data: 42)) + try generic3Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: 42)) + try generic3Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: ["a", "b", "c"])) + try generic3Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: S(data: 42))) try generic3Invocation.doneRecording() var generic3Decoder = generic3Invocation.makeDecoder() @@ -418,9 +418,9 @@ func test() async throws { try generic4Invocation.recordGenericSubstitution(Int.self) try generic4Invocation.recordGenericSubstitution(Int.self) try generic4Invocation.recordGenericSubstitution(String.self) - try generic4Invocation.recordArgument(42) - try generic4Invocation.recordArgument(S(data: 42)) - try generic4Invocation.recordArgument(["a", "b", "c"]) + try generic4Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: 42)) + try generic4Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: S(data: 42))) + try generic4Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: ["a", "b", "c"])) try generic4Invocation.doneRecording() var generic4Decoder = generic4Invocation.makeDecoder() @@ -441,10 +441,10 @@ func test() async throws { try generic5Invocation.recordGenericSubstitution(Int.self) try generic5Invocation.recordGenericSubstitution(String.self) try generic5Invocation.recordGenericSubstitution([Int].self) - try generic5Invocation.recordArgument(42) - try generic5Invocation.recordArgument(S(data: 42)) - try generic5Invocation.recordArgument("Hello, World!") - try generic5Invocation.recordArgument([0, 42]) + try generic5Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: 42)) + try generic5Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: S(data: 42))) + try generic5Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: "Hello, World!")) + try generic5Invocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: [0, 42])) try generic5Invocation.doneRecording() var generic5Decoder = generic5Invocation.makeDecoder() @@ -467,7 +467,7 @@ func test() async throws { var genericOptInvocation = system.makeInvocationEncoder() try genericOptInvocation.recordGenericSubstitution([Int].self) - try genericOptInvocation.recordArgument([0, 42]) + try genericOptInvocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: [0, 42])) try genericOptInvocation.doneRecording() var genericOptDecoder = genericOptInvocation.makeDecoder() @@ -482,7 +482,7 @@ func test() async throws { var decodeErrInvocation = system.makeInvocationEncoder() - try decodeErrInvocation.recordArgument(42) + try decodeErrInvocation.recordArgument(RemoteCallArgument(label: "argument-name", name: "argument-name", value: 42)) try decodeErrInvocation.doneRecording() var decodeErrDecoder = decodeErrInvocation.makeDecoder() diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift b/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift index fffb546d6e058..b68824964b88e 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall_roundtrip.swift @@ -46,7 +46,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) let reply = try await ref.echo(name: "Caplin") - // CHECK: > encode argument: Caplin + // CHECK: > encode argument name:name, value: Caplin // CHECK-NOT: > encode error type // CHECK: > encode return type: Swift.String // CHECK: > done recording diff --git a/test/Distributed/Runtime/distributed_actor_remote_functions.swift b/test/Distributed/Runtime/distributed_actor_remote_functions.swift index a12103c470bb6..8fdd824b838cf 100644 --- a/test/Distributed/Runtime/distributed_actor_remote_functions.swift +++ b/test/Distributed/Runtime/distributed_actor_remote_functions.swift @@ -153,7 +153,7 @@ struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} diff --git a/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift b/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift index 831a9f0b47545..c7c282ab6ea2a 100644 --- a/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift +++ b/test/Distributed/Runtime/distributed_actor_remote_retains_system.swift @@ -101,7 +101,7 @@ class FakeInvocation: DistributedTargetInvocationEncoder, DistributedTargetInvoc typealias SerializationRequirement = Codable func recordGenericSubstitution(_ type: T.Type) throws {} - func recordArgument(_ argument: Argument) throws {} + func recordArgument(_ argument: RemoteCallArgument) throws {} func recordReturnType(_ type: R.Type) throws {} func recordErrorType(_ type: E.Type) throws {} func doneRecording() throws {} diff --git a/test/Distributed/Runtime/distributed_actor_self_calls.swift b/test/Distributed/Runtime/distributed_actor_self_calls.swift index 2afcc63c9a1c1..805bc8d4e65f2 100644 --- a/test/Distributed/Runtime/distributed_actor_self_calls.swift +++ b/test/Distributed/Runtime/distributed_actor_self_calls.swift @@ -99,7 +99,7 @@ struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} diff --git a/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift b/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift index f0f89a1f3bc40..d3e144a0c7a4f 100644 --- a/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift +++ b/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift @@ -500,7 +500,7 @@ struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} @@ -510,7 +510,7 @@ struct AnyInvocationEncoder: DistributedTargetInvocationEncoder { typealias SerializationRequirement = Any mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} @@ -520,7 +520,7 @@ struct LargeSerializationReqFakeInvocationEncoder: DistributedTargetInvocationEn typealias SerializationRequirement = Codable & SomeProtocol mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} @@ -530,7 +530,7 @@ public struct PublicFakeInvocationEncoder: DistributedTargetInvocationEncoder { public typealias SerializationRequirement = Codable public mutating func recordGenericSubstitution(_ type: T.Type) throws {} - public mutating func recordArgument(_ argument: Argument) throws {} + public mutating func recordArgument(_ argument: RemoteCallArgument) throws {} public mutating func recordReturnType(_ type: R.Type) throws {} public mutating func recordErrorType(_ type: E.Type) throws {} public mutating func doneRecording() throws {} @@ -542,7 +542,7 @@ struct FakeInvocationEncoder_missing_recordArgument: DistributedTargetInvocation typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - // MISSING: mutating func recordArgument(_ argument: Argument) throws {} + // MISSING: mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} @@ -566,7 +566,7 @@ struct FakeInvocationEncoder_missing_recordReturnType: DistributedTargetInvocati typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} // MISSING: mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} @@ -577,7 +577,7 @@ struct FakeInvocationEncoder_missing_recordErrorType: DistributedTargetInvocatio typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} // MISSING: mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} @@ -596,6 +596,17 @@ struct FakeInvocationEncoder_recordArgument_wrongType: DistributedTargetInvocati mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {} } +struct FakeInvocationEncoder_recordArgument_missingMutating: DistributedTargetInvocationEncoder { + //expected-error@-1{{struct 'FakeInvocationEncoder_recordArgument_missingMutating' is missing witness for protocol requirement 'recordArgument'}} + //expected-note@-2{{protocol 'FakeInvocationEncoder_recordArgument_missingMutating' requires function 'recordArgument' with signature:}} + typealias SerializationRequirement = Codable + + mutating func recordGenericSubstitution(_ type: T.Type) throws {} + func recordArgument(_ argument: RemoteCallArgument) throws {} + mutating func recordReturnType(_ type: R.Type) throws {} + mutating func recordErrorType(_ type: E.Type) throws {} + mutating func doneRecording() throws {} +} struct FakeInvocationEncoder_recordResultType_wrongType: DistributedTargetInvocationEncoder { //expected-error@-1{{struct 'FakeInvocationEncoder_recordResultType_wrongType' is missing witness for protocol requirement 'recordReturnType'}} @@ -603,7 +614,7 @@ struct FakeInvocationEncoder_recordResultType_wrongType: DistributedTargetInvoca typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(s: String, _ resultType: R.Type) throws {} // BAD mutating func recordReturnType(_ resultType: R.Type) throws {} // BAD mutating func recordReturnType(badName: R.Type) throws {} // BAD @@ -616,7 +627,7 @@ struct FakeInvocationEncoder_recordErrorType_wrongType: DistributedTargetInvocat typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(BadName type: E.Type) throws {} // BAD mutating func recordErrorType(_ type: E.Type) throws {} // BAD diff --git a/test/IRGen/distributed_actor.swift b/test/IRGen/distributed_actor.swift index 650b9c27b6fe3..3d79b94d9de08 100644 --- a/test/IRGen/distributed_actor.swift +++ b/test/IRGen/distributed_actor.swift @@ -102,7 +102,7 @@ public struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { public typealias SerializationRequirement = Codable public mutating func recordGenericSubstitution(_ type: T.Type) throws {} - public mutating func recordArgument(_ argument: Argument) throws {} + public mutating func recordArgument(_ argument: RemoteCallArgument) throws {} public mutating func recordReturnType(_ type: R.Type) throws {} public mutating func recordErrorType(_ type: E.Type) throws {} public mutating func doneRecording() throws {} diff --git a/test/SILGen/distributed_thunk.swift b/test/SILGen/distributed_thunk.swift index 8a7cef11da516..a712879190cbd 100644 --- a/test/SILGen/distributed_thunk.swift +++ b/test/SILGen/distributed_thunk.swift @@ -106,7 +106,7 @@ public struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { public typealias SerializationRequirement = Codable public mutating func recordGenericSubstitution(_ type: T.Type) throws {} - public mutating func recordArgument(_ argument: Argument) throws {} + public mutating func recordArgument(_ argument: RemoteCallArgument) throws {} public mutating func recordReturnType(_ type: R.Type) throws {} public mutating func recordErrorType(_ type: E.Type) throws {} public mutating func doneRecording() throws {} diff --git a/test/Serialization/Inputs/def_distributed.swift b/test/Serialization/Inputs/def_distributed.swift index 977d6962718e7..2c401dd44c445 100644 --- a/test/Serialization/Inputs/def_distributed.swift +++ b/test/Serialization/Inputs/def_distributed.swift @@ -99,7 +99,7 @@ public struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { public typealias SerializationRequirement = Codable public mutating func recordGenericSubstitution(_ type: T.Type) throws {} - public mutating func recordArgument(_ argument: Argument) throws {} + public mutating func recordArgument(_ argument: RemoteCallArgument) throws {} public mutating func recordReturnType(_ type: R.Type) throws {} public mutating func recordErrorType(_ type: E.Type) throws {} public mutating func doneRecording() throws {} diff --git a/test/TBD/distributed.swift b/test/TBD/distributed.swift index 3de6fce702e1d..3eb079c3df344 100644 --- a/test/TBD/distributed.swift +++ b/test/TBD/distributed.swift @@ -115,7 +115,7 @@ public struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { public typealias SerializationRequirement = Codable public mutating func recordGenericSubstitution(_ type: T.Type) throws {} - public mutating func recordArgument(_ argument: Argument) throws {} + public mutating func recordArgument(_ argument: RemoteCallArgument) throws {} public mutating func recordReturnType(_ type: R.Type) throws {} public mutating func recordErrorType(_ type: E.Type) throws {} public mutating func doneRecording() throws {} diff --git a/test/decl/protocol/special/DistributedActor.swift b/test/decl/protocol/special/DistributedActor.swift index 239059bcbacec..85841ec084e02 100644 --- a/test/decl/protocol/special/DistributedActor.swift +++ b/test/decl/protocol/special/DistributedActor.swift @@ -161,7 +161,7 @@ struct FakeInvocationEncoder: DistributedTargetInvocationEncoder { typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} - mutating func recordArgument(_ argument: Argument) throws {} + mutating func recordArgument(_ argument: RemoteCallArgument) throws {} mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(_ type: E.Type) throws {} mutating func doneRecording() throws {}