Skip to content

Commit a249ccd

Browse files
committed
[Distributed] Survive generics with Sendable requirement in executeDistTarget
resolves rdar://90293494
1 parent 6c0ccfc commit a249ccd

File tree

4 files changed

+38
-14
lines changed

4 files changed

+38
-14
lines changed

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2120,7 +2120,10 @@ swift_distributed_getWitnessTables(GenericEnvironmentDescriptor *genericEnv,
21202120
},
21212121
[&substFn](const Metadata *type, unsigned index) {
21222122
return substFn.getWitnessTable(type, index);
2123-
});
2123+
}, /*skipUnknownKinds=*/true);
2124+
// The reason we skip unknown kinds is to avoid reporting missing
2125+
// conformances to Sendable, which cannot be checked at runtime, where we're
2126+
// calling this from 'executeDistributedTarget'.
21242127

21252128
if (error) {
21262129
return {/*ptr=*/nullptr, -1};

stdlib/public/runtime/Private.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -462,13 +462,17 @@ class TypeInfo {
462462
/// \param extraArguments The extra arguments determined while checking
463463
/// generic requirements (e.g., those that need to be
464464
/// passed to an instantiation function) will be added to this vector.
465+
/// \param skipUnknownKinds If true, unknown requirement kinds will not be
466+
/// reported as errors. This should used with care, and e.g. only to ignore
467+
/// @_marker protocols at runtime, which cannot be checked at runtime.
465468
///
466469
/// \returns the error if an error occurred, None otherwise.
467470
llvm::Optional<TypeLookupError> _checkGenericRequirements(
468471
llvm::ArrayRef<GenericRequirementDescriptor> requirements,
469472
llvm::SmallVectorImpl<const void *> &extraArguments,
470473
SubstGenericParameterFn substGenericParam,
471-
SubstDependentWitnessTableFn substWitnessTable);
474+
SubstDependentWitnessTableFn substWitnessTable,
475+
bool skipUnknownKinds = false);
472476

473477
/// A helper function which avoids performing a store if the destination
474478
/// address already contains the source value. This is useful when

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1234,11 +1234,18 @@ llvm::Optional<TypeLookupError> swift::_checkGenericRequirements(
12341234
llvm::ArrayRef<GenericRequirementDescriptor> requirements,
12351235
llvm::SmallVectorImpl<const void *> &extraArguments,
12361236
SubstGenericParameterFn substGenericParam,
1237-
SubstDependentWitnessTableFn substWitnessTable) {
1237+
SubstDependentWitnessTableFn substWitnessTable,
1238+
bool skipUnknownKinds) {
12381239
for (const auto &req : requirements) {
12391240
// Make sure we understand the requirement we're dealing with.
1240-
if (!req.hasKnownKind())
1241-
return TypeLookupError("unknown kind");
1241+
if (!req.hasKnownKind()) {
1242+
if (skipUnknownKinds) {
1243+
continue;
1244+
} else {
1245+
return TypeLookupError("unknown kind");
1246+
}
1247+
}
1248+
12421249

12431250
// Resolve the subject generic parameter.
12441251
auto result = swift_getTypeByMangledName(

test/Distributed/Runtime/distributed_actor_remoteCallTarget_demanglingTargetNames.swift

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,9 @@ import FakeDistributedActorSystems
1919

2020
typealias DefaultDistributedActorSystem = FakeRoundtripActorSystem
2121

22+
protocol SomeProtocol {}
23+
extension String: SomeProtocol {}
24+
2225
distributed actor Greeter {
2326
distributed func noParams() {}
2427
distributed func noParamsThrows() throws {}
@@ -28,9 +31,10 @@ distributed actor Greeter {
2831
distributed func oneLabel(value: String, _ value2: String, _ value3: String) {}
2932
distributed func parameterSingle(first: String) {}
3033
distributed func parameterPair(first: String, second: Int) {}
31-
// FIXME(distributed): rdar://90293494 fails to get
32-
// distributed func generic<A: Codable & Sendable>(first: A) {}
33-
// distributed func genericNoLabel<A: Codable & Sendable>(_ first: A) {}
34+
35+
distributed func generic<A: Codable & Sendable>(first: A) {}
36+
distributed func genericThree<A: Codable & Sendable & SomeProtocol>(first: A) {}
37+
distributed func genericThreeTwo<A: Codable & Sendable, B: Codable & SomeProtocol>(first: A, second: B) {}
3438
}
3539
extension Greeter {
3640
distributed func parameterTriple(first: String, second: Int, third: Double) {}
@@ -62,19 +66,25 @@ func test() async throws {
6266
_ = try await greeter.parameterPair(first: "X", second: 2)
6367
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterPair(first:second:)
6468

65-
_ = try await greeter.parameterTriple(first: "X", second: 2, third: 3.0)
66-
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterTriple(first:second:third:)
69+
_ = try await greeter.generic(first: "X")
70+
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.generic(first:)
71+
72+
_ = try await greeter.genericThree(first: "X")
73+
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.genericThree(first:)
6774

68-
// FIXME: rdar://90293494 seems to fail getting the substitutions?
69-
// _ = try await greeter.generic(first: "X")
70-
// // TODO: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.parameterTriple(first:second:third:)
75+
_ = try await greeter.genericThreeTwo(first: "X", second: "SecondValue")
76+
// CHECK: >> remoteCallVoid: on:main.Greeter, target:main.Greeter.genericThreeTwo(first:second:)
7177

7278
print("done")
7379
// CHECK: done
7480
}
7581

7682
@main struct Main {
7783
static func main() async {
78-
try! await test()
84+
do {
85+
try await test()
86+
} catch {
87+
print("ERROR: \(error)")
88+
}
7989
}
8090
}

0 commit comments

Comments
 (0)