Skip to content

Commit 44ba366

Browse files
authored
Merge pull request #83662 from hamishknight/unqualified-fallback
[Completion] Fall back to unqualified lookup on solver failure
2 parents 4f010f0 + a3edf17 commit 44ba366

File tree

4 files changed

+70
-4
lines changed

4 files changed

+70
-4
lines changed

lib/IDE/ExprCompletion.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,12 @@ void ExprTypeCheckCompletionCallback::collectResults(
119119
UnifiedCanHandleAsync |= Result.IsInAsyncContext;
120120
}
121121

122+
// If we didn't find any results, at least try to collect unqualified results.
123+
if (Results.empty()) {
124+
Lookup.getValueCompletionsInDeclContext(CCLoc);
125+
Lookup.getSelfTypeCompletionInDeclContext(CCLoc, /*isForDeclResult=*/false);
126+
}
127+
122128
collectCompletionResults(CompletionCtx, Lookup, DC, UnifiedTypeContext,
123129
UnifiedCanHandleAsync);
124130
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// RUN: %batch-code-completion
2+
3+
protocol P0 {}
4+
protocol P1 {}
5+
protocol P2 {}
6+
protocol P3 {}
7+
protocol P4 {}
8+
protocol P5 {}
9+
protocol P6 {}
10+
protocol P7 {}
11+
protocol P8 {}
12+
protocol P9 {}
13+
14+
struct FooBar: P0 {}
15+
16+
@resultBuilder
17+
struct Builder {
18+
static func buildBlock<T>(_ x: T) -> T { x }
19+
static func buildExpression<T: P0>(_ x: T) -> T { x }
20+
static func buildExpression<T: P1>(_ x: T) -> T { x }
21+
static func buildExpression<T: P2>(_ x: T) -> T { x }
22+
static func buildExpression<T: P3>(_ x: T) -> T { x }
23+
static func buildExpression<T: P4>(_ x: T) -> T { x }
24+
static func buildExpression<T: P5>(_ x: T) -> T { x }
25+
static func buildExpression<T: P6>(_ x: T) -> T { x }
26+
static func buildExpression<T: P7>(_ x: T) -> T { x }
27+
static func buildExpression<T: P8>(_ x: T) -> T { x }
28+
static func buildExpression<T: P9>(_ x: T) -> T { x }
29+
}
30+
31+
struct S<T> {}
32+
extension S: P0 where T : P0 { init(@Builder fn: () -> T) {} }
33+
extension S: P1 where T : P1 { init(@Builder fn: () -> T) {} }
34+
extension S: P2 where T : P2 { init(@Builder fn: () -> T) {} }
35+
extension S: P3 where T : P3 { init(@Builder fn: () -> T) {} }
36+
extension S: P4 where T : P4 { init(@Builder fn: () -> T) {} }
37+
extension S: P5 where T : P5 { init(@Builder fn: () -> T) {} }
38+
extension S: P6 where T : P6 { init(@Builder fn: () -> T) {} }
39+
extension S: P7 where T : P7 { init(@Builder fn: () -> T) {} }
40+
extension S: P8 where T : P8 { init(@Builder fn: () -> T) {} }
41+
extension S: P9 where T : P9 { init(@Builder fn: () -> T) {} }
42+
43+
// This is currently too complex, make sure we can still do an unqualified
44+
// lookup though.
45+
S {
46+
S {
47+
S {
48+
S {
49+
S {
50+
#^COMPLETE^#
51+
// COMPLETE: Decl[Struct]/CurrModule: FooBar[#FooBar#]; name=FooBar
52+
}
53+
}
54+
}
55+
}
56+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// Make sure we don't crash
2+
struct S {
3+
init?() {
4+
return nil
5+
// RUN: %sourcekitd-test -req=complete.open -pos=%(line-1):12 %s -- %s
6+
}
7+
}

tools/SourceKit/lib/SwiftLang/CodeCompletionOrganizer.cpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -847,10 +847,7 @@ static void sortTopN(const Options &options, Group *group,
847847
unsigned endNewIndex = 0;
848848
for (unsigned i = 1; i < contents.size(); ++i) {
849849
auto bucket = getResultBucket(*contents[i], hasRequiredTypes);
850-
if (bucket < best) {
851-
// This algorithm assumes we don't have both literal and
852-
// literal-type-match at the start of the list.
853-
assert(bucket != ResultBucket::Literal);
850+
if (bucket < best && bucket != ResultBucket::Literal) {
854851
if (isTopNonLiteralResult(*contents[i], best)) {
855852
beginNewIndex = i;
856853
endNewIndex = beginNewIndex + 1;

0 commit comments

Comments
 (0)