[BuilderTransform] AST Transform: Inject buildOptional to top-level if else conditions

Fixes a bug in `buildOptional` injection for `if else` branches
without unconditional `else` which leaves type-join with just `.some(...)`
and results in optionality mismatch if `buildOptional` don't not produce
an optional type.
This commit is contained in:
Pavel Yaskevich
2022-09-01 13:31:00 -07:00
parent af94916552
commit 87816457c1
2 changed files with 54 additions and 2 deletions

View File

@@ -1245,10 +1245,26 @@ protected:
auto *builderCall =
buildWrappedChainPayload(branchVarRef, i, numPayloads, isOptional);
auto isTopLevel = [&](Stmt *anchor) {
if (ifStmt->getThenStmt() == anchor)
return true;
// The situation is this:
//
// if <cond> {
// ...
// } else if <other-cond> {
// ...
// }
if (auto *innerIf = getAsStmt<IfStmt>(ifStmt->getElseStmt()))
return innerIf->getThenStmt() == anchor;
return ifStmt->getElseStmt() == anchor;
};
// The operand should have optional type if we had optional results,
// so we just need to call `buildIf` now, since we're at the top level.
if (isOptional && (ifStmt->getThenStmt() == anchor ||
ifStmt->getElseStmt() == anchor)) {
if (isOptional && isTopLevel(anchor)) {
builderCall = buildCallIfWanted(ifStmt->getEndLoc(),
builder.getBuildOptionalId(),
builderCall, /*argLabels=*/{});