Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
d8ce7c3
Sema: Tweak VarDecl concurrency adjustment in getTypeOfReference() to…
slavapestov Sep 15, 2025
1efc9a6
Sema: Split off getTypeOfReferenceImpl() from getTypeOfReference()
slavapestov Sep 15, 2025
35a439d
Sema: Remove replacements parameter from getMemberReferenceTypeFromOp…
slavapestov Sep 15, 2025
05d5769
Sema: Pass baseObjTy instead of baseRValueTy to adjustFunctionTypeFor…
slavapestov Sep 15, 2025
8397c08
Sema: Remove duplicate logic for throwing accessor witness matching
slavapestov Sep 16, 2025
2fde4a5
Sema: Split off getTypeOfMemberReferenceImpl() from getTypeOfMemberRe…
slavapestov Sep 16, 2025
d8ead6c
Sema: Refactor getTypeOf{Member,}Reference() to take the OverloadChoice
slavapestov Sep 16, 2025
a028eb3
Sema: Don't need to return new baseObjTy from getTypeOfMemberReferenc…
slavapestov Sep 16, 2025
4ea2f17
Sema: Simplify getConcreteReplacementForProtocolSelfType()
slavapestov Sep 17, 2025
182c384
Sema: Remove replacementsPtr parameter from getTypeOfMemberReference()
slavapestov Sep 16, 2025
c344d6b
Sema: Rename getTypeOf{Member,}ReferenceImpl() to Pre() and factor ou…
slavapestov Sep 16, 2025
b181fcf
Sema: Get prepared overloads working again with the Pre()/Post() split
slavapestov Sep 17, 2025
a12c160
Sema: Replace calls to OverloadChoice constructor with two overloads …
slavapestov Sep 17, 2025
8744e8a
Sema: Sink ModuleDecl handling back down into getTypeOfMemberReferenc…
slavapestov Sep 17, 2025
ad324b7
Sema: Clean up ConstraintSystem::resolveOverload() a bit
slavapestov Sep 17, 2025
9dea725
Sema: Record ASTNode type changes in PreparedOverload
slavapestov Sep 18, 2025
7f8c4e0
Sema: Correctly thread PreparedOverloadBuilder through InferableTypeO…
slavapestov Sep 18, 2025
e9070cf
Sema: Remove unused variable
slavapestov Sep 13, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
155 changes: 56 additions & 99 deletions include/swift/Sema/ConstraintSystem.h
Original file line number Diff line number Diff line change
Expand Up @@ -3068,7 +3068,7 @@ class ConstraintSystem {
return nullptr;
}

