Skip to content

Commit 4e9d3a1

Browse files
authored
Merge pull request #34522 from rintaro/ide-completion-rdar69246891pt2
[CodeCompletion] Fix crashes in TypeCheckASTNodeAtLocRequest
2 parents c36a302 + d78bf22 commit 4e9d3a1

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1841,12 +1841,23 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(Evaluator &evaluator,
18411841

18421842
std::pair<bool, Stmt *> walkToStmtPre(Stmt *S) override {
18431843
if (auto *brace = dyn_cast<BraceStmt>(S)) {
1844+
auto braceCharRange = Lexer::getCharSourceRangeFromSourceRange(
1845+
SM, brace->getSourceRange());
1846+
// Unless this brace contains the loc, there's nothing to do.
1847+
if (!braceCharRange.contains(Loc))
1848+
return {false, S};
1849+
1850+
// Reset the node found in a parent context.
1851+
if (!brace->isImplicit())
1852+
FoundNode = nullptr;
1853+
18441854
for (ASTNode &node : brace->getElements()) {
18451855
if (SM.isBeforeInBuffer(Loc, node.getStartLoc()))
18461856
break;
18471857

18481858
// NOTE: We need to check the character loc here because the target
1849-
// loc can be inside the last token of the node. i.e. interpolated string.
1859+
// loc can be inside the last token of the node. i.e. interpolated
1860+
// string.
18501861
SourceLoc endLoc = Lexer::getLocForEndOfToken(SM, node.getEndLoc());
18511862
if (SM.isBeforeInBuffer(endLoc, Loc) || endLoc == Loc)
18521863
continue;
@@ -1858,8 +1869,9 @@ bool TypeCheckASTNodeAtLocRequest::evaluate(Evaluator &evaluator,
18581869

18591870
// Walk into the node to narrow down.
18601871
node.walk(*this);
1861-
}
18621872

1873+
break;
1874+
}
18631875
// Already walked into.
18641876
return {false, nullptr};
18651877
}

validation-test/IDE/crashers_2_fixed/rdar69246891.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
// RUN: %target-swift-ide-test -code-completion -code-completion-token=COMPLETE -source-filename=%s
2+
// RUN: %target-swift-ide-test -code-completion -code-completion-token=COMPLETE_2 -source-filename=%s
23

34
class MyCls {
45
public init(body: (Int) throws -> Void) {}
@@ -10,3 +11,11 @@ func foo() {
1011
}
1112
}
1213
}
14+
15+
func receive(fn: () -> throws Void) {}
16+
17+
func test2() {
18+
receive {
19+
switch #^COMPLETE_2^#
20+
}
21+
}

0 commit comments

Comments
 (0)