Skip to content

Commit a94b2c1

Browse files
authored
Merge pull request #38602 from hamishknight/errors-as-warnings-5.5
[5.5] [Async Refactoring] Add parens around custom error cast
2 parents f3e29e3 + d1a8fb9 commit a94b2c1

File tree

3 files changed

+30
-16
lines changed

3 files changed

+30
-16
lines changed

lib/IDE/Refactoring.cpp

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7612,17 +7612,32 @@ class AsyncConverter : private SourceEntityWalker {
76127612
OS << tok::r_paren;
76137613
}
76147614

7615-
/// If the error type of \p HandlerDesc is more specialized than \c Error,
7616-
/// adds an 'as! CustomError' cast to the more specialized error type to the
7617-
/// output stream.
7618-
void
7619-
addCastToCustomErrorTypeIfNecessary(const AsyncHandlerDesc &HandlerDesc) {
7620-
const ASTContext &Ctx = HandlerDesc.getHandler()->getASTContext();
7615+
/// Adds a forwarded error argument to a completion handler call. If the error
7616+
/// type of \p HandlerDesc is more specialized than \c Error, an
7617+
/// 'as! CustomError' cast to the more specialized error type will be added to
7618+
/// the output stream.
7619+
void addForwardedErrorArgument(StringRef ErrorName,
7620+
const AsyncHandlerDesc &HandlerDesc) {
7621+
// If the error type is already Error, we can pass it as-is.
76217622
auto ErrorType = *HandlerDesc.getErrorType();
7622-
if (ErrorType->getCanonicalType() != Ctx.getExceptionType()) {
7623-
OS << " " << tok::kw_as << tok::exclaim_postfix << " ";
7624-
ErrorType->lookThroughSingleOptionalType()->print(OS);
7623+
if (ErrorType->getCanonicalType() == getASTContext().getExceptionType()) {
7624+
OS << ErrorName;
7625+
return;
76257626
}
7627+
7628+
// Otherwise we need to add a force cast to the destination custom error
7629+
// type. If this is for an Error? parameter, we'll need to add parens around
7630+
// the cast to silence a compiler warning about force casting never
7631+
// producing nil.
7632+
auto RequiresParens = HandlerDesc.getErrorParam().hasValue();
7633+
if (RequiresParens)
7634+
OS << tok::l_paren;
7635+
7636+
OS << ErrorName << " " << tok::kw_as << tok::exclaim_postfix << " ";
7637+
ErrorType->lookThroughSingleOptionalType()->print(OS);
7638+
7639+
if (RequiresParens)
7640+
OS << tok::r_paren;
76267641
}
76277642

76287643
/// If \p T has a natural default value like \c nil for \c Optional or \c ()
@@ -7653,8 +7668,7 @@ class AsyncConverter : private SourceEntityWalker {
76537668
if (HandlerDesc.HasError && Index == HandlerDesc.params().size() - 1) {
76547669
// The error parameter is the last argument of the completion handler.
76557670
if (ResultName.empty()) {
7656-
OS << "error";
7657-
addCastToCustomErrorTypeIfNecessary(HandlerDesc);
7671+
addForwardedErrorArgument("error", HandlerDesc);
76587672
} else {
76597673
addDefaultValueOrPlaceholder(HandlerDesc.params()[Index].getPlainType());
76607674
}
@@ -7723,8 +7737,8 @@ class AsyncConverter : private SourceEntityWalker {
77237737
OS << tok::period_prefix << "success" << tok::l_paren << ResultName
77247738
<< tok::r_paren;
77257739
} else {
7726-
OS << tok::period_prefix << "failure" << tok::l_paren << "error";
7727-
addCastToCustomErrorTypeIfNecessary(HandlerDesc);
7740+
OS << tok::period_prefix << "failure" << tok::l_paren;
7741+
addForwardedErrorArgument("error", HandlerDesc);
77287742
OS << tok::r_paren;
77297743
}
77307744
break;

test/refactoring/ConvertAsync/basic.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -133,7 +133,7 @@ func customError(completion: (String?, CustomError?) -> Void) { }
133133
// ASYNC-CUSTOMERROR-NEXT: let result = try await customError()
134134
// ASYNC-CUSTOMERROR-NEXT: completion(result, nil)
135135
// ASYNC-CUSTOMERROR-NEXT: } catch {
136-
// ASYNC-CUSTOMERROR-NEXT: completion(nil, error as! CustomError)
136+
// ASYNC-CUSTOMERROR-NEXT: completion(nil, (error as! CustomError))
137137
// ASYNC-CUSTOMERROR-NEXT: }
138138
// ASYNC-CUSTOMERROR-NEXT: }
139139
// ASYNC-CUSTOMERROR-NEXT: }
@@ -308,7 +308,7 @@ func genericError<E>(completion: (String?, E?) -> Void) where E: Error { }
308308
// GENERIC-ERROR-NEXT: let result: String = try await genericError()
309309
// GENERIC-ERROR-NEXT: completion(result, nil)
310310
// GENERIC-ERROR-NEXT: } catch {
311-
// GENERIC-ERROR-NEXT: completion(nil, error as! E)
311+
// GENERIC-ERROR-NEXT: completion(nil, (error as! E))
312312
// GENERIC-ERROR-NEXT: }
313313
// GENERIC-ERROR-NEXT: }
314314
// GENERIC-ERROR-NEXT: }

test/refactoring/ConvertAsync/variable_as_callback.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -317,7 +317,7 @@ func testGenericErrorVariableCompletionHandler<MyGenericError>(completionHandler
317317
// GENERIC-ERROR-NEXT: let result: String = try await genericError()
318318
// GENERIC-ERROR-NEXT: completionHandler(result, nil)
319319
// GENERIC-ERROR-NEXT: } catch {
320-
// GENERIC-ERROR-NEXT: completionHandler(nil, error as! MyGenericError)
320+
// GENERIC-ERROR-NEXT: completionHandler(nil, (error as! MyGenericError))
321321
// GENERIC-ERROR-NEXT: }
322322

323323
// RUN: %refactor-check-compiles -convert-to-async -dump-text -source-filename %s -pos=%(line+2):1 | %FileCheck -check-prefix=DEFAULT-ARGS-FUNC %s

0 commit comments

Comments
 (0)