@@ -5724,6 +5724,12 @@ static void applyContextualClosureFlags(
57245724 captureList->getClosureBody (), sendable, forMainActor,
57255725 implicitSelfCapture, inheritActorContext);
57265726 }
5727+
5728+ if (auto identity = dyn_cast<IdentityExpr>(expr)) {
5729+ applyContextualClosureFlags (
5730+ identity->getSubExpr (), sendable, forMainActor,
5731+ implicitSelfCapture, inheritActorContext);
5732+ }
57275733}
57285734
57295735// / Whether this is a reference to a method on the main dispatch queue.
@@ -6116,6 +6122,20 @@ static bool isClosureLiteralExpr(Expr *expr) {
61166122 return (isa<CaptureListExpr>(expr) || isa<ClosureExpr>(expr));
61176123}
61186124
6125+ // / Whether we should propagate async down to a closure.
6126+ static bool shouldPropagateAsyncToClosure (Expr *expr) {
6127+ if (auto IE = dyn_cast<IdentityExpr>(expr))
6128+ return shouldPropagateAsyncToClosure (IE->getSubExpr ());
6129+
6130+ if (auto CLE = dyn_cast<CaptureListExpr>(expr))
6131+ return shouldPropagateAsyncToClosure (CLE->getClosureBody ());
6132+
6133+ if (auto CE = dyn_cast<ClosureExpr>(expr))
6134+ return CE->inheritsActorContext ();
6135+
6136+ return false ;
6137+ }
6138+
61196139// / If the expression is an explicit closure expression (potentially wrapped in
61206140// / IdentityExprs), change the type of the closure and identities to the
61216141// / specified type and return true. Otherwise, return false with no effect.
@@ -6994,6 +7014,22 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
69947014 }
69957015 }
69967016
7017+ // If we have a ClosureExpr, then we can safely propagate the 'async'
7018+ // bit to the closure without invalidating prior analysis.
7019+ fromEI = fromFunc->getExtInfo ();
7020+ if (toEI.isAsync () && !fromEI.isAsync () &&
7021+ shouldPropagateAsyncToClosure (expr)) {
7022+ auto newFromFuncType = fromFunc->withExtInfo (fromEI.withAsync ());
7023+ if (applyTypeToClosureExpr (cs, expr, newFromFuncType)) {
7024+ fromFunc = newFromFuncType->castTo <FunctionType>();
7025+
7026+ // Propagating the 'concurrent' bit might have satisfied the entire
7027+ // conversion. If so, we're done, otherwise keep converting.
7028+ if (fromFunc->isEqual (toType))
7029+ return expr;
7030+ }
7031+ }
7032+
69977033 // If we have a ClosureExpr, then we can safely propagate a global actor
69987034 // to the closure without invalidating prior analysis.
69997035 fromEI = fromFunc->getExtInfo ();
0 commit comments