Skip to content

Commit 96562cc

Browse files
committed
Pavel feedback
1 parent 789545d commit 96562cc

File tree

4 files changed

+163
-3
lines changed

4 files changed

+163
-3
lines changed

lib/Sema/CSApply.cpp

Lines changed: 19 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7789,11 +7789,21 @@ Expr *ExprRewriter::finishApply(ApplyExpr *apply, Type openedType,
77897789
apply->setArgs(args);
77907790
cs.setType(apply, fnType->getResult());
77917791

7792-
// If this is a call to a distributed method thunk,
7793-
// let's mark the call as implicitly throwing/async.
7792+
// If this is a call to a distributed method thunk or
7793+
// distributed protocol requirement, let's mark the
7794+
// call as implicitly throwing/async.
77947795
if (isa<SelfApplyExpr>(apply->getFn())) {
77957796
auto *FD = dyn_cast<FuncDecl>(callee.getDecl());
7796-
if (FD && FD->isDistributedThunk()) {
7797+
auto isDistributedProtocolRequirement = [&](FuncDecl *func) {
7798+
if (!func->isDistributed())
7799+
return false;
7800+
7801+
auto *DC = func->getDeclContext();
7802+
return isa_and_nonnull<ProtocolDecl>(DC->getAsDecl());
7803+
};
7804+
7805+
if (FD &&
7806+
(FD->isDistributedThunk() || isDistributedProtocolRequirement(FD))) {
77977807
apply->setImplicitlyThrows(true);
77987808
apply->setImplicitlyAsync(ImplicitActorHopTarget::forInstanceSelf());
77997809
apply->setUsesDistributedThunk(true);
@@ -7922,6 +7932,12 @@ bool ExprRewriter::requiresDistributedThunk(Expr *base, SourceLoc memberLoc,
79227932
auto *memberDecl = memberRef.getDecl();
79237933
assert(memberDecl);
79247934

7935+
auto *memberDC = memberDecl->getDeclContext();
7936+
// Protocol requirements are dispatched through a witness which is always
7937+
// a distributed thunk.
7938+
if (isa_and_nonnull<ProtocolDecl>(memberDC->getAsDecl()))
7939+
return false;
7940+
79257941
if (auto *FD = dyn_cast<FuncDecl>(memberDecl)) {
79267942
if (!(FD->isInstanceMember() && FD->isDistributed()))
79277943
return false;

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -508,7 +508,11 @@ bool CheckDistributedFunctionRequest::evaluate(
508508
serializationRequirements = getDistributedSerializationRequirementProtocols(
509509
getDistributedActorSystemType(actor)->getAnyNominal(),
510510
C.getProtocol(KnownProtocolKind::DistributedActorSystem));
511+
} else if (auto proto = dyn_cast<ProtocolDecl>(DC)) {
512+
// FIXME: if it has a n AS defined, we can do checks based on that, otherwise, don't
513+
return false;
511514
} else {
515+
func->dump();
512516
llvm_unreachable("Cannot handle types other than extensions and actor "
513517
"declarations in distributed function checking.");
514518
}
Lines changed: 94 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,94 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/../Inputs/FakeDistributedActorSystems.swift
3+
// RUN: %target-build-swift -module-name main -Xfrontend -disable-availability-checking -j2 -parse-as-library -I %t %s %S/../Inputs/FakeDistributedActorSystems.swift -o %t/a.out
4+
// RUN: %target-run %t/a.out | %FileCheck %s --color --dump-input=always
5+
6+
// REQUIRES: executable_test
7+
// REQUIRES: concurrency
8+
// REQUIRES: distributed
9+
10+
// rdar://76038845
11+
// UNSUPPORTED: use_os_stdlib
12+
// UNSUPPORTED: back_deployment_runtime
13+
14+
// FIXME(distributed): Distributed actors currently have some issues on windows, isRemote always returns false. rdar://82593574
15+
// UNSUPPORTED: OS=windows-msvc
16+
17+
import Distributed
18+
import FakeDistributedActorSystems
19+
20+
21+
typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem
22+
23+
protocol DistributedWorker: DistributedActor where ActorSystem == DefaultDistributedActorSystem {
24+
associatedtype WorkItem: Sendable & Codable
25+
associatedtype WorkResult: Sendable & Codable
26+
27+
distributed func submit(work: WorkItem) async throws -> WorkResult
28+
}
29+
30+
distributed actor TheWorker: DistributedWorker {
31+
typealias ActorSystem = DefaultDistributedActorSystem
32+
typealias WorkItem = String
33+
typealias WorkResult = String
34+
35+
distributed func submit(work: WorkItem) async throws -> WorkResult {
36+
"\(Self.self) echo: \(work)"
37+
}
38+
}
39+
40+
actor WorkerPool<Worker: DistributedWorker> {
41+
typealias ActorSystem = FakeRoundtripActorSystem
42+
typealias WorkItem = Worker.WorkItem
43+
typealias WorkResult = Worker.WorkResult
44+
45+
let actorSystem: ActorSystem
46+
let worker: Worker
47+
48+
init(worker: Worker, actorSystem: ActorSystem) {
49+
self.worker = worker
50+
self.actorSystem = actorSystem
51+
}
52+
53+
func submit(work: WorkItem) async throws -> WorkResult {
54+
let worker = try await self.selectWorker()
55+
return try await worker.submit(work: work)
56+
}
57+
58+
func selectWorker() async throws -> Worker {
59+
return self.worker
60+
}
61+
}
62+
63+
func test() async throws {
64+
let system = DefaultDistributedActorSystem()
65+
66+
let w = TheWorker(actorSystem: system)
67+
let remoteW = try! TheWorker.resolve(id: w.id, using: system)
68+
print("remoteW is remote: \(__isRemoteActor(remoteW))")
69+
70+
// direct calls work ok:
71+
// let reply = try await remoteW.submit(work: "Hello")
72+
73+
// Fails with:
74+
// Cannot handle types other than extensions and actor declarations in distributed function checking.
75+
// UNREACHABLE executed at /Users/ktoso/code/swift-project/swift/lib/Sema/TypeCheckDistributed.cpp:514!
76+
func callWorker<W: DistributedWorker>(w: W) async throws -> String where W.WorkItem == String, W.WorkResult == String {
77+
try await w.submit(work: "Hello")
78+
}
79+
let reply = try await callWorker(w: remoteW)
80+
81+
// let pool = WorkerPool<TheWorker>(worker: remoteW, actorSystem: system)
82+
// let reply = try await pool.submit(work: "Hello")
83+
// CHECK: >> remoteCall: on:main.TheWorker, target:main.TheWorker.submit(work:), invocation:FakeInvocationEncoder(genericSubs: [], arguments: ["Hello"], returnType: Optional(Swift.String), errorType: Optional(Swift.Error)), throwing:Swift.Error, returning:Swift.String
84+
85+
// CHECK: << remoteCall return: TheWorker echo: Hello
86+
print("reply: \(reply)")
87+
// CHECK: reply: TheWorker echo: Hello
88+
}
89+
90+
@main struct Main {
91+
static func main() async {
92+
try! await test()
93+
}
94+
}
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend-emit-module -emit-module-path %t/FakeDistributedActorSystems.swiftmodule -module-name FakeDistributedActorSystems -disable-availability-checking %S/Inputs/FakeDistributedActorSystems.swift
3+
// RUN: %target-swift-frontend -typecheck -verify -disable-availability-checking -I %t 2>&1 %s
4+
// REQUIRES: concurrency
5+
// REQUIRES: distributed
6+
7+
import Distributed
8+
import FakeDistributedActorSystems
9+
10+
@available(SwiftStdlib 5.5, *)
11+
typealias DefaultDistributedActorSystem = FakeActorSystem
12+
13+
import Distributed
14+
15+
protocol DistributedWorker: DistributedActor {
16+
associatedtype WorkItem: Sendable & Codable
17+
associatedtype WorkResult: Sendable & Codable
18+
19+
distributed func submit(work: WorkItem) async throws -> WorkResult
20+
}
21+
22+
distributed actor TheWorker: DistributedWorker {
23+
typealias ActorSystem = FakeActorSystem
24+
typealias WorkItem = String
25+
typealias WorkResult = String
26+
27+
distributed func submit(work: WorkItem) async throws -> WorkResult {
28+
work
29+
}
30+
}
31+
32+
distributed actor WorkerPool<Worker: DistributedWorker> {
33+
typealias ActorSystem = FakeActorSystem
34+
typealias WorkItem = Worker.WorkItem
35+
typealias WorkResult = Worker.WorkResult
36+
37+
func submit(work: WorkItem) async throws -> WorkResult {
38+
let worker = try await self.selectWorker()
39+
return try await worker.submit(work: work)
40+
// return try await TheWorker(actorSystem: actorSystem).submit(work: "X")
41+
}
42+
43+
func selectWorker() async throws -> Worker {
44+
fatalError()
45+
}
46+
}

0 commit comments

Comments
 (0)