Skip to content

Commit e2cb7e7

Browse files
authored
Merge pull request #39811 from DougGregor/distributed-actor-init-concrete-transport
2 parents df26a6d + 9db2638 commit e2cb7e7

File tree

2 files changed

+64
-59
lines changed

2 files changed

+64
-59
lines changed

lib/SILGen/SILGenDistributed.cpp

Lines changed: 56 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,6 @@ static void emitDistributedActorStore_transport(
128128
SILArgument *transportArg) {
129129
auto &B = SGF.B;
130130

131-
auto &SGM = SGF.SGM;
132-
SILGenFunctionBuilder builder(SGM);
133-
134131
auto *dc = func->getDeclContext();
135132
auto classDecl = dc->getSelfClassDecl();
136133

@@ -148,42 +145,36 @@ static void emitDistributedActorStore_transport(
148145
loc, actorSelf, var,
149146
SGF.getLoweredType(var->getInterfaceType()));
150147

151-
// ==== Store the transport
152-
B.createCopyAddr(loc,
153-
/*src*/transportArg,
154-
/*dest*/fieldAddr,
155-
IsNotTake, IsInitialization);
156-
}
157-
158-
// TODO(distributed): remove this store impl and reuse Store_transport
159-
static void
160-
emitDistributedActor_init_transportStore(
161-
SILGenFunction &SGF,
162-
ManagedValue borrowedSelfArg, VarDecl *selfDecl,
163-
ConstructorDecl *ctor,
164-
Pattern *pattern, VarDecl *var) {
165-
auto &C = selfDecl->getASTContext();
166-
auto &B = SGF.B;
167-
auto &F = SGF.F;
168-
auto &SGM = SGF.SGM;
169-
SILGenFunctionBuilder builder(SGM);
170-
171-
auto loc = SILLocation(ctor);
172-
loc.markAutoGenerated();
173-
174-
// ==== Prepare assignment: get the self.transport address
175-
SILValue transportArgValue = getActorTransportArgument(C, F, ctor);
176-
177-
// ----
178-
179-
auto transportFieldAddr = B.createRefElementAddr(
180-
loc, borrowedSelfArg.getValue(), var,
181-
SGF.getLoweredType(var->getInterfaceType()));
148+
// If the argument is not existential, it will be a concrete type
149+
// that can be erased to that existential.
150+
SILValue transportValue = transportArg;
151+
if (!transportArg->getType().isExistentialType()) {
152+
auto &existentialTL = SGF.getTypeLowering(var->getInterfaceType());
153+
auto concreteFormalType = transportArg->getType().getASTType();
154+
155+
auto archetype = OpenedArchetypeType::getAny(var->getInterfaceType());
156+
AbstractionPattern abstractionPattern(archetype);
157+
auto &concreteTL = SGF.getTypeLowering(abstractionPattern,
158+
concreteFormalType);
159+
160+
auto module = dc->getParentModule();
161+
auto actorTransportProto = C.getProtocol(KnownProtocolKind::ActorTransport);
162+
ProtocolConformanceRef conformances[] = {
163+
module->lookupConformance(concreteFormalType, actorTransportProto) };
164+
ManagedValue mv = SGF.emitExistentialErasure(loc, concreteFormalType,
165+
concreteTL, existentialTL,
166+
C.AllocateCopy(conformances),
167+
SGFContext(),
168+
[&](SGFContext C) -> ManagedValue {
169+
return ManagedValue::forBorrowedRValue(transportArg);
170+
});
171+
transportValue = mv.getValue();
172+
}
182173

183174
// ==== Store the transport
184175
B.createCopyAddr(loc,
185-
/*src*/transportArgValue,
186-
/*dest*/transportFieldAddr,
176+
/*src*/transportValue,
177+
/*dest*/fieldAddr,
187178
IsNotTake, IsInitialization);
188179
}
189180

