Distributed: Fixes for non-copyable generics

This commit is contained in:
Slava Pestov
2024-01-30 17:09:07 -05:00
parent 778e6d5fcb
commit 4a46717325
4 changed files with 51 additions and 17 deletions

View File

@@ -528,9 +528,13 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
}
auto sig = getGenericSignature();
auto requirements = sig.getRequirements();
if (requirements.size() != expectedRequirementsNum) {
SmallVector<Requirement, 2> reqs;
SmallVector<InverseRequirement, 2> inverseReqs;
sig->getRequirementsWithInverses(reqs, inverseReqs);
assert(inverseReqs.empty() && "Non-copyable generics not supported here!");
if (reqs.size() != expectedRequirementsNum) {
return false;
}
@@ -545,7 +549,7 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
// same_type: Act.ID FakeActorSystem.ActorID // LAST one
// --- Check requirement: conforms_to: Act DistributedActor
auto actorReq = requirements[0];
auto actorReq = reqs[0];
if (actorReq.getKind() != RequirementKind::Conformance) {
return false;
}
@@ -554,7 +558,7 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
}
// --- Check requirement: conforms_to: Err Error
auto errorReq = requirements[1];
auto errorReq = reqs[1];
if (errorReq.getKind() != RequirementKind::Conformance) {
return false;
}
@@ -593,7 +597,7 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
}
// -- Check requirement: same_type Actor.ID Self.ActorID
auto actorIdReq = requirements.back();
auto actorIdReq = reqs.back();
if (actorIdReq.getKind() != RequirementKind::SameType) {
return false;
}
@@ -667,10 +671,14 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordGenericSubstitut
return false;
}
SmallVector<Requirement, 2> reqs;
SmallVector<InverseRequirement, 2> inverseReqs;
fd->getGenericSignature()->getRequirementsWithInverses(reqs, inverseReqs);
assert(inverseReqs.empty() && "Non-copyable generics not supported here!");
// No requirements on the generic parameter
if (fd->getGenericRequirements().size() != 0) {
if (!reqs.empty())
return false;
}
if (!fd->getResultInterfaceType()->isVoid())
return false;
@@ -785,9 +793,13 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordArgument() const
auto sig = getGenericSignature();
auto requirements = sig.getRequirements();
if (requirements.size() != expectedRequirementsNum) {
SmallVector<Requirement, 2> reqs;
SmallVector<InverseRequirement, 2> inverseReqs;
sig->getRequirementsWithInverses(reqs, inverseReqs);
assert(inverseReqs.empty() && "Non-copyable generics not supported here!");
if (reqs.size() != expectedRequirementsNum) {
return false;
}
@@ -891,9 +903,13 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordReturnType() con
GenericTypeParamDecl *ArgumentParam = genericParams->getParams()[0];
auto sig = getGenericSignature();
auto requirements = sig.getRequirements();
if (requirements.size() != expectedRequirementsNum) {
SmallVector<Requirement, 2> reqs;
SmallVector<InverseRequirement, 2> inverseReqs;
sig->getRequirementsWithInverses(reqs, inverseReqs);
assert(inverseReqs.empty() && "Non-copyable generics not supported here!");
if (reqs.size() != expectedRequirementsNum) {
return false;
}
@@ -1000,8 +1016,13 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordErrorType() cons
// --- Check: Argument: SerializationRequirement
auto sig = getGenericSignature();
auto requirements = sig.getRequirements();
if (requirements.size() != 1) {
SmallVector<Requirement, 2> reqs;
SmallVector<InverseRequirement, 2> inverseReqs;
sig->getRequirementsWithInverses(reqs, inverseReqs);
assert(inverseReqs.empty() && "Non-copyable generics not supported here!");
if (reqs.size() != 1) {
return false;
}
@@ -1016,7 +1037,7 @@ AbstractFunctionDecl::isDistributedTargetInvocationEncoderRecordErrorType() cons
}
// --- Check requirement: conforms_to: Err Error
auto errorReq = requirements[0];
auto errorReq = reqs[0];
if (errorReq.getKind() != RequirementKind::Conformance) {
return false;
}

View File

@@ -1315,6 +1315,9 @@ SequenceExpr *SequenceExpr::create(ASTContext &ctx, ArrayRef<Expr*> elements) {
ErasureExpr *ErasureExpr::create(ASTContext &ctx, Expr *subExpr, Type type,
ArrayRef<ProtocolConformanceRef> conformances,
ArrayRef<ConversionPair> argConversions) {
auto layout = type->getExistentialLayout();
assert(layout.getProtocols().size() == conformances.size());
auto size = totalSizeToAlloc<ProtocolConformanceRef, ConversionPair>(conformances.size(),
argConversions.size());
auto mem = ctx.Allocate(size, alignof(ErasureExpr));

View File

@@ -98,11 +98,14 @@ void SILGenFunction::emitDistributedIfRemoteBranch(SILLocation Loc,
assert(isRemoteFn && "Could not find 'is remote' function, is the "
"'Distributed' module available?");
auto conformances = SGM.M.getSwiftModule()->collectExistentialConformances(
selfTy->getCanonicalType(), ctx.getAnyObjectType());
ManagedValue selfAnyObject = B.createInitExistentialRef(
Loc,
/*existentialType=*/getLoweredType(ctx.getAnyObjectType()),
/*formalConcreteType=*/selfValue.getType().getASTType(),
selfValue, {});
/*formalConcreteType=*/selfTy->getCanonicalType(),
selfValue, conformances);
auto result = emitApplyOfLibraryIntrinsic(
Loc, isRemoteFn, SubstitutionMap(), {selfAnyObject}, SGFContext());

View File

@@ -645,6 +645,8 @@ deriveBodyDistributedActor_unownedExecutor(AbstractFunctionDecl *getter, void *)
// }
ASTContext &ctx = getter->getASTContext();
auto *module = getter->getParentModule();
// Produce an empty brace statement on failure.
auto failure = [&]() -> std::pair<BraceStmt *, bool> {
auto body = BraceStmt::create(
@@ -680,9 +682,14 @@ deriveBodyDistributedActor_unownedExecutor(AbstractFunctionDecl *getter, void *)
ctx.getBoolType()));
Expr *selfForIsLocalArg = DerivedConformance::createSelfDeclRef(getter);
selfForIsLocalArg->setType(selfType);
auto conformances = module->collectExistentialConformances(selfType->getCanonicalType(),
ctx.getAnyObjectType());
auto *argListForIsLocal =
ArgumentList::forImplicitSingle(ctx, Identifier(),
ErasureExpr::create(ctx, selfForIsLocalArg, ctx.getAnyObjectType(), {}, {}));
ErasureExpr::create(ctx, selfForIsLocalArg,
ctx.getAnyObjectType(),
conformances, {}));
CallExpr *isLocalActorCall = CallExpr::createImplicit(ctx, isLocalActorExpr, argListForIsLocal);
isLocalActorCall->setType(ctx.getBoolType());
isLocalActorCall->setThrows(nullptr);