Skip to content

Commit 5c83cae

Browse files
authored
Merge pull request #71105 from DougGregor/silgen-hack-distributed-actor-as-actor
[SILGen] Ensure that we emit the distributed-actor-as-actor conformance
2 parents a44f5ba + 07c6b78 commit 5c83cae

File tree

6 files changed

+81
-48
lines changed

6 files changed

+81
-48
lines changed

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ IDENTIFIER(accumulated)
3232
IDENTIFIER(ActorType)
3333
IDENTIFIER(Any)
3434
IDENTIFIER(ArrayLiteralElement)
35+
IDENTIFIER(asLocalActor)
3536
IDENTIFIER(atIndexedSubscript)
3637
IDENTIFIER_(bridgeToObjectiveC)
3738
IDENTIFIER(buildArray)

lib/SILGen/SILGen.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,10 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
8383
/// Set of delayed conformances that have already been forced.
8484
llvm::DenseSet<NormalProtocolConformance *> forcedConformances;
8585

86+
/// The conformance for any DistributedActor to the Actor protocol,
87+
/// used only by the `distributedActorAsAnyActor` builtin.
88+
RootProtocolConformance *distributedActorAsActorConformance = nullptr;
89+
8690
size_t anonymousSymbolCounter = 0;
8791

8892
llvm::Optional<SILDeclRef> StringToNSStringFn;
@@ -605,6 +609,20 @@ class LLVM_LIBRARY_VISIBILITY SILGenModule : public ASTVisitor<SILGenModule> {
605609
/// mentioned by the given type.
606610
void useConformancesFromObjectiveCType(CanType type);
607611

612+
/// Retrieve a protocol conformance to the `Actor` protocol for a
613+
/// distributed actor type that is described via a substitution map for
614+
/// the generic signature `<T: DistributedActor>`.
615+
///
616+
/// The protocol conformance is a special one that is currently
617+
/// only used by the `distributedActorAsAnyActor` builtin.
618+
ProtocolConformanceRef
619+
getDistributedActorAsActorConformance(SubstitutionMap subs);
620+
621+
/// Make a note of a member reference expression, which allows us
622+
/// to ensure that the conformance above is emitted wherever it
623+
/// needs to be.
624+
void noteMemberRefExpr(MemberRefExpr *e);
625+
608626
/// Map the substitutions for the original declaration to substitutions for
609627
/// the overridden declaration.
610628
static SubstitutionMap mapSubstitutionsForWitnessOverride(

lib/SILGen/SILGenBuiltin.cpp

Lines changed: 54 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -1889,13 +1889,10 @@ static ManagedValue emitBuiltinInjectEnumTag(SILGenFunction &SGF, SILLocation lo
18891889
return ManagedValue::forObjectRValueWithoutOwnership(bi);
18901890
}
18911891

1892-
static ExtensionDecl *distributedActorAsAnyActorExt = nullptr;
1893-
18941892
/// Find the extension on DistributedActor that defines __actorUnownedExecutor.
18951893
static ExtensionDecl *findDistributedActorAsActorExtension(
18961894
ProtocolDecl *distributedActorProto, ModuleDecl *module) {
18971895
ASTContext &ctx = distributedActorProto->getASTContext();
1898-
#if true
18991896
auto name = ctx.getIdentifier("__actorUnownedExecutor");
19001897
auto results = distributedActorProto->lookupDirect(
19011898
name, SourceLoc(),
@@ -1907,53 +1904,73 @@ static ExtensionDecl *findDistributedActorAsActorExtension(
19071904
}
19081905

19091906
return nullptr;
1910-
#else
1911-
if (!distributedActorAsAnyActorExt) {
1912-
auto ext = ExtensionDecl::create(
1913-
ctx, SourceLoc(), nullptr, { }, module, nullptr);
1914-
ctx.evaluator.cacheOutput(ExtendedTypeRequest{ext},
1915-
distributedActorProto->getDeclaredInterfaceType());
1916-
ctx.evaluator.cacheOutput(ExtendedNominalRequest{ext},
1917-
distributedActorProto);
1918-
1919-
distributedActorAsAnyActorExt = ext;
1907+
}
1908+
1909+
ProtocolConformanceRef
1910+
SILGenModule::getDistributedActorAsActorConformance(SubstitutionMap subs) {
1911+
ASTContext &ctx = M.getASTContext();
1912+
auto actorProto = ctx.getProtocol(KnownProtocolKind::Actor);
1913+
Type distributedActorType = subs.getReplacementTypes()[0];
1914+
1915+
if (!distributedActorAsActorConformance) {
1916+
auto distributedActorProto = ctx.getProtocol(KnownProtocolKind::DistributedActor);
1917+
if (!distributedActorProto)
1918+
return ProtocolConformanceRef();
1919+
1920+
auto ext = findDistributedActorAsActorExtension(
1921+
distributedActorProto, M.getSwiftModule());
1922+
if (!ext)
1923+
return ProtocolConformanceRef();
1924+
1925+
// Conformance of DistributedActor to Actor.
1926+
auto genericParam = subs.getGenericSignature().getGenericParams()[0];
1927+
distributedActorAsActorConformance = ctx.getNormalConformance(
1928+
Type(genericParam), actorProto, SourceLoc(), ext,
1929+
ProtocolConformanceState::Incomplete, /*isUnchecked=*/false,
1930+
/*isPreconcurrency=*/false);
1931+
}
1932+
1933+
return ProtocolConformanceRef(
1934+
actorProto,
1935+
ctx.getSpecializedConformance(distributedActorType,
1936+
distributedActorAsActorConformance,
1937+
subs));
1938+
}
1939+
1940+
void SILGenModule::noteMemberRefExpr(MemberRefExpr *e) {
1941+
VarDecl *var = cast<VarDecl>(e->getMember().getDecl());
1942+
1943+
// If the member is the special `asLocalActor` operation on
1944+
// distributed actors, make sure we have the conformance needed
1945+
// for a builtin.
1946+
ASTContext &ctx = var->getASTContext();
1947+
if (var->getName() == ctx.Id_asLocalActor &&
1948+
var->getDeclContext()->getSelfProtocolDecl() &&
1949+
var->getDeclContext()->getSelfProtocolDecl()
1950+
->isSpecificProtocol(KnownProtocolKind::DistributedActor)) {
1951+
auto conformance =
1952+
getDistributedActorAsActorConformance(
1953+
e->getMember().getSubstitutions());
1954+
useConformance(conformance);
19201955
}
19211956

1922-
return distributedActorAsAnyActorExt;
1923-
#endif
19241957
}
19251958

19261959
static ManagedValue emitBuiltinDistributedActorAsAnyActor(
19271960
SILGenFunction &SGF, SILLocation loc, SubstitutionMap subs,
19281961
ArrayRef<ManagedValue> args, SGFContext C) {
19291962
auto &ctx = SGF.getASTContext();
19301963
auto distributedActor = args[0];
1931-
1932-
auto builtinDecl = cast<FuncDecl>(getBuiltinValueDecl(
1933-
ctx, ctx.getIdentifier("distributedActorAsAnyActor")));
1934-
auto genericSignature = builtinDecl->getGenericSignature();
1935-
auto genericParam = genericSignature.getGenericParams()[0];
1936-
1937-
auto distributedActorProto = ctx.getProtocol(KnownProtocolKind::DistributedActor);
1938-
auto ext = findDistributedActorAsActorExtension(
1939-
distributedActorProto, SGF.getModule().getSwiftModule());
1940-
1941-
// Conformance of DistributedActor to Actor.
1942-
auto actorProto = ctx.getProtocol(KnownProtocolKind::Actor);
1943-
CanType distributedActorType = distributedActor.getType().getASTType();
1944-
RootProtocolConformance *daAsActorConformance = ctx.getNormalConformance(
1945-
Type(genericParam), actorProto, SourceLoc(), ext,
1946-
ProtocolConformanceState::Incomplete, /*isUnchecked=*/false,
1947-
/*isPreconcurrency=*/false);
1948-
ProtocolConformanceRef conformance(
1949-
actorProto,
1950-
ctx.getSpecializedConformance(distributedActorType, daAsActorConformance,
1951-
subs));
1952-
ProtocolConformanceRef conformances[1] = { conformance };
1964+
ProtocolConformanceRef conformances[1] = {
1965+
SGF.SGM.getDistributedActorAsActorConformance(subs)
1966+
};
19531967

19541968
// Erase the distributed actor instance into an `any Actor` existential with
19551969
// the special conformance.
1970+
CanType distributedActorType =
1971+
subs.getReplacementTypes()[0]->getCanonicalType();
19561972
auto &distributedActorTL = SGF.getTypeLowering(distributedActorType);
1973+
auto actorProto = ctx.getProtocol(KnownProtocolKind::Actor);
19571974
auto &anyActorTL = SGF.getTypeLowering(actorProto->getDeclaredExistentialType());
19581975
return SGF.emitExistentialErasure(
19591976
loc, distributedActorType, distributedActorTL, anyActorTL,

lib/SILGen/SILGenLValue.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3055,6 +3055,9 @@ class LLVM_LIBRARY_VISIBILITY SILGenBorrowedBaseVisitor
30553055
options, e->isSuper(), accessKind, strategy,
30563056
getSubstFormalRValueType(e),
30573057
false /*is on self parameter*/, actorIso);
3058+
3059+
SGF.SGM.noteMemberRefExpr(e);
3060+
30583061
return lv;
30593062
}
30603063

@@ -3864,6 +3867,9 @@ LValue SILGenLValue::visitMemberRefExpr(MemberRefExpr *e,
38643867
lv.addMemberVarComponent(SGF, e, var, e->getMember().getSubstitutions(),
38653868
options, e->isSuper(), accessKind, strategy,
38663869
substFormalRValueType, isOnSelfParameter, actorIso);
3870+
3871+
SGF.SGM.noteMemberRefExpr(e);
3872+
38673873
return lv;
38683874
}
38693875

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3465,7 +3465,7 @@ namespace {
34653465
// actor.
34663466
if (isolation.isDistributedActor()) {
34673467
actorExpr = UnresolvedDotExpr::createImplicit(
3468-
ctx, actorExpr, ctx.getIdentifier("asLocalActor"));
3468+
ctx, actorExpr, ctx.Id_asLocalActor);
34693469
}
34703470
break;
34713471
}

test/Distributed/Runtime/distributed_actor_to_actor.swift

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
// RUN: %empty-directory(%t)
22
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems %S/../Inputs/FakeDistributedActorSystems.swift
3-
// RUN: %target-build-swift -module-name main %import-libdispatch -j2 -parse-as-library -Xfrontend -disable-availability-checking -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -g -o %t/a.out -enable-experimental-feature BuiltinModule
3+
// RUN: %target-build-swift -module-name main %import-libdispatch -j2 -parse-as-library -Xfrontend -disable-availability-checking -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -g -o %t/a.out
44
// RUN: %target-codesign %t/a.out
55
// RUN: %target-run %t/a.out | %FileCheck %s --color
66

@@ -16,21 +16,12 @@
1616
// FIXME(distributed): Distributed actors currently have some issues on windows rdar://82593574
1717
// UNSUPPORTED: OS=windows-msvc
1818

19-
import Builtin // FIXME: Part of a hack to get the protocol conformance defined properly
2019
import Dispatch
2120
import Distributed
2221
import FakeDistributedActorSystems
2322

2423
typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem
2524

26-
extension DistributedActor {
27-
func localDistributedAsActor() -> any Actor {
28-
// FIXME: Part of a hack that forces the protocol conformance for DistributedActor -> Actor to be defined
29-
// FIXME: Drop usage of this once we resolve the issue above
30-
Builtin.distributedActorAsAnyActor(self)
31-
}
32-
}
33-
3425
distributed actor Worker {
3526
var counter: Int = 0
3627

0 commit comments

Comments
 (0)