Skip to content

Commit ebdb061

Browse files
committed
[Distributed] Fix when a distributed thunk is invoked, unlock tests
1 parent d993112 commit ebdb061

File tree

8 files changed

+38
-21
lines changed

8 files changed

+38
-21
lines changed

include/swift/AST/Expr.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1206,7 +1206,9 @@ class DeclRefExpr : public Expr {
12061206
/// which are cross-actor invoked, because such calls actually go over the
12071207
/// transport/network, and may throw from this, rather than the function
12081208
/// implementation itself..
1209-
bool isImplicitlyThrows() const { return Bits.DeclRefExpr.IsImplicitlyThrows; }
1209+
bool isImplicitlyThrows() const {
1210+
return Bits.DeclRefExpr.IsImplicitlyThrows;
1211+
}
12101212

12111213
/// Set whether this reference must account for a `throw` occurring for reasons
12121214
/// other than the function implementation itself throwing, e.g. an
@@ -4391,7 +4393,7 @@ class ApplyExpr : public Expr {
43914393
///
43924394
/// where the new closure is declared to be async.
43934395
///
4394-
/// When the application is implciitly async, the result describes
4396+
/// When the application is implicitly async, the result describes
43954397
/// the actor to which we need to need to hop.
43964398
Optional<ImplicitActorHopTarget> isImplicitlyAsync() const {
43974399
if (!Bits.ApplyExpr.ImplicitlyAsync)
@@ -4419,6 +4421,10 @@ class ApplyExpr : public Expr {
44194421
Bits.ApplyExpr.ImplicitlyThrows = flag;
44204422
}
44214423

4424+
/// Informs IRGen to that this expression should be applied as its distributed
4425+
/// thunk, rather than invoking the function directly.
4426+
bool shouldApplyDistributedThunk() const;
4427+
44224428
ValueDecl *getCalledValue() const;
44234429

44244430
static bool classof(const Expr *E) {

lib/AST/Expr.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1068,6 +1068,22 @@ Type OverloadSetRefExpr::getBaseType() const {
10681068
llvm_unreachable("Unhandled overloaded set reference expression");
10691069
}
10701070

1071+
bool ApplyExpr::shouldApplyDistributedThunk() const {
1072+
// only a distributed decl has a chance of needing to be invoked as a thunk
1073+
auto func = dyn_cast<AbstractFunctionDecl>(getCalledValue());
1074+
if (!func || !func->isDistributed())
1075+
return false;
1076+
1077+
if (implicitlyThrows())
1078+
return true;
1079+
1080+
auto isEffectivelyAsync = func->hasAsync() || isImplicitlyAsync();
1081+
if (func->hasThrows() && isEffectivelyAsync)
1082+
return true;
1083+
1084+
return false;
1085+
}
1086+
10711087
bool OverloadSetRefExpr::hasBaseObject() const {
10721088
if (Type BaseTy = getBaseType())
10731089
return !BaseTy->is<AnyMetatypeType>();

lib/SILGen/SILGenApply.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1117,12 +1117,8 @@ class SILGenApply : public Lowering::ExprVisitor<SILGenApply> {
11171117

11181118
// Otherwise, we have a statically-dispatched call.
11191119
auto constant = SILDeclRef(e->getDecl());
1120-
if (e->getDecl()->getAttrs().hasAttribute<DistributedActorAttr>()) {
1121-
// we're calling a distributed function, only in cross-actor situations
1122-
// does this actually need to call the thunk.
1123-
if (!selfApply) {
1124-
constant = constant.asDistributed(true);
1125-
}
1120+
if (callSite && callSite->shouldApplyDistributedThunk()) {
1121+
constant = constant.asDistributed(true);
11261122
} else {
11271123
constant = constant.asForeign(
11281124
!isConstructorWithGeneratedAllocatorThunk(e->getDecl())

lib/Sema/TypeCheckConcurrency.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2277,7 +2277,8 @@ namespace {
22772277
} else if (func->isDistributed()) {
22782278
tryMarkImplicitlyAsync(memberLoc, memberRef, context,
22792279
ImplicitActorHopTarget::forInstanceSelf());
2280-
tryMarkImplicitlyThrows(memberLoc, memberRef, context);
2280+
tryMarkImplicitlyThrows(memberLoc, memberRef, context);
2281+
22812282
} else {
22822283
// neither static or distributed, apply full distributed isolation
22832284
ctx.Diags.diagnose(memberLoc, diag::distributed_actor_isolated_method)

test/Distributed/Runtime/distributed_actor_dynamic_remote_func.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -54,7 +54,7 @@ struct FakeTransport: ActorTransport {
5454
fatalError("not implemented:\(#function)")
5555
}
5656

57-
func resolve<Act>(_ identity: Act.ID, as actorType: Act.Type)
57+
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type)
5858
throws -> Act?
5959
where Act: DistributedActor {
6060
return nil
@@ -95,7 +95,7 @@ func test_remote() async throws {
9595
let address = ActorAddress(parse: "")
9696
let transport = FakeTransport()
9797

98-
let worker = try LocalWorker(resolve: .init(address), using: transport)
98+
let worker = try LocalWorkerresolve(.init(address), using: transport)
9999
let x = try await worker.function()
100100
print("call: \(x)")
101101
// CHECK: call: _cluster_remote_function():

test/Distributed/Runtime/distributed_actor_local.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ struct FakeTransport: ActorTransport {
4949
fatalError("not implemented \(#function)")
5050
}
5151

52-
func resolve<Act>(_ identity: Act.ID, as actorType: Act.Type) throws -> Act?
52+
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type) throws -> Act?
5353
where Act: DistributedActor {
5454
return nil
5555
}
@@ -75,7 +75,7 @@ func test_initializers() {
7575
let transport = FakeTransport()
7676

7777
_ = SomeSpecificDistributedActor(transport: transport)
78-
_ = try! SomeSpecificDistributedActor(resolve: .init(address), using: transport)
78+
_ = try! SomeSpecificDistributedActor.resolve(.init(address), using: transport)
7979
}
8080

8181
@available(SwiftStdlib 5.5, *)

test/Distributed/Runtime/distributed_actor_remote_functions.swift

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,6 @@
1111
// rdar://77798215
1212
// UNSUPPORTED: OS=windows-msvc
1313

14-
// REQUIRES: rdar78290608
15-
1614
import _Distributed
1715
import _Concurrency
1816

@@ -114,7 +112,7 @@ struct FakeTransport: ActorTransport {
114112
fatalError("not implemented:\(#function)")
115113
}
116114

117-
func resolve<Act>(_ identity: Act.ID, as actorType: Act.Type)
115+
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type)
118116
throws -> Act?
119117
where Act: DistributedActor {
120118
return nil
@@ -155,21 +153,21 @@ func test_remote_invoke(address: ActorAddress, transport: ActorTransport) async
155153
if __isRemoteActor(actor) {
156154
do {
157155
_ = try await actor.helloThrowsTransportBoom()
158-
preconditionFailure("helloThrowsTransportBoom: should have thrown")
156+
print("WRONG: helloThrowsTransportBoom: should have thrown")
159157
} catch {
160158
print("\(personality) - helloThrowsTransportBoom: \(error)")
161159
}
162160
} else {
163161
do {
164162
_ = try await actor.helloThrowsImplBoom()
165-
preconditionFailure("helloThrowsImplBoom: Should have thrown")
163+
print("WRONG: helloThrowsImplBoom: Should have thrown")
166164
} catch {
167165
print("\(personality) - helloThrowsImplBoom: \(error)")
168166
}
169167
}
170168
}
171169

172-
let remote = try! SomeSpecificDistributedActor(resolve: .init(address), using: transport)
170+
let remote = try! SomeSpecificDistributedActor.resolve(.init(address), using: transport)
173171
assert(__isRemoteActor(remote) == true, "should be remote")
174172

175173
let local = SomeSpecificDistributedActor(transport: transport)

test/Distributed/Runtime/distributed_no_transport_boom.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ struct FakeTransport: ActorTransport {
3636
fatalError("not implemented:\(#function)")
3737
}
3838

39-
func resolve<Act>(_ identity: Act.ID, as actorType: Act.Type)
39+
func resolve<Act>(_ identity: AnyActorIdentity, as actorType: Act.Type)
4040
throws -> Act?
4141
where Act: DistributedActor {
4242
return nil
@@ -65,7 +65,7 @@ func test_remote() async {
6565
let address = ActorAddress(parse: "")
6666
let transport = FakeTransport()
6767

68-
let remote = try! SomeSpecificDistributedActor(resolve: .init(address), using: transport)
68+
let remote = try! SomeSpecificDistributedActor.resolve(.init(address), using: transport)
6969
_ = try! await remote.hello() // let it crash!
7070

7171
// CHECK: SOURCE_DIR/test/Distributed/Runtime/distributed_no_transport_boom.swift:18: Fatal error: Invoked remote placeholder function '_remote_hello' on remote distributed actor of type 'main.SomeSpecificDistributedActor'. Configure an appropriate 'ActorTransport' for this actor to resolve this error (e.g. by depending on some specific transport library).

0 commit comments

Comments
 (0)