Skip to content

Commit 7c145cc

Browse files
authored
Merge pull request #41179 from ktoso/wip-improved-adhoc-checks
[Distributed] improve ad-hoc requirement typechecking
2 parents 7893f74 + 1125241 commit 7c145cc

37 files changed

+2728
-1067
lines changed

include/swift/AST/ASTContext.h

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -674,20 +674,30 @@ class ASTContext final {
674674
FuncDecl *getRecordGenericSubstitutionOnDistributedInvocationEncoder(
675675
NominalTypeDecl *nominal) const;
676676

677-
// Retrieve the declaration of DistributedInvocationEncoder.recordArgument(_:).
677+
// Retrieve the declaration of DistributedTargetInvocationEncoder.recordArgument(_:).
678678
//
679679
// \param nominal optionally provide a 'NominalTypeDecl' from which the
680680
// function decl shall be extracted. This is useful to avoid witness calls
681681
// through the protocol which is looked up when nominal is null.
682-
FuncDecl *getRecordArgumentOnDistributedInvocationEncoder(
682+
AbstractFunctionDecl *getRecordArgumentOnDistributedInvocationEncoder(
683683
NominalTypeDecl *nominal) const;
684684

685-
// Retrieve the declaration of DistributedInvocationEncoder.recordErrorType(_:).
686-
FuncDecl *getRecordErrorTypeOnDistributedInvocationEncoder(
685+
// Retrieve the declaration of DistributedTargetInvocationEncoder.recordReturnType(_:).
686+
AbstractFunctionDecl *getRecordReturnTypeOnDistributedInvocationEncoder(
687687
NominalTypeDecl *nominal) const;
688688

689-
// Retrieve the declaration of DistributedInvocationEncoder.recordReturnType(_:).
690-
FuncDecl *getRecordReturnTypeOnDistributedInvocationEncoder(
689+
// Retrieve the declaration of DistributedTargetInvocationEncoder.recordErrorType(_:).
690+
AbstractFunctionDecl *getRecordErrorTypeOnDistributedInvocationEncoder(
691+
NominalTypeDecl *nominal) const;
692+
693+
// Retrieve the declaration of
694+
// DistributedTargetInvocationDecoder.getDecodeNextArgumentOnDistributedInvocationDecoder(_:).
695+
AbstractFunctionDecl *getDecodeNextArgumentOnDistributedInvocationDecoder(
696+
NominalTypeDecl *nominal) const;
697+
698+
// Retrieve the declaration of
699+
// getOnReturnOnDistributedTargetInvocationResultHandler.onReturn(_:).
700+
AbstractFunctionDecl *getOnReturnOnDistributedTargetInvocationResultHandler(
691701
NominalTypeDecl *nominal) const;
692702

693703
// Retrieve the declaration of DistributedInvocationEncoder.doneRecording().
@@ -1337,11 +1347,8 @@ class ASTContext final {
13371347
/// alternative specified via the -entry-point-function-name frontend flag.
13381348
std::string getEntryPointFunctionName() const;
13391349

1340-
/// Find the type of SerializationRequirement on the passed nominal.
1341-
///
1342-
/// This type exists as a typealias/associatedtype on all distributed actors,
1343-
/// actor systems, and related serialization types.
1344-
Type getDistributedSerializationRequirementType(NominalTypeDecl *);
1350+
Type getAssociatedTypeOfDistributedSystemOfActor(NominalTypeDecl *actor,
1351+
Identifier member);
13451352

13461353
/// Find the concrete invocation decoder associated with the given actor.
13471354
NominalTypeDecl *

include/swift/AST/Decl.h

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6412,6 +6412,31 @@ class AbstractFunctionDecl : public GenericContext, public ValueDecl {
64126412
/// 'DistributedActorSystem' protocol.
64136413
bool isDistributedActorSystemRemoteCall(bool isVoidReturn) const;
64146414

6415+
/// Determines if this function is a 'recordArgument' function,
6416+
/// which is used as ad-hoc protocol requirement by the
6417+
/// 'DistributedTargetInvocationEncoder' protocol.
6418+
bool isDistributedTargetInvocationEncoderRecordArgument() const;
6419+
6420+
/// Determines if this function is a 'recordReturnType' function,
6421+
/// which is used as ad-hoc protocol requirement by the
6422+
/// 'DistributedTargetInvocationEncoder' protocol.
6423+
bool isDistributedTargetInvocationEncoderRecordReturnType() const;
6424+
6425+
/// Determines if this function is a 'recordErrorType' function,
6426+
/// which is used as ad-hoc protocol requirement by the
6427+
/// 'DistributedTargetInvocationEncoder' protocol.
6428+
bool isDistributedTargetInvocationEncoderRecordErrorType() const;
6429+
6430+
/// Determines if this function is a 'decodeNextArgument' function,
6431+
/// which is used as ad-hoc protocol requirement by the
6432+
/// 'DistributedTargetInvocationDecoder' protocol.
6433+
bool isDistributedTargetInvocationDecoderDecodeNextArgument() const;
6434+
6435+
/// Determines if this function is a 'onReturn' function,
6436+
/// which is used as ad-hoc protocol requirement by the
6437+
/// 'DistributedTargetInvocationResultHandler' protocol.
6438+
bool isDistributedTargetInvocationResultHandlerOnReturn() const;
6439+
64156440
/// For a method of a class, checks whether it will require a new entry in the
64166441
/// vtable.
64176442
bool needsNewVTableEntry() const;

include/swift/AST/DistributedDecl.h

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
//===-- DistributedDecl.h - Distributed declaration utils -------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2021 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file provides functions for working with declarations of distributed
14+
// actors and declarations related to them, like associated types and protocols.
15+
//
16+
//===----------------------------------------------------------------------===//
17+
18+
#ifndef SWIFT_DECL_TYPECHECKDISTRIBUTED_H
19+
#define SWIFT_DECL_TYPECHECKDISTRIBUTED_H
20+
21+
#include "swift/AST/ConcreteDeclRef.h"
22+
#include "swift/AST/DiagnosticEngine.h"
23+
#include "swift/AST/Type.h"
24+
25+
namespace swift {
26+
27+
class ClassDecl;
28+
class ConstructorDecl;
29+
class Decl;
30+
class DeclContext;
31+
class FuncDecl;
32+
class NominalTypeDecl;
33+
34+
/// Determine the `ActorSystem` type for the given actor.
35+
Type getDistributedActorSystemType(NominalTypeDecl *actor);
36+
37+
/// Determine the `ID` type for the given actor.
38+
Type getDistributedActorIDType(NominalTypeDecl *actor);
39+
40+
/// Get specific 'SerializationRequirement' as defined in 'nominal'
41+
/// type, which must conform to the passed 'protocol' which is expected
42+
/// to require the 'SerializationRequirement'.
43+
Type getDistributedSerializationRequirementType(
44+
NominalTypeDecl *nominal, ProtocolDecl *protocol);
45+
46+
///// Determine the serialization requirement for the given actor, actor system
47+
///// or other type that has the SerializationRequirement associated type.
48+
//Type getDistributedSerializationRequirementType(
49+
// NominalTypeDecl *nominal, ProtocolDecl *protocol);
50+
51+
Type getDistributedActorSystemActorIDRequirementType(
52+
NominalTypeDecl *system);
53+
54+
55+
/// Get the specific protocols that the `SerializationRequirement` specifies,
56+
/// and all parameters / return types of distributed targets must conform to.
57+
///
58+
/// E.g. if a system declares `typealias SerializationRequirement = Codable`
59+
/// then this will return `{encodableProtocol, decodableProtocol}`.
60+
///
61+
/// Returns an empty set if the requirement was `Any`.
62+
llvm::SmallPtrSet<ProtocolDecl *, 2>
63+
getDistributedSerializationRequirementProtocols(
64+
NominalTypeDecl *decl, ProtocolDecl* protocol);
65+
66+
/// Desugar and flatten the `SerializationRequirement` type into a set of
67+
/// specific protocol declarations.
68+
llvm::SmallPtrSet<ProtocolDecl *, 2>
69+
flattenDistributedSerializationTypeToRequiredProtocols(
70+
TypeBase *serializationRequirement);
71+
72+
/// Check if the `allRequirements` represent *exactly* the
73+
/// `Encodable & Decodable` (also known as `Codable`) requirement.
74+
///
75+
/// If so, we can emit slightly nicer diagnostics.
76+
bool checkDistributedSerializationRequirementIsExactlyCodable(
77+
ASTContext &C,
78+
const llvm::SmallPtrSetImpl<ProtocolDecl *> &allRequirements);
79+
80+
/// Get the `SerializationRequirement`, explode it into the specific
81+
/// protocol requirements and insert them into `requirements`.
82+
///
83+
/// The passed `protocol` must be conformed to by the `decl`, e.g. a specific
84+
/// actor system implementation and the `DistributedActorSystem` protocol,
85+
/// or any of the specific encoder/decoder and the respective
86+
/// Distributed...Encoder/Decoder protocol etc.
87+
///
88+
/// Returns false if failed to get the protocol decls.
89+
bool
90+
getDistributedSerializationRequirements(
91+
NominalTypeDecl *decl,
92+
ProtocolDecl *protocol,
93+
llvm::SmallPtrSetImpl<ProtocolDecl *> &requirementProtos);
94+
95+
/// Given any set of generic requirements, locate those which are about the
96+
/// `SerializationRequirement`. Those need to be applied in the parameter and
97+
/// return type checking of distributed targets.
98+
llvm::SmallPtrSet<ProtocolDecl *, 2>
99+
extractDistributedSerializationRequirements(
100+
ASTContext &C, ArrayRef<Requirement> allRequirements);
101+
}
102+
103+
#endif /* SWIFT_DECL_TYPECHECKDISTRIBUTED_H */

include/swift/AST/KnownIdentifiers.def

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ IDENTIFIER(invocation)
276276
IDENTIFIER(invocationDecoder)
277277
IDENTIFIER(makeInvocationEncoder)
278278
IDENTIFIER(on)
279+
IDENTIFIER(onReturn)
279280
IDENTIFIER(recordArgument)
280281
IDENTIFIER(recordErrorType)
281282
IDENTIFIER(recordGenericSubstitution)

include/swift/AST/TypeCheckRequests.h

Lines changed: 109 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1056,6 +1056,96 @@ class GetDistributedActorSystemRemoteCallFunctionRequest :
10561056
bool isCached() const { return true; }
10571057
};
10581058

1059+
/// Obtain the 'recordArgument' function of a 'DistributedTargetInvocationEncoder'.
1060+
class GetDistributedTargetInvocationEncoderRecordArgumentFunctionRequest :
1061+
public SimpleRequest<GetDistributedTargetInvocationEncoderRecordArgumentFunctionRequest,
1062+
AbstractFunctionDecl *(NominalTypeDecl *),
1063+
RequestFlags::Cached> {
1064+
public:
1065+
using SimpleRequest::SimpleRequest;
1066+
1067+
private:
1068+
friend SimpleRequest;
1069+
1070+
AbstractFunctionDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *encoder) const;
1071+
1072+
public:
1073+
// Caching
1074+
bool isCached() const { return true; }
1075+
};
1076+
1077+
/// Obtain the 'recordReturnType' function of a 'DistributedTargetInvocationEncoder'.
1078+
class GetDistributedTargetInvocationEncoderRecordReturnTypeFunctionRequest :
1079+
public SimpleRequest<GetDistributedTargetInvocationEncoderRecordReturnTypeFunctionRequest,
1080+
AbstractFunctionDecl *(NominalTypeDecl *),
1081+
RequestFlags::Cached> {
1082+
public:
1083+
using SimpleRequest::SimpleRequest;
1084+
1085+
private:
1086+
friend SimpleRequest;
1087+
1088+
AbstractFunctionDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *encoder) const;
1089+
1090+
public:
1091+
// Caching
1092+
bool isCached() const { return true; }
1093+
};
1094+
1095+
/// Obtain the 'recordErrorType' function of a 'DistributedTargetInvocationEncoder'.
1096+
class GetDistributedTargetInvocationEncoderRecordErrorTypeFunctionRequest :
1097+
public SimpleRequest<GetDistributedTargetInvocationEncoderRecordErrorTypeFunctionRequest,
1098+
AbstractFunctionDecl *(NominalTypeDecl *),
1099+
RequestFlags::Cached> {
1100+
public:
1101+
using SimpleRequest::SimpleRequest;
1102+
1103+
private:
1104+
friend SimpleRequest;
1105+
1106+
AbstractFunctionDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *encoder) const;
1107+
1108+
public:
1109+
// Caching
1110+
bool isCached() const { return true; }
1111+
};
1112+
1113+
/// Obtain the 'decodeNextArgument' function of a 'DistributedTargetInvocationDecoder'.
1114+
class GetDistributedTargetInvocationDecoderDecodeNextArgumentFunctionRequest :
1115+
public SimpleRequest<GetDistributedTargetInvocationDecoderDecodeNextArgumentFunctionRequest,
1116+
AbstractFunctionDecl *(NominalTypeDecl *),
1117+
RequestFlags::Cached> {
1118+
public:
1119+
using SimpleRequest::SimpleRequest;
1120+
1121+
private:
1122+
friend SimpleRequest;
1123+
1124+
AbstractFunctionDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *encoder) const;
1125+
1126+
public:
1127+
// Caching
1128+
bool isCached() const { return true; }
1129+
};
1130+
1131+
/// Obtain the 'onReturn' function of a 'DistributedTargetInvocationResultHandler'.
1132+
class GetDistributedTargetInvocationResultHandlerOnReturnFunctionRequest :
1133+
public SimpleRequest<GetDistributedTargetInvocationResultHandlerOnReturnFunctionRequest,
1134+
AbstractFunctionDecl *(NominalTypeDecl *),
1135+
RequestFlags::Cached> {
1136+
public:
1137+
using SimpleRequest::SimpleRequest;
1138+
1139+
private:
1140+
friend SimpleRequest;
1141+
1142+
AbstractFunctionDecl *evaluate(Evaluator &evaluator, NominalTypeDecl *encoder) const;
1143+
1144+
public:
1145+
// Caching
1146+
bool isCached() const { return true; }
1147+
};
1148+
10591149
/// Obtain the 'actorSystem' property of a 'distributed actor'.
10601150
class GetDistributedActorSystemPropertyRequest :
10611151
public SimpleRequest<GetDistributedActorSystemPropertyRequest,
@@ -1074,6 +1164,25 @@ class GetDistributedActorSystemPropertyRequest :
10741164
bool isCached() const { return true; }
10751165
};
10761166

