@@ -426,6 +426,32 @@ static FuncDecl *deriveDistributedActorSystem_invokeHandlerOnReturn(
426426/* ****************************** PROPERTIES ***********************************/
427427/* *****************************************************************************/
428428
429+ // TODO(distributed): make use of this after all, but FORCE it?
430+ static ValueDecl *deriveDistributedActor_id (DerivedConformance &derived) {
431+ assert (derived.Nominal ->isDistributedActor ());
432+ auto &C = derived.Context ;
433+
434+ // ```
435+ // nonisolated let id: Self.ID // Self.ActorSystem.ActorID
436+ // ```
437+ auto propertyType = getDistributedActorIDType (derived.Nominal );
438+
439+ VarDecl *propDecl;
440+ PatternBindingDecl *pbDecl;
441+ std::tie (propDecl, pbDecl) = derived.declareDerivedProperty (
442+ DerivedConformance::SynthesizedIntroducer::Let, C.Id_id , propertyType,
443+ propertyType,
444+ /* isStatic=*/ false , /* isFinal=*/ true );
445+
446+ // mark as nonisolated, allowing access to it from everywhere
447+ propDecl->getAttrs ().add (
448+ new (C) NonisolatedAttr (/* IsImplicit=*/ true ));
449+
450+ derived.addMemberToConformanceContext (pbDecl, /* insertAtHead=*/ true );
451+ derived.addMemberToConformanceContext (propDecl, /* insertAtHead=*/ true );
452+ return propDecl;
453+ }
454+
429455static ValueDecl *deriveDistributedActor_actorSystem (
430456 DerivedConformance &derived) {
431457 auto &C = derived.Context ;
@@ -454,9 +480,17 @@ static ValueDecl *deriveDistributedActor_actorSystem(
454480 // `actorSystem` MUST be the second field, because for a remote instance
455481 // we don't allocate memory after those two fields, so their order is very
456482 // important. The `hint` below makes sure the system is inserted right after.
457- auto id = derived.Nominal ->getDistributedActorIDProperty ();
458- derived.addMemberToConformanceContext (pbDecl, /* hint=*/ id);
459- derived.addMemberToConformanceContext (propDecl, /* hint=*/ id);
483+ if (auto id = derived.Nominal ->getDistributedActorIDProperty ()) {
484+ derived.addMemberToConformanceContext (pbDecl, /* hint=*/ id);
485+ derived.addMemberToConformanceContext (propDecl, /* hint=*/ id);
486+ } else {
487+ // `id` will be synthesized next, and will insert at head,
488+ // so in order for system to be SECOND (as it must be),
489+ // we'll insert at head right now and as id gets synthesized we'll get
490+ // the correct order: id, actorSystem.
491+ derived.addMemberToConformanceContext (pbDecl, /* insertAtHead==*/ true );
492+ derived.addMemberToConformanceContext (propDecl, /* insertAtHead=*/ true );
493+ }
460494
461495 return propDecl;
462496}
@@ -551,14 +585,11 @@ deriveDistributedActorType_SerializationRequirement(
551585
552586ValueDecl *DerivedConformance::deriveDistributedActor (ValueDecl *requirement) {
553587 if (auto var = dyn_cast<VarDecl>(requirement)) {
588+ if (var->getName () == Context.Id_id )
589+ return deriveDistributedActor_id (*this );
590+
554591 if (var->getName () == Context.Id_actorSystem )
555592 return deriveDistributedActor_actorSystem (*this );
556-
557- if (var->getName () == Context.Id_id )
558- llvm_unreachable (" DistributedActor.id MUST be synthesized earlier, "
559- " because it is forced by the Identifiable conformance. "
560- " If we attempted to do synthesis here, the earlier phase "
561- " failed and something is wrong: please report a bug." );
562593 }
563594
564595 if (auto func = dyn_cast<FuncDecl>(requirement)) {
0 commit comments