@@ -1004,6 +1004,9 @@ class ClosureConstraintApplication
10041004 RewriteTargetFn rewriteTarget;
10051005 bool isSingleExpression;
10061006
1007+ // / All `func`s declared in the body of the closure.
1008+ SmallVector<FuncDecl *, 4 > LocalFuncs;
1009+
10071010public:
10081011 // / Whether an error was encountered while generating constraints.
10091012 bool hadError = false ;
@@ -1048,6 +1051,14 @@ class ClosureConstraintApplication
10481051 // information e.g. accessors and do access/availability checks.
10491052 }
10501053
1054+ // Local functions cannot be type-checked in-order because they can
1055+ // capture variables declared after them. Let's save them to be
1056+ // processed after the solution has been applied to the body.
1057+ if (auto *func = dyn_cast<FuncDecl>(decl)) {
1058+ LocalFuncs.push_back (func);
1059+ return ;
1060+ }
1061+
10511062 TypeChecker::typeCheckDecl (decl);
10521063 }
10531064
@@ -1456,6 +1467,19 @@ class ClosureConstraintApplication
14561467 UNSUPPORTED_STMT(Fail)
14571468#undef UNSUPPORTED_STMT
14581469
1470+ public:
1471+ // / Apply solution to the closure and return updated body.
1472+ ASTNode apply () {
1473+ auto body = visit (closure->getBody ());
1474+
1475+ // Since local functions can capture variables that are declared
1476+ // after them, let's type-check them after all of the pattern
1477+ // bindings have been resolved by applying solution to the body.
1478+ for (auto *func : LocalFuncs)
1479+ TypeChecker::typeCheckDecl (func);
1480+
1481+ return body;
1482+ }
14591483};
14601484
14611485}
@@ -1552,7 +1576,7 @@ bool ConstraintSystem::applySolutionToBody(Solution &solution,
15521576 auto closureType = cs.getType (closure)->castTo <FunctionType>();
15531577 ClosureConstraintApplication application (
15541578 solution, closure, closureType->getResult (), rewriteTarget);
1555- auto body = application.visit (closure-> getBody () );
1579+ auto body = application.apply ( );
15561580
15571581 if (!body || application.hadError )
15581582 return true ;
0 commit comments