@@ -1066,7 +1066,7 @@ class ResultBuilderTransform
10661066 return None;
10671067 }
10681068
1069- std::pair<NullablePtr<VarDecl >, Optional<UnsupportedElt>>
1069+ std::pair<NullablePtr<Expr >, Optional<UnsupportedElt>>
10701070 transform (BraceStmt *braceStmt, SmallVectorImpl<ASTNode> &newBody) {
10711071 SmallVector<Expr *, 4 > buildBlockArguments;
10721072
@@ -1082,7 +1082,6 @@ class ResultBuilderTransform
10821082 }
10831083
10841084 // Synthesize `buildBlock` or `buildPartial` based on captured arguments.
1085- NullablePtr<VarDecl> buildBlockVar;
10861085 {
10871086 // If the builder supports `buildPartialBlock(first:)` and
10881087 // `buildPartialBlock(accumulated:next:)`, use this to combine
@@ -1097,16 +1096,19 @@ class ResultBuilderTransform
10971096 {buildBlockArguments.front ()},
10981097 /* argLabels=*/ {ctx.Id_first });
10991098
1100- buildBlockVar = captureExpr (buildPartialFirst, newBody);
1099+ auto * buildBlockVar = captureExpr (buildPartialFirst, newBody);
11011100
11021101 for (auto *argExpr : llvm::drop_begin (buildBlockArguments)) {
11031102 auto *accumPartialBlock = builder.buildCall (
11041103 braceStmt->getStartLoc (), ctx.Id_buildPartialBlock ,
1105- {builder.buildVarRef (buildBlockVar. get () , argExpr->getStartLoc ()),
1104+ {builder.buildVarRef (buildBlockVar, argExpr->getStartLoc ()),
11061105 argExpr},
11071106 {ctx.Id_accumulated , ctx.Id_next });
11081107 buildBlockVar = captureExpr (accumPartialBlock, newBody);
11091108 }
1109+
1110+ return std::make_pair (
1111+ builder.buildVarRef (buildBlockVar, braceStmt->getStartLoc ()), None);
11101112 }
11111113 // If `buildBlock` does not exist at this point, it could be the case that
11121114 // `buildPartialBlock` did not have the sufficient availability for this
@@ -1118,17 +1120,14 @@ class ResultBuilderTransform
11181120 builder.getType ());
11191121 return failTransform (braceStmt);
11201122 }
1123+
11211124 // Otherwise, call `buildBlock` on all subexpressions.
1122- else {
1123- // Call Builder.buildBlock(... args ...)
1124- auto *buildBlock = builder.buildCall (
1125- braceStmt->getStartLoc (), ctx.Id_buildBlock , buildBlockArguments,
1126- /* argLabels=*/ {});
1127- buildBlockVar = captureExpr (buildBlock, newBody);
1128- }
1125+ // Call Builder.buildBlock(... args ...)
1126+ auto *buildBlock = builder.buildCall (
1127+ braceStmt->getStartLoc (), ctx.Id_buildBlock , buildBlockArguments,
1128+ /* argLabels=*/ {});
1129+ return std::make_pair (buildBlock, None);
11291130 }
1130-
1131- return std::make_pair (buildBlockVar.get (), None);
11321131 }
11331132
11341133 std::pair<bool , UnsupportedElt>
@@ -1141,10 +1140,10 @@ class ResultBuilderTransform
11411140 return std::make_pair (true , element);
11421141 };
11431142
1144- NullablePtr<VarDecl> buildBlockVar ;
1143+ NullablePtr<Expr> buildBlockVarRef ;
11451144 Optional<UnsupportedElt> unsupported;
11461145
1147- std::tie (buildBlockVar , unsupported) = transform (braceStmt, elements);
1146+ std::tie (buildBlockVarRef , unsupported) = transform (braceStmt, elements);
11481147 if (unsupported)
11491148 return failure (*unsupported);
11501149
@@ -1156,14 +1155,12 @@ class ResultBuilderTransform
11561155 // are attached to the beginning of the brace instead of its end.
11571156 auto resultLoc = braceStmt->getStartLoc ();
11581157 if (bodyVar) {
1159- elements.push_back (new (ctx) AssignExpr (
1160- builder.buildVarRef (bodyVar.get (), resultLoc),
1161- /* EqualLoc=*/ SourceLoc (),
1162- builder.buildVarRef (buildBlockVar.get (), resultLoc),
1163- /* Implicit=*/ true ));
1158+ elements.push_back (
1159+ new (ctx) AssignExpr (builder.buildVarRef (bodyVar.get (), resultLoc),
1160+ /* EqualLoc=*/ SourceLoc (), buildBlockVarRef.get (),
1161+ /* Implicit=*/ true ));
11641162 } else {
1165- Expr *buildBlockResult =
1166- builder.buildVarRef (buildBlockVar.get (), resultLoc);
1163+ Expr *buildBlockResult = buildBlockVarRef.get ();
11671164 // Otherwise, it's a top-level brace and we need to synthesize
11681165 // a call to `buildFialBlock` if supported.
11691166 if (builder.supports (ctx.Id_buildFinalResult , {Identifier ()})) {
@@ -1220,9 +1217,9 @@ class ResultBuilderTransform
12201217 if (!isBuildableIfChain (ifStmt, numPayloads, isOptional))
12211218 return failTransform (ifStmt);
12221219
1223- SmallVector<std::pair<VarDecl *, Stmt *>, 4 > branchVars ;
1220+ SmallVector<std::pair<Expr *, Stmt *>, 4 > branchVarRefs ;
12241221
1225- auto transformed = transformIf (ifStmt, branchVars );
1222+ auto transformed = transformIf (ifStmt, branchVarRefs );
12261223 if (!transformed)
12271224 return failTransform (ifStmt);
12281225
@@ -1236,17 +1233,15 @@ class ResultBuilderTransform
12361233 // `if` goes first.
12371234 doBody.push_back (ifStmt);
12381235
1239- assert (numPayloads == branchVars .size ());
1236+ assert (numPayloads == branchVarRefs .size ());
12401237
12411238 SmallVector<Expr *, 4 > buildEitherCalls;
12421239 for (unsigned i = 0 ; i != numPayloads; i++) {
1243- VarDecl *branchVar ;
1240+ Expr *branchVarRef ;
12441241 Stmt *anchor;
12451242
1246- std::tie (branchVar , anchor) = branchVars [i];
1243+ std::tie (branchVarRef , anchor) = branchVarRefs [i];
12471244
1248- auto *branchVarRef =
1249- builder.buildVarRef (branchVar, ifStmt->getEndLoc ());
12501245 auto *builderCall =
12511246 buildWrappedChainPayload (branchVarRef, i, numPayloads, isOptional);
12521247
@@ -1308,7 +1303,7 @@ class ResultBuilderTransform
13081303
13091304 NullablePtr<IfStmt>
13101305 transformIf (IfStmt *ifStmt,
1311- SmallVectorImpl<std::pair<VarDecl *, Stmt *>> &branchVars ) {
1306+ SmallVectorImpl<std::pair<Expr *, Stmt *>> &branchVarRefs ) {
13121307 Optional<UnsupportedElt> unsupported;
13131308
13141309 // If there is a #available in the condition, wrap the 'then' or 'else'
@@ -1317,42 +1312,40 @@ class ResultBuilderTransform
13171312 bool supportsAvailability =
13181313 availabilityCond && builder.supports (ctx.Id_buildLimitedAvailability );
13191314
1320- NullablePtr<VarDecl> thenVar ;
1315+ NullablePtr<Expr> thenVarRef ;
13211316 NullablePtr<Stmt> thenBranch;
13221317 {
13231318 SmallVector<ASTNode, 4 > thenBody;
13241319
13251320 auto *ifBraceStmt = cast<BraceStmt>(ifStmt->getThenStmt ());
13261321
1327- std::tie (thenVar , unsupported) = transform (ifBraceStmt, thenBody);
1322+ std::tie (thenVarRef , unsupported) = transform (ifBraceStmt, thenBody);
13281323 if (unsupported) {
13291324 recordUnsupported (*unsupported);
13301325 return nullptr ;
13311326 }
13321327
13331328 if (supportsAvailability &&
13341329 !availabilityCond->getAvailability ()->isUnavailability ()) {
1335- auto *thenVarRef =
1336- builder.buildVarRef (thenVar.get (), ifBraceStmt->getEndLoc ());
1337-
13381330 auto *builderCall = buildCallIfWanted (
1339- ifStmt-> getThenStmt ()-> getEndLoc (), ctx.Id_buildLimitedAvailability ,
1340- {thenVarRef}, {Identifier ()});
1331+ ifBraceStmt-> getStartLoc (), ctx.Id_buildLimitedAvailability ,
1332+ {thenVarRef. get () }, {Identifier ()});
13411333
1342- thenVar = captureExpr (builderCall, thenBody);
1334+ thenVarRef = builder.buildVarRef (captureExpr (builderCall, thenBody),
1335+ ifBraceStmt->getStartLoc ());
13431336 }
13441337
13451338 thenBranch = cloneBraceWith (ifBraceStmt, thenBody);
1346- branchVars .push_back ({thenVar .get (), thenBranch.get ()});
1339+ branchVarRefs .push_back ({thenVarRef .get (), thenBranch.get ()});
13471340 }
13481341
13491342 NullablePtr<Stmt> elseBranch;
13501343
13511344 if (auto *elseStmt = ifStmt->getElseStmt ()) {
1352- NullablePtr<VarDecl> elseVar ;
1345+ NullablePtr<Expr> elseVarRef ;
13531346
13541347 if (auto *innerIfStmt = getAsStmt<IfStmt>(elseStmt)) {
1355- elseBranch = transformIf (innerIfStmt, branchVars );
1348+ elseBranch = transformIf (innerIfStmt, branchVarRefs );
13561349 if (!elseBranch) {
13571350 recordUnsupported (innerIfStmt);
13581351 return nullptr ;
@@ -1361,7 +1354,7 @@ class ResultBuilderTransform
13611354 auto *elseBraceStmt = cast<BraceStmt>(elseStmt);
13621355 SmallVector<ASTNode> elseBody;
13631356
1364- std::tie (elseVar , unsupported) = transform (elseBraceStmt, elseBody);
1357+ std::tie (elseVarRef , unsupported) = transform (elseBraceStmt, elseBody);
13651358 if (unsupported) {
13661359 recordUnsupported (*unsupported);
13671360 return nullptr ;
@@ -1371,18 +1364,16 @@ class ResultBuilderTransform
13711364 // call to buildLimitedAvailability(_:).
13721365 if (supportsAvailability &&
13731366 availabilityCond->getAvailability ()->isUnavailability ()) {
1374- auto *elseVarRef =
1375- builder.buildVarRef (elseVar.get (), elseBraceStmt->getEndLoc ());
1376-
1377- auto *builderCall = buildCallIfWanted (elseBraceStmt->getStartLoc (),
1378- ctx.Id_buildLimitedAvailability ,
1379- {elseVarRef}, {Identifier ()});
1367+ auto *builderCall = buildCallIfWanted (
1368+ elseBraceStmt->getStartLoc (), ctx.Id_buildLimitedAvailability ,
1369+ {elseVarRef.get ()}, {Identifier ()});
13801370
1381- elseVar = captureExpr (builderCall, elseBody);
1371+ elseVarRef = builder.buildVarRef (captureExpr (builderCall, elseBody),
1372+ elseBraceStmt->getStartLoc ());
13821373 }
13831374
13841375 elseBranch = cloneBraceWith (elseBraceStmt, elseBody);
1385- branchVars .push_back ({elseVar .get (), elseBranch.get ()});
1376+ branchVarRefs .push_back ({elseVarRef .get (), elseBranch.get ()});
13861377 }
13871378 }
13881379
@@ -1404,23 +1395,23 @@ class ResultBuilderTransform
14041395 SmallVector<ASTNode, 4 > doBody;
14051396
14061397 SmallVector<ASTNode, 4 > cases;
1407- SmallVector<VarDecl *, 4 > caseVars ;
1398+ SmallVector<Expr *, 4 > caseVarRefs ;
14081399
14091400 for (auto *caseStmt : switchStmt->getCases ()) {
14101401 auto transformed = transformCase (caseStmt);
14111402 if (!transformed)
14121403 return failTransform (caseStmt);
14131404
14141405 cases.push_back (transformed->second );
1415- caseVars .push_back (transformed->first );
1406+ caseVarRefs .push_back (transformed->first );
14161407 }
14171408
14181409 // If there are no 'case' statements in the body let's try
14191410 // to diagnose this situation via limited exhaustiveness check
14201411 // before failing a builder transform, otherwise type-checker
14211412 // might end up without any diagnostics which leads to crashes
14221413 // in SILGen.
1423- if (caseVars .empty ()) {
1414+ if (caseVarRefs .empty ()) {
14241415 TypeChecker::checkSwitchExhaustiveness (switchStmt, dc,
14251416 /* limitChecking=*/ true );
14261417 return failTransform (switchStmt);
@@ -1434,15 +1425,13 @@ class ResultBuilderTransform
14341425 doBody.push_back (transformedSwitch);
14351426
14361427 SmallVector<Expr *, 4 > injectedExprs;
1437- for (auto idx : indices (caseVars)) {
1438- auto caseStmt = cases[idx];
1439- auto *caseVar = caseVars[idx];
1428+ for (auto idx : indices (caseVarRefs)) {
1429+ auto *caseVarRef = caseVarRefs[idx];
14401430
14411431 // Build the expression that injects the case variable into appropriate
14421432 // buildEither(first:)/buildEither(second:) chain.
1443- Expr *caseVarRef = builder.buildVarRef (caseVar, caseStmt.getEndLoc ());
14441433 Expr *injectedCaseExpr = buildWrappedChainPayload (
1445- caseVarRef, idx, caseVars .size (), /* isOptional=*/ false );
1434+ caseVarRef, idx, caseVarRefs .size (), /* isOptional=*/ false );
14461435
14471436 injectedExprs.push_back (injectedCaseExpr);
14481437 }
@@ -1454,7 +1443,7 @@ class ResultBuilderTransform
14541443 return DoStmt::createImplicit (ctx, LabeledStmtInfo (), doBody);
14551444 }
14561445
1457- Optional<std::pair<VarDecl *, CaseStmt *>> transformCase (CaseStmt *caseStmt) {
1446+ Optional<std::pair<Expr *, CaseStmt *>> transformCase (CaseStmt *caseStmt) {
14581447 auto *body = caseStmt->getBody ();
14591448
14601449 // Explicitly disallow `case` statements with empty bodies
@@ -1470,11 +1459,11 @@ class ResultBuilderTransform
14701459 }
14711460 }
14721461
1473- NullablePtr<VarDecl> caseVar ;
1462+ NullablePtr<Expr> caseVarRef ;
14741463 Optional<UnsupportedElt> unsupported;
14751464 SmallVector<ASTNode, 4 > newBody;
14761465
1477- std::tie (caseVar , unsupported) = transform (body, newBody);
1466+ std::tie (caseVarRef , unsupported) = transform (body, newBody);
14781467
14791468 if (unsupported) {
14801469 recordUnsupported (*unsupported);
@@ -1489,7 +1478,7 @@ class ResultBuilderTransform
14891478 caseStmt->getCaseBodyVariablesOrEmptyArray (), caseStmt->isImplicit (),
14901479 caseStmt->getFallthroughStmt ());
14911480
1492- return std::make_pair (caseVar .get (), newCase);
1481+ return std::make_pair (caseVarRef .get (), newCase);
14931482 }
14941483
14951484 // / do {
@@ -1533,12 +1522,12 @@ class ResultBuilderTransform
15331522 ArrayExpr::create (ctx, /* LBrace=*/ endLoc, /* Elements=*/ {},
15341523 /* Commas=*/ {}, /* RBrace=*/ endLoc));
15351524
1536- NullablePtr<VarDecl> bodyVar ;
1525+ NullablePtr<Expr> bodyVarRef ;
15371526 Optional<UnsupportedElt> unsupported;
15381527
15391528 SmallVector<ASTNode, 4 > newBody;
15401529 {
1541- std::tie (bodyVar , unsupported) =
1530+ std::tie (bodyVarRef , unsupported) =
15421531 transform (forEachStmt->getBody (), newBody);
15431532 if (unsupported)
15441533 return failTransform (*unsupported);
@@ -1552,9 +1541,8 @@ class ResultBuilderTransform
15521541 DeclNameLoc (endLoc), /* implicit=*/ true );
15531542 arrayAppendRef->setFunctionRefKind (FunctionRefKind::SingleApply);
15541543
1555- auto bodyVarRef = builder.buildVarRef (bodyVar.get (), endLoc);
15561544 auto *argList = ArgumentList::createImplicit (
1557- ctx, endLoc, {Argument::unlabeled (bodyVarRef)}, endLoc);
1545+ ctx, endLoc, {Argument::unlabeled (bodyVarRef. get () )}, endLoc);
15581546
15591547 newBody.push_back (
15601548 CallExpr::createImplicit (ctx, arrayAppendRef, argList));
0 commit comments