@@ -254,14 +245,17 @@ static void emitDistributedActorStore_init_assignIdentity(
254245
assert(distributedActorProto);
255246
assert(transportProto);
256247

257-
// --- Open the transport existential
258-
OpenedArchetypeType *Opened;
248+
// --- Open the transport existential, if needed.
249+
SILValue transportValue = transportArgValue;
259250
auto transportASTType = transportArgValue->getType().getASTType();
260-
auto openedTransportType =
261-
transportASTType->openAnyExistentialType(Opened)->getCanonicalType();
262-
auto openedTransportSILType = F.getLoweredType(openedTransportType);
263-
auto transportArchetypeValue = B.createOpenExistentialAddr(
264-
loc, transportArgValue, openedTransportSILType, OpenedExistentialAccess::Immutable);
251+
if (transportASTType->isAnyExistentialType()) {
252+
OpenedArchetypeType *Opened;
253+
transportASTType =
254+
transportASTType->openAnyExistentialType(Opened)->getCanonicalType();
255+
transportValue = B.createOpenExistentialAddr(
256+
loc, transportValue, F.getLoweredType(transportASTType),
257+
OpenedExistentialAccess::Immutable);
258+
}
265259

266260
// --- prepare `Self.self` metatype
267261
auto *selfTyDecl = ctor->getParent()->getSelfNominalTypeDecl();
@@ -298,7 +292,7 @@ static void emitDistributedActorStore_init_assignIdentity(
298292

299293
auto assignWitnessMethod = B.createWitnessMethod(
300294
loc,
301-
/*lookupTy*/openedTransportType,
295+
/*lookupTy*/transportASTType,
302296
/*Conformance*/transportConfRef,
303297
/*member*/assignIdentityRef,
304298
/*methodTy*/assignIdentitySILTy);
@@ -308,7 +302,7 @@ static void emitDistributedActorStore_init_assignIdentity(
308302

309303
SubstitutionMap subs =
310304
SubstitutionMap::get(genericSig,
311-
{openedTransportType, selfTy},
305+
{transportASTType, selfTy},
312306
{transportConfRef, distributedActorConfRef});
313307

314308
// --- create a temporary storage for the result of the call
@@ -319,7 +313,7 @@ static void emitDistributedActorStore_init_assignIdentity(
319313
// ---- actually call transport.assignIdentity(Self.self)
320314
B.createApply(
321315
loc, assignWitnessMethod, subs,
322-
{ temp, selfMetatypeValue, transportArchetypeValue});
316+
{ temp, selfMetatypeValue, transportValue});
323317

324318
// ==== Assign the identity to stored property
325319
// TODO(distributed): reuse emitDistributedActorStore_id here, pass the SILValue
@@ -374,9 +368,9 @@ void SILGenFunction::initializeDistributedActorImplicitStorageInit(
374368
if (var->getName() == C.Id_actorTransport &&
375369
var->getInterfaceType()->isEqual(transportTy)) {
376370
transportMember = var;
377-
// TODO(distributed): reuse emitDistributedActorStore_transport
378-
emitDistributedActor_init_transportStore(
379-
*this, borrowedSelfArg, selfVarDecl, ctor, pattern, var);
371+
emitDistributedActorStore_transport(
372+
C, *this, borrowedSelfArg.getValue(), ctor,
373+
getActorTransportArgument(C, F, ctor));
380374
} else if (var->getName() == C.Id_id &&
381375
(var->getInterfaceType()->isEqual(identityProtoTy) ||
382376
var->getInterfaceType()->isEqual(anyIdentityTy))) { // TODO(distributed): stick one way to store, but today we can't yet store the existential
@@ -417,13 +411,16 @@ void SILGenFunction::emitDistributedActorReady(
417411
assert(transportProto);
418412

419413
// --- Open the transport existential
420-
OpenedArchetypeType *Opened;
421-
auto transportASTType = transportArgValue->getType().getASTType();
422-
auto openedTransportType =
423-
transportASTType->openAnyExistentialType(Opened)->getCanonicalType();
424-
auto openedTransportSILType = F.getLoweredType(openedTransportType);
425-
auto transportArchetypeValue = B.createOpenExistentialAddr(
426-
loc, transportArgValue, openedTransportSILType, OpenedExistentialAccess::Immutable);
414+
SILValue transportValue = transportArgValue;
415+
auto transportASTType = transportValue->getType().getASTType();
416+
if (transportASTType->isAnyExistentialType()) {
417+
OpenedArchetypeType *Opened;
418+
transportASTType =
419+
transportASTType->openAnyExistentialType(Opened)->getCanonicalType();
420+
transportValue = B.createOpenExistentialAddr(
421+
loc, transportValue, F.getLoweredType(transportASTType),
422+
OpenedExistentialAccess::Immutable);
423+
}
427424

428425
// === Make the transport.actorReady call
429426
// --- prepare the witness_method
@@ -453,7 +450,7 @@ void SILGenFunction::emitDistributedActorReady(
453450

454451
auto readyWitnessMethod = B.createWitnessMethod(
455452
loc,
456-
/*lookupTy*/openedTransportType,
453+
/*lookupTy*/transportASTType,
457454
/*Conformance*/transportConfRef,
458455
/*member*/actorReadyRef,
459456
/*methodTy*/actorReadySILTy);
@@ -463,13 +460,13 @@ void SILGenFunction::emitDistributedActorReady(
463460

464461
SubstitutionMap subs =
465462
SubstitutionMap::get(genericSig,
466-
{openedTransportType, selfTy},
463+
{transportASTType, selfTy},
467464
{transportConfRef, distributedActorConfRef});
468465

469466
// ---- actually call transport.actorReady(self)
470467
B.createApply(
471468
loc, readyWitnessMethod, subs,
472-
{ selfArgValue, transportArchetypeValue});
469+
{ selfArgValue, transportValue});
473470
}
474471

475472
/******************************************************************************/

test/SIL/Distributed/distributed_actor_user_transport_init_sil.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,3 +73,11 @@ distributed actor SimpleUserDefinedInitDistributedActor {
7373
// While in AST the return was "return null" after SILGen we properly return the self
7474
// CHECK: return %2 : $SimpleUserDefinedInitDistributedActor // id: %18
7575
// CHECK: } // end sil function '$s41distributed_actor_user_transport_init_sil37SimpleUserDefinedInitDistributedActorC5other12theTransportACSi_01_K00lO0_ptcfc'
76+
77+
@available(SwiftStdlib 5.5, *)
78+
distributed actor GenericUserDefinedInitDistributedActor {
79+
// CHECK-LABEL: sil shared @$s41distributed_actor_user_transport_init_sil38GenericUserDefinedInitDistributedActorC0D0ACx_tc01_K00L9TransportRzlufcTf4gn_n : $@convention(method) <T where T : ActorTransport> (@in_guaranteed T, @owned GenericUserDefinedInitDistributedActor) -> @owned GenericUserDefinedInitDistributedActor
80+
// CHECK: metatype $@thick GenericUserDefinedInitDistributedActor.Type
81+
// CHECK: witness_method $T, #ActorTransport.assignIdentity
82+
init<T: ActorTransport>(transport: T) { }
83+
}

0 commit comments

Comments
 (0)