Skip to content

Commit 881ceed

Browse files
authored
Merge pull request swiftlang#29773 from akyrtzi/structure-walk-closure-var-once
[IDE/SyntaxModel] For syntactic structure, make sure to not visit the captured list variables twice
2 parents 151fc79 + 73c3e1c commit 881ceed

File tree

2 files changed

+15
-0
lines changed

2 files changed

+15
-0
lines changed

lib/IDE/SyntaxModel.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -664,6 +664,19 @@ std::pair<bool, Expr *> ModelASTWalker::walkToExprPre(Expr *E) {
664664
Closure->getExplicitResultTypeLoc().getSourceRange());
665665

666666
pushStructureNode(SN, Closure);
667+
668+
} else if (auto *CLE = dyn_cast<CaptureListExpr>(E)) {
669+
// The ASTWalker visits captured variables twice, from a `CaptureListEntry` they are visited
670+
// from the `VarDecl` and the `PatternBindingDecl` entries.
671+
// We take over visitation here to avoid walking the `PatternBindingDecl` ones.
672+
for (auto c : CLE->getCaptureList()) {
673+
if (auto *VD = c.Var)
674+
VD->walk(*this);
675+
}
676+
if (auto *CE = CLE->getClosureBody())
677+
CE->walk(*this);
678+
return { false, walkToExprPost(E) };
679+
667680
} else if (auto SE = dyn_cast<SequenceExpr>(E)) {
668681
// In SequenceExpr, explicit cast expressions (e.g. 'as', 'is') appear
669682
// twice. Skip pointers we've already seen.

test/IDE/structure.swift

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -330,3 +330,5 @@ thirdCall("""
330330
fourthCall(a: @escaping () -> Int)
331331
// CHECK: <call><name>fourthCall</name>(<arg><name>a</name>: @escaping () -> Int</arg>)</call>
332332

333+
// CHECK: <call><name>foo</name> <closure>{ [unowned <lvar><name>self</name></lvar>, <lvar><name>x</name></lvar>] in _ }</closure></call>
334+
foo { [unowned self, x] in _ }

0 commit comments

Comments
 (0)