Hello everyone!
I'm very intriguing in new distributed actors functionality, so I started to play with it before it officially released. As first step I would like to build some very simple distributed system on top of it,
Unfortunately during development I've faced some problems with compiling my code and after some investigation / googling I'm not sure lies in my code, but not in synthesized code.
Basically I have class conforming DistributedActorSystem protocol
@available(macOS 9999, *)
final class DataSystem : DistributedActorSystem {
typealias ActorID = InstanceId
typealias InvocationEncoder = DataInvocationEncoder
typealias InvocationDecoder = DataInvocationDecoder
typealias ResultHandler = DataInvocationResultHandler
typealias SerializationRequirement = Codable
...
DataInvocationEncoder / DataInvocationDecoder are structs conforming corresponding protocols, all functions are declared, but implementation is basically empty or returning stubs.
It compiles fine with latest (4th of May) snapshot of trunk. Then I add first distributed actor declaration
@available(macOS 9999, *)
distributed actor Server {
typealias ActorSystem = DataSystem
typealias SerializationRequirement = Codable
distributed func send() {
}
}
and then compilation fails with next error which is unclear for me
<unknown>:0: error: '&' used with non-inout argument of type 'DataSystem.InvocationEncoder' (aka 'DataInvocationEncoder')
<unknown>:0: error: '&' used with non-inout argument of type 'DataSystem.InvocationEncoder' (aka 'DataInvocationEncoder')
Possible it could be some bug in code synthesized by compiler which pass &encoder to functions like remoteCall(...) where non-inout argument is expected or, most probably, I'm missing something.
Do you have any idea why I can get this error?
ktoso
(Konrad 'ktoso' Malawski 🐟🏴☠️)
2
Hi there and thanks for the interest!
Would you mind pasting your entire distributed actor system implementation -- including all the method declarations? Since some of the protocol requirements are "ad-hoc" perhaps one of the signatures is wrong and we missed to diagnose it maybe?
I'm most interested in making sure your remoteCall(Void) signatures are correct; These do include an inout Encoder:
func remoteCall<Act, Err, Res>(
on actor: Act,
target: RemoteCallTarget,
invocation: inout InvocationEncoder, // must be inout
throwing: Err.Type,
returning: Res.Type
) async throws -> Res
where Act: DistributedActor,
Act.ID == ActorID,
Err: Error,
Res: SerializationRequirement {
--
minor: you don't need to declare the SerializationRequirement on the actor; it'll be synthesized from the ActorSystem used.
ktoso
(Konrad 'ktoso' Malawski 🐟🏴☠️)
3
Yeap, pretty sure that's it -- we missed to diagnose a missing inout on the encoder parameter on remote call ad-hoc requirements, I'll send in a PR to fix it -- thanks for reporting!
Please verify on your end and let me know 
Bug: https://github.com/apple/swift/issues/58671
Solution PR: https://github.com/apple/swift/pull/58672
Note that this is only a diagnosis bug; the signature of your remoteCall is wrong and cannot work if you are seeing the error from the first post -- so let's confirm you indeed were missing that inout there.
4 Likes
Hello Konrad!
Thanks for prompt reply!
Yep, seems it is a reason, I didn't have inout in removeCall / remoteCallVoid. I think I copied the signatures from proposal and there is no inout there.
After I added inout it compiles! Thanks!
Will be happy to verify changes in PR as soon it will be merged to trunk and I can download new toolchain.
3 Likes
ktoso
(Konrad 'ktoso' Malawski 🐟🏴☠️)
5
Oh, thanks — I’ll make sure to fix up the proposal as well, so others don’t run into the same issue.
Thanks!