Skip to content

[Distributed] Remove @_dynamic replacements; impl remoteCall ad-hoc reqs #41036

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 44 additions & 0 deletions include/swift/AST/ASTContext.h
Original file line number Diff line number Diff line change
Expand Up @@ -659,6 +659,50 @@ class ASTContext final {
// Retrieve the declaration of Swift._stdlib_isOSVersionAtLeast.
FuncDecl *getIsOSVersionAtLeastDecl() const;

/// Retrieve the declaration of DistributedActorSystem.remoteCall(Void)(...).
///
/// \param actorOrSystem distributed actor or actor system to get the
/// remoteCall function for. Since the method we're looking for is an ad-hoc
/// requirement, a specific type MUST be passed here as it is not possible
/// to obtain the decl from just the `DistributedActorSystem` protocol type.
/// \param isVoidReturn true if the call will be returning `Void`.
AbstractFunctionDecl *getRemoteCallOnDistributedActorSystem(
NominalTypeDecl *actorOrSystem,
bool isVoidReturn) const;

// Retrieve the declaration of DistributedInvocationEncoder.recordArgument(_:).
//
// \param nominal optionally provide a 'NominalTypeDecl' from which the
// function decl shall be extracted. This is useful to avoid witness calls
// through the protocol which is looked up when nominal is null.
FuncDecl *getRecordArgumentOnDistributedInvocationEncoder(
NominalTypeDecl *nominal = nullptr) const;

// Retrieve the declaration of DistributedInvocationEncoder.recordErrorType().
//
// \param nominal optionally provide a 'NominalTypeDecl' from which the
// function decl shall be extracted. This is useful to avoid witness calls
// through the protocol which is looked up when nominal is null.
FuncDecl *getRecordErrorTypeOnDistributedInvocationEncoder(
NominalTypeDecl *nominal = nullptr) const;

// Retrieve the declaration of DistributedInvocationEncoder.recordReturnType().
//
// \param nominal optionally provide a 'NominalTypeDecl' from which the
// function decl shall be extracted. This is useful to avoid witness calls
// through the protocol which is looked up when nominal is null.
FuncDecl *getRecordReturnTypeOnDistributedInvocationEncoder(
NominalTypeDecl *nominal = nullptr) const;

// Retrieve the declaration of DistributedInvocationEncoder.doneRecording().
//
// \param nominal optionally provide a 'NominalTypeDecl' from which the
// function decl shall be extracted. This is useful to avoid witness calls
// through the protocol which is looked up when nominal is null.
FuncDecl *getDoneRecordingOnDistributedInvocationEncoder(
NominalTypeDecl *nominal = nullptr) const;


/// Look for the declaration with the given name within the
/// passed in module.
void lookupInModule(ModuleDecl *M, StringRef name,
Expand Down
23 changes: 14 additions & 9 deletions include/swift/AST/Decl.h
Original file line number Diff line number Diff line change
Expand Up @@ -3364,13 +3364,17 @@ class NominalTypeDecl : public GenericTypeDecl, public IterableDeclContext {
OptionSet<LookupDirectFlags> flags =
OptionSet<LookupDirectFlags>());

/// Find the '_remote_<...>' counterpart function to a 'distributed func'.
///
/// If the passed in function is not distributed this function returns null.
AbstractFunctionDecl* lookupDirectRemoteFunc(AbstractFunctionDecl *func);
/// Find the distributed actor system instance of this distributed actor.
VarDecl *getDistributedActorSystemProperty() const;

/// Find, or potentially synthesize, the implicit 'id' property of this actor.
ValueDecl *getDistributedActorIDProperty() const;
VarDecl *getDistributedActorIDProperty() const;

/// Find the 'makeInvocation' function.
AbstractFunctionDecl* getDistributedActorSystemMakeInvocationEncoderFunction() const;

/// Find the 'RemoteCallTarget.init(_mangledName:)' initializer function
ConstructorDecl* getDistributedRemoteCallTargetInitFunction() const;

/// Collect the set of protocols to which this type should implicitly
/// conform, such as AnyObject (for classes).
Expand Down Expand Up @@ -6245,10 +6249,6 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
/// Returns 'true' if the function is distributed.
bool isDistributed() const;

/// Get (or synthesize) the associated remote function for this one.
/// For example, for `distributed func hi()` get `func _remote_hi()`.
AbstractFunctionDecl *getDistributedActorRemoteFuncDecl() const;

PolymorphicEffectKind getPolymorphicEffectKind(EffectKind kind) const;

// FIXME: Hack that provides names with keyword arguments for accessors.
Expand Down Expand Up @@ -6388,6 +6388,11 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
&& getSILSynthesizeKind() == SILSynthesizeKind::DistributedActorFactory;
}

/// Determines whether this function is a 'remoteCall' function,
/// which is used as ad-hoc protocol requirement by the
/// 'DistributedActorSystem' protocol.
bool isDistributedActorSystemRemoteCall(bool isVoidReturn) const;

/// For a method of a class, checks whether it will require a new entry in the
/// vtable.
bool needsNewVTableEntry() const;
Expand Down
6 changes: 6 additions & 0 deletions include/swift/AST/DiagnosticsSema.def
Original file line number Diff line number Diff line change
Expand Up @@ -4450,6 +4450,12 @@ ERROR(distributed_actor_protocol_illegal_inheritance,none,
(DeclName))
ERROR(broken_distributed_actor_requirement,none,
"DistributedActor protocol is broken: unexpected requirement", ())
ERROR(distributed_actor_system_conformance_missing_adhoc_requirement,none,
"%0 %1 is missing witness for protocol requirement %2"
"", (DescriptiveDeclKind, DeclName, DeclName))
NOTE(note_distributed_actor_system_conformance_missing_adhoc_requirement,none,
"protocol %0 requires function %1 with signature:\n%2",
(DeclName, DeclName, StringRef))

ERROR(override_implicit_unowned_executor,none,
"cannot override an actor's 'unownedExecutor' property that wasn't "
Expand Down
36 changes: 24 additions & 12 deletions include/swift/AST/KnownIdentifiers.def
Original file line number Diff line number Diff line change
Expand Up @@ -257,26 +257,38 @@ IDENTIFIER(version)
IDENTIFIER_(StringProcessing)

// Distributed actors
IDENTIFIER(ActorID)
IDENTIFIER(ActorSystem)
IDENTIFIER(ID)
IDENTIFIER(Invocation)
IDENTIFIER(__isRemoteActor)
IDENTIFIER(_distributedActorDestroy)
IDENTIFIER(_distributedActorRemoteInitialize)
IDENTIFIER(actor)
IDENTIFIER(actorReady)
IDENTIFIER(ActorSystem)
IDENTIFIER(actorSystem)
IDENTIFIER(ActorID)
IDENTIFIER(actorType)
IDENTIFIER(using)
IDENTIFIER(assignID)
IDENTIFIER(decodeNext)
IDENTIFIER(doneRecording)
IDENTIFIER(id)
IDENTIFIER(invocation)
IDENTIFIER(invocationDecoder)
IDENTIFIER(makeInvocationEncoder)
IDENTIFIER(on)
IDENTIFIER(recordArgument)
IDENTIFIER(recordErrorType)
IDENTIFIER(recordGenericSubstitution)
IDENTIFIER(recordReturnType)
IDENTIFIER(remoteCall)
IDENTIFIER(remoteCallVoid)
IDENTIFIER(resignID)
IDENTIFIER(resolve)
IDENTIFIER(remoteCall)
IDENTIFIER(makeInvocationEncoder)
IDENTIFIER(returning)
IDENTIFIER(system)
IDENTIFIER(ID)
IDENTIFIER(id)
IDENTIFIER(Invocation)
IDENTIFIER(invocationDecoder)
IDENTIFIER(_distributedActorRemoteInitialize)
IDENTIFIER(_distributedActorDestroy)
IDENTIFIER(__isRemoteActor)
IDENTIFIER(target)
IDENTIFIER(throwing)
IDENTIFIER(using)
IDENTIFIER(whenLocal)

#undef IDENTIFIER
Expand Down
2 changes: 1 addition & 1 deletion include/swift/AST/KnownProtocols.def
Original file line number Diff line number Diff line change
Expand Up @@ -97,10 +97,10 @@ PROTOCOL(Differentiable)

// Distributed Actors
PROTOCOL(DistributedActor)
PROTOCOL(ActorIdentity)
PROTOCOL(DistributedActorSystem)
PROTOCOL(DistributedTargetInvocationEncoder)
PROTOCOL(DistributedTargetInvocationDecoder)
PROTOCOL(DistributedTargetInvocationResultHandler)

PROTOCOL(AsyncSequence)
PROTOCOL(AsyncIteratorProtocol)
Expand Down
1 change: 0 additions & 1 deletion include/swift/AST/KnownSDKDecls.def
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
# define KNOWN_SDK_FUNC_DECL(Module, Name, Id)
#endif

KNOWN_SDK_FUNC_DECL(Distributed, MissingDistributedActorSystem, "_missingDistributedActorSystem")
KNOWN_SDK_FUNC_DECL(Distributed, IsRemoteDistributedActor, "__isRemoteActor")

#undef KNOWN_SDK_FUNC_DECL
Expand Down
3 changes: 1 addition & 2 deletions include/swift/AST/KnownSDKTypes.def
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,7 @@ KNOWN_SDK_TYPE_DECL(Concurrency, TaskLocal, ClassDecl, 1)

// Distributed actors
KNOWN_SDK_TYPE_DECL(Distributed, DistributedActor, ProtocolDecl, 0)
KNOWN_SDK_TYPE_DECL(Distributed, ActorIdentity, ProtocolDecl, 0)
KNOWN_SDK_TYPE_DECL(Distributed, AnyActorIdentity, StructDecl, 0)
KNOWN_SDK_TYPE_DECL(Distributed, RemoteCallTarget, StructDecl, 0)

// String processing
KNOWN_SDK_TYPE_DECL(StringProcessing, Regex, StructDecl, 1)
Expand Down
32 changes: 25 additions & 7 deletions include/swift/AST/TypeCheckRequests.h
Original file line number Diff line number Diff line change
Expand Up @@ -1017,18 +1017,36 @@ class IsDistributedActorRequest :
bool isCached() const { return true; }
};

/// Obtain the 'remote' counterpart of a 'distributed func'.
class GetDistributedRemoteFuncRequest :
public SimpleRequest<GetDistributedRemoteFuncRequest,
AbstractFunctionDecl *(AbstractFunctionDecl *),
/// Obtain the 'remoteCall' function of a 'DistributedActorSystem'.
class GetDistributedActorSystemRemoteCallFunctionRequest :
public SimpleRequest<GetDistributedActorSystemRemoteCallFunctionRequest,
AbstractFunctionDecl *(NominalTypeDecl *, bool voidReturn),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

AbstractFunctionDecl *evaluate(Evaluator &evaluator, AbstractFunctionDecl *func) const;
AbstractFunctionDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *actorSystem, bool voidReturn) const;

