Skip to content

Commit cf3dab1

Browse files
authored
Merge pull request #84339 from slavapestov/better-prepared-overloads
Sema: Better prepared overloads
2 parents 84cf0a3 + e9070cf commit cf3dab1

File tree

10 files changed

+578
-424
lines changed

10 files changed

+578
-424
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 56 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -3068,7 +3068,7 @@ class ConstraintSystem {
30683068
return nullptr;
30693069
}
30703070

3071-
TypeBase* getFavoredType(Expr *E) {
3071+
TypeBase *getFavoredType(Expr *E) {
30723072
assert(E != nullptr);
30733073
return this->FavoredTypes[E];
30743074
}
@@ -3082,95 +3082,46 @@ class ConstraintSystem {
30823082
///
30833083
/// The side tables are used through the expression type checker to avoid
30843084
/// mutating nodes until we know we have successfully type-checked them.
3085-
void setType(ASTNode node, Type type) {
3086-
ASSERT(!node.isNull() && "Cannot set type information on null node");
3087-
ASSERT(type && "Expected non-null type");
3088-
3089-
// Record the type.
3090-
Type &entry = NodeTypes[node];
3091-
Type oldType = entry;
3092-
entry = type;
3093-
3094-
if (oldType.getPointer() != type.getPointer()) {
3095-
// Record the fact that we assigned a type to this node.
3096-
if (solverState)
3097-
recordChange(SolverTrail::Change::RecordedNodeType(node, oldType));
3098-
}
3099-
}
3085+
void setType(ASTNode node, Type type,
3086+
PreparedOverloadBuilder *preparedOverload=nullptr);
31003087

31013088
/// Undo the above change.
3102-
void restoreType(ASTNode node, Type oldType) {
3103-
ASSERT(!node.isNull() && "Cannot set type information on null node");
3104-
3105-
if (oldType) {
3106-
auto found = NodeTypes.find(node);
3107-
ASSERT(found != NodeTypes.end());
3108-
found->second = oldType;
3109-
} else {
3110-
bool erased = NodeTypes.erase(node);
3111-
ASSERT(erased);
3112-
}
3113-
}
3089+
void restoreType(ASTNode node, Type oldType);
31143090

31153091
/// Check to see if we have a type for a node.
31163092
bool hasType(ASTNode node) const {
3117-
assert(!node.isNull() && "Expected non-null node");
3093+
ASSERT(!node.isNull() && "Expected non-null node");
31183094
return NodeTypes.count(node) > 0;
31193095
}
31203096

31213097
/// Set the type in our type map for a given expression. The side
31223098
/// map is used throughout the expression type checker in order to
31233099
/// avoid mutating expressions until we know we have successfully
31243100
/// type-checked them.
3125-
void setType(const KeyPathExpr *KP, unsigned I, Type T) {
3126-
ASSERT(KP && "Expected non-null key path parameter!");
3127-
ASSERT(T && "Expected non-null type!");
3128-
3129-
Type &entry = KeyPathComponentTypes[{KP, I}];
3130-
Type oldType = entry;
3131-
entry = T;
3101+
void setType(const KeyPathExpr *KP, unsigned I, Type T);
31323102

3133-
if (oldType.getPointer() != T.getPointer()) {
3134-
if (solverState) {
3135-
recordChange(
3136-
SolverTrail::Change::RecordedKeyPathComponentType(
3137-
KP, I, oldType));
3138-
}
3139-
}
3140-
}
3141-
3142-
void restoreType(const KeyPathExpr *KP, unsigned I, Type T) {
3143-
ASSERT(KP && "Expected non-null key path parameter!");
3144-
3145-
if (T) {
3146-
auto found = KeyPathComponentTypes.find({KP, I});
3147-
ASSERT(found != KeyPathComponentTypes.end());
3148-
found->second = T;
3149-
} else {
3150-
bool erased = KeyPathComponentTypes.erase({KP, I});
3151-
ASSERT(erased);
3152-
}
3153-
}
3103+
void restoreType(const KeyPathExpr *KP, unsigned I, Type T);
31543104

31553105
bool hasType(const KeyPathExpr *KP, unsigned I) const {
3156-
assert(KP && "Expected non-null key path parameter!");
3106+
ASSERT(KP && "Expected non-null key path parameter!");
31573107
return KeyPathComponentTypes.find(std::make_pair(KP, I))
31583108
!= KeyPathComponentTypes.end();
31593109
}
31603110

31613111
/// Get the type for an node.
31623112
Type getType(ASTNode node) const {
3163-
assert(hasType(node) && "Expected type to have been set!");
3164-
// FIXME: lvalue differences
3165-
// assert((!E->getType() ||
3166-
// E->getType()->isEqual(ExprTypes.find(E)->second)) &&
3167-
// "Mismatched types!");
3168-
return NodeTypes.find(node)->second;
3113+
ASSERT(!node.isNull() && "Expected non-null node");
3114+
auto found = NodeTypes.find(node);
3115+
ASSERT(found != NodeTypes.end() && "Expected type to have been set!");
3116+
return found->second;
31693117
}
31703118

31713119
Type getType(const KeyPathExpr *KP, unsigned I) const {
3172-
assert(hasType(KP, I) && "Expected type to have been set!");
3173-
return KeyPathComponentTypes.find(std::make_pair(KP, I))->second;
3120+
ASSERT(KP && "Expected non-null key path parameter!");
3121+
auto found = KeyPathComponentTypes.find(std::make_pair(KP, I));
3122+
ASSERT(found != KeyPathComponentTypes.end() &&
3123+
"Expected type to have been set!");
3124+
return found->second;
31743125
}
31753126

31763127
/// Retrieve the type of the node, if known.
@@ -3182,11 +3133,6 @@ class ConstraintSystem {
31823133
return known->second;
31833134
}
31843135

3185-
/// Retrieve type of the given declaration to be used in
3186-
/// constraint system, this is better than calling `getType()`
3187-
/// directly because it accounts of constraint system flags.
3188-
Type getVarType(const VarDecl *var);
3189-
31903136
/// Cache the type of the expression argument and return that same
31913137
/// argument.
31923138
template <typename T>
@@ -3795,7 +3741,7 @@ class ConstraintSystem {
37953741
/// Add a constraint that binds an overload set to a specific choice.
37963742
void addBindOverloadConstraint(Type boundTy, OverloadChoice choice,
37973743
ConstraintLocator *locator, DeclContext *useDC) {
3798-
resolveOverload(locator, boundTy, choice, useDC,
3744+
resolveOverload(choice, useDC, locator, boundTy,
37993745
/*preparedOverload=*/nullptr);
38003746
}
38013747

@@ -4437,24 +4383,18 @@ class ConstraintSystem {
44374383
FunctionType *adjustFunctionTypeForConcurrency(
44384384
FunctionType *fnType, Type baseType, ValueDecl *decl, DeclContext *dc,
44394385
unsigned numApplies, bool isMainDispatchQueue,
4440-
ArrayRef<OpenedType> replacements, ConstraintLocatorBuilder locator,
4441-
PreparedOverloadBuilder *preparedOverload);
4386+
bool openGlobalActorType, ConstraintLocatorBuilder locator);
44424387

44434388
/// Retrieve the type of a reference to the given value declaration.
44444389
///
44454390
/// For references to polymorphic function types, this routine "opens up"
44464391
/// the type by replacing each instance of an archetype with a fresh type
44474392
/// variable.
44484393
///
4449-
/// \param decl The declarations whose type is being computed.
4450-
///
44514394
/// \returns a description of the type of this declaration reference.
44524395
DeclReferenceType getTypeOfReference(
4453-
ValueDecl *decl,
4454-
FunctionRefInfo functionRefInfo,
4455-
ConstraintLocatorBuilder locator,
4456-
DeclContext *useDC,
4457-
PreparedOverloadBuilder *preparedOverload);
4396+
OverloadChoice choice, DeclContext *useDC, ConstraintLocatorBuilder locator,
4397+
PreparedOverloadBuilder *preparedOverload);
44584398

44594399
/// Retrieve the type of a reference to the given value declaration,
44604400
/// as a member with a base of the given type.
@@ -4463,15 +4403,10 @@ class ConstraintSystem {
44634403
/// this routine "opens up" the type by replacing each instance of a generic
44644404
/// parameter with a fresh type variable.
44654405
///
4466-
/// \param isDynamicLookup Indicates that this declaration was found via
4467-
/// dynamic lookup.
4468-
///
44694406
/// \returns a description of the type of this declaration reference.
44704407
DeclReferenceType getTypeOfMemberReference(
4471-
Type baseTy, ValueDecl *decl, DeclContext *useDC, bool isDynamicLookup,
4472-
FunctionRefInfo functionRefInfo, ConstraintLocator *locator,
4473-
SmallVectorImpl<OpenedType> *replacements = nullptr,
4474-
PreparedOverloadBuilder *preparedOverload = nullptr);
4408+
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
4409+
PreparedOverloadBuilder *preparedOverload);
44754410

44764411
/// Retrieve a list of generic parameter types solver has "opened" (replaced
44774412
/// with a type variable) at the given location.
@@ -4483,7 +4418,25 @@ class ConstraintSystem {
44834418
}
44844419

44854420
private:
4486-
DeclReferenceType getTypeOfMemberTypeReference(
4421+
/// \returns The opened type and the thrown error type.
4422+
std::pair<Type, Type> getTypeOfReferencePre(
4423+
OverloadChoice choice, DeclContext *useDC, ConstraintLocatorBuilder locator,
4424+
PreparedOverloadBuilder *preparedOverload);
4425+
4426+
DeclReferenceType getTypeOfReferencePost(
4427+
OverloadChoice choice, DeclContext *useDC, ConstraintLocatorBuilder locator,
4428+
Type openedType, Type thrownErrorType);
4429+
4430+
/// \returns the opened type and the thrown error type.
4431+
std::pair<Type, Type> getTypeOfMemberReferencePre(
4432+
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
4433+
PreparedOverloadBuilder *preparedOverload);
4434+
4435+
DeclReferenceType getTypeOfMemberReferencePost(
4436+
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
4437+
Type openedType, Type thrownErrorType);
4438+
4439+
Type getTypeOfMemberTypeReference(
44874440
Type baseObjTy, TypeDecl *typeDecl, ConstraintLocator *locator,
44884441
PreparedOverloadBuilder *preparedOverload);
44894442

@@ -4513,8 +4466,7 @@ class ConstraintSystem {
45134466
/// determine the reference type of the member reference.
45144467
Type getMemberReferenceTypeFromOpenedType(
45154468
Type type, Type baseObjTy, ValueDecl *value,
4516-
ConstraintLocator *locator, bool hasAppliedSelf, bool isDynamicLookup,
4517-
ArrayRef<OpenedType> replacements);
4469+
ConstraintLocator *locator, bool hasAppliedSelf, bool isDynamicLookup);
45184470

45194471
/// Add the constraints needed to bind an overload's type variable.
45204472
void bindOverloadType(const SelectedOverload &overload, Type boundType,
@@ -4918,26 +4870,31 @@ class ConstraintSystem {
49184870
SelectedOverload choice);
49194871

49204872
/// Build and allocate a prepared overload in the solver arena.
4921-
PreparedOverload *prepareOverload(ConstraintLocator *locator,
4922-
OverloadChoice choice,
4923-
DeclContext *useDC);
4873+
PreparedOverload *prepareOverload(OverloadChoice choice,
4874+
DeclContext *useDC,
4875+
ConstraintLocator *locator);
49244876

49254877
/// Populate the prepared overload with all type variables and constraints
49264878
/// that are to be introduced into the constraint system when this choice
49274879
/// is taken.
4928-
DeclReferenceType
4929-
prepareOverloadImpl(ConstraintLocator *locator,
4930-
OverloadChoice choice,
4880+
///
4881+
/// Returns a pair consisting of the opened type, and the thrown error type.
4882+
///
4883+
/// FIXME: As a transitional mechanism, if preparedOverload is nullptr, this
4884+
/// immediately performs all operations.
4885+
std::pair<Type, Type>
4886+
prepareOverloadImpl(OverloadChoice choice,
49314887
DeclContext *useDC,
4888+
ConstraintLocator *locator,
49324889
PreparedOverloadBuilder *preparedOverload);
49334890

49344891
void replayChanges(
49354892
ConstraintLocator *locator,
49364893
PreparedOverload *preparedOverload);
49374894

49384895
/// Resolve the given overload set to the given choice.
4939-
void resolveOverload(ConstraintLocator *locator, Type boundType,
4940-
OverloadChoice choice, DeclContext *useDC,
4896+
void resolveOverload(OverloadChoice choice, DeclContext *useDC,
4897+
ConstraintLocator *locator, Type boundType,
49414898
PreparedOverload *preparedOverload);
49424899

49434900
/// Simplify a type, by replacing type variables with either their

include/swift/Sema/OverloadChoice.h

Lines changed: 19 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,19 @@ class OverloadChoice {
126126
/// FIXME: This needs three bits. Can we pack them somewhere?
127127
FunctionRefInfo TheFunctionRefInfo = FunctionRefInfo::unappliedBaseName();
128128

129-
public:
130-
OverloadChoice() : BaseAndDeclKind(nullptr, 0), DeclOrKind() {}
131-
132129
OverloadChoice(Type base, ValueDecl *value,
133130
FunctionRefInfo functionRefInfo)
134131
: BaseAndDeclKind(base, 0),
135132
TheFunctionRefInfo(functionRefInfo) {
136-
assert(!base || !base->hasTypeParameter());
137133
assert((reinterpret_cast<uintptr_t>(value) & (uintptr_t)0x03) == 0 &&
138134
"Badly aligned decl");
139135

140136
DeclOrKind = value;
141137
}
142138

139+
public:
140+
OverloadChoice() : BaseAndDeclKind(nullptr, 0), DeclOrKind() {}
141+
143142
OverloadChoice(Type base, OverloadChoiceKind kind)
144143
: BaseAndDeclKind(base, 0), DeclOrKind(uint32_t(kind)) {
145144
assert(base && "Must have a base type for overload choice");
@@ -162,6 +161,22 @@ class OverloadChoice {
162161
BaseAndDeclKind.getInt() == 0 && DeclOrKind.isNull();
163162
}
164163

164+
/// Retrieve an overload choice for a declaration that was found via
165+
/// unqualified lookup.
166+
static OverloadChoice getDecl(ValueDecl *value,
167+
FunctionRefInfo functionRefInfo) {
168+
return OverloadChoice(Type(), value, functionRefInfo);
169+
}
170+
171+
172+
/// Retrieve an overload choice for a declaration that was found via
173+
/// qualified lookup.
174+
static OverloadChoice getDecl(Type base, ValueDecl *value,
175+
FunctionRefInfo functionRefInfo) {
176+
ASSERT(!base->hasTypeParameter());
177+
return OverloadChoice(base, value, functionRefInfo);
178+
}
179+
165180
/// Retrieve an overload choice for a declaration that was found via
166181
/// dynamic lookup.
167182
static OverloadChoice getDeclViaDynamic(Type base, ValueDecl *value,

0 commit comments

Comments
 (0)