TypeBase* getFavoredType(Expr *E) {
TypeBase *getFavoredType(Expr *E) {
assert(E != nullptr);
return this->FavoredTypes[E];
}
Expand All @@ -3082,95 +3082,46 @@ class ConstraintSystem {
///
/// The side tables are used through the expression type checker to avoid
/// mutating nodes until we know we have successfully type-checked them.
void setType(ASTNode node, Type type) {
ASSERT(!node.isNull() && "Cannot set type information on null node");
ASSERT(type && "Expected non-null type");

// Record the type.
Type &entry = NodeTypes[node];
Type oldType = entry;
entry = type;

if (oldType.getPointer() != type.getPointer()) {
// Record the fact that we assigned a type to this node.
if (solverState)
recordChange(SolverTrail::Change::RecordedNodeType(node, oldType));
}
}
void setType(ASTNode node, Type type,
PreparedOverloadBuilder *preparedOverload=nullptr);

/// Undo the above change.
void restoreType(ASTNode node, Type oldType) {
ASSERT(!node.isNull() && "Cannot set type information on null node");

if (oldType) {
auto found = NodeTypes.find(node);
ASSERT(found != NodeTypes.end());
found->second = oldType;
} else {
bool erased = NodeTypes.erase(node);
ASSERT(erased);
}
}
void restoreType(ASTNode node, Type oldType);

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

/// Set the type in our type map for a given expression. The side
/// map is used throughout the expression type checker in order to
/// avoid mutating expressions until we know we have successfully
/// type-checked them.
void setType(const KeyPathExpr *KP, unsigned I, Type T) {
ASSERT(KP && "Expected non-null key path parameter!");
ASSERT(T && "Expected non-null type!");

Type &entry = KeyPathComponentTypes[{KP, I}];
Type oldType = entry;
entry = T;
void setType(const KeyPathExpr *KP, unsigned I, Type T);

if (oldType.getPointer() != T.getPointer()) {
if (solverState) {
recordChange(
SolverTrail::Change::RecordedKeyPathComponentType(
KP, I, oldType));
}
}
}

void restoreType(const KeyPathExpr *KP, unsigned I, Type T) {
ASSERT(KP && "Expected non-null key path parameter!");

if (T) {
auto found = KeyPathComponentTypes.find({KP, I});
ASSERT(found != KeyPathComponentTypes.end());
found->second = T;
} else {
bool erased = KeyPathComponentTypes.erase({KP, I});
ASSERT(erased);
}
}
void restoreType(const KeyPathExpr *KP, unsigned I, Type T);

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

/// Get the type for an node.
Type getType(ASTNode node) const {
assert(hasType(node) && "Expected type to have been set!");
// FIXME: lvalue differences
// assert((!E->getType() ||
// E->getType()->isEqual(ExprTypes.find(E)->second)) &&
// "Mismatched types!");
return NodeTypes.find(node)->second;
ASSERT(!node.isNull() && "Expected non-null node");
auto found = NodeTypes.find(node);
ASSERT(found != NodeTypes.end() && "Expected type to have been set!");
return found->second;
}

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

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

/// Retrieve type of the given declaration to be used in
/// constraint system, this is better than calling `getType()`
/// directly because it accounts of constraint system flags.
Type getVarType(const VarDecl *var);

/// Cache the type of the expression argument and return that same
/// argument.
template <typename T>
Expand Down Expand Up @@ -3795,7 +3741,7 @@ class ConstraintSystem {
/// Add a constraint that binds an overload set to a specific choice.
void addBindOverloadConstraint(Type boundTy, OverloadChoice choice,
ConstraintLocator *locator, DeclContext *useDC) {
resolveOverload(locator, boundTy, choice, useDC,
resolveOverload(choice, useDC, locator, boundTy,
/*preparedOverload=*/nullptr);
}

Expand Down Expand Up @@ -4437,24 +4383,18 @@ class ConstraintSystem {
FunctionType *adjustFunctionTypeForConcurrency(
FunctionType *fnType, Type baseType, ValueDecl *decl, DeclContext *dc,
unsigned numApplies, bool isMainDispatchQueue,
ArrayRef<OpenedType> replacements, ConstraintLocatorBuilder locator,
PreparedOverloadBuilder *preparedOverload);
bool openGlobalActorType, ConstraintLocatorBuilder locator);

/// Retrieve the type of a reference to the given value declaration.
///
/// For references to polymorphic function types, this routine "opens up"
/// the type by replacing each instance of an archetype with a fresh type
/// variable.
///
/// \param decl The declarations whose type is being computed.
///
/// \returns a description of the type of this declaration reference.
DeclReferenceType getTypeOfReference(
ValueDecl *decl,
FunctionRefInfo functionRefInfo,
ConstraintLocatorBuilder locator,
DeclContext *useDC,
PreparedOverloadBuilder *preparedOverload);
OverloadChoice choice, DeclContext *useDC, ConstraintLocatorBuilder locator,
PreparedOverloadBuilder *preparedOverload);

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

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

private:
DeclReferenceType getTypeOfMemberTypeReference(
/// \returns The opened type and the thrown error type.
std::pair<Type, Type> getTypeOfReferencePre(
OverloadChoice choice, DeclContext *useDC, ConstraintLocatorBuilder locator,
PreparedOverloadBuilder *preparedOverload);

DeclReferenceType getTypeOfReferencePost(
OverloadChoice choice, DeclContext *useDC, ConstraintLocatorBuilder locator,
Type openedType, Type thrownErrorType);

/// \returns the opened type and the thrown error type.
std::pair<Type, Type> getTypeOfMemberReferencePre(
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
PreparedOverloadBuilder *preparedOverload);

DeclReferenceType getTypeOfMemberReferencePost(
OverloadChoice choice, DeclContext *useDC, ConstraintLocator *locator,
Type openedType, Type thrownErrorType);

Type getTypeOfMemberTypeReference(
Type baseObjTy, TypeDecl *typeDecl, ConstraintLocator *locator,
PreparedOverloadBuilder *preparedOverload);

Expand Down Expand Up @@ -4513,8 +4466,7 @@ class ConstraintSystem {
/// determine the reference type of the member reference.
Type getMemberReferenceTypeFromOpenedType(
Type type, Type baseObjTy, ValueDecl *value,
ConstraintLocator *locator, bool hasAppliedSelf, bool isDynamicLookup,
ArrayRef<OpenedType> replacements);
ConstraintLocator *locator, bool hasAppliedSelf, bool isDynamicLookup);

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

/// Build and allocate a prepared overload in the solver arena.
PreparedOverload *prepareOverload(ConstraintLocator *locator,
OverloadChoice choice,
DeclContext *useDC);
PreparedOverload *prepareOverload(OverloadChoice choice,
DeclContext *useDC,
ConstraintLocator *locator);

/// Populate the prepared overload with all type variables and constraints
/// that are to be introduced into the constraint system when this choice
/// is taken.
DeclReferenceType
prepareOverloadImpl(ConstraintLocator *locator,
OverloadChoice choice,
///
/// Returns a pair consisting of the opened type, and the thrown error type.
///
/// FIXME: As a transitional mechanism, if preparedOverload is nullptr, this
/// immediately performs all operations.
std::pair<Type, Type>
prepareOverloadImpl(OverloadChoice choice,
DeclContext *useDC,
ConstraintLocator *locator,
PreparedOverloadBuilder *preparedOverload);

void replayChanges(
ConstraintLocator *locator,
PreparedOverload *preparedOverload);

/// Resolve the given overload set to the given choice.
void resolveOverload(ConstraintLocator *locator, Type boundType,
OverloadChoice choice, DeclContext *useDC,
void resolveOverload(OverloadChoice choice, DeclContext *useDC,
ConstraintLocator *locator, Type boundType,
PreparedOverload *preparedOverload);

/// Simplify a type, by replacing type variables with either their
Expand Down
23 changes: 19 additions & 4 deletions include/swift/Sema/OverloadChoice.h
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,19 @@ class OverloadChoice {
/// FIXME: This needs three bits. Can we pack them somewhere?
FunctionRefInfo TheFunctionRefInfo = FunctionRefInfo::unappliedBaseName();

public:
OverloadChoice() : BaseAndDeclKind(nullptr, 0), DeclOrKind() {}

OverloadChoice(Type base, ValueDecl *value,
FunctionRefInfo functionRefInfo)
: BaseAndDeclKind(base, 0),
TheFunctionRefInfo(functionRefInfo) {
assert(!base || !base->hasTypeParameter());
assert((reinterpret_cast<uintptr_t>(value) & (uintptr_t)0x03) == 0 &&
"Badly aligned decl");

DeclOrKind = value;
}

public:
OverloadChoice() : BaseAndDeclKind(nullptr, 0), DeclOrKind() {}

OverloadChoice(Type base, OverloadChoiceKind kind)
: BaseAndDeclKind(base, 0), DeclOrKind(uint32_t(kind)) {
assert(base && "Must have a base type for overload choice");
Expand All @@ -162,6 +161,22 @@ class OverloadChoice {
BaseAndDeclKind.getInt() == 0 && DeclOrKind.isNull();
}

/// Retrieve an overload choice for a declaration that was found via
/// unqualified lookup.
static OverloadChoice getDecl(ValueDecl *value,
FunctionRefInfo functionRefInfo) {
return OverloadChoice(Type(), value, functionRefInfo);
}


/// Retrieve an overload choice for a declaration that was found via
/// qualified lookup.
static OverloadChoice getDecl(Type base, ValueDecl *value,
FunctionRefInfo functionRefInfo) {
ASSERT(!base->hasTypeParameter());
return OverloadChoice(base, value, functionRefInfo);
}

/// Retrieve an overload choice for a declaration that was found via
/// dynamic lookup.
static OverloadChoice getDeclViaDynamic(Type base, ValueDecl *value,
Expand Down
Loading