Skip to content

Commit e09411f

Browse files
committed
[Distributed] Correct accessor handling of generics
1 parent 699b165 commit e09411f

File tree

5 files changed

+97
-28
lines changed

5 files changed

+97
-28
lines changed

lib/IRGen/GenDistributed.cpp

Lines changed: 12 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -221,7 +221,10 @@ static CanSILFunctionType getAccessorType(IRGenModule &IGM,
221221
// A generic parameter that represents instance of invocation decoder.
222222
auto *decoderType =
223223
GenericTypeParamType::get(/*isParameterPack=*/false,
224-
/*depth=*/1, /*index=*/0, Context);
224+
/*depth=*/0, /*index=*/0, Context);
225+
auto *actorType =
226+
GenericTypeParamType::get(/*isParameterPack=*/false,
227+
/*depth=*/0, /*index=*/1, Context);
225228

226229
// decoder
227230
parameters.push_back(GenericFunctionType::Param(
@@ -248,14 +251,8 @@ static CanSILFunctionType getAccessorType(IRGenModule &IGM,
248251
// number of witness tables
249252
parameters.push_back(GenericFunctionType::Param(Context.getUIntType()));
250253

251-
// actor
252-
{
253-
auto targetTy = Target->getLoweredFunctionType();
254-
auto actorLoc = targetTy->getParameters().back();
255-
256-
parameters.push_back(
257-
GenericFunctionType::Param(actorLoc.getInterfaceType()));
258-
}
254+
// actor type
255+
parameters.push_back(GenericFunctionType::Param(actorType));
259256

260257
auto decoderProtocolTy =
261258
Context
@@ -268,19 +265,17 @@ static CanSILFunctionType getAccessorType(IRGenModule &IGM,
268265
SmallVector<GenericTypeParamType *, 4> genericParams;
269266
SmallVector<Requirement, 4> genericRequirements;
270267

271-
auto *actor = getDistributedActorOf(Target);
272-
assert(actor);
273-
274-
for (auto *genericParam : actor->getInnermostGenericParamTypes())
275-
genericParams.push_back(genericParam);
276-
277268
// Add a generic parameter `D` which stands for decoder type in the
278269
// accessor signature - `inout D`.
279270
genericParams.push_back(decoderType);
280271
// Add a requirement that decoder conforms to the expected protocol.
281272
genericRequirements.push_back(
282273
{RequirementKind::Conformance, decoderType, decoderProtocolTy});
283274

275+
// Add a generic type for the actor type of the target.
276+
// We don't have to put any requirement on it; all we need is a type here to use for the self.
277+
genericParams.push_back(actorType);
278+
284279
signature = GenericSignature::get(genericParams, genericRequirements);
285280
}
286281

@@ -649,11 +644,8 @@ void DistributedAccessor::emit() {
649644
// Metadata that represents passed in the invocation decoder.
650645
auto *decoderType = params.claimNext();
651646

652-
// If the distributed thunk is declared in a protocol that conforms
653-
// to `DistributedActor` protocol, there is an extract parameter that
654-
// represents a type of protocol witness.
655-
if (isa<ProtocolDecl>(actor))
656-
(void)params.claimNext();
647+
// Metadata of the distributed actor the accessor is for.
648+
(void)params.claimNext();
657649

658650
// Witness table for decoder conformance to DistributedTargetInvocationDecoder
659651
auto *decoderProtocolWitness = params.claimNext();

stdlib/public/Distributed/DistributedActor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@ using TargetExecutorSignature =
6262
/*numWitnessTables=*/size_t,
6363
/*decoderType=*/Metadata *,
6464
/*decoderWitnessTable=*/void **),
65-
/*throws=*/true>;
65+
/*throws=*/true>;
6666

6767
SWIFT_CC(swiftasync)
6868
SWIFT_EXPORT_FROM(swiftDistributed)
@@ -89,7 +89,7 @@ using DistributedAccessorSignature =
8989
/*actor=*/HeapObject *,
9090
/*decoderType=*/Metadata *,
9191
/*decoderWitnessTable=*/void **),
92-
/*throws=*/true>;
92+
/*throws=*/true>;
9393

9494
SWIFT_CC(swiftasync)
9595
static DistributedAccessorSignature::ContinuationType
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
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
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+
import Distributed
15+
import FakeDistributedActorSystems
16+
17+
import Distributed
18+
import FakeDistributedActorSystems
19+
20+
typealias DefaultDistributedActorSystem = FakeActorSystem
21+
22+
protocol SomeProtocol {
23+
static var isInteger: Bool { get }
24+
}
25+
26+
distributed actor TestActor<Value> where Value: Codable & Identifiable, Value.ID: SomeProtocol {
27+
distributed func requirementsFromActor(value: Value) async throws {
28+
self.preconditionIsolated()
29+
print("OK: \(value)")
30+
}
31+
distributed func requirementsFromActorAndMethod(value: Value) async throws where Value: VerySpecific {
32+
self.preconditionIsolated()
33+
print("OK: \(value)")
34+
}
35+
}
36+
37+
protocol VerySpecific {}
38+
39+
struct TheValue: Codable, Identifiable, VerySpecific {
40+
let id: String
41+
init() {
42+
self.id = "id"
43+
}
44+
}
45+
extension String: SomeProtocol {
46+
static var isInteger: Bool { false }
47+
}
48+
49+
@main struct Main {
50+
static func main() async throws {
51+
let ta: TestActor<TheValue> = TestActor(actorSystem: .init())
52+
try await ta.requirementsFromActor(value: TheValue())
53+
try await ta.requirementsFromActorAndMethod(value: TheValue())
54+
// CHECK: OK
55+
}
56+
}

test/Distributed/Runtime/distributed_actor_hop_to.swift

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ protocol LifecycleWatch: DistributedActor where ActorSystem == FakeRoundtripActo
2626

2727
extension LifecycleWatch {
2828
func watch<T: Codable>(x: Int, _ y: T) async throws {
29+
self.preconditionIsolated()
2930
print("executed: \(#function) - x = \(x), y = \(y)")
3031
}
3132

@@ -39,15 +40,35 @@ extension LifecycleWatch {
3940
distributed actor Worker: LifecycleWatch {
4041
}
4142

43+
extension Worker {
44+
distributed actor Inside<Something> {
45+
distributed func testSecond<A: Codable>(_: A) async throws {
46+
self.preconditionIsolated()
47+
print("executed: \(#function)")
48+
}
49+
distributed func moreParams<A: Codable, B: Codable>(_: A, _: B) async throws {
50+
self.preconditionIsolated()
51+
print("executed: \(#function)")
52+
}
53+
}
54+
}
55+
4256
@main struct Main {
4357
static func main() async {
44-
let worker: any LifecycleWatch = Worker(actorSystem: DefaultDistributedActorSystem())
58+
let system = DefaultDistributedActorSystem()
59+
let worker: any LifecycleWatch = Worker(actorSystem: system)
4560
try! await worker.test(x: 42, "on protocol")
4661

4762
// CHECK: executed: test(x:_:)
4863
// CHECK: executed: watch(x:_:) - x = 42, y = on protocol
4964
// CHECK: done executed: test(x:_:)
5065

66+
try! await Worker.Inside<String>(actorSystem: system).testSecond(42)
67+
// CHECK: executed: test
68+
69+
try! await Worker.Inside<String>(actorSystem: system).moreParams(21, 42)
70+
// CHECK: executed: moreParams
71+
5172
print("OK") // CHECK: OK
5273
}
5374
}

test/Distributed/distributed_actor_accessor_thunks_64bit.swift

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ public distributed actor MyOtherActor {
9494

9595
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTE"
9696

97-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETF"(ptr swiftasync %0, ptr %1, ptr %2, ptr %3, {{.*}}, ptr [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
97+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple1yySiYaKFTETF"(ptr swiftasync %0, ptr %1, ptr %2, ptr %3, {{.*}}, ptr {{(noalias)?}} [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]], {{.*}})
9898

9999
/// Read the current offset and cast an element to `Int`
100100

@@ -192,7 +192,7 @@ public distributed actor MyOtherActor {
192192
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTE"
193193

194194
/// !!! in `simple3` interesting bits are: argument value extraction (because string is exploded into N arguments) and call to distributed thunk
195-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
195+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7simple3ySiSSYaKFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr {{(noalias)?}} [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]], {{.*}})
196196

197197

198198
// CHECK: [[ARG_SIZE:%.*]] = and i64 {{.*}}, -16
@@ -232,7 +232,7 @@ public distributed actor MyOtherActor {
232232

233233
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTE"
234234

235-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
235+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC16single_case_enumyAA7SimpleEOAFYaKFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr {{(noalias)?}} [[ACTOR]], ptr [[DECODER_TYPE]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]], {{.*}})
236236

237237
/// Let's check that the call doesn't have any arguments and returns nothing.
238238

@@ -272,7 +272,7 @@ public distributed actor MyOtherActor {
272272

273273
// CHECK: define hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTE"
274274

275-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETF"(ptr swiftasync {{.*}}, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
275+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC7complexyAA11LargeStructVSaySiG_AA3ObjCSSSgAFtYaKFTETF"(ptr swiftasync {{.*}}, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUFF:%.*]], ptr [[SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr noalias [[ACTOR]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]], {{.*}})
276276

277277
/// First, let's check that all of the different argument types here are loaded correctly.
278278

@@ -319,7 +319,7 @@ public distributed actor MyOtherActor {
319319

320320
/// ---> Accessor for `genericArgs`
321321

322-
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtYaKSeRzSERzSeR_SER_r0_lFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUF:%.*]], ptr [[GENERIC_SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
322+
// CHECK: define linkonce_odr hidden swift{{(tail)?}}cc void @"$s27distributed_actor_accessors7MyActorC11genericArgsyyx_Sayq_GtYaKSeRzSERzSeR_SER_r0_lFTETF"(ptr swiftasync %0, ptr [[ARG_DECODER:%.*]], ptr [[ARG_TYPES:%.*]], ptr [[RESULT_BUF:%.*]], ptr [[GENERIC_SUBS:%.*]], ptr [[WITNESS_TABLES:%.*]], i64 [[NUM_WITNESS_TABLES:%.*]], ptr {{(noalias)?}} [[ACTOR:%.*]], ptr [[DECODER_TYPE:%.*]], ptr [[DECODER_PROTOCOL_WITNESS:%.*]])
323323

324324
/// ---> Load `T`
325325

0 commit comments

Comments
 (0)