Eliminate the required use of existentials in distributed actors by
introducing the `Transport` associated type into the
`DistributedActor` protocol. Each distributed actor has a known
(concrete) actor transport type, reducing storage requirements and
transport dynamism when it isn't needed.
Distributed actors can manually specify their `Transport` associated
type or pick up a default by looking for a type named
`DefaultActorTransport`. A library that vends an actor transport can
make create a public typealias `DefaultActorTransport` referring to
its transport, so importing that library and defining a distributed
actor will use that library's transport.
Introduce a type-erased `AnyActorTransport` type to provide an
explicitly dynamic actor transport. This is still an important option,
e.g., for cases where one wants to be able to dynamically change the
transport for testing or different kinds of deployment. For now, we
default to this transport in the library (via `DefaultActorTransport`),
but we may very well want to eliminate this because it will be
ambiguous with client libraries that vend their own
`DefaultActorTransport`.
Refactor the code that generates SIL to call into the distributed actor
transport to eliminate duplication and better cope with concrete actor
transports. Centralize the knowledge of which actor transport is used
with a given distributed actor type.
Immediately after the hop_to_executor in an async, distributed
actor init, we need to notify the transport that the actor is ready.
This patch does not yet account for more complex cases. In particular,
we will need a mechanism to prevent multiple calls to actorReady,
which can happen if a loop appears in the init:
distributed actor Dactor {
var x: Int
init(tport: ActorTransport, count: Int) async {
var i = count
repeat {
self.x = count
// hop is injected here
i -= 1
} while i > 0
}
}
We need to be able to inject a call to a distributed actor's
transport.actorReady, passing the actor instance to it,
during definite initialization. This means that its dependence
on SILGenFunction must be broken, hence this refactoring as
a SILOptimizer utility.