@@ -7596,17 +7596,32 @@ class AsyncConverter : private SourceEntityWalker {
75967596 OS << tok::r_paren;
75977597 }
75987598
7599- // / If the error type of \p HandlerDesc is more specialized than \c Error,
7600- // / adds an 'as! CustomError' cast to the more specialized error type to the
7601- // / output stream.
7602- void
7603- addCastToCustomErrorTypeIfNecessary (const AsyncHandlerDesc &HandlerDesc) {
7604- const ASTContext &Ctx = HandlerDesc.getHandler ()->getASTContext ();
7599+ // / Adds a forwarded error argument to a completion handler call. If the error
7600+ // / type of \p HandlerDesc is more specialized than \c Error, an
7601+ // / 'as! CustomError' cast to the more specialized error type will be added to
7602+ // / the output stream.
7603+ void addForwardedErrorArgument (StringRef ErrorName,
7604+ const AsyncHandlerDesc &HandlerDesc) {
7605+ // If the error type is already Error, we can pass it as-is.
76057606 auto ErrorType = *HandlerDesc.getErrorType ();
7606- if (ErrorType->getCanonicalType () != Ctx .getExceptionType ()) {
7607- OS << " " << tok::kw_as << tok::exclaim_postfix << " " ;
7608- ErrorType-> lookThroughSingleOptionalType ()-> print (OS) ;
7607+ if (ErrorType->getCanonicalType () == getASTContext () .getExceptionType ()) {
7608+ OS << ErrorName ;
7609+ return ;
76097610 }
7611+
7612+ // Otherwise we need to add a force cast to the destination custom error
7613+ // type. If this is for an Error? parameter, we'll need to add parens around
7614+ // the cast to silence a compiler warning about force casting never
7615+ // producing nil.
7616+ auto RequiresParens = HandlerDesc.getErrorParam ().hasValue ();
7617+ if (RequiresParens)
7618+ OS << tok::l_paren;
7619+
7620+ OS << ErrorName << " " << tok::kw_as << tok::exclaim_postfix << " " ;
7621+ ErrorType->lookThroughSingleOptionalType ()->print (OS);
7622+
7623+ if (RequiresParens)
7624+ OS << tok::r_paren;
76107625 }
76117626
76127627 // / If \p T has a natural default value like \c nil for \c Optional or \c ()
@@ -7637,8 +7652,7 @@ class AsyncConverter : private SourceEntityWalker {
76377652 if (HandlerDesc.HasError && Index == HandlerDesc.params ().size () - 1 ) {
76387653 // The error parameter is the last argument of the completion handler.
76397654 if (ResultName.empty ()) {
7640- OS << " error" ;
7641- addCastToCustomErrorTypeIfNecessary (HandlerDesc);
7655+ addForwardedErrorArgument (" error" , HandlerDesc);
76427656 } else {
76437657 addDefaultValueOrPlaceholder (HandlerDesc.params ()[Index].getPlainType ());
76447658 }
@@ -7707,8 +7721,8 @@ class AsyncConverter : private SourceEntityWalker {
77077721 OS << tok::period_prefix << " success" << tok::l_paren << ResultName
77087722 << tok::r_paren;
77097723 } else {
7710- OS << tok::period_prefix << " failure" << tok::l_paren << " error " ;
7711- addCastToCustomErrorTypeIfNecessary ( HandlerDesc);
7724+ OS << tok::period_prefix << " failure" << tok::l_paren;
7725+ addForwardedErrorArgument ( " error " , HandlerDesc);
77127726 OS << tok::r_paren;
77137727 }
77147728 break ;
0 commit comments