@@ -5726,6 +5726,12 @@ static void applyContextualClosureFlags(
5726
5726
captureList->getClosureBody (), sendable, forMainActor,
5727
5727
implicitSelfCapture, inheritActorContext);
5728
5728
}
5729
+
5730
+ if (auto identity = dyn_cast<IdentityExpr>(expr)) {
5731
+ applyContextualClosureFlags (
5732
+ identity->getSubExpr (), sendable, forMainActor,
5733
+ implicitSelfCapture, inheritActorContext);
5734
+ }
5729
5735
}
5730
5736
5731
5737
// / Whether this is a reference to a method on the main dispatch queue.
@@ -6141,6 +6147,20 @@ static bool isClosureLiteralExpr(Expr *expr) {
6141
6147
return (isa<CaptureListExpr>(expr) || isa<ClosureExpr>(expr));
6142
6148
}
6143
6149
6150
+ // / Whether we should propagate async down to a closure.
6151
+ static bool shouldPropagateAsyncToClosure (Expr *expr) {
6152
+ if (auto IE = dyn_cast<IdentityExpr>(expr))
6153
+ return shouldPropagateAsyncToClosure (IE->getSubExpr ());
6154
+
6155
+ if (auto CLE = dyn_cast<CaptureListExpr>(expr))
6156
+ return shouldPropagateAsyncToClosure (CLE->getClosureBody ());
6157
+
6158
+ if (auto CE = dyn_cast<ClosureExpr>(expr))
6159
+ return CE->inheritsActorContext ();
6160
+
6161
+ return false ;
6162
+ }
6163
+
6144
6164
// / If the expression is an explicit closure expression (potentially wrapped in
6145
6165
// / IdentityExprs), change the type of the closure and identities to the
6146
6166
// / specified type and return true. Otherwise, return false with no effect.
@@ -7020,6 +7040,22 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
7020
7040
}
7021
7041
}
7022
7042
7043
+ // If we have a ClosureExpr, then we can safely propagate the 'async'
7044
+ // bit to the closure without invalidating prior analysis.
7045
+ fromEI = fromFunc->getExtInfo ();
7046
+ if (toEI.isAsync () && !fromEI.isAsync () &&
7047
+ shouldPropagateAsyncToClosure (expr)) {
7048
+ auto newFromFuncType = fromFunc->withExtInfo (fromEI.withAsync ());
7049
+ if (applyTypeToClosureExpr (cs, expr, newFromFuncType)) {
7050
+ fromFunc = newFromFuncType->castTo <FunctionType>();
7051
+
7052
+ // Propagating the 'concurrent' bit might have satisfied the entire
7053
+ // conversion. If so, we're done, otherwise keep converting.
7054
+ if (fromFunc->isEqual (toType))
7055
+ return expr;
7056
+ }
7057
+ }
7058
+
7023
7059
// If we have a ClosureExpr, then we can safely propagate a global actor
7024
7060
// to the closure without invalidating prior analysis.
7025
7061
fromEI = fromFunc->getExtInfo ();
0 commit comments