@@ -1149,7 +1149,7 @@ class PreCheckTarget final : public ASTWalker {
11491149
11501150 ASTContext &getASTContext () const { return Ctx; }
11511151
1152- bool walkToClosureExprPre (ClosureExpr *expr);
1152+ bool walkToClosureExprPre (ClosureExpr *expr, ParentTy &parent );
11531153
11541154 MacroWalking getMacroWalkingBehavior () const override {
11551155 return MacroWalking::Arguments;
@@ -1251,7 +1251,7 @@ class PreCheckTarget final : public ASTWalker {
12511251 // but do not walk into the body. That will be type-checked after
12521252 // we've determine the complete function type.
12531253 if (auto closure = dyn_cast<ClosureExpr>(expr))
1254- return finish (walkToClosureExprPre (closure), expr);
1254+ return finish (walkToClosureExprPre (closure, Parent ), expr);
12551255
12561256 if (auto *unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr))
12571257 return finish (true , TypeChecker::resolveDeclRefExpr (unresolved, DC));
@@ -1533,7 +1533,27 @@ class PreCheckTarget final : public ASTWalker {
15331533
15341534// / Perform prechecking of a ClosureExpr before we dive into it. This returns
15351535// / true when we want the body to be considered part of this larger expression.
1536- bool PreCheckTarget::walkToClosureExprPre (ClosureExpr *closure) {
1536+ bool PreCheckTarget::walkToClosureExprPre (ClosureExpr *closure,
1537+ ParentTy &parent) {
1538+ if (auto *expandedBody = closure->getExpandedBody ()) {
1539+ if (Parent.getAsExpr ()) {
1540+ // We cannot simply replace the body when closure i.e. is passed
1541+ // as an argument to a call or is a source of an assignment
1542+ // because the source range of the argument list would cross
1543+ // buffer boundaries. One way to avoid that is to inject
1544+ // elements into a new implicit brace statement with the original
1545+ // source locations. Brace statement has to be implicit because its
1546+ // elements are in a different buffer.
1547+ auto sourceRange = closure->getSourceRange ();
1548+ closure->setBody (BraceStmt::create (getASTContext (), sourceRange.Start ,
1549+ expandedBody->getElements (),
1550+ sourceRange.End ,
1551+ /* implicit=*/ true ));
1552+ } else {
1553+ closure->setBody (expandedBody);
1554+ }
1555+ }
1556+
15371557 // Pre-check the closure body.
15381558 (void )evaluateOrDefault (Ctx.evaluator , PreCheckClosureBodyRequest{closure},
15391559 nullptr );
0 commit comments