Skip to content

Commit 7dba418

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 9913173 commit 7dba418

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
@@ -3596,6 +3596,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
35963596
bool IncludeTopLevel = false,
35973597
bool RequestCache = true,
35983598
bool LiteralCompletions = true) {
3599+
ExprType = Type();
35993600
Kind = LookupKind::ValueInDeclContext;
36003601
NeedLeadingDot = false;
36013602
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)