@@ -1149,7 +1149,7 @@ class PreCheckTarget final : public ASTWalker {
1149
1149
1150
1150
ASTContext &getASTContext () const { return Ctx; }
1151
1151
1152
- bool walkToClosureExprPre (ClosureExpr *expr);
1152
+ bool walkToClosureExprPre (ClosureExpr *expr, ParentTy &parent );
1153
1153
1154
1154
MacroWalking getMacroWalkingBehavior () const override {
1155
1155
return MacroWalking::Arguments;
@@ -1251,7 +1251,7 @@ class PreCheckTarget final : public ASTWalker {
1251
1251
// but do not walk into the body. That will be type-checked after
1252
1252
// we've determine the complete function type.
1253
1253
if (auto closure = dyn_cast<ClosureExpr>(expr))
1254
- return finish (walkToClosureExprPre (closure), expr);
1254
+ return finish (walkToClosureExprPre (closure, Parent ), expr);
1255
1255
1256
1256
if (auto *unresolved = dyn_cast<UnresolvedDeclRefExpr>(expr))
1257
1257
return finish (true , TypeChecker::resolveDeclRefExpr (unresolved, DC));
@@ -1533,7 +1533,27 @@ class PreCheckTarget final : public ASTWalker {
1533
1533
1534
1534
// / Perform prechecking of a ClosureExpr before we dive into it. This returns
1535
1535
// / 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
+
1537
1557
// Pre-check the closure body.
1538
1558
(void )evaluateOrDefault (Ctx.evaluator , PreCheckClosureBodyRequest{closure},
1539
1559
nullptr );
0 commit comments