1167+
/// Obtain the constructor of the RemoteCallTarget type.
1168+
class GetDistributedRemoteCallTargetInitFunctionRequest :
1169+
public SimpleRequest<GetDistributedRemoteCallTargetInitFunctionRequest,
1170+
ConstructorDecl *(NominalTypeDecl *),
1171+
RequestFlags::Cached> {
1172+
public:
1173+
using SimpleRequest::SimpleRequest;
1174+
1175+
private:
1176+
friend SimpleRequest;
1177+
1178+
ConstructorDecl *evaluate(Evaluator &evaluator,
1179+
NominalTypeDecl *nominal) const;
1180+
1181+
public:
1182+
// Caching
1183+
bool isCached() const { return true; }
1184+
};
1185+
10771186
/// Obtain the 'id' property of a 'distributed actor'.
10781187
class GetDistributedActorIDPropertyRequest :
10791188
public SimpleRequest<GetDistributedActorIDPropertyRequest,

include/swift/AST/TypeCheckerTypeIDZone.def

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,29 @@ SWIFT_REQUEST(TypeChecker, IsDistributedActorRequest, bool(NominalTypeDecl *),
108108
SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemRemoteCallFunctionRequest,
109109
AbstractFunctionDecl *(NominalTypeDecl *, bool),
110110
Cached, NoLocationInfo)
111-
SWIFT_REQUEST(TypeChecker, GetDistributedActorIDPropertyRequest, VarDecl *(NominalTypeDecl *),
111+
SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationEncoderRecordArgumentFunctionRequest,
112+
AbstractFunctionDecl *(NominalTypeDecl *),
112113
Cached, NoLocationInfo)
113-
SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemPropertyRequest, VarDecl *(NominalTypeDecl *),
114+
SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationEncoderRecordReturnTypeFunctionRequest,
115+
AbstractFunctionDecl *(NominalTypeDecl *),
116+
Cached, NoLocationInfo)
117+
SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationEncoderRecordErrorTypeFunctionRequest,
118+
AbstractFunctionDecl *(NominalTypeDecl *),
119+
Cached, NoLocationInfo)
120+
SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationDecoderDecodeNextArgumentFunctionRequest,
121+
AbstractFunctionDecl *(NominalTypeDecl *),
122+
Cached, NoLocationInfo)
123+
SWIFT_REQUEST(TypeChecker, GetDistributedTargetInvocationResultHandlerOnReturnFunctionRequest,
124+
AbstractFunctionDecl *(NominalTypeDecl *),
125+
Cached, NoLocationInfo)
126+
SWIFT_REQUEST(TypeChecker, GetDistributedActorIDPropertyRequest,
127+
VarDecl *(NominalTypeDecl *),
128+
Cached, NoLocationInfo)
129+
SWIFT_REQUEST(TypeChecker, GetDistributedActorSystemPropertyRequest,
130+
VarDecl *(NominalTypeDecl *),
131+
Cached, NoLocationInfo)
132+
SWIFT_REQUEST(TypeChecker, GetDistributedRemoteCallTargetInitFunctionRequest,
133+
ConstructorDecl *(NominalTypeDecl *),
114134
Cached, NoLocationInfo)
115135
SWIFT_REQUEST(TypeChecker, GetDistributedActorInvocationDecoderRequest,
116136
NominalTypeDecl *(NominalTypeDecl *),

0 commit comments

Comments
 (0)