Skip to content

Commit cc62c11

Browse files
committed
[ASTWalker] Don't visit capture list vars twice
Previously we were walking them once when visiting the capture list, and then again as a part of the pattern binding decl. Change the logic to only visit them as a part of their pattern binding decl.
1 parent 85891fd commit cc62c11

File tree

4 files changed

+16
-44
lines changed

4 files changed

+16
-44
lines changed

lib/AST/ASTWalker.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -802,8 +802,11 @@ class Traversal : public ASTVisitor<Traversal, Expr*, Stmt*,
802802
else
803803
return nullptr;
804804
}
805-
} else if (doIt(c.Var) || doIt(c.Init)) {
806-
return nullptr;
805+
} else {
806+
// Note we do not walk c.Var here, as it'll be visited as a part of the
807+
// PatternBindingDecl.
808+
if (doIt(c.Init))
809+
return nullptr;
807810
}
808811
}
809812

lib/IDE/SyntaxModel.cpp

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -668,23 +668,6 @@ std::pair<bool, Expr *> ModelASTWalker::walkToExprPre(Expr *E) {
668668

669669
pushStructureNode(SN, Closure);
670670

671-
} else if (auto *CLE = dyn_cast<CaptureListExpr>(E)) {
672-
// The ASTWalker visits captured variables twice, from a `CaptureListEntry` they are visited
673-
// from the `VarDecl` and the `PatternBindingDecl` entries.
674-
// We take over visitation here to avoid walking the `PatternBindingDecl` ones.
675-
for (auto c : CLE->getCaptureList()) {
676-
if (auto *VD = c.Var) {
677-
// We're skipping over the PatternBindingDecl so we need to handle the
678-
// the VarDecl's attributes that we'd normally process visiting the PBD.
679-
if (!handleAttrs(VD->getAttrs()))
680-
return { false, nullptr };
681-
VD->walk(*this);
682-
}
683-
}
684-
if (auto *CE = CLE->getClosureBody())
685-
CE->walk(*this);
686-
return { false, walkToExprPost(E) };
687-
688671
} else if (auto SE = dyn_cast<SequenceExpr>(E)) {
689672
// In SequenceExpr, explicit cast expressions (e.g. 'as', 'is') appear
690673
// twice. Skip pointers we've already seen.

lib/SILGen/SILGenExpr.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1568,10 +1568,8 @@ ManagedValue emitCFunctionPointer(SILGenFunction &SGF,
15681568
// Ensure that weak captures are in a separate scope.
15691569
DebugScope scope(SGF, CleanupLocation(captureList));
15701570
// CaptureListExprs evaluate their bound variables.
1571-
for (auto capture : captureList->getCaptureList()) {
1572-
SGF.visit(capture.Var);
1571+
for (auto capture : captureList->getCaptureList())
15731572
SGF.visit(capture.Init);
1574-
}
15751573

15761574
// Emit the closure body.
15771575
auto *closure = captureList->getClosureBody();
@@ -2418,10 +2416,8 @@ RValue RValueEmitter::visitCaptureListExpr(CaptureListExpr *E, SGFContext C) {
24182416
// Ensure that weak captures are in a separate scope.
24192417
DebugScope scope(SGF, CleanupLocation(E));
24202418
// CaptureListExprs evaluate their bound variables.
2421-
for (auto capture : E->getCaptureList()) {
2422-
SGF.visit(capture.Var);
2419+
for (auto capture : E->getCaptureList())
24232420
SGF.visit(capture.Init);
2424-
}
24252421

24262422
// Then they evaluate to their body.
24272423
return visit(E->getClosureBody(), C);

lib/Sema/MiscDiagnostics.cpp

Lines changed: 9 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2492,26 +2492,16 @@ class VarDeclUsageChecker : public ASTWalker {
24922492
// If this is a VarDecl, then add it to our list of things to track.
24932493
if (auto *vd = dyn_cast<VarDecl>(D)) {
24942494
if (shouldTrackVarDecl(vd)) {
2495-
// Inline constructor.
2496-
auto defaultFlags = [&]() -> unsigned {
2497-
// If this VarDecl is nested inside of a CaptureListExpr, remember
2498-
// that fact for better diagnostics.
2499-
auto parentAsExpr = Parent.getAsExpr();
2500-
if (parentAsExpr && isa<CaptureListExpr>(parentAsExpr))
2501-
return RK_CaptureList | RK_Defined;
2502-
// Otherwise, return none.
2503-
return RK_Defined;
2504-
}();
2505-
2506-
if (!vd->isImplicit()) {
2507-
if (auto *childVd =
2508-
vd->getCorrespondingCaseBodyVariable().getPtrOrNull()) {
2509-
// Child vars are never in capture lists.
2510-
assert(defaultFlags == RK_Defined);
2511-
VarDecls[childVd] |= RK_Defined;
2512-
}
2495+
unsigned flags = RK_Defined;
2496+
if (vd->isCaptureList())
2497+
flags |= RK_CaptureList;
2498+
2499+
if (auto childVd = vd->getCorrespondingCaseBodyVariable()) {
2500+
// Child vars are never in capture lists.
2501+
assert(flags == RK_Defined);
2502+
addMark(childVd.get(), flags);
25132503
}
2514-
VarDecls[vd] |= defaultFlags;
2504+
addMark(vd, flags);
25152505
}
25162506
}
25172507

0 commit comments

Comments
 (0)