Skip to content

Commit 27e2514

Browse files
committed
[CS] Better handle unsupported result builder elements for completion
Instead of failing, fall back to solving as a regular function body. rdar://144303920
1 parent e0791bb commit 27e2514

File tree

2 files changed

+40
-14
lines changed

2 files changed

+40
-14
lines changed

lib/Sema/BuilderTransform.cpp

Lines changed: 8 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -269,12 +269,7 @@ class ResultBuilderTransform
269269
for (auto element : braceStmt->getElements()) {
270270
if (auto unsupported =
271271
transformBraceElement(element, newBody, buildBlockArguments)) {
272-
// When in code completion mode, simply ignore unsported constructs to
273-
// get results for anything that's unrelated to the unsupported
274-
// constructs.
275-
if (!ctx.CompletionCallback) {
276-
return failTransform(*unsupported);
277-
}
272+
return failTransform(*unsupported);
278273
}
279274
}
280275

@@ -1156,18 +1151,17 @@ ConstraintSystem::matchResultBuilder(AnyFunctionRef fn, Type builderType,
11561151
auto *body = transform.apply(fn.getBody());
11571152

11581153
if (auto unsupported = transform.getUnsupportedElement()) {
1159-
assert(!body || getASTContext().CompletionCallback);
1160-
1161-
// If we aren't supposed to attempt fixes, fail.
1162-
if (!shouldAttemptFixes()) {
1163-
return getTypeMatchFailure(locator);
1164-
}
1154+
assert(!body);
11651155

11661156
// If we're solving for code completion and the body contains the code
1167-
// completion location, skipping it won't get us to a useful solution so
1168-
// just bail.
1157+
// completion location, fall back to solving as a regular function body.
11691158
if (isForCodeCompletion() &&
11701159
containsIDEInspectionTarget(fn.getBody())) {
1160+
return std::nullopt;
1161+
}
1162+
1163+
// If we aren't supposed to attempt fixes, fail.
1164+
if (!shouldAttemptFixes()) {
11711165
return getTypeMatchFailure(locator);
11721166
}
11731167

test/IDE/complete_in_result_builder.swift

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,12 @@ func testGlobalLookup() {
5353
}
5454
}
5555

56+
buildStringTuple {
57+
if {
58+
#^GLOBAL_LOOKUP_IN_IF_BODY_WITHOUT_CONDITION_CLOSURE?check=GLOBAL_LOOKUP_IN_IF_BODY^#
59+
}
60+
}
61+
5662
@TupleBuilder<String> var x4 {
5763
guard else {
5864
#^GLOBAL_LOOKUP_IN_GUARD_BODY_WITHOUT_CONDITION?check=GLOBAL_LOOKUP_IN_IF_BODY^#
@@ -146,6 +152,11 @@ func testPatternMatching() {
146152
let x: FooStruct? = FooStruct()
147153
guard case .#^GUARD_CASE_PATTERN_2?check=OPTIONAL_FOOSTRUCT^#some() = x {}
148154
}
155+
156+
buildStringTuple {
157+
let x: FooStruct? = FooStruct()
158+
guard case .#^GUARD_CASE_PATTERN_3?check=OPTIONAL_FOOSTRUCT^#some() = x {}
159+
}
149160
}
150161
151162
func testCompleteFunctionArgumentLabels() {
@@ -428,3 +439,24 @@ func testInForLoop(_ x: [Int]) {
428439
}
429440
}
430441
}
442+
443+
func testUnsupportedForLoop() {
444+
@resultBuilder
445+
struct Builder {
446+
static func buildBlock<T>(_ components: T...) -> T {
447+
components.first!
448+
}
449+
}
450+
451+
func foo(@Builder fn: () -> Int) {}
452+
453+
foo {
454+
for i in [0].#^COMPLETE_IN_UNSUPPORTED_FOR^# {}
455+
}
456+
// COMPLETE_IN_UNSUPPORTED_FOR: Decl[InstanceVar]/Super/IsSystem: first[#Int?#]; name=first
457+
458+
foo {
459+
for i in [0].#^COMPLETE_IN_UNSUPPORTED_FOR_2?check=COMPLETE_IN_UNSUPPORTED_FOR^# {}
460+
return 0
461+
}
462+
}

0 commit comments

Comments
 (0)