Skip to content

Commit 9889586

Browse files
authored
Merge pull request #59162 from ktoso/wip-adhoc-mutating-onreturn
[Distributed] Missing diagnostic for onReturn ad-hoc req when it is mutating witness
2 parents a6ffb09 + 402501d commit 9889586

File tree

4 files changed

+121
-35
lines changed

4 files changed

+121
-35
lines changed

lib/AST/DistributedDecl.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -404,6 +404,11 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
404404
return false;
405405
}
406406

407+
auto *func = dyn_cast<FuncDecl>(this);
408+
if (!func) {
409+
return false;
410+
}
411+
407412
// === Structural Checks
408413
// -- Must be throwing
409414
if (!hasThrows()) {
@@ -415,6 +420,11 @@ bool AbstractFunctionDecl::isDistributedActorSystemRemoteCall(bool isVoidReturn)
415420
return false;
416421
}
417422

423+
// -- Must not be mutating, use classes to implement a system instead
424+
if (func->isMutating()) {
425+
return false;
426+
}
427+
418428
// === Check generics
419429
if (!isGeneric()) {
420430
return false;
@@ -1166,6 +1176,11 @@ AbstractFunctionDecl::isDistributedTargetInvocationResultHandlerOnReturn() const
11661176
return false;
11671177
}
11681178

1179+
// --- must not be mutating
1180+
if (func->isMutating()) {
1181+
return false;
1182+
}
1183+
11691184
// === Check generics
11701185
if (!isGeneric()) {
11711186
return false;

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 8 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -247,7 +247,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements(
247247
decl->getDescriptiveKind(), decl->getName(), identifier);
248248
decl->diagnose(
249249
diag::note_distributed_actor_system_conformance_missing_adhoc_requirement,
250-
decl->getName(), identifier,
250+
Proto->getName(), identifier,
251251
"func remoteCall<Act, Err, Res>(\n"
252252
" on actor: Act,\n"
253253
" target: RemoteCallTarget,\n"
@@ -274,7 +274,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements(
274274
decl->getDescriptiveKind(), decl->getName(), identifier);
275275
decl->diagnose(
276276
diag::note_distributed_actor_system_conformance_missing_adhoc_requirement,
277-
decl->getName(), identifier,
277+
Proto->getName(), identifier,
278278
"func remoteCallVoid<Act, Err>(\n"
279279
" on actor: Act,\n"
280280
" target: RemoteCallTarget,\n"
@@ -303,7 +303,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements(
303303
diag::distributed_actor_system_conformance_missing_adhoc_requirement,
304304
decl->getDescriptiveKind(), decl->getName(), identifier);
305305
decl->diagnose(diag::note_distributed_actor_system_conformance_missing_adhoc_requirement,
306-
decl->getName(), identifier,
306+
Proto->getName(), identifier,
307307
"mutating func recordArgument<Value: SerializationRequirement>(_ argument: RemoteCallArgument<Value>) throws\n");
308308
anyMissingAdHocRequirements = true;
309309
}
@@ -318,7 +318,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements(
318318
diag::distributed_actor_system_conformance_missing_adhoc_requirement,
319319
decl->getDescriptiveKind(), decl->getName(), identifier);
320320
decl->diagnose(diag::note_distributed_actor_system_conformance_missing_adhoc_requirement,
321-
decl->getName(), identifier,
321+
Proto->getName(), identifier,
322322
"mutating func recordReturnType<Res: SerializationRequirement>(_ resultType: Res.Type) throws\n");
323323
anyMissingAdHocRequirements = true;
324324
}
@@ -339,7 +339,7 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements(
339339
diag::distributed_actor_system_conformance_missing_adhoc_requirement,
340340
decl->getDescriptiveKind(), decl->getName(), identifier);
341341
decl->diagnose(diag::note_distributed_actor_system_conformance_missing_adhoc_requirement,
342-
decl->getName(), identifier,
342+
Proto->getName(), identifier,
343343
"mutating func decodeNextArgument<Argument: SerializationRequirement>() throws -> Argument\n");
344344
anyMissingAdHocRequirements = true;
345345
}
@@ -360,10 +360,9 @@ bool swift::checkDistributedActorSystemAdHocProtocolRequirements(
360360
diag::distributed_actor_system_conformance_missing_adhoc_requirement,
361361
decl->getDescriptiveKind(), decl->getName(), identifier);
362362
decl->diagnose(
363-
diag::
364-
note_distributed_actor_system_conformance_missing_adhoc_requirement,
365-
decl->getName(), identifier,
366-
"mutating func onReturn<Success: SerializationRequirement>(value: "
363+
diag::note_distributed_actor_system_conformance_missing_adhoc_requirement,
364+
Proto->getName(), identifier,
365+
"func onReturn<Success: SerializationRequirement>(value: "
367366
"Success) async throws\n");
368367
anyMissingAdHocRequirements = true;
369368
}