public:
// Caching
bool isCached() const { return true; }
};

/// Obtain the 'actorSystem' property of a 'distributed actor'.
class GetDistributedActorSystemPropertyRequest :
public SimpleRequest<GetDistributedActorSystemPropertyRequest,
VarDecl *(NominalTypeDecl *),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

VarDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *actor) const;

public:
// Caching
Expand All @@ -1038,15 +1056,15 @@ class GetDistributedRemoteFuncRequest :
/// Obtain the 'id' property of a 'distributed actor'.
class GetDistributedActorIDPropertyRequest :
public SimpleRequest<GetDistributedActorIDPropertyRequest,
ValueDecl *(NominalTypeDecl *),
VarDecl *(NominalTypeDecl *),
RequestFlags::Cached> {
public:
using SimpleRequest::SimpleRequest;

private:
friend SimpleRequest;

ValueDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *actor) const;
VarDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *actor) const;

public:
// Caching
Expand Down
7 changes: 5 additions & 2 deletions include/swift/AST/TypeCheckerTypeIDZone.def
Original file line number Diff line number Diff line change
Expand Up @@ -105,9 +105,12 @@ SWIFT_REQUEST(TypeChecker, IsDefaultActorRequest,
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, IsDistributedActorRequest, bool(NominalTypeDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, GetDistributedRemoteFuncRequest, AbstractFunctionDecl *(AbstractFunctionDecl *),
SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemRemoteCallFunctionRequest,
AbstractFunctionDecl *(NominalTypeDecl *, bool),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, GetDistributedActorIDPropertyRequest, ValueDecl *(NominalTypeDecl *),
SWIFT_REQUEST(TypeChecker, GetDistributedActorIDPropertyRequest, VarDecl *(NominalTypeDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemPropertyRequest, VarDecl *(NominalTypeDecl *),
Cached, NoLocationInfo)
SWIFT_REQUEST(TypeChecker, GlobalActorInstanceRequest,
VarDecl *(NominalTypeDecl *),
Expand Down
9 changes: 5 additions & 4 deletions include/swift/SILOptimizer/Utils/DistributedActor.h
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

#include "llvm/ADT/ArrayRef.h"
#include "llvm/ADT/Optional.h"
#include "swift/AST/Decl.h"
#include <utility>

namespace swift {
Expand All @@ -35,18 +36,18 @@ class SILValue;
/// \returns nullptr if the function does not have such a parameter.
SILArgument *findFirstDistributedActorSystemArg(SILFunction &F);

/// Emit a call to a witness of the actor actorSystem protocol.
/// Emit a call to a witness of the DistributedActorSystem protocol.
///
/// \param methodName The name of the method on the DistributedActorSystem protocol.
/// \param actorSystem The actorSystem on which to invoke the method
/// \param base The base on which to invoke the method
/// \param actorType If non-empty, the type of the distributed actor that is
/// provided as one of the arguments.
/// \param args The arguments provided to the call, not including the actorSystem.
/// \param args The arguments provided to the call, not including the base.
/// \param tryTargets For a call that can throw, the normal and error basic
/// blocks that the call will branch to.
void emitDistributedActorSystemWitnessCall(
SILBuilder &B, SILLocation loc, DeclName methodName,
SILValue actorSystem, SILType actorType, llvm::ArrayRef<SILValue> args,
SILValue base, SILType actorType, llvm::ArrayRef<SILValue> args,
llvm::Optional<std::pair<SILBasicBlock *, SILBasicBlock *>> tryTargets =
llvm::None);

Expand Down
Loading