Skip to content

Commit c68157a

Browse files
committed
[CodeCompletion] Remove unresolved type in prepareForRetypechecking()
Unresolved type attached to expressions may fail re-typechecking. Also, disallow unresolved type in typeCheckCompletionSequence(). It doesn't provide useful completions to developers. rdar://problem/41224316
1 parent bc3189a commit c68157a

File tree

4 files changed

+18
-13
lines changed

4 files changed

+18
-13
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -412,21 +412,24 @@ static void prepareForRetypechecking(Expr *E) {
412412
assert(E);
413413
struct Eraser : public ASTWalker {
414414
std::pair<bool, Expr *> walkToExprPre(Expr *expr) override {
415-
if (expr && expr->getType() && expr->getType()->hasError())
415+
if (expr && expr->getType() && (expr->getType()->hasError() ||
416+
expr->getType()->hasUnresolvedType()))
416417
expr->setType(Type());
417418
if (auto *ACE = dyn_cast_or_null<AutoClosureExpr>(expr)) {
418419
return { true, ACE->getSingleExpressionBody() };
419420
}
420421
return { true, expr };
421422
}
422423
bool walkToTypeLocPre(TypeLoc &TL) override {
423-
if (TL.getType() && TL.getType()->hasError())
424+
if (TL.getType() && (TL.getType()->hasError() ||
425+
TL.getType()->hasUnresolvedType()))
424426
TL.setType(Type());
425427
return true;
426428
}
427429

428430
std::pair<bool, Pattern*> walkToPatternPre(Pattern *P) override {
429-
if (P && P->hasType() && P->getType()->hasError()) {
431+
if (P && P->hasType() && (P->getType()->hasError() ||
432+
P->getType()->hasUnresolvedType())) {
430433
P->setType(Type());
431434
}
432435
return { true, P };
@@ -3304,6 +3307,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
33043307
// FIXME: This is workaround for getTypeOfExpressionWithoutApplying()
33053308
// modifies type of 'expr'.
33063309
expr->setType(Ty);
3310+
prepareForRetypechecking(expr);
33073311
};
33083312

33093313
// We allocate these expressions on the stack because we know they can't
@@ -3425,8 +3429,8 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
34253429
Expr *expr = SE;
34263430
if (!typeCheckCompletionSequence(const_cast<DeclContext *>(CurrDeclContext),
34273431
expr)) {
3428-
3429-
if (!LHS->getType()->getRValueType()->getOptionalObjectType()) {
3432+
if (!LHS->getType() ||
3433+
!LHS->getType()->getRValueType()->getOptionalObjectType()) {
34303434
// Don't complete optional operators on non-optional types.
34313435
// FIXME: can we get the type-checker to disallow these for us?
34323436
if (op->getName().str() == "??")

lib/Sema/TypeCheckConstraints.cpp

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2242,7 +2242,7 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
22422242

22432243
// Attempt to solve the constraint system.
22442244
SmallVector<Solution, 4> viable;
2245-
if (CS.solve(expr, viable, FreeTypeVariableBinding::UnresolvedType))
2245+
if (CS.solve(expr, viable, FreeTypeVariableBinding::Disallow))
22462246
return true;
22472247

22482248
auto &solution = viable[0];
@@ -2255,12 +2255,7 @@ bool TypeChecker::typeCheckCompletionSequence(Expr *&expr, DeclContext *DC) {
22552255
auto &solutionCS = solution.getConstraintSystem();
22562256
expr->setType(solution.simplifyType(solutionCS.getType(expr)));
22572257
auto completionType = solution.simplifyType(solutionCS.getType(CCE));
2258-
2259-
// If completion expression is unresolved it doesn't provide
2260-
// any meaningful information so shouldn't be in the results.
2261-
if (completionType->is<UnresolvedType>())
2262-
return true;
2263-
2258+
assert(!completionType->hasUnresolvedType());
22642259
CCE->setType(completionType);
22652260
return false;
22662261
}

test/SourceKit/CodeComplete/complete_inner.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,7 +38,7 @@ func test010(x: E1, y: FooBar) {
3838
// RUN: %sourcekitd-test -req=complete.open -pos=26:11 -req-opts=filtertext=one %s -- %s | %FileCheck %s -check-prefix=INNER_POSTFIX_0b
3939
// INNER_POSTFIX_0b-NOT: key.description: "one{{.+}}"
4040
// INNER_POSTFIX_0b: key.description: "one",{{$}}
41-
// INNER_POSTFIX_0b: key.description: "one...",{{$}}
41+
// INNER_POSTFIX_0b: key.description: "one.",{{$}}
4242
// INNER_POSTFIX_0b-NOT: key.description: "one{{.+}}"
4343

4444
// RUN: %sourcekitd-test -req=complete.open -pos=29:9 -req-opts=filtertext=pro %s -- %s | %FileCheck %s -check-prefix=INNER_POSTFIX_1
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// RUN: %target-swift-ide-test -code-completion -code-completion-token=A -source-filename=%s
2+
// REQUIRES: asserts
3+
4+
func test(str: String?) {
5+
_ = str == nil #^A^#
6+
}

0 commit comments

Comments
 (0)