Skip to content

Commit 627a1c0

Browse files
committed
[TypeChecker/CodeCompletion] Move hole -> archetype conversion logic into sawSolution
Instead of exposing archetypes during solution generation, let's do that based on solution data when a type of code completion expression is requested by code completion callback.
1 parent 9fc3bee commit 627a1c0

File tree

2 files changed

+46
-61
lines changed

2 files changed

+46
-61
lines changed

lib/Sema/CSSolver.cpp

Lines changed: 0 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -53,58 +53,6 @@ STATISTIC(TotalNumTypeVariables, "# of type variables created");
5353
#include "ConstraintSolverStats.def"
5454
STATISTIC(LargestSolutionAttemptNumber, "# of the largest solution attempt");
5555

56-
/// To aid code completion, we need to attempt to convert type holes
57-
/// back into underlying generic parameters if possible, since type
58-
/// of the code completion expression is used as "expected" (or contextual)
59-
/// type so it's helpful to know what requirements it has to filter
60-
/// the list of possible member candidates e.g.
61-
///
62-
/// \code
63-
/// func test<T: P>(_: [T]) {}
64-
///
65-
/// test(42.#^MEMBERS^#)
66-
/// \code
67-
///
68-
/// It's impossible to resolve `T` in this case but code completion
69-
/// expression should still have a type of `[T]` instead of `[<<hole>>]`
70-
/// because it helps to produce correct contextual member list based on
71-
/// a conformance requirement associated with generic parameter `T`.
72-
///
73-
/// \param cs The constraint system to retrieve type data from.
74-
/// \param typeVar The type variable associated with the code completion
75-
/// expression.
76-
///
77-
/// \returns Completely resolved type, which could be used as "expected"
78-
/// type by code completion.
79-
static Type simplifyCodeCompletionType(ConstraintSystem &cs,
80-
TypeVariableType *typeVar) {
81-
auto completionTy = cs.getFixedType(typeVar);
82-
if (!completionTy)
83-
return Type();
84-
85-
auto resultTy = completionTy.transform([&cs](Type type) -> Type {
86-
if (auto *typeVar = type->getAs<TypeVariableType>()) {
87-
auto fixedType = cs.getFixedType(typeVar);
88-
if (!fixedType->isHole())
89-
return fixedType;
90-
91-
if (auto *GP = typeVar->getImpl().getGenericParameter()) {
92-
// Code completion depends on generic parameter type being
93-
// represented in terms of `ArchetypeType` since it's easy
94-
// to extract protocol requirements from it.
95-
if (auto *GPD = GP->getDecl())
96-
return GPD->getInnermostDeclContext()->mapTypeIntoContext(GP);
97-
}
98-
99-
return fixedType;
100-
}
101-
102-
return type;
103-
});
104-
105-
return cs.simplifyType(resultTy)->reconstituteSugar(false);
106-
}
107-
10856
TypeVariableType *ConstraintSystem::createTypeVariable(
10957
ConstraintLocator *locator,
11058
unsigned options) {
@@ -149,14 +97,6 @@ Solution ConstraintSystem::finalize() {
14997

15098
// For each of the type variables, get its fixed type.
15199
for (auto tv : getTypeVariables()) {
152-
if (shouldAttemptFixes()) {
153-
auto *locator = tv->getImpl().getLocator();
154-
if (locator && locator->directlyAt<CodeCompletionExpr>()) {
155-
solution.typeBindings[tv] = simplifyCodeCompletionType(*this, tv);
156-
continue;
157-
}
158-
}
159-
160100
solution.typeBindings[tv] = simplifyType(tv)->reconstituteSugar(false);
161101
}
162102

lib/Sema/TypeCheckCodeCompletion.cpp

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -938,7 +938,52 @@ void DotExprLookup::sawSolution(const constraints::Solution &S) {
938938
GotCallback = true;
939939
auto &CS = S.getConstraintSystem();
940940

941-
auto GetType = [&](Expr *E) { return S.getResolvedType(E); };
941+
auto GetType = [&](Expr *E) {
942+
// To aid code completion, we need to attempt to convert type holes
943+
// back into underlying generic parameters if possible, since type
944+
// of the code completion expression is used as "expected" (or contextual)
945+
// type so it's helpful to know what requirements it has to filter
946+
// the list of possible member candidates e.g.
947+
//
948+
// \code
949+
// func test<T: P>(_: [T]) {}
950+
//
951+
// test(42.#^MEMBERS^#)
952+
// \code
953+
//
954+
// It's impossible to resolve `T` in this case but code completion
955+
// expression should still have a type of `[T]` instead of `[<<hole>>]`
956+
// because it helps to produce correct contextual member list based on
957+
// a conformance requirement associated with generic parameter `T`.
958+
if (isa<CodeCompletionExpr>(E)) {
959+
auto completionTy = S.getType(E).transform([&](Type type) -> Type {
960+
if (auto *typeVar = type->getAs<TypeVariableType>())
961+
return S.getFixedType(typeVar);
962+
return type;
963+
});
964+
965+
return S.simplifyType(completionTy.transform([&](Type type) {
966+
if (auto *hole = type->getAs<HoleType>()) {
967+
if (auto *typeVar =
968+
hole->getOriginatorType().dyn_cast<TypeVariableType *>()) {
969+
if (auto *GP = typeVar->getImpl().getGenericParameter()) {
970+
// Code completion depends on generic parameter type being
971+
// represented in terms of `ArchetypeType` since it's easy
972+
// to extract protocol requirements from it.
973+
if (auto *GPD = GP->getDecl())
974+
return GPD->getInnermostDeclContext()->mapTypeIntoContext(GP);
975+
}
976+
}
977+
978+
return Type(CS.getASTContext().TheUnresolvedType);
979+
}
980+
981+
return type;
982+
}));
983+
}
984+
985+
return S.getResolvedType(E);
986+
};
942987

943988
auto *ParsedExpr = CompletionExpr->getBase();
944989
auto *SemanticExpr = ParsedExpr->getSemanticsProvidingExpr();

0 commit comments

Comments
 (0)