@@ -364,68 +364,70 @@ class BuilderClosureVisitor
364364 }
365365 }
366366
367- VarDecl *visitBraceStmt (BraceStmt *braceStmt) {
368- SmallVector<Expr *, 4 > expressions;
367+ void visitBraceElement (ASTNode node, SmallVectorImpl<Expr *> &expressions) {
369368 auto addChild = [&](VarDecl *childVar) {
370369 if (!childVar)
371370 return ;
372371
373372 expressions.push_back (builder.buildVarRef (childVar, childVar->getLoc ()));
374373 };
375374
376- for (auto node : braceStmt->getElements ()) {
377- // Implicit returns in single-expression function bodies are treated
378- // as the expression.
379- if (auto returnStmt =
380- dyn_cast_or_null<ReturnStmt>(node.dyn_cast <Stmt *>())) {
381- assert (returnStmt->isImplicit ());
382- node = returnStmt->getResult ();
383- }
384-
385- if (auto stmt = node.dyn_cast <Stmt *>()) {
386- addChild (visit (stmt));
387- continue ;
388- }
375+ // Implicit returns in single-expression function bodies are treated
376+ // as the expression.
377+ if (auto returnStmt =
378+ dyn_cast_or_null<ReturnStmt>(node.dyn_cast <Stmt *>())) {
379+ assert (returnStmt->isImplicit ());
380+ node = returnStmt->getResult ();
381+ }
389382
390- if (auto decl = node.dyn_cast <Decl *>()) {
391- // Just ignore #if; the chosen children should appear in the
392- // surrounding context. This isn't good for source tools but it
393- // at least works.
394- if (isa<IfConfigDecl>(decl))
395- continue ;
383+ if (auto stmt = node.dyn_cast <Stmt *>()) {
384+ addChild (visit (stmt));
385+ return ;
386+ }
396387
397- // Skip #warning/#error; we'll handle them when applying the builder.
398- if (isa<PoundDiagnosticDecl>(decl)) {
399- continue ;
400- }
388+ if (auto decl = node.dyn_cast <Decl *>()) {
389+ // Just ignore #if; the chosen children should appear in the
390+ // surrounding context. This isn't good for source tools but it
391+ // at least works.
392+ if (isa<IfConfigDecl>(decl))
393+ return ;
401394
402- // Pattern bindings are okay so long as all of the entries are
403- // initialized.
404- if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
405- visitPatternBindingDecl (patternBinding);
406- continue ;
407- }
395+ // Skip #warning/#error; we'll handle them when applying the builder.
396+ if (isa<PoundDiagnosticDecl>(decl))
397+ return ;
408398
409- // Ignore variable declarations, because they're always handled within
410- // their enclosing pattern bindings.
411- if (isa<VarDecl>(decl))
412- continue ;
399+ // Pattern bindings are okay so long as all of the entries are
400+ // initialized.
401+ if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
402+ visitPatternBindingDecl (patternBinding);
403+ return ;
404+ }
413405
414- if (!unhandledNode)
415- unhandledNode = decl;
406+ // Ignore variable declarations, because they're always handled within
407+ // their enclosing pattern bindings.
408+ if (isa<VarDecl>(decl))
409+ return ;
416410
417- continue ;
418- }
411+ if (!unhandledNode)
412+ unhandledNode = decl;
419413
420- auto expr = node.get <Expr *>();
421- if (cs && builder.supports (ctx.Id_buildExpression )) {
422- expr = buildCallIfWanted (expr->getLoc (), ctx.Id_buildExpression ,
423- { expr }, { Identifier () });
424- }
414+ return ;
415+ }
425416
426- addChild (captureExpr (expr, /* oneWay=*/ true , node.get <Expr *>()));
417+ auto expr = node.get <Expr *>();
418+ if (cs && builder.supports (ctx.Id_buildExpression )) {
419+ expr = buildCallIfWanted (expr->getLoc (), ctx.Id_buildExpression ,
420+ {expr}, {Identifier ()});
427421 }
428422
423+ addChild (captureExpr (expr, /* oneWay=*/ true , node.get <Expr *>()));
424+ }
425+
426+ VarDecl *visitBraceStmt (BraceStmt *braceStmt) {
427+ SmallVector<Expr *, 4 > expressions;
428+ for (auto node : braceStmt->getElements ())
429+ visitBraceElement (node, expressions);
430+
429431 if (!cs || hadError)
430432 return nullptr ;
431433
@@ -1762,107 +1764,113 @@ class BuilderClosureRewriter
17621764 solution (solution), dc(dc), builderTransform(builderTransform),
17631765 rewriteTarget(rewriteTarget) { }
17641766
1765- NullablePtr<Stmt>
1766- visitBraceStmt (BraceStmt *braceStmt, ResultBuilderTarget target,
1767- Optional<ResultBuilderTarget> innerTarget = None ) {
1768- std::vector<ASTNode> newElements;
1769-
1770- // If there is an "inner" target corresponding to this brace, declare
1771- // it's temporary variable if needed.
1772- if (innerTarget) {
1773- declareTemporaryVariable (innerTarget-> captured . first , newElements );
1767+ // / Visit the element of a brace statement, returning \c false if the element
1768+ // / was rewritten successfully, or \c true if there was an error.
1769+ bool visitBraceElement (ASTNode node, std::vector<ASTNode> &newElements ) {
1770+ // Implicit returns in single-expression function bodies are treated
1771+ // as the expression.
1772+ if ( auto returnStmt =
1773+ dyn_cast_or_null<ReturnStmt>(node. dyn_cast <Stmt *>())) {
1774+ assert (returnStmt-> isImplicit ());
1775+ node = returnStmt-> getResult ( );
17741776 }
17751777
1776- for (auto node : braceStmt->getElements ()) {
1777- // Implicit returns in single-expression function bodies are treated
1778- // as the expression.
1779- if (auto returnStmt =
1780- dyn_cast_or_null<ReturnStmt>(node.dyn_cast <Stmt *>())) {
1781- assert (returnStmt->isImplicit ());
1782- node = returnStmt->getResult ();
1783- }
1778+ if (auto expr = node.dyn_cast <Expr *>()) {
1779+ // Skip error expressions.
1780+ if (isa<ErrorExpr>(expr))
1781+ return false ;
17841782
1785- if (auto expr = node.dyn_cast <Expr *>()) {
1786- // Skip error expressions.
1787- if (isa<ErrorExpr>(expr))
1788- continue ;
1783+ // Each expression turns into a 'let' that captures the value of
1784+ // the expression.
1785+ auto recorded = takeCapturedExpr (expr);
17891786
1790- // Each expression turns into a 'let' that captures the value of
1791- // the expression.
1792- auto recorded = takeCapturedExpr (expr);
1787+ // Rewrite the expression
1788+ Expr *finalExpr = rewriteExpr (recorded.generatedExpr );
17931789
1794- // Rewrite the expression
1795- Expr *finalExpr = rewriteExpr (recorded.generatedExpr );
1790+ // Form a new pattern binding to bind the temporary variable to the
1791+ // transformed expression.
1792+ declareTemporaryVariable (recorded.temporaryVar , newElements, finalExpr);
1793+ return false ;
1794+ }
17961795
1797- // Form a new pattern binding to bind the temporary variable to the
1798- // transformed expression.
1799- declareTemporaryVariable (recorded.temporaryVar , newElements, finalExpr);
1800- continue ;
1796+ if (auto stmt = node.dyn_cast <Stmt *>()) {
1797+ // "throw" statements produce no value. Transform them directly.
1798+ if (auto throwStmt = dyn_cast<ThrowStmt>(stmt)) {
1799+ if (auto newStmt = visitThrowStmt (throwStmt)) {
1800+ newElements.push_back (newStmt.get ());
1801+ }
1802+ return false ;
18011803 }
18021804
1803- if (auto stmt = node.dyn_cast <Stmt *>()) {
1804- // "throw" statements produce no value. Transform them directly.
1805- if (auto throwStmt = dyn_cast<ThrowStmt>(stmt)) {
1806- if (auto newStmt = visitThrowStmt (throwStmt)) {
1807- newElements.push_back (newStmt.get ());
1808- }
1809- continue ;
1810- }
1805+ // Each statement turns into a (potential) temporary variable
1806+ // binding followed by the statement itself.
1807+ auto captured = takeCapturedStmt (stmt);
18111808
1812- // Each statement turns into a (potential) temporary variable
1813- // binding followed by the statement itself.
1814- auto captured = takeCapturedStmt (stmt);
1809+ declareTemporaryVariable (captured.first , newElements);
18151810
1816- declareTemporaryVariable (captured.first , newElements);
1811+ auto finalStmt =
1812+ visit (stmt, ResultBuilderTarget{ResultBuilderTarget::TemporaryVar,
1813+ std::move (captured)});
18171814
1818- auto finalStmt = visit (
1819- stmt,
1820- ResultBuilderTarget{ResultBuilderTarget::TemporaryVar,
1821- std::move (captured)}) ;
1815+ // Re-write of statements that envolve type-checking
1816+ // could fail, such a failure terminates the walk.
1817+ if (!finalStmt)
1818+ return true ;
18221819
1823- // Re-write of statements that envolve type-checking
1824- // could fail, such a failure terminates the walk.
1825- if (!finalStmt)
1826- return nullptr ;
1820+ newElements.push_back (finalStmt.get ());
1821+ return false ;
1822+ }
18271823
1828- newElements.push_back (finalStmt.get ());
1829- continue ;
1830- }
1824+ auto decl = node.get <Decl *>();
18311825
1832- auto decl = node.get <Decl *>();
1826+ // Skip #if declarations.
1827+ if (isa<IfConfigDecl>(decl)) {
1828+ newElements.push_back (decl);
1829+ return false ;
1830+ }
18331831
1834- // Skip #if declarations.
1835- if (isa<IfConfigDecl>(decl)) {
1836- newElements.push_back (decl);
1837- continue ;
1838- }
1832+ // Diagnose #warning / #error during application.
1833+ if (auto poundDiag = dyn_cast<PoundDiagnosticDecl>(decl)) {
1834+ TypeChecker::typeCheckDecl (poundDiag);
1835+ newElements.push_back (decl);
1836+ return false ;
1837+ }
18391838
1840- // Diagnose #warning / #error during application.
1841- if (auto poundDiag = dyn_cast<PoundDiagnosticDecl>(decl)) {
1842- TypeChecker::typeCheckDecl (poundDiag);
1843- newElements.push_back (decl);
1844- continue ;
1845- }
1839+ // Skip variable declarations; they're always part of a pattern
1840+ // binding.
1841+ if (isa<VarDecl>(decl)) {
1842+ TypeChecker::typeCheckDecl (decl);
1843+ newElements.push_back (decl);
1844+ return false ;
1845+ }
18461846
1847- // Skip variable declarations; they're always part of a pattern
1848- // binding.
1849- if (isa<VarDecl>(decl)) {
1850- TypeChecker::typeCheckDecl (decl);
1851- newElements.push_back (decl);
1852- continue ;
1853- }
1847+ // Handle pattern bindings.
1848+ if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
1849+ auto resultTarget =
1850+ rewriteTarget (SolutionApplicationTarget{patternBinding});
1851+ assert (resultTarget.has_value () &&
1852+ " Could not rewrite pattern binding entries!" );
1853+ TypeChecker::typeCheckDecl (resultTarget->getAsPatternBinding ());
1854+ newElements.push_back (resultTarget->getAsPatternBinding ());
1855+ return false ;
1856+ }
18541857
1855- // Handle pattern bindings.
1856- if (auto patternBinding = dyn_cast<PatternBindingDecl>(decl)) {
1857- auto resultTarget = rewriteTarget (SolutionApplicationTarget{patternBinding});
1858- assert (resultTarget.has_value ()
1859- && " Could not rewrite pattern binding entries!" );
1860- TypeChecker::typeCheckDecl (resultTarget->getAsPatternBinding ());
1861- newElements.push_back (resultTarget->getAsPatternBinding ());
1862- continue ;
1863- }
1858+ llvm_unreachable (" Cannot yet handle declarations" );
1859+ }
18641860
1865- llvm_unreachable (" Cannot yet handle declarations" );
1861+ NullablePtr<Stmt>
1862+ visitBraceStmt (BraceStmt *braceStmt, ResultBuilderTarget target,
1863+ Optional<ResultBuilderTarget> innerTarget = None) {
1864+ std::vector<ASTNode> newElements;
1865+
1866+ // If there is an "inner" target corresponding to this brace, declare
1867+ // it's temporary variable if needed.
1868+ if (innerTarget)
1869+ declareTemporaryVariable (innerTarget->captured .first , newElements);
1870+
1871+ for (auto node : braceStmt->getElements ()) {
1872+ if (visitBraceElement (node, newElements))
1873+ return nullptr ;
18661874 }
18671875
18681876 // If there is an "inner" target corresponding to this brace, initialize
0 commit comments