Skip to content

Commit 9e745ed

Browse files
committed
[CursorInfo] Fix a bug that caused incorrect discriminators to be assigned to variables inside closures
1 parent b414fb8 commit 9e745ed

File tree

2 files changed

+31
-3
lines changed

2 files changed

+31
-3
lines changed

lib/IDE/CursorInfo.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,20 @@ void typeCheckDeclAndParentClosures(ValueDecl *VD) {
3737
// encoded in the USR of ParentContexts in the cursor info response.
3838
auto DC = VD->getDeclContext();
3939
while (DC->getParent()) {
40-
if (auto Closure = dyn_cast<AbstractClosureExpr>(DC)) {
41-
if (Closure->getType().isNull()) {
40+
if (auto AbstractClosure = dyn_cast<AbstractClosureExpr>(DC)) {
41+
if (AbstractClosure->getType().isNull()) {
4242
typeCheckASTNodeAtLoc(
4343
TypeCheckASTNodeAtLocContext::declContext(DC->getParent()),
44-
Closure->getLoc());
44+
AbstractClosure->getLoc());
45+
}
46+
if (auto Closure = dyn_cast<ClosureExpr>(AbstractClosure)) {
47+
// Set the closure's body state to `TypeCheckedWithSignature`. This
48+
// matches what the type checker is doing when applying the solution and
49+
// is necessary so the USRs we compute in solver-based cursor info match
50+
// those in the AST - the critical point is that
51+
// `isSeparatelyTypeChecked` in `SetLocalDiscriminators::walkToExprPre`
52+
// needs to evaluate to `false`.
53+
Closure->setBodyState(ClosureExpr::BodyState::TypeCheckedWithSignature);
4554
}
4655
}
4756
DC = DC->getParent();
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
func sink(_ a: (Int) -> Void) {}
2+
3+
func testSingleStatementClosure() {
4+
sink { items in
5+
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):9 %s -- %s | %FileCheck %s --check-prefix=SINGLE-STMT-CLOSURE
6+
var items = items
7+
}
8+
// SINGLE-STMT-CLOSURE: s:33variable_discriminator_in_closure26testSingleStatementClosureyyFySiXEfU_5itemsL_Sivp
9+
}
10+
11+
12+
func testMultiStatementClosure() {
13+
sink { items in
14+
// RUN: %sourcekitd-test -req=cursor -pos=%(line + 1):9 %s -- %s | %FileCheck %s --check-prefix=MULTI-STMT-CLOSURE
15+
var items = items
16+
print("xxx")
17+
}
18+
// MULTI-STMT-CLOSURE: s:33variable_discriminator_in_closure25testMultiStatementClosureyyFySiXEfU_5itemsL_Sivp
19+
}

0 commit comments

Comments
 (0)