@@ -6120,13 +6120,14 @@ static bool isClosureLiteralExpr(Expr *expr) {
61206120 return (isa<CaptureListExpr>(expr) || isa<ClosureExpr>(expr));
61216121}
61226122
6123- // / Whether we should propagate async down to a closure.
6124- static bool shouldPropagateAsyncToClosure (Expr *expr) {
6123+ // / Whether the given expression is a closure that should inherit
6124+ // / the actor context from where it was formed.
6125+ static bool closureInheritsActorContext (Expr *expr) {
61256126 if (auto IE = dyn_cast<IdentityExpr>(expr))
6126- return shouldPropagateAsyncToClosure (IE->getSubExpr ());
6127+ return closureInheritsActorContext (IE->getSubExpr ());
61276128
61286129 if (auto CLE = dyn_cast<CaptureListExpr>(expr))
6129- return shouldPropagateAsyncToClosure (CLE->getClosureBody ());
6130+ return closureInheritsActorContext (CLE->getClosureBody ());
61306131
61316132 if (auto CE = dyn_cast<ClosureExpr>(expr))
61326133 return CE->inheritsActorContext ();
@@ -7012,22 +7013,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
70127013 }
70137014 }
70147015
7015- // If we have a ClosureExpr, then we can safely propagate the 'async'
7016- // bit to the closure without invalidating prior analysis.
7017- fromEI = fromFunc->getExtInfo ();
7018- if (toEI.isAsync () && !fromEI.isAsync () &&
7019- shouldPropagateAsyncToClosure (expr)) {
7020- auto newFromFuncType = fromFunc->withExtInfo (fromEI.withAsync ());
7021- if (applyTypeToClosureExpr (cs, expr, newFromFuncType)) {
7022- fromFunc = newFromFuncType->castTo <FunctionType>();
7023-
7024- // Propagating the 'concurrent' bit might have satisfied the entire
7025- // conversion. If so, we're done, otherwise keep converting.
7026- if (fromFunc->isEqual (toType))
7027- return expr;
7028- }
7029- }
7030-
70317016 // If we have a ClosureExpr, then we can safely propagate a global actor
70327017 // to the closure without invalidating prior analysis.
70337018 fromEI = fromFunc->getExtInfo ();
@@ -7044,27 +7029,28 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
70447029 }
70457030 }
70467031
7047- // / Whether the given effect should be propagated to a closure expression .
7048- auto shouldApplyEffect = [&](EffectKind kind) -> bool {
7032+ // / Whether the given effect is polymorphic at this location .
7033+ auto isEffectPolymorphic = [&](EffectKind kind) -> bool {
70497034 auto last = locator.last ();
70507035 if (!(last && last->is <LocatorPathElt::ApplyArgToParam>()))
7051- return true ;
7036+ return false ;
70527037
7053- // The effect should not be applied if the closure is an argument
7054- // to a function where that effect is polymorphic.
70557038 if (auto *call = getAsExpr<ApplyExpr>(locator.getAnchor ())) {
70567039 if (auto *declRef = dyn_cast<DeclRefExpr>(call->getFn ())) {
70577040 if (auto *fn = dyn_cast<AbstractFunctionDecl>(declRef->getDecl ()))
7058- return ! fn->hasPolymorphicEffect (kind);
7041+ return fn->hasPolymorphicEffect (kind);
70597042 }
70607043 }
70617044
7062- return true ;
7045+ return false ;
70637046 };
70647047
7065- // If we have a ClosureExpr, we can safely propagate 'async' to the closure.
7048+ // If we have a ClosureExpr, and we can safely propagate 'async' to the
7049+ // closure, do that here.
70667050 fromEI = fromFunc->getExtInfo ();
7067- if (toEI.isAsync () && !fromEI.isAsync () && shouldApplyEffect (EffectKind::Async)) {
7051+ bool shouldPropagateAsync =
7052+ !isEffectPolymorphic (EffectKind::Async) || closureInheritsActorContext (expr);
7053+ if (toEI.isAsync () && !fromEI.isAsync () && shouldPropagateAsync) {
70687054 auto newFromFuncType = fromFunc->withExtInfo (fromEI.withAsync ());
70697055 if (applyTypeToClosureExpr (cs, expr, newFromFuncType)) {
70707056 fromFunc = newFromFuncType->castTo <FunctionType>();
0 commit comments