From 14bbd27e83fabd69bfc7c0faa687f2f9ee057878 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 14 Mar 2022 09:46:51 +0900 Subject: [PATCH 1/5] [Distributed] remove a few warnings --- lib/SILGen/SILGenDistributed.cpp | 2 -- lib/Sema/CodeSynthesisDistributedActor.cpp | 1 - 2 files changed, 3 deletions(-) diff --git a/lib/SILGen/SILGenDistributed.cpp b/lib/SILGen/SILGenDistributed.cpp index e687b0eb3e9ca..0acf739f552ee 100644 --- a/lib/SILGen/SILGenDistributed.cpp +++ b/lib/SILGen/SILGenDistributed.cpp @@ -43,8 +43,6 @@ using namespace Lowering; /// or the subsequent cast to VarDecl failed. static VarDecl* lookupProperty(NominalTypeDecl *decl, DeclName name) { assert(decl && "decl was null"); - auto &C = decl->getASTContext(); - if (auto clazz = dyn_cast(decl)) { auto refs = decl->lookupDirect(name); if (refs.size() != 1) diff --git a/lib/Sema/CodeSynthesisDistributedActor.cpp b/lib/Sema/CodeSynthesisDistributedActor.cpp index 96eed482a31c6..a9737f8d566b4 100644 --- a/lib/Sema/CodeSynthesisDistributedActor.cpp +++ b/lib/Sema/CodeSynthesisDistributedActor.cpp @@ -564,7 +564,6 @@ addDistributedActorCodableConformance( assert(proto->isSpecificProtocol(swift::KnownProtocolKind::Decodable) || proto->isSpecificProtocol(swift::KnownProtocolKind::Encodable)); auto &C = actor->getASTContext(); - auto DC = actor->getDeclContext(); auto module = actor->getParentModule(); // === Only Distributed actors can gain this implicit conformance From 8925f9d8fb2cf6946b434e51057fdb0f2f153bc9 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 14 Mar 2022 13:32:57 +0900 Subject: [PATCH 2/5] [Distributed] recordErrorType is not ad-hoc requirement anymore --- lib/Sema/TypeCheckDistributed.cpp | 17 +---------------- .../Distributed/DistributedActorSystem.swift | 8 +++----- 2 files changed, 4 insertions(+), 21 deletions(-) diff --git a/lib/Sema/TypeCheckDistributed.cpp b/lib/Sema/TypeCheckDistributed.cpp index 8bd39063ebde1..80aa6d47c29ab 100644 --- a/lib/Sema/TypeCheckDistributed.cpp +++ b/lib/Sema/TypeCheckDistributed.cpp @@ -310,22 +310,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements( } if (checkAdHocRequirementAccessControl(decl, Proto, recordArgumentDecl)) anyMissingAdHocRequirements = true; - - // - recordErrorType - auto recordErrorTypeDecl = C.getRecordErrorTypeOnDistributedInvocationEncoder(decl); - if (!recordErrorTypeDecl) { - auto identifier = C.Id_recordErrorType; - decl->diagnose( - diag::distributed_actor_system_conformance_missing_adhoc_requirement, - decl->getDescriptiveKind(), decl->getName(), identifier); - decl->diagnose(diag::note_distributed_actor_system_conformance_missing_adhoc_requirement, - decl->getName(), identifier, - "mutating func recordErrorType(_ errorType: Err.Type) throws\n"); - anyMissingAdHocRequirements = true; - } - if (checkAdHocRequirementAccessControl(decl, Proto, recordErrorTypeDecl)) - anyMissingAdHocRequirements = true; - + // - recordReturnType auto recordReturnTypeDecl = C.getRecordReturnTypeOnDistributedInvocationEncoder(decl); if (!recordReturnTypeDecl) { diff --git a/stdlib/public/Distributed/DistributedActorSystem.swift b/stdlib/public/Distributed/DistributedActorSystem.swift index 474fe7086ba36..0cfe4cc918890 100644 --- a/stdlib/public/Distributed/DistributedActorSystem.swift +++ b/stdlib/public/Distributed/DistributedActorSystem.swift @@ -407,11 +407,9 @@ public protocol DistributedTargetInvocationEncoder { // mutating func recordArgument(_ argument: Argument) throws // TODO(distributed): offer recordArgument(label:type:) -// /// Ad-hoc requirement -// /// -// /// Record the error type of the distributed method. -// /// This method will not be invoked if the target is not throwing. -// mutating func recordErrorType(_ type: E.Type) throws // TODO: make not adhoc + /// Record the error type of the distributed method. + /// This method will not be invoked if the target is not throwing. + mutating func recordErrorType(_ type: E.Type) throws // /// Ad-hoc requirement // /// From 4fa0855907c59d845bfb124f0258adec506b891a Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Mon, 14 Mar 2022 21:01:43 +0900 Subject: [PATCH 3/5] [Distributed] RemoteCallTarget now pretty prints and hides mangled names --- include/swift/Runtime/HeapObject.h | 9 ++ lib/Sema/TypeCheckDistributed.cpp | 2 +- .../Distributed/DistributedActorSystem.swift | 98 +++++++----- stdlib/public/core/Misc.swift | 29 ++++ stdlib/public/runtime/Casting.cpp | 141 ++++++++++++++++++ .../Inputs/BadDistributedActorSystems.swift | 8 +- .../Inputs/FakeDistributedActorSystems.swift | 8 +- ...ted_actor_func_calls_remoteCall_echo.swift | 2 +- ...ed_actor_func_calls_remoteCall_empty.swift | 2 +- ...or_func_calls_remoteCall_genericFunc.swift | 4 +- ...ed_actor_func_calls_remoteCall_hello.swift | 2 +- ...ted_actor_func_calls_remoteCall_take.swift | 2 +- ...unc_calls_remoteCall_takeThrowReturn.swift | 2 +- ...actor_func_calls_remoteCall_take_two.swift | 2 +- ...ed_actor_func_calls_remoteCall_throw.swift | 2 +- .../distributed_actor_remoteCall.swift | 28 ++-- ...moteCallTarget_demanglingTargetNames.swift | 80 ++++++++++ .../distributed_actor_remote_functions.swift | 22 +-- ...stem_missing_adhoc_requirement_impls.swift | 37 +++-- 19 files changed, 376 insertions(+), 104 deletions(-) create mode 100644 test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift diff --git a/include/swift/Runtime/HeapObject.h b/include/swift/Runtime/HeapObject.h index e3487eaef3ced..efb50b3f93c57 100644 --- a/include/swift/Runtime/HeapObject.h +++ b/include/swift/Runtime/HeapObject.h @@ -1101,6 +1101,15 @@ swift_getTypeName(const Metadata *type, bool qualified); /// -> (UnsafePointer, Int) SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API TypeNamePair +swift_getFunctionFullNameFromMangledName( + const char *mangledNameStart, uintptr_t mangledNameLength); + +/// Return the human-readable full name of the mangled function name passed in. +/// func _getMangledTypeName(_ mangledName: UnsafePointer, +/// mangledNameLength: UInt) +/// -> (UnsafePointer, Int) +SWIFT_CC(swift) SWIFT_RUNTIME_STDLIB_API +TypeNamePair swift_getMangledTypeName(const Metadata *type); } // end namespace swift diff --git a/lib/Sema/TypeCheckDistributed.cpp b/lib/Sema/TypeCheckDistributed.cpp index 80aa6d47c29ab..f8bec3cdf3df0 100644 --- a/lib/Sema/TypeCheckDistributed.cpp +++ b/lib/Sema/TypeCheckDistributed.cpp @@ -310,7 +310,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements( } if (checkAdHocRequirementAccessControl(decl, Proto, recordArgumentDecl)) anyMissingAdHocRequirements = true; - + // - recordReturnType auto recordReturnTypeDecl = C.getRecordReturnTypeOnDistributedInvocationEncoder(decl); if (!recordReturnTypeDecl) { diff --git a/stdlib/public/Distributed/DistributedActorSystem.swift b/stdlib/public/Distributed/DistributedActorSystem.swift index 0cfe4cc918890..d57f6bead91ef 100644 --- a/stdlib/public/Distributed/DistributedActorSystem.swift +++ b/stdlib/public/Distributed/DistributedActorSystem.swift @@ -172,23 +172,18 @@ extension DistributedActorSystem { /// latency sensitive-use-cases. public func executeDistributedTarget( on actor: Act, - mangledTargetName: String, + target: RemoteCallTarget, invocationDecoder: inout InvocationDecoder, handler: ResultHandler ) async throws where Act: DistributedActor, // Act.ID == ActorID, // FIXME(distributed): can we bring this back? ResultHandler: DistributedTargetInvocationResultHandler { - // NOTE: this implementation is not the most efficient, nor final, version of this func - // we end up demangling the name multiple times, perform more heap allocations than - // we truly need to etc. We'll eventually move this implementation to a specialized one - // avoiding these issues. - guard mangledTargetName.count > 0 && mangledTargetName.first == "$" else { + // Get the expected parameter count of the func + guard let targetName = target.identifier else { throw ExecuteDistributedTargetError( - message: "Illegal mangledTargetName detected, must start with '$'") + message: "Unable to extract target identifier from remote call target: \(target)") } - - // Get the expected parameter count of the func - let nameUTF8 = Array(mangledTargetName.utf8) + let nameUTF8 = Array(targetName.utf8) // Gen the generic environment (if any) associated with the target. let genericEnv = nameUTF8.withUnsafeBufferPointer { nameUTF8 in @@ -207,7 +202,9 @@ extension DistributedActorSystem { if let genericEnv = genericEnv { let subs = try invocationDecoder.decodeGenericSubstitutions() - + for item in subs { + print("SUB: \(item)") + } if subs.isEmpty { throw ExecuteDistributedTargetError( message: "Cannot call generic method without generic argument substitutions") @@ -224,7 +221,7 @@ extension DistributedActorSystem { genericArguments: substitutionsBuffer!) if numWitnessTables < 0 { throw ExecuteDistributedTargetError( - message: "Generic substitutions \(subs) do not satisfy generic requirements of \(mangledTargetName)") + message: "Generic substitutions \(subs) do not satisfy generic requirements of \(target) (\(targetName))") } } @@ -237,7 +234,7 @@ extension DistributedActorSystem { message: """ Failed to decode distributed invocation target expected parameter count, error code: \(paramCount) - mangled name: \(mangledTargetName) + mangled name: \(targetName) """) } @@ -262,7 +259,7 @@ extension DistributedActorSystem { message: """ Failed to decode the expected number of params of distributed invocation target, error code: \(decodedNum) (decoded: \(decodedNum), expected params: \(paramCount) - mangled name: \(mangledTargetName) + mangled name: \(targetName) """) } @@ -280,7 +277,7 @@ extension DistributedActorSystem { return UnsafeRawPointer(UnsafeMutablePointer.allocate(capacity: 1)) } - guard let returnTypeFromTypeInfo: Any.Type = _getReturnTypeInfo(mangledMethodName: mangledTargetName, + guard let returnTypeFromTypeInfo: Any.Type = _getReturnTypeInfo(mangledMethodName: targetName, genericEnv: genericEnv, genericArguments: substitutionsBuffer) else { throw ExecuteDistributedTargetError( @@ -307,7 +304,7 @@ extension DistributedActorSystem { // Execute the target! try await _executeDistributedTarget( on: actor, - mangledTargetName, UInt(mangledTargetName.count), + targetName, UInt(targetName.count), argumentDecoder: &invocationDecoder, argumentTypes: argumentTypesBuffer.baseAddress!._rawValue, resultBuffer: resultBuffer._rawValue, @@ -326,6 +323,52 @@ extension DistributedActorSystem { } } +/// Represents a 'target' of a distributed call, such as a `distributed func` or +/// `distributed` computed property. Identification schemes may vary between +/// systems, and are subject to evolution. +/// +/// Actor systems generally should treat the `identifier` as an opaque string, +/// and pass it along to the remote system for in their `remoteCall` +/// implementation. Alternative approaches are possible, where the identifiers +/// are either compressed, cached, or represented in other ways, as long as the +/// recipient system is able to determine which target was intended to be +/// invoked. +/// +/// 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 { + private let _storage: _Storage + private enum _Storage { + case mangledName(String) + } + + // Only intended to be created by the _Distributed library. + // TODO(distributed): make this internal and only allow calling by the synthesized code? + public init(_mangledName: String) { + self._storage = .mangledName(_mangledName) + } + + /// The underlying identifier of the target, returned as-is. + public var identifier: String? { + switch self._storage { + case .mangledName(let name): + return name + } + } + + public var description: String { + switch self._storage { + case .mangledName(let mangledName): + if let name = _getFunctionFullNameFromMangledName(mangledName: mangledName) { + return name + } else { + return "\(mangledName)" + } + } + } +} + @available(SwiftStdlib 5.7, *) @_silgen_name("swift_distributed_execute_target") func _executeDistributedTarget( @@ -339,29 +382,6 @@ func _executeDistributedTarget( numWitnessTables: UInt ) async throws -// ==== ---------------------------------------------------------------------------------------------------------------- -// MARK: Support types -/// A distributed 'target' can be a `distributed func` or `distributed` computed property. -@available(SwiftStdlib 5.7, *) -public struct RemoteCallTarget { // TODO: ship this around always; make printing nice - let _mangledName: String // TODO: StaticString would be better here; no arc, codesize of cleanups - - // Only intended to be created by the _Distributed library. - // TODO(distributed): make this internal and only allow calling by the synthesized code? - public init(_mangledName: String) { - self._mangledName = _mangledName - } - - public var mangledName: String { - _mangledName - } - - // .Base.hello(hi:) - public var fullName: String { // TODO: make description - fatalError("NOT IMPLEMENTED YET: \(#function)") - } -} - /// Used to encode an invocation of a distributed target (method or computed property). /// /// ## Forming an invocation diff --git a/stdlib/public/core/Misc.swift b/stdlib/public/core/Misc.swift index 572443f90cfc3..d1d40ba895bdc 100644 --- a/stdlib/public/core/Misc.swift +++ b/stdlib/public/core/Misc.swift @@ -46,6 +46,35 @@ public func _autorelease(_ x: AnyObject) { } #endif + +@available(SwiftStdlib 5.7, *) +@_silgen_name("swift_getFunctionFullNameFromMangledName") +public // SPI (Distributed) +func _getFunctionFullNameFromMangledNameImpl( + _ mangledName: UnsafePointer, _ mangledNameLength: UInt +) -> (UnsafePointer, UInt) + +/// Given a function's mangled name, return a human readable name. +/// Used e.g. by Distributed.RemoteCallTarget to hide mangled names. +@available(SwiftStdlib 5.7, *) +public // SPI (Distributed) +func _getFunctionFullNameFromMangledName(mangledName: String) -> String? { + let mangledNameUTF8 = Array(mangledName.utf8) + let (stringPtr, count) = + mangledNameUTF8.withUnsafeBufferPointer { (mangledNameUTF8) in + return _getFunctionFullNameFromMangledNameImpl( + mangledNameUTF8.baseAddress!, + UInt(mangledNameUTF8.endIndex)) + } + + guard count > 0 else { + return nil + } + + return String._fromUTF8Repairing( + UnsafeBufferPointer(start: stringPtr, count: Int(count))).0 +} + // FIXME(ABI)#51 : this API should allow controlling different kinds of // qualification separately: qualification with module names and qualification // with type names that we are nested in. diff --git a/stdlib/public/runtime/Casting.cpp b/stdlib/public/runtime/Casting.cpp index 566a1802cbe92..34880edce5f13 100644 --- a/stdlib/public/runtime/Casting.cpp +++ b/stdlib/public/runtime/Casting.cpp @@ -146,6 +146,7 @@ using TypeNameCacheKey = llvm::PointerIntPair #if SWIFT_CASTING_SUPPORTS_MUTEX static StaticReadWriteLock TypeNameCacheLock; +static StaticReadWriteLock MangledToPrettyFunctionNameCacheLock; #endif /// Cache containing rendered names for Metadata. @@ -153,6 +154,11 @@ static StaticReadWriteLock TypeNameCacheLock; static Lazy>> TypeNameCache; +/// Cache containing rendered human-readable names for incoming mangled names. +static Lazy>> +/// Access MUST be protected using `MangledToPrettyFunctionNameCache`. + MangledToPrettyFunctionNameCache; + TypeNamePair swift::swift_getTypeName(const Metadata *type, bool qualified) { TypeNameCacheKey key = TypeNameCacheKey(type, qualified ? TypeNameKind::Qualified: TypeNameKind::NotQualified); @@ -255,6 +261,141 @@ swift::swift_getMangledTypeName(const Metadata *type) { } } + +TypeNamePair +swift::swift_getFunctionFullNameFromMangledName( + const char *mangledNameStart, uintptr_t mangledNameLength) { + llvm::StringRef mangledName(mangledNameStart, mangledNameLength); + + auto &cache = MangledToPrettyFunctionNameCache.get(); + // Attempt read-only lookup of cache entry. + { + #if SWIFT_CASTING_SUPPORTS_MUTEX + StaticScopedReadLock guard(MangledToPrettyFunctionNameCacheLock); + #endif + + auto found = cache.find(mangledName); + if (found != cache.end()) { + auto result = found->second; + return TypeNamePair{result.first, result.second}; + } + } + + for (char c : mangledName) { + if (c >= '\x01' && c <= '\x1F') + return TypeNamePair{nullptr, 0}; + } + + // Read-only lookup failed, we may need to demangle and cache the entry. + // We have to copy the string to be able to refer to it "forever": + auto copy = (char *)malloc(mangledNameLength); + memcpy(copy, mangledNameStart, mangledNameLength); + mangledName = StringRef(copy, mangledNameLength); + + std::string demangled; + StackAllocatedDemangler<1024> Dem; + NodePointer node = Dem.demangleSymbol(mangledName); + if (!node) { + return TypeNamePair{nullptr, 0}; + } + + // Form the demangled string from the node tree. + node = node->findByKind(Demangle::Node::Kind::Function, /*maxDepth=*/3); + if (!node || node->getNumChildren() < 3) { + // we normally expect Class/Identifier/Type, but don't need `Type` + return TypeNamePair{nullptr, 0}; + } + + // Class identifier: + auto clazz = node->findByKind(Demangle::Node::Kind::Class, 1); + if (clazz) { + if (auto module = clazz->findByKind(Demangle::Node::Kind::Module, 1)) { + demangled += module->getText(); + demangled += "."; + } + if (auto clazzIdent = clazz->findByKind(Demangle::Node::Kind::Identifier, 1)) { + demangled += clazzIdent->getText(); + demangled += "."; + } + } + + // Function identifier: + NodePointer funcIdent = nullptr; // node == Function + for (size_t i = 0; i < node->getNumChildren(); ++i) { + if (node->getChild(i)->getKind() == Demangle::Node::Kind::Identifier) { + funcIdent = node->getChild(i); + } + } + + // We always expect to work with functions here and they must have idents + if (!funcIdent) { + return TypeNamePair{nullptr, 0}; + } + assert(funcIdent->getKind() == Demangle::Node::Kind::Identifier); + demangled += funcIdent->getText(); + demangled += "("; + + if (auto labelList = node->findByKind(Demangle::Node::Kind::LabelList, /*maxDepth=*/1)) { + if (labelList->getNumChildren()) { + size_t paramIdx = 0; + while (paramIdx < labelList->getNumChildren()) { + auto labelIdentifier = labelList->getChild(paramIdx++); + if (labelIdentifier) { + if (labelIdentifier->getKind() == Demangle::Node::Kind::Identifier) { + demangled += labelIdentifier->getText(); + demangled += ":"; + } else if (labelIdentifier->getKind() == + Demangle::Node::Kind::FirstElementMarker) { + demangled += "_:"; + } + } + } + } else if (auto argumentTuple = node->findByKind( + Demangle::Node::Kind::ArgumentTuple, /*maxDepth=*/5)) { + // LabelList was empty. + // + // The function has no labels at all, but could have some parameters... + // we need to check for their count, and render it as e.g. (::) for two + // anonymous parameters. + auto params = argumentTuple->getFirstChild(); + if (auto paramsType = params->getFirstChild()) { + if (paramsType->getKind() != Demangle::Node::Kind::Tuple) { + // was a single, unnamed, parameter + demangled += "_:"; + } else { + // there are a few parameters; find out how many + while (params && params->getFirstChild() && + params->getFirstChild()->getKind() != + Demangle::Node::Kind::TupleElement) { + params = params->getFirstChild(); + } + if (params) { + for (size_t i = 0; i < params->getNumChildren(); ++i) { + demangled += "_:"; + } + } + } + } + } + } + demangled += ")"; + + // We have to copy the string to be able to refer to it; + auto size = demangled.size(); + auto result = (char *)malloc(size + 1); + memcpy(result, demangled.data(), size); + result[size] = 0; // 0-terminated string + + { + #if SWIFT_CASTING_SUPPORTS_MUTEX + StaticScopedWriteLock guard(MangledToPrettyFunctionNameCacheLock); + #endif + + cache.insert({mangledName, {result, size}}); + return TypeNamePair{result, size}; + } +} + /// Report a dynamic cast failure. // This is noinline to preserve this frame in stack traces. // We want "dynamicCastFailure" to appear in crash logs even we crash diff --git a/test/Distributed/Inputs/BadDistributedActorSystems.swift b/test/Distributed/Inputs/BadDistributedActorSystems.swift index d40693b3838be..26ba103035ea7 100644 --- a/test/Distributed/Inputs/BadDistributedActorSystems.swift +++ b/test/Distributed/Inputs/BadDistributedActorSystems.swift @@ -87,7 +87,7 @@ public struct MissingRemoteCallVoidActorSystem: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } // func remoteCallVoid( @@ -99,7 +99,7 @@ public struct MissingRemoteCallVoidActorSystem: DistributedActorSystem { // where Act: DistributedActor, // Act.ID == ActorID, // Err: Error { -// throw ExecuteDistributedTargetError(message: "Not implemented.") +// throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") // } } @@ -177,7 +177,7 @@ public final class FakeRoundtripActorSystem: DistributedActorSystem, @unchecked } try await executeDistributedTarget( on: active, - mangledTargetName: target.mangledName, + target: target, invocationDecoder: invocation.makeDecoder(), handler: resultHandler ) @@ -224,7 +224,7 @@ public final class FakeRoundtripActorSystem: DistributedActorSystem, @unchecked } try await executeDistributedTarget( on: active, - mangledTargetName: target.mangledName, + target: target, invocationDecoder: invocation.makeDecoder(), handler: resultHandler ) diff --git a/test/Distributed/Inputs/FakeDistributedActorSystems.swift b/test/Distributed/Inputs/FakeDistributedActorSystems.swift index 385477d54cca6..b7f276b903cef 100644 --- a/test/Distributed/Inputs/FakeDistributedActorSystems.swift +++ b/test/Distributed/Inputs/FakeDistributedActorSystems.swift @@ -87,7 +87,7 @@ public struct FakeActorSystem: DistributedActorSystem, CustomStringConvertible { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } public func remoteCallVoid( @@ -99,7 +99,7 @@ public struct FakeActorSystem: DistributedActorSystem, CustomStringConvertible { where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } public nonisolated var description: Swift.String { @@ -184,7 +184,7 @@ public final class FakeRoundtripActorSystem: DistributedActorSystem, @unchecked try await executeDistributedTarget( on: active, - mangledTargetName: target.mangledName, + target: target, invocationDecoder: &decoder, handler: resultHandler ) @@ -234,7 +234,7 @@ public final class FakeRoundtripActorSystem: DistributedActorSystem, @unchecked try await executeDistributedTarget( on: active, - mangledTargetName: target.mangledName, + target: target, invocationDecoder: &decoder, handler: resultHandler ) diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift index 425b83e6589f9..6583b545faadd 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_echo.swift @@ -32,7 +32,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) let reply = try await ref.echo(name: "Caplin") - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4echo4nameS2S_tYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:main.Greeter.echo(name:), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String // CHECK: << remoteCall return: Echo: Caplin print("reply: \(reply)") diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift index e5505a1401b5f..9d37fdab58e38 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_empty.swift @@ -31,7 +31,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) try await ref.empty() - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC5emptyyyYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: nil), throwing:Swift.Never + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.empty(), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: nil), throwing:Swift.Never // CHECK: << onReturn: () } 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 a7635d6af064c..db62c1a0c35b3 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_genericFunc.swift @@ -43,7 +43,7 @@ func test() async throws { // CHECK: > encode argument: Caplin // CHECK: > encode return type: Swift.String // CHECK: > done recording - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC7genericySSxYaKSeRzSERzlFTE"), invocation:FakeInvocationEncoder(genericSubs: [Swift.String], arguments: ["Caplin"], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String + // 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 print("reply: \(r1)") // CHECK: reply: Caplin @@ -59,7 +59,7 @@ func test() async throws { // CHECK: > encode argument: [1, 2, 3] // CHECK: > encode return type: Swift.String // CHECK: > done recording - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC8generic26strict__SSSd_xSayq_GtYaKSeRzSERzSeR_SER_r0_lFTE"), 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 + // 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 print("reply: \(r2)") // CHECK: reply: Caplin } diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift index 12995b7a52f9c..623161522b23a 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_hello.swift @@ -32,7 +32,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) let response = try await ref.hello() - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC5helloSSyYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:main.Greeter.hello(), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: Optional(Swift.String), errorType: nil), throwing:Swift.Never, returning:Swift.String print("response: \(response)") // CHECK: response: Hello, World! diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift index 2716946afec5a..092d207a74b22 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_take.swift @@ -32,7 +32,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) try await ref.take(name: "Caplin") - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4take4nameySS_tYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: nil, errorType: nil), throwing:Swift.Never + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.take(name:), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin"], returnType: nil, errorType: nil), throwing:Swift.Never // CHECK: take: Caplin } diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift index 79d90abb81f4b..222f6d40d378a 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_takeThrowReturn.swift @@ -35,7 +35,7 @@ func test() async throws { do { let value = try await ref.takeThrowReturn(name: "Example") - // CHECK: >> remoteCall: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC15takeThrowReturn4nameS2S_tYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Example"], returnType: Optional(Swift.String), errorType: Optional(Swift.Error)), throwing:Swift.Error, returning:Swift.String + // CHECK: >> remoteCall: on:main.Greeter, target:main.Greeter.takeThrowReturn(name:), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Example"], returnType: Optional(Swift.String), errorType: Optional(Swift.Error)), throwing:Swift.Error, returning:Swift.String print("did not throw") // CHECK-NOT: did not throw 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 19de7df32e262..97179d10be875 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 @@ -38,7 +38,7 @@ func test() async throws { let ref = try Greeter.resolve(id: local.id, using: system) try await ref.take(name: "Caplin", int: 1337) - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC4take4name3intySS_SitYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Caplin", 1337], returnType: nil, errorType: nil), throwing:Swift.Never + // 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 diff --git a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift index ad81ce107e07d..6f110d876cdba 100644 --- a/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift +++ b/test/Distributed/Runtime/distributed_actor_func_calls_remoteCall_throw.swift @@ -35,7 +35,7 @@ func test() async throws { do { try await ref.maybeThrows() - // CHECK: >> remoteCallVoid: on:main.Greeter, target:RemoteCallTarget(_mangledName: "$s4main7GreeterC11maybeThrowsyyYaKFTE"), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: Optional(Swift.Error)), throwing:Swift.Error + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.maybeThrows(), invocation:FakeInvocationEncoder(genericSubs: [], arguments: [], returnType: nil, errorType: Optional(Swift.Error)), throwing:Swift.Error print("did not throw") // CHECK-NOT: did not throw diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall.swift b/test/Distributed/Runtime/distributed_actor_remoteCall.swift index 887deb1149c5e..e156d9463f07c 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall.swift @@ -1,6 +1,6 @@ // RUN: %empty-directory(%t) // RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeCodableForDistributedTests.swiftmodule -module-name FakeCodableForDistributedTests -disable-availability-checking %S/../Inputs/FakeCodableForDistributedTests.swift -// RUN: %target-build-swift -module-name main -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeCodableForDistributedTests.swift -o %t/a.out +// RUN: %target-build-swift -module-name main -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeCodableForDistributedTests.swift -o %t/a.out // RUN: %target-run %t/a.out | %FileCheck %s --color // REQUIRES: executable_test @@ -304,7 +304,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - mangledTargetName: emptyName, + target: RemoteCallTarget(_mangledName: emptyName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -312,7 +312,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - mangledTargetName: helloName, + target: RemoteCallTarget(_mangledName: helloName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -320,7 +320,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - mangledTargetName: answerName, + target: RemoteCallTarget(_mangledName: answerName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -328,7 +328,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - mangledTargetName: largeResultName, + target: RemoteCallTarget(_mangledName: largeResultName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -336,7 +336,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - mangledTargetName: enumResultName, + target: RemoteCallTarget(_mangledName: enumResultName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -350,7 +350,7 @@ func test() async throws { var echoDecoder = echoInvocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: echoName, + target: RemoteCallTarget(_mangledName: echoName), invocationDecoder: &echoDecoder, handler: FakeResultHandler() ) @@ -365,7 +365,7 @@ func test() async throws { var generic1Decoder = generic1Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: generic1Name, + target: RemoteCallTarget(_mangledName: generic1Name), invocationDecoder: &generic1Decoder, handler: FakeResultHandler() ) @@ -383,7 +383,7 @@ func test() async throws { var generic2Decoder = generic2Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: generic2Name, + target: RemoteCallTarget(_mangledName: generic2Name), invocationDecoder: &generic2Decoder, handler: FakeResultHandler() ) @@ -404,7 +404,7 @@ func test() async throws { var generic3Decoder = generic3Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: generic3Name, + target: RemoteCallTarget(_mangledName: generic3Name), invocationDecoder: &generic3Decoder, handler: FakeResultHandler() ) @@ -426,7 +426,7 @@ func test() async throws { var generic4Decoder = generic4Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: generic4Name, + target: RemoteCallTarget(_mangledName: generic4Name), invocationDecoder: &generic4Decoder, handler: FakeResultHandler() ) @@ -450,7 +450,7 @@ func test() async throws { var generic5Decoder = generic5Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: generic5Name, + target: RemoteCallTarget(_mangledName: generic5Name), invocationDecoder: &generic5Decoder, handler: FakeResultHandler() ) @@ -473,7 +473,7 @@ func test() async throws { var genericOptDecoder = genericOptInvocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: genericOptionalName, + target: RemoteCallTarget(_mangledName: genericOptionalName), invocationDecoder: &genericOptDecoder, handler: FakeResultHandler() ) @@ -488,7 +488,7 @@ func test() async throws { var decodeErrDecoder = decodeErrInvocation.makeDecoder() try await system.executeDistributedTarget( on: local, - mangledTargetName: expectsDecodeErrorName, + target: RemoteCallTarget(_mangledName: expectsDecodeErrorName), invocationDecoder: &decodeErrDecoder, handler: FakeResultHandler() ) diff --git a/test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift b/test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift new file mode 100644 index 0000000000000..7c0a73d45d873 --- /dev/null +++ b/test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift @@ -0,0 +1,80 @@ +// RUN: %empty-directory(%t) +// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift +// 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 +// RUN: %target-run %t/a.out | %FileCheck %s --color + +// REQUIRES: executable_test +// REQUIRES: concurrency +// REQUIRES: distributed + +// rdar://76038845 +// UNSUPPORTED: use_os_stdlib +// UNSUPPORTED: back_deployment_runtime + +// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574 +// UNSUPPORTED: windows + +import _Distributed +import FakeDistributedActorSystems + +typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem + +distributed actor Greeter { + distributed func noParams() {} + distributed func noParamsThrows() throws {} + distributed func noLabel(_ value: String) {} + distributed func noLabels2(_ value: String, _ value2: String) {} + distributed func noLabels3(_ value: String, _ value2: String, _ value3: String) {} + distributed func oneLabel(value: String, _ value2: String, _ value3: String) {} + distributed func parameterSingle(first: String) {} + distributed func parameterPair(first: String, second: Int) {} + // FIXME(distributed): rdar://90293494 fails to get +// distributed func generic(first: A) {} +// distributed func genericNoLabel(_ first: A) {} +} +extension Greeter { + distributed func parameterTriple(first: String, second: Int, third: Double) {} +} + +func test() async throws { + let system = DefaultDistributedActorSystem() + let g = Greeter(system: system) + let greeter = try Greeter.resolve(id: g.id, using: system) + + try await greeter.noParams() + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.noParams() + + _ = try await greeter.parameterSingle(first: "X") + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterSingle(first:) + + try await greeter.noLabel("") + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.noLabel(_:) + + try await greeter.noLabels2("", "") + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.noLabels2(_:_:) + + try await greeter.noLabels3("", "", "") + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.noLabels3(_:_:_:) + + try await greeter.oneLabel(value: "", "", "") + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.oneLabel(value:_:_:) + + _ = try await greeter.parameterPair(first: "X", second: 2) + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterPair(first:second:) + + _ = try await greeter.parameterTriple(first: "X", second: 2, third: 3.0) + // CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterTriple(first:second:third:) + + // FIXME: rdar://90293494 seems to fail getting the substitutions? +// _ = try await greeter.generic(first: "X") +// // TODO: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterTriple(first:second:third:) + + print("done") + // CHECK: done +} + +@main struct Main { + static func main() async { + try! await test() + } +} diff --git a/test/Distributed/Runtime/distributed_actor_remote_functions.swift b/test/Distributed/Runtime/distributed_actor_remote_functions.swift index 2dff787567eda..3f60926193053 100644 --- a/test/Distributed/Runtime/distributed_actor_remote_functions.swift +++ b/test/Distributed/Runtime/distributed_actor_remote_functions.swift @@ -128,11 +128,11 @@ struct FakeActorSystem: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - guard target.mangledName != "$s4main28SomeSpecificDistributedActorC24helloThrowsTransportBoomSSyYaKFTE" else { + guard "\(target)" != "main.SomeSpecificDistributedActor.helloThrowsTransportBoom()" else { throw Boom("system") } - return "remote(\(target.mangledName))" as! Res + return "remote(\(target))" as! Res } func remoteCallVoid( @@ -234,18 +234,12 @@ func test_remote_invoke(address: ActorAddress, system: FakeActorSystem) async { print("remote isRemote: \(__isRemoteActor(remote))") // CHECK: remote isRemote: true await check(actor: remote) - // TODO(distributed): remote - helloAsyncThrows: remote(_remote_impl_helloAsyncThrows()) - // CHECK: remote - helloAsyncThrows: remote($s4main28SomeSpecificDistributedActorC16helloAsyncThrowsSSyYaKFTE) - // TODO(distributed): remote - helloAsync: remote() - // CHECK: remote - helloAsync: remote($s4main28SomeSpecificDistributedActorC10helloAsyncSSyYaKFTE) - // TODO(distributed): remote - helloThrows: remote(_remote_impl_helloThrows()) - // CHECK: remote - helloThrows: remote($s4main28SomeSpecificDistributedActorC11helloThrowsSSyYaKFTE) - // TODO(distributed): remote - hello: remote(_remote_impl_hello()) - // CHECK: remote - hello: remote($s4main28SomeSpecificDistributedActorC5helloSSyYaKFTE) - // TODO(distributed): remote - callTaskSelf: remote(_remote_impl_callTaskSelf()) - // CHECK: remote - callTaskSelf: remote($s4main28SomeSpecificDistributedActorC12callTaskSelfSSyYaKFTE) - // TODO(distributed): remote - callDetachedSelf: remote(_remote_impl_callDetachedSelf()) - // CHECK: remote - callDetachedSelf: remote($s4main28SomeSpecificDistributedActorC16callDetachedSelfSSyYaKFTE) + // CHECK: remote - helloAsyncThrows: remote(main.SomeSpecificDistributedActor.helloAsyncThrows()) + // CHECK: remote - helloAsync: remote(main.SomeSpecificDistributedActor.helloAsync()) + // CHECK: remote - helloThrows: remote(main.SomeSpecificDistributedActor.helloThrows()) + // CHECK: remote - hello: remote(main.SomeSpecificDistributedActor.hello()) + // CHECK: remote - callTaskSelf: remote(main.SomeSpecificDistributedActor.callTaskSelf()) + // CHECK: remote - callDetachedSelf: remote(main.SomeSpecificDistributedActor.callDetachedSelf()) // CHECK: remote - helloThrowsTransportBoom: Boom(whoFailed: "system") print(local) 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 26fe5d44fe575..be10bc5e2799c 100644 --- a/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift +++ b/test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift @@ -139,7 +139,7 @@ struct Error_wrongReturn: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } public func remoteCall( @@ -153,7 +153,7 @@ struct Error_wrongReturn: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } public func remoteCallVoid( @@ -165,7 +165,7 @@ struct Error_wrongReturn: DistributedActorSystem { where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } } @@ -209,7 +209,7 @@ struct BadRemoteCall_param: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } public func remoteCallVoid( @@ -221,7 +221,7 @@ struct BadRemoteCall_param: DistributedActorSystem { where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } } @@ -260,7 +260,7 @@ public struct BadRemoteCall_notPublic: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } // expected-error@+1{{method 'remoteCallVoid(on:target:invocation:throwing:)' must be as accessible as its enclosing type because it matches a requirement in protocol 'DistributedActorSystem'}} @@ -273,7 +273,7 @@ public struct BadRemoteCall_notPublic: DistributedActorSystem { where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } } @@ -314,7 +314,7 @@ public struct BadRemoteCall_badResultConformance: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SomeProtocol { // ERROR: bad, this must be SerializationRequirement - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } public func remoteCallVoid( @@ -326,7 +326,7 @@ public struct BadRemoteCall_badResultConformance: DistributedActorSystem { where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } } @@ -366,7 +366,7 @@ struct BadRemoteCall_largeSerializationRequirement: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } func remoteCallVoid( @@ -378,7 +378,7 @@ struct BadRemoteCall_largeSerializationRequirement: DistributedActorSystem { where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } } @@ -419,7 +419,7 @@ struct BadRemoteCall_largeSerializationRequirementSlightlyOffInDefinition: Distr Act.ID == ActorID, Err: Error, Res: SomeProtocol { // ERROR: missing Codable!!! - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } func remoteCallVoid( @@ -431,7 +431,7 @@ struct BadRemoteCall_largeSerializationRequirementSlightlyOffInDefinition: Distr where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } } @@ -469,7 +469,7 @@ struct BadRemoteCall_anySerializationRequirement: DistributedActorSystem { Act.ID == ActorID, Err: Error, Res: SerializationRequirement { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } func remoteCallVoid( @@ -481,7 +481,7 @@ struct BadRemoteCall_anySerializationRequirement: DistributedActorSystem { where Act: DistributedActor, Act.ID == ActorID, Err: Error { - throw ExecuteDistributedTargetError(message: "Not implemented.") + throw ExecuteDistributedTargetError(message: "\(#function) not implemented.") } } @@ -573,8 +573,7 @@ struct FakeInvocationEncoder_missing_recordReturnType: DistributedTargetInvocati } struct FakeInvocationEncoder_missing_recordErrorType: DistributedTargetInvocationEncoder { - //expected-error@-1{{struct 'FakeInvocationEncoder_missing_recordErrorType' is missing witness for protocol requirement 'recordErrorType'}} - //expected-note@-2{{protocol 'FakeInvocationEncoder_missing_recordErrorType' requires function 'recordErrorType' with signature:}} + //expected-error@-1{{type 'FakeInvocationEncoder_missing_recordErrorType' does not conform to protocol 'DistributedTargetInvocationEncoder'}} typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} @@ -613,8 +612,7 @@ struct FakeInvocationEncoder_recordResultType_wrongType: DistributedTargetInvoca } struct FakeInvocationEncoder_recordErrorType_wrongType: DistributedTargetInvocationEncoder { - //expected-error@-1{{struct 'FakeInvocationEncoder_recordErrorType_wrongType' is missing witness for protocol requirement 'recordErrorType'}} - //expected-note@-2{{protocol 'FakeInvocationEncoder_recordErrorType_wrongType' requires function 'recordErrorType' with signature:}} + //expected-error@-1{{type 'FakeInvocationEncoder_recordErrorType_wrongType' does not conform to protocol 'DistributedTargetInvocationEncoder'}} typealias SerializationRequirement = Codable mutating func recordGenericSubstitution(_ type: T.Type) throws {} @@ -622,6 +620,7 @@ struct FakeInvocationEncoder_recordErrorType_wrongType: DistributedTargetInvocat mutating func recordReturnType(_ type: R.Type) throws {} mutating func recordErrorType(BadName type: E.Type) throws {} // BAD mutating func recordErrorType(_ type: E.Type) throws {} // BAD + //expected-note@-1{{candidate has non-matching type ' (E.Type) throws -> ()'}} mutating func doneRecording() throws {} } From 7718448636ad3ca42646d1162f680013eaa1b148 Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 15 Mar 2022 17:54:59 +0900 Subject: [PATCH 4/5] [Distributed] Simplify repr of RemoteCallTarget --- .../Distributed/DistributedActorSystem.swift | 35 +++++++++---------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/stdlib/public/Distributed/DistributedActorSystem.swift b/stdlib/public/Distributed/DistributedActorSystem.swift index d57f6bead91ef..e393ac1db21e0 100644 --- a/stdlib/public/Distributed/DistributedActorSystem.swift +++ b/stdlib/public/Distributed/DistributedActorSystem.swift @@ -178,6 +178,12 @@ extension DistributedActorSystem { ) async throws where Act: DistributedActor, // Act.ID == ActorID, // FIXME(distributed): can we bring this back? ResultHandler: DistributedTargetInvocationResultHandler { + // NOTE: Implementation could be made more efficient because we still risk + // demangling a RemoteCallTarget identity (if it is a mangled name) multiple + // times. We would prefer to store if it is a mangled name, demangle, and + // always refer to that demangled repr perhaps? We do cache the resulting + // pretty formatted name of the call target, but perhaps we can do better. + // Get the expected parameter count of the func guard let targetName = target.identifier else { throw ExecuteDistributedTargetError( @@ -338,33 +344,24 @@ extension DistributedActorSystem { /// however its exact format is not specified and may change in future versions. @available(SwiftStdlib 5.7, *) public struct RemoteCallTarget: CustomStringConvertible { - private let _storage: _Storage - private enum _Storage { - case mangledName(String) - } + private let _identifier: String - // Only intended to be created by the _Distributed library. - // TODO(distributed): make this internal and only allow calling by the synthesized code? - public init(_mangledName: String) { - self._storage = .mangledName(_mangledName) + public init(_ identifier: String) { + self._identifier = identifier } /// The underlying identifier of the target, returned as-is. public var identifier: String? { - switch self._storage { - case .mangledName(let name): - return name - } + return _identifier } + /// Attempts to pretty format the underlying target identifier. + /// If unable to, returns the raw underlying identifier. public var description: String { - switch self._storage { - case .mangledName(let mangledName): - if let name = _getFunctionFullNameFromMangledName(mangledName: mangledName) { - return name - } else { - return "\(mangledName)" - } + if let name = _getFunctionFullNameFromMangledName(mangledName: _identifier) { + return name + } else { + return "\(_identifier)" } } } From 6caeecdc586175d553e57fec36e4d4d72bb7541b Mon Sep 17 00:00:00 2001 From: Konrad `ktoso` Malawski Date: Tue, 15 Mar 2022 23:41:03 +0900 Subject: [PATCH 5/5] fix locating constructor --- lib/Sema/TypeCheckDistributed.cpp | 4 +-- .../Distributed/DistributedActorSystem.swift | 7 ++--- .../distributed_actor_remoteCall.swift | 26 +++++++++---------- 3 files changed, 17 insertions(+), 20 deletions(-) diff --git a/lib/Sema/TypeCheckDistributed.cpp b/lib/Sema/TypeCheckDistributed.cpp index f8bec3cdf3df0..35c476ed39344 100644 --- a/lib/Sema/TypeCheckDistributed.cpp +++ b/lib/Sema/TypeCheckDistributed.cpp @@ -721,13 +721,13 @@ GetDistributedRemoteCallTargetInitFunctionRequest::evaluate( if (params->size() != 1) return nullptr; - if (params->get(0)->getArgumentName() == C.getIdentifier("_mangledName")) + // _ identifier + if (params->get(0)->getArgumentName().empty()) return ctor; return nullptr; } - // TODO(distributed): make a Request for it? return nullptr; } diff --git a/stdlib/public/Distributed/DistributedActorSystem.swift b/stdlib/public/Distributed/DistributedActorSystem.swift index e393ac1db21e0..841c132b9d234 100644 --- a/stdlib/public/Distributed/DistributedActorSystem.swift +++ b/stdlib/public/Distributed/DistributedActorSystem.swift @@ -185,10 +185,7 @@ extension DistributedActorSystem { // pretty formatted name of the call target, but perhaps we can do better. // Get the expected parameter count of the func - guard let targetName = target.identifier else { - throw ExecuteDistributedTargetError( - message: "Unable to extract target identifier from remote call target: \(target)") - } + let targetName = target.identifier let nameUTF8 = Array(targetName.utf8) // Gen the generic environment (if any) associated with the target. @@ -351,7 +348,7 @@ public struct RemoteCallTarget: CustomStringConvertible { } /// The underlying identifier of the target, returned as-is. - public var identifier: String? { + public var identifier: String { return _identifier } diff --git a/test/Distributed/Runtime/distributed_actor_remoteCall.swift b/test/Distributed/Runtime/distributed_actor_remoteCall.swift index e156d9463f07c..74bde0ec1f61d 100644 --- a/test/Distributed/Runtime/distributed_actor_remoteCall.swift +++ b/test/Distributed/Runtime/distributed_actor_remoteCall.swift @@ -304,7 +304,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: emptyName), + target: RemoteCallTarget(emptyName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -312,7 +312,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: helloName), + target: RemoteCallTarget(helloName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -320,7 +320,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: answerName), + target: RemoteCallTarget(answerName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -328,7 +328,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: largeResultName), + target: RemoteCallTarget(largeResultName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -336,7 +336,7 @@ func test() async throws { try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: enumResultName), + target: RemoteCallTarget(enumResultName), invocationDecoder: &emptyInvocation, handler: FakeResultHandler() ) @@ -350,7 +350,7 @@ func test() async throws { var echoDecoder = echoInvocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: echoName), + target: RemoteCallTarget(echoName), invocationDecoder: &echoDecoder, handler: FakeResultHandler() ) @@ -365,7 +365,7 @@ func test() async throws { var generic1Decoder = generic1Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: generic1Name), + target: RemoteCallTarget(generic1Name), invocationDecoder: &generic1Decoder, handler: FakeResultHandler() ) @@ -383,7 +383,7 @@ func test() async throws { var generic2Decoder = generic2Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: generic2Name), + target: RemoteCallTarget(generic2Name), invocationDecoder: &generic2Decoder, handler: FakeResultHandler() ) @@ -404,7 +404,7 @@ func test() async throws { var generic3Decoder = generic3Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: generic3Name), + target: RemoteCallTarget(generic3Name), invocationDecoder: &generic3Decoder, handler: FakeResultHandler() ) @@ -426,7 +426,7 @@ func test() async throws { var generic4Decoder = generic4Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: generic4Name), + target: RemoteCallTarget(generic4Name), invocationDecoder: &generic4Decoder, handler: FakeResultHandler() ) @@ -450,7 +450,7 @@ func test() async throws { var generic5Decoder = generic5Invocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: generic5Name), + target: RemoteCallTarget(generic5Name), invocationDecoder: &generic5Decoder, handler: FakeResultHandler() ) @@ -473,7 +473,7 @@ func test() async throws { var genericOptDecoder = genericOptInvocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: genericOptionalName), + target: RemoteCallTarget(genericOptionalName), invocationDecoder: &genericOptDecoder, handler: FakeResultHandler() ) @@ -488,7 +488,7 @@ func test() async throws { var decodeErrDecoder = decodeErrInvocation.makeDecoder() try await system.executeDistributedTarget( on: local, - target: RemoteCallTarget(_mangledName: expectsDecodeErrorName), + target: RemoteCallTarget(expectsDecodeErrorName), invocationDecoder: &decodeErrDecoder, handler: FakeResultHandler() )