@@ -8011,18 +8011,66 @@ namespace {
8011
8011
public:
8012
8012
ExprWalker (ExprRewriter &Rewriter) : Rewriter(Rewriter) { }
8013
8013
8014
+ ~ExprWalker () {
8015
+ assert (ClosuresToTypeCheck.empty ());
8016
+ assert (TapsToTypeCheck.empty ());
8017
+ }
8018
+
8014
8019
bool shouldWalkIntoPropertyWrapperPlaceholderValue () override {
8015
8020
// Property wrapper placeholder underlying values are filled in
8016
8021
// with already-type-checked expressions. Don't walk into them.
8017
8022
return false ;
8018
8023
}
8019
8024
8020
- const SmallVectorImpl<ClosureExpr *> &getClosuresToTypeCheck () const {
8021
- return ClosuresToTypeCheck;
8022
- }
8025
+ // / Process delayed closure bodies and `Tap` expressions.
8026
+ // /
8027
+ // / \returns true if any part of the processing fails.
8028
+ bool processDelayed () {
8029
+ bool hadError = false ;
8030
+
8031
+ while (!ClosuresToTypeCheck.empty ()) {
8032
+ auto *closure = ClosuresToTypeCheck.pop_back_val ();
8033
+ // If experimental multi-statement closure support
8034
+ // is enabled, solution should have all of required
8035
+ // information.
8036
+ //
8037
+ // Note that in this mode `ClosuresToTypeCheck` acts
8038
+ // as a stack because multi-statement closures could
8039
+ // have other multi-statement closures in the body.
8040
+ auto &ctx = closure->getASTContext ();
8041
+ if (ctx.TypeCheckerOpts .EnableMultiStatementClosureInference ) {
8042
+ auto &solution = Rewriter.solution ;
8043
+ auto &cs = solution.getConstraintSystem ();
8044
+
8045
+ hadError |= cs.applySolutionToBody (
8046
+ solution, closure, Rewriter.dc ,
8047
+ [&](SolutionApplicationTarget target) {
8048
+ auto resultTarget = rewriteTarget (target);
8049
+ if (resultTarget) {
8050
+ if (auto expr = resultTarget->getAsExpr ())
8051
+ solution.setExprTypes (expr);
8052
+ }
8053
+
8054
+ return resultTarget;
8055
+ });
8056
+ continue ;
8057
+ }
8023
8058
8024
- const SmallVectorImpl<std::pair<TapExpr *, DeclContext *>> &getTapsToTypeCheck () const {
8025
- return TapsToTypeCheck;
8059
+ hadError |= TypeChecker::typeCheckClosureBody (closure);
8060
+ }
8061
+
8062
+ // Tap expressions too; they should or should not be
8063
+ // type-checked under the same conditions as closure bodies.
8064
+ {
8065
+ for (const auto &tuple : TapsToTypeCheck) {
8066
+ auto tap = std::get<0 >(tuple);
8067
+ auto tapDC = std::get<1 >(tuple);
8068
+ hadError |= TypeChecker::typeCheckTapBody (tap, tapDC);
8069
+ }
8070
+ TapsToTypeCheck.clear ();
8071
+ }
8072
+
8073
+ return hadError;
8026
8074
}
8027
8075
8028
8076
std::pair<bool , Expr *> walkToExprPre (Expr *expr) override {
@@ -8819,19 +8867,10 @@ Optional<SolutionApplicationTarget> ConstraintSystem::applySolution(
8819
8867
if (!resultTarget)
8820
8868
return None;
8821
8869
8822
- // Visit closures that have non-single expression bodies.
8823
- bool hadError = false ;
8824
-
8825
- for (auto *closure : walker.getClosuresToTypeCheck ())
8826
- hadError |= TypeChecker::typeCheckClosureBody (closure);
8827
-
8828
- // Tap expressions too; they should or should not be
8829
- // type-checked under the same conditions as closure bodies.
8830
- for (auto tuple : walker.getTapsToTypeCheck ()) {
8831
- auto tap = std::get<0 >(tuple);
8832
- auto tapDC = std::get<1 >(tuple);
8833
- hadError |= TypeChecker::typeCheckTapBody (tap, tapDC);
8834
- }
8870
+ // Visit closures that have non-single expression bodies, tap expressions,
8871
+ // and possibly other types of AST nodes which could only be processed
8872
+ // after contextual expression.
8873
+ bool hadError = walker.processDelayed ();
8835
8874
8836
8875
// If any of them failed to type check, bail.
8837
8876
if (hadError)
0 commit comments