Skip to content

Commit 4a01aed

Browse files
committed
[CodeCompletion] Delete expr type state after getting expr completions
When we are getting completions for an initializer at the open parenthesis, as in: class C { func foo<S: Sequence>(x: S) { String(#^A^# } } after getting all of the overloads for String.init or other applicable completions for the expression, we leave the stateful expression type set when performing the last part of code completion, which is getting other visible declarations at that point. In this example, C.foo is available to call. However, if the expression type is left around, we will mistakenly try to use it to substitute generics of the found declaration, which doesn't make sense, because foo is a method on C, not String in this case. We really need to make this part of the compiler less stateful in the future, or at least formalize the state changes more. It might also make sense to further separate different kinds of completions and the mechanisms for getting types, as we reuse the same machinery for methods and module functions, making a lot of fallback assumptions. rdar://problem/30137466
1 parent 493db43 commit 4a01aed

File tree

2 files changed

+53
-0
lines changed

2 files changed

+53
-0
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3591,6 +3591,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
35913591
bool IncludeTopLevel = false,
35923592
bool RequestCache = true,
35933593
bool LiteralCompletions = true) {
3594+
ExprType = Type();
35943595
Kind = LookupKind::ValueInDeclContext;
35953596
NeedLeadingDot = false;
35963597
FilteredDeclConsumer Consumer(*this, Filter);
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
// RUN: %swift-ide-test -code-completion -code-completion-token=A -source-filename %s
2+
// RUN: %swift-ide-test -code-completion -code-completion-token=B -source-filename %s
3+
// RUN: %swift-ide-test -code-completion -code-completion-token=C -source-filename %s
4+
// RUN: %swift-ide-test -code-completion -code-completion-token=D -source-filename %s
5+
// RUN: %swift-ide-test -code-completion -code-completion-token=E -source-filename %s
6+
// RUN: %swift-ide-test -code-completion -code-completion-token=F -source-filename %s
7+
8+
// Make sure that visible members don't mess up code completion,
9+
// having seen a constructor for an incompatible declaration.
10+
11+
class CompeteInMethod {
12+
// Here, the method foo is actually visible at the
13+
// point of code-completion.
14+
func foo() {
15+
String(#^A^#
16+
}
17+
}
18+
19+
class CompleteInVar {
20+
// Same here - var decls are added to code completion results
21+
// in a different but similarly shaped code path. So here,
22+
// the var x is actually visible at the point of code-completion.
23+
var x: Int {
24+
String(#^B^#
25+
}
26+
}
27+
28+
class CompleteOutsideMethod {
29+
func foo() {}
30+
init() {
31+
String(#^C^#
32+
}
33+
}
34+
35+
class CompleteOutsideVar {
36+
var x: Int { return 1 }
37+
init() {
38+
String(#^D^#
39+
}
40+
}
41+
42+
class CompleteInsideGenericFunc {
43+
func foo<S: Sequence>(x: S) {
44+
String(#^E^#
45+
}
46+
}
47+
48+
class CompleteInsideGenericClass<S: Sequence> {
49+
func foo(x: S) {
50+
String(#^F^#
51+
}
52+
}

0 commit comments

Comments
 (0)