test/Distributed/distributed_actor_system_missing_adhoc_requirement_impls.swift

Lines changed: 91 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -8,10 +8,10 @@ import Distributed
88

99
struct MissingRemoteCall: DistributedActorSystem {
1010
// expected-error@-1{{struct 'MissingRemoteCall' is missing witness for protocol requirement 'remoteCall'}}
11-
// expected-note@-2{{protocol 'MissingRemoteCall' requires function 'remoteCall' with signature:}}
11+
// expected-note@-2{{protocol 'DistributedActorSystem' requires function 'remoteCall' with signature:}}
1212

1313
// expected-error@-4{{struct 'MissingRemoteCall' is missing witness for protocol requirement 'remoteCallVoid'}}
14-
// expected-note@-5{{protocol 'MissingRemoteCall' requires function 'remoteCallVoid' with signature:}}
14+
// expected-note@-5{{protocol 'DistributedActorSystem' requires function 'remoteCallVoid' with signature:}}
1515

1616
typealias ActorID = ActorAddress
1717
typealias InvocationDecoder = FakeInvocationDecoder
@@ -41,12 +41,73 @@ struct MissingRemoteCall: DistributedActorSystem {
4141
}
4242
}
4343

44+
struct RemoteCallMutating: DistributedActorSystem {
45+
// expected-error@-1{{struct 'RemoteCallMutating' is missing witness for protocol requirement 'remoteCall'}}
46+
// expected-note@-2{{protocol 'DistributedActorSystem' requires function 'remoteCall' with signature:}}
47+
48+
// expected-error@-4{{struct 'RemoteCallMutating' is missing witness for protocol requirement 'remoteCallVoid'}}
49+
// expected-note@-5{{protocol 'DistributedActorSystem' requires function 'remoteCallVoid' with signature:}}
50+
51+
typealias ActorID = ActorAddress
52+
typealias InvocationDecoder = FakeInvocationDecoder
53+
typealias InvocationEncoder = FakeInvocationEncoder
54+
typealias SerializationRequirement = Codable
55+
typealias ResultHandler = FakeResultHandler
56+
57+
func resolve<Act>(id: ActorID, as actorType: Act.Type)
58+
throws -> Act? where Act: DistributedActor {
59+
return nil
60+
}
61+
62+
func assignID<Act>(_ actorType: Act.Type) -> ActorID
63+
where Act: DistributedActor {
64+
ActorAddress(parse: "fake://123")
65+
}
66+
67+
func actorReady<Act>(_ actor: Act)
68+
where Act: DistributedActor,
69+
Act.ID == ActorID {
70+
}
71+
72+
func resignID(_ id: ActorID) {
73+
}
74+
75+
mutating func remoteCall<Act, Err, Res>(
76+
on actor: Act,
77+
target: RemoteCallTarget,
78+
invocation: inout InvocationEncoder,
79+
throwing: Err.Type,
80+
returning: Res.Type
81+
) async throws -> Res
82+
where Act: DistributedActor,
83+
Act.ID == ActorID,
84+
Err: Error,
85+
Res: SerializationRequirement {
86+
fatalError("NOT IMPLEMENTED \(#function)")
87+
}
88+
89+
mutating func remoteCallVoid<Act, Err>(
90+
on actor: Act,
91+
target: RemoteCallTarget,
92+
invocation: inout InvocationEncoder,
93+
throwing: Err.Type
94+
) async throws
95+
where Act: DistributedActor,
96+
Act.ID == ActorID,
97+
Err: Error {
98+
fatalError("NOT IMPLEMENTED \(#function)")
99+
}
100+
101+
func makeInvocationEncoder() -> InvocationEncoder {
102+
}
103+
}
104+
44105
struct MissingRemoteCall_missingInout_on_encoder: DistributedActorSystem {
45106
// expected-error@-1{{struct 'MissingRemoteCall_missingInout_on_encoder' is missing witness for protocol requirement 'remoteCall'}}
46-
// expected-note@-2{{protocol 'MissingRemoteCall_missingInout_on_encoder' requires function 'remoteCall' with signature:}}
107+
// expected-note@-2{{protocol 'DistributedActorSystem' requires function 'remoteCall' with signature:}}
47108

48109
// expected-error@-4{{struct 'MissingRemoteCall_missingInout_on_encoder' is missing witness for protocol requirement 'remoteCallVoid'}}
49-
// expected-note@-5{{protocol 'MissingRemoteCall_missingInout_on_encoder' requires function 'remoteCallVoid' with signature:}}
110+
// expected-note@-5{{protocol 'DistributedActorSystem' requires function 'remoteCallVoid' with signature:}}
50111

51112
typealias ActorID = ActorAddress
52113
typealias InvocationDecoder = FakeInvocationDecoder
@@ -160,10 +221,10 @@ struct MissingRemoteCall_missing_makeInvocationEncoder: DistributedActorSystem {
160221

161222
struct Error_wrongReturn: DistributedActorSystem {
162223
// expected-error@-1{{struct 'Error_wrongReturn' is missing witness for protocol requirement 'remoteCall'}}
163-
// expected-note@-2{{protocol 'Error_wrongReturn' requires function 'remoteCall' with signature:}}
224+
// expected-note@-2{{protocol 'DistributedActorSystem' requires function 'remoteCall' with signature:}}
164225

165226
// expected-error@-4{{struct 'Error_wrongReturn' is missing witness for protocol requirement 'remoteCallVoid'}}
166-
// expected-note@-5{{protocol 'Error_wrongReturn' requires function 'remoteCallVoid' with signature:}}
227+
// expected-note@-5{{protocol 'DistributedActorSystem' requires function 'remoteCallVoid' with signature:}}
167228

168229
typealias ActorID = ActorAddress
169230
typealias InvocationDecoder = FakeInvocationDecoder
@@ -235,10 +296,10 @@ struct Error_wrongReturn: DistributedActorSystem {
235296

236297
struct BadRemoteCall_param: DistributedActorSystem {
237298
// expected-error@-1{{struct 'BadRemoteCall_param' is missing witness for protocol requirement 'remoteCall'}}
238-
// expected-note@-2{{protocol 'BadRemoteCall_param' requires function 'remoteCall' with signature:}}
299+
// expected-note@-2{{protocol 'DistributedActorSystem' requires function 'remoteCall' with signature:}}
239300

240301
// expected-error@-4{{struct 'BadRemoteCall_param' is missing witness for protocol requirement 'remoteCallVoid'}}
241-
// expected-note@-5{{protocol 'BadRemoteCall_param' requires function 'remoteCallVoid' with signature:}}
302+
// expected-note@-5{{protocol 'DistributedActorSystem' requires function 'remoteCallVoid' with signature:}}
242303

243304
typealias ActorID = ActorAddress
244305
typealias InvocationDecoder = FakeInvocationDecoder
@@ -345,7 +406,7 @@ public struct BadRemoteCall_notPublic: DistributedActorSystem {
345406

346407
public struct BadRemoteCall_badResultConformance: DistributedActorSystem {
347408
// expected-error@-1{{struct 'BadRemoteCall_badResultConformance' is missing witness for protocol requirement 'remoteCall'}}
348-
// expected-note@-2{{protocol 'BadRemoteCall_badResultConformance' requires function 'remoteCall' with signature:}}
409+
// expected-note@-2{{protocol 'DistributedActorSystem' requires function 'remoteCall' with signature:}}
349410

350411
public typealias ActorID = ActorAddress
351412
public typealias InvocationDecoder = PublicFakeInvocationDecoder
@@ -452,7 +513,7 @@ struct BadRemoteCall_largeSerializationRequirement: DistributedActorSystem {
452513

453514
struct BadRemoteCall_largeSerializationRequirementSlightlyOffInDefinition: DistributedActorSystem {
454515
// expected-error@-1{{struct 'BadRemoteCall_largeSerializationRequirementSlightlyOffInDefinition' is missing witness for protocol requirement 'remoteCall'}}
455-
// expected-note@-2{{protocol 'BadRemoteCall_largeSerializationRequirementSlightlyOffInDefinition' requires function 'remoteCall' with signature:}}
516+
// expected-note@-2{{protocol 'DistributedActorSystem' requires function 'remoteCall' with signature:}}
456517

457518
typealias ActorID = ActorAddress
458519
typealias InvocationDecoder = LargeSerializationReqFakeInvocationDecoder
@@ -608,7 +669,7 @@ public struct PublicFakeInvocationEncoder: DistributedTargetInvocationEncoder {
608669

609670
struct FakeInvocationEncoder_missing_recordArgument: DistributedTargetInvocationEncoder {
610671
//expected-error@-1{{struct 'FakeInvocationEncoder_missing_recordArgument' is missing witness for protocol requirement 'recordArgument'}}
611-
//expected-note@-2{{protocol 'FakeInvocationEncoder_missing_recordArgument' requires function 'recordArgument' with signature:}}
672+
//expected-note@-2{{protocol 'DistributedTargetInvocationEncoder' requires function 'recordArgument' with signature:}}
612673
typealias SerializationRequirement = Codable
613674

614675
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
@@ -620,7 +681,7 @@ struct FakeInvocationEncoder_missing_recordArgument: DistributedTargetInvocation
620681

621682
struct FakeInvocationEncoder_missing_recordArgument2: DistributedTargetInvocationEncoder {
622683
//expected-error@-1{{struct 'FakeInvocationEncoder_missing_recordArgument2' is missing witness for protocol requirement 'recordArgument'}}
623-
//expected-note@-2{{protocol 'FakeInvocationEncoder_missing_recordArgument2' requires function 'recordArgument' with signature:}}
684+
//expected-note@-2{{protocol 'DistributedTargetInvocationEncoder' requires function 'recordArgument' with signature:}}
624685
typealias SerializationRequirement = Codable
625686

626687
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
@@ -632,7 +693,7 @@ struct FakeInvocationEncoder_missing_recordArgument2: DistributedTargetInvocatio
632693

633694
struct FakeInvocationEncoder_missing_recordReturnType: DistributedTargetInvocationEncoder {
634695
//expected-error@-1{{struct 'FakeInvocationEncoder_missing_recordReturnType' is missing witness for protocol requirement 'recordReturnType'}}
635-
//expected-note@-2{{protocol 'FakeInvocationEncoder_missing_recordReturnType' requires function 'recordReturnType' with signature:}}
696+
//expected-note@-2{{protocol 'DistributedTargetInvocationEncoder' requires function 'recordReturnType' with signature:}}
636697
typealias SerializationRequirement = Codable
637698

638699
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
@@ -655,7 +716,7 @@ struct FakeInvocationEncoder_missing_recordErrorType: DistributedTargetInvocatio
655716

656717
struct FakeInvocationEncoder_recordArgument_wrongType: DistributedTargetInvocationEncoder {
657718
//expected-error@-1{{struct 'FakeInvocationEncoder_recordArgument_wrongType' is missing witness for protocol requirement 'recordArgument'}}
658-
//expected-note@-2{{protocol 'FakeInvocationEncoder_recordArgument_wrongType' requires function 'recordArgument' with signature:}}
719+
//expected-note@-2{{protocol 'DistributedTargetInvocationEncoder' requires function 'recordArgument' with signature:}}
659720
typealias SerializationRequirement = Codable
660721

661722
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
@@ -668,7 +729,7 @@ struct FakeInvocationEncoder_recordArgument_wrongType: DistributedTargetInvocati
668729
}
669730
struct FakeInvocationEncoder_recordArgument_missingMutating: DistributedTargetInvocationEncoder {
670731
//expected-error@-1{{struct 'FakeInvocationEncoder_recordArgument_missingMutating' is missing witness for protocol requirement 'recordArgument'}}
671-
//expected-note@-2{{protocol 'FakeInvocationEncoder_recordArgument_missingMutating' requires function 'recordArgument' with signature:}}
732+
//expected-note@-2{{protocol 'DistributedTargetInvocationEncoder' requires function 'recordArgument' with signature:}}
672733
typealias SerializationRequirement = Codable
673734

674735
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
@@ -680,7 +741,7 @@ struct FakeInvocationEncoder_recordArgument_missingMutating: DistributedTargetIn
680741

681742
struct FakeInvocationEncoder_recordResultType_wrongType: DistributedTargetInvocationEncoder {
682743
//expected-error@-1{{struct 'FakeInvocationEncoder_recordResultType_wrongType' is missing witness for protocol requirement 'recordReturnType'}}
683-
//expected-note@-2{{protocol 'FakeInvocationEncoder_recordResultType_wrongType' requires function 'recordReturnType' with signature:}}
744+
//expected-note@-2{{protocol 'DistributedTargetInvocationEncoder' requires function 'recordReturnType' with signature:}}
684745
typealias SerializationRequirement = Codable
685746

686747
mutating func recordGenericSubstitution<T>(_ type: T.Type) throws {}
@@ -757,7 +818,7 @@ public final class PublicFakeInvocationDecoder_badNotPublic: DistributedTargetIn
757818

758819
final class PublicFakeInvocationDecoder_badBadProtoRequirement: DistributedTargetInvocationDecoder {
759820
// expected-error@-1{{class 'PublicFakeInvocationDecoder_badBadProtoRequirement' is missing witness for protocol requirement 'decodeNextArgument'}}
760-
// expected-note@-2{{protocol 'PublicFakeInvocationDecoder_badBadProtoRequirement' requires function 'decodeNextArgument' with signature:}}
821+
// expected-note@-2{{protocol 'DistributedTargetInvocationDecoder' requires function 'decodeNextArgument' with signature:}}
761822
typealias SerializationRequirement = Codable
762823

763824
func decodeGenericSubstitutions() throws -> [Any.Type] { [] }
@@ -809,23 +870,34 @@ struct LargeSerializationReqFakeInvocationResultHandler: DistributedTargetInvoca
809870

810871
struct BadResultHandler_missingOnReturn: DistributedTargetInvocationResultHandler {
811872
// expected-error@-1{{struct 'BadResultHandler_missingOnReturn' is missing witness for protocol requirement 'onReturn'}}
812-
// expected-note@-2{{protocol 'BadResultHandler_missingOnReturn' requires function 'onReturn' with signature:}}
873+
// expected-note@-2{{protocol 'DistributedTargetInvocationResultHandler' requires function 'onReturn' with signature:}}
813874
typealias SerializationRequirement = Codable
814875

815876
// func onReturn<Res: SerializationRequirement>(value: Res) async throws {} // MISSING
816877
func onReturnVoid() async throws {}
817878
func onThrow<Err: Error>(error: Err) async throws {}
818879
}
880+
819881
struct BadResultHandler_missingRequirement: DistributedTargetInvocationResultHandler {
820882
// expected-error@-1{{struct 'BadResultHandler_missingRequirement' is missing witness for protocol requirement 'onReturn'}}
821-
// expected-note@-2{{protocol 'BadResultHandler_missingRequirement' requires function 'onReturn' with signature:}}
883+
// expected-note@-2{{protocol 'DistributedTargetInvocationResultHandler' requires function 'onReturn' with signature:}}
822884
typealias SerializationRequirement = Codable
823885

824886
func onReturn<Success>(value: Success) async throws {} // MISSING : Codable
825887
func onReturnVoid() async throws {}
826888
func onThrow<Err: Error>(error: Err) async throws {}
827889
}
828890

891+
struct BadResultHandler_mutatingButShouldNotBe: DistributedTargetInvocationResultHandler {
892+
// expected-error@-1{{struct 'BadResultHandler_mutatingButShouldNotBe' is missing witness for protocol requirement 'onReturn'}}
893+
// expected-note@-2{{protocol 'DistributedTargetInvocationResultHandler' requires function 'onReturn' with signature:}}
894+
typealias SerializationRequirement = Codable
895+
896+
mutating func onReturn<Success: Codable>(value: Success) async throws {} // WRONG: can't be mutating
897+
func onReturnVoid() async throws {}
898+
func onThrow<Err: Error>(error: Err) async throws {}
899+
}
900+
829901
public struct PublicFakeResultHandler: DistributedTargetInvocationResultHandler {
830902
public typealias SerializationRequirement = Codable
831903

0 commit comments

Comments
 (0)