@@ -39,6 +39,10 @@ class FindCapturedVars : public ASTWalker {
39
39
SmallVector<CapturedValue, 4 > Captures;
40
40
llvm::SmallDenseMap<ValueDecl*, unsigned , 4 > captureEntryNumber;
41
41
42
+ // / We track the pack expansion expressions in ForEachStmts, because
43
+ // / their local generics remain in scope until the end of the statement.
44
+ llvm::DenseSet<PackExpansionExpr *> ForEachPatternSequences;
45
+
42
46
// / A stack of pack element environments we're currently walking into.
43
47
// / A reference to an element archetype defined by one of these is not
44
48
// / a capture.
@@ -652,13 +656,52 @@ class FindCapturedVars : public ASTWalker {
652
656
if (auto expansion = dyn_cast<PackExpansionExpr>(E)) {
653
657
if (auto *env = expansion->getGenericEnvironment ()) {
654
658
assert (env == VisitingEnvironments.back ());
655
- VisitingEnvironments.pop_back ();
656
659
(void ) env;
660
+
661
+ // If this is the pack expansion of a for .. in loop, the generic
662
+ // environment remains in scope until the end of the loop.
663
+ if (ForEachPatternSequences.count (expansion) == 0 )
664
+ VisitingEnvironments.pop_back ();
657
665
}
658
666
}
659
667
660
668
return Action::Continue (E);
661
669
}
670
+
671
+ PreWalkResult<Stmt *> walkToStmtPre (Stmt *S) override {
672
+ if (auto *forEachStmt = dyn_cast<ForEachStmt>(S)) {
673
+ if (auto *expansion =
674
+ dyn_cast<PackExpansionExpr>(forEachStmt->getParsedSequence ())) {
675
+ if (auto *env = expansion->getGenericEnvironment ()) {
676
+ // Remember this generic environment, so that it remains on the
677
+ // visited stack until the end of the for .. in loop.
678
+ assert (ForEachPatternSequences.count (expansion) == 0 );
679
+ ForEachPatternSequences.insert (expansion);
680
+ }
681
+ }
682
+ }
683
+
684
+ return Action::Continue (S);
685
+ }
686
+
687
+ PostWalkResult<Stmt *> walkToStmtPost (Stmt *S) override {
688
+ if (auto *forEachStmt = dyn_cast<ForEachStmt>(S)) {
689
+ if (auto *expansion =
690
+ dyn_cast<PackExpansionExpr>(forEachStmt->getParsedSequence ())) {
691
+ if (auto *env = expansion->getGenericEnvironment ()) {
692
+ assert (ForEachPatternSequences.count (expansion) != 0 );
693
+ ForEachPatternSequences.erase (expansion);
694
+
695
+ // Clean up the generic environment bound by the for loop.
696
+ assert (env == VisitingEnvironments.back ());
697
+ VisitingEnvironments.pop_back ();
698
+ (void ) env;
699
+ }
700
+ }
701
+ }
702
+
703
+ return Action::Continue (S);
704
+ }
662
705
};
663
706
664
707
} // end anonymous namespace
0 commit comments