@@ -5724,6 +5724,12 @@ static void applyContextualClosureFlags(
5724
5724
captureList->getClosureBody (), sendable, forMainActor,
5725
5725
implicitSelfCapture, inheritActorContext);
5726
5726
}
5727
+
5728
+ if (auto identity = dyn_cast<IdentityExpr>(expr)) {
5729
+ applyContextualClosureFlags (
5730
+ identity->getSubExpr (), sendable, forMainActor,
5731
+ implicitSelfCapture, inheritActorContext);
5732
+ }
5727
5733
}
5728
5734
5729
5735
// / Whether this is a reference to a method on the main dispatch queue.
@@ -6116,6 +6122,20 @@ static bool isClosureLiteralExpr(Expr *expr) {
6116
6122
return (isa<CaptureListExpr>(expr) || isa<ClosureExpr>(expr));
6117
6123
}
6118
6124
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
+
6119
6139
// / If the expression is an explicit closure expression (potentially wrapped in
6120
6140
// / IdentityExprs), change the type of the closure and identities to the
6121
6141
// / specified type and return true. Otherwise, return false with no effect.
@@ -6994,6 +7014,22 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
6994
7014
}
6995
7015
}
6996
7016
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
+
6997
7033
// If we have a ClosureExpr, then we can safely propagate a global actor
6998
7034
// to the closure without invalidating prior analysis.
6999
7035
fromEI = fromFunc->getExtInfo ();
0 commit comments