Skip to content

Commit 00977af

Browse files
committed
[Async Refactoring] Placeholder dropped params in fallback case
Make sure to convert any references to parameters that get dropped in the fallback case to placeholders.
1 parent 1e34f31 commit 00977af

File tree

2 files changed

+43
-12
lines changed

2 files changed

+43
-12
lines changed

lib/IDE/Refactoring.cpp

Lines changed: 26 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7184,10 +7184,9 @@ class AsyncConverter : private SourceEntityWalker {
71847184
AllBindings.append(SuccessBindings.begin(), SuccessBindings.end());
71857185
AllBindings.push_back(ErrParam);
71867186

7187-
// Don't do any unwrapping or placeholder replacement since all params
7188-
// are still valid in the fallback case
71897187
prepareNames(ClassifiedBlock(), AllBindings, InlinePatterns);
7190-
7188+
preparePlaceholdersAndUnwraps(HandlerDesc, CallbackParams,
7189+
PlaceholderMode::FALLBACK);
71917190
addFallbackVars(AllBindings, Blocks);
71927191
addDo();
71937192
addAwaitCall(CE, Blocks.SuccessBlock, SuccessBindings, InlinePatterns,
@@ -7243,7 +7242,7 @@ class AsyncConverter : private SourceEntityWalker {
72437242

72447243
prepareNames(Blocks.SuccessBlock, SuccessBindings, InlinePatterns);
72457244
preparePlaceholdersAndUnwraps(HandlerDesc, CallbackParams,
7246-
/*Success=*/true);
7245+
PlaceholderMode::SUCCESS_BLOCK);
72477246

72487247
addAwaitCall(CE, Blocks.SuccessBlock, SuccessBindings, InlinePatterns,
72497248
HandlerDesc, /*AddDeclarations=*/true);
@@ -7260,7 +7259,7 @@ class AsyncConverter : private SourceEntityWalker {
72607259
ErrInlinePatterns,
72617260
/*AddIfMissing=*/HandlerDesc.Type != HandlerType::RESULT);
72627261
preparePlaceholdersAndUnwraps(HandlerDesc, CallbackParams,
7263-
/*Success=*/false);
7262+
PlaceholderMode::ERROR_BLOCK);
72647263

72657264
addCatch(ErrOrResultParam);
72667265
convertNodes(Blocks.ErrorBlock.nodesToPrint());
@@ -7547,14 +7546,31 @@ class AsyncConverter : private SourceEntityWalker {
75477546
OS << tok::l_brace;
75487547
}
75497548

7549+
enum class PlaceholderMode {
7550+
SUCCESS_BLOCK, ERROR_BLOCK, FALLBACK
7551+
};
7552+
75507553
void preparePlaceholdersAndUnwraps(AsyncHandlerDesc HandlerDesc,
75517554
const ClosureCallbackParams &Params,
7552-
bool Success) {
7555+
PlaceholderMode Mode) {
7556+
// Params that have been dropped always need placeholdering.
7557+
for (auto *Param : Params.getAllParams()) {
7558+
if (!Params.hasBinding(Param))
7559+
Placeholders.insert(Param);
7560+
}
7561+
// For the fallback case, no other params need placeholdering, as they are
7562+
// all freely accessible in the fallback case.
7563+
if (Mode == PlaceholderMode::FALLBACK)
7564+
return;
7565+
75537566
switch (HandlerDesc.Type) {
75547567
case HandlerType::PARAMS: {
75557568
auto *ErrParam = Params.getErrParam();
75567569
auto SuccessParams = Params.getSuccessParams();
7557-
if (!Success) {
7570+
switch (Mode) {
7571+
case PlaceholderMode::FALLBACK:
7572+
llvm_unreachable("Already handled");
7573+
case PlaceholderMode::ERROR_BLOCK:
75587574
if (ErrParam) {
75597575
if (HandlerDesc.shouldUnwrap(ErrParam->getType())) {
75607576
Placeholders.insert(ErrParam);
@@ -7563,7 +7579,8 @@ class AsyncConverter : private SourceEntityWalker {
75637579
// Can't use success params in the error body
75647580
Placeholders.insert(SuccessParams.begin(), SuccessParams.end());
75657581
}
7566-
} else {
7582+
break;
7583+
case PlaceholderMode::SUCCESS_BLOCK:
75677584
for (auto *SuccessParam : SuccessParams) {
75687585
auto Ty = SuccessParam->getType();
75697586
if (HandlerDesc.shouldUnwrap(Ty)) {
@@ -7573,10 +7590,6 @@ class AsyncConverter : private SourceEntityWalker {
75737590
Placeholders.insert(SuccessParam);
75747591
}
75757592

7576-
// If the parameter doesn't have a binding, it needs placeholdering.
7577-
if (!Params.hasBinding(SuccessParam))
7578-
Placeholders.insert(SuccessParam);
7579-
75807593
// Void parameters get omitted where possible, so turn any reference
75817594
// into a placeholder, as its usage is unlikely what the user wants.
75827595
if (HandlerDesc.getSuccessParamAsyncReturnType(Ty)->isVoid())
@@ -7585,6 +7598,7 @@ class AsyncConverter : private SourceEntityWalker {
75857598
// Can't use the error param in the success body
75867599
if (ErrParam)
75877600
Placeholders.insert(ErrParam);
7601+
break;
75887602
}
75897603
break;
75907604
}

test/refactoring/ConvertAsync/convert_bool.swift

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -459,4 +459,21 @@ func testConvertBool() async throws {
459459
// OBJC-BOOL-WITH-ERR2-NEXT: print("neat")
460460
// OBJC-BOOL-WITH-ERR2-NEXT: print("neato")
461461
// OBJC-BOOL-WITH-ERR2-NEXT: }
462+
463+
// RUN: %refactor-check-compiles -convert-call-to-async-alternative -dump-text -source-filename %s -pos=%(line+1):3 -I %S/Inputs -I %t -target %target-triple %clang-importer-sdk-nosource | %FileCheck -check-prefix=OBJC-BOOL-WITH-ERR-FALLBACK %s
464+
ClassWithHandlerMethods.firstBoolFlagSuccess("") { str, success, unrelated, err in
465+
guard success && success == .random() else { fatalError() }
466+
print("much success", unrelated, str)
467+
}
468+
// OBJC-BOOL-WITH-ERR-FALLBACK: var str: String? = nil
469+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: var unrelated: Bool? = nil
470+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: var err: Error? = nil
471+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: do {
472+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: (str, unrelated) = try await ClassWithHandlerMethods.firstBoolFlagSuccess("")
473+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: } catch {
474+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: err = error
475+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: }
476+
// OBJC-BOOL-WITH-ERR-FALLBACK-EMPTY:
477+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: guard <#success#> && <#success#> == .random() else { fatalError() }
478+
// OBJC-BOOL-WITH-ERR-FALLBACK-NEXT: print("much success", unrelated, str)
462479
}

0 commit comments

Comments
 (0)