@@ -6120,13 +6120,14 @@ static bool isClosureLiteralExpr(Expr *expr) {
6120
6120
return (isa<CaptureListExpr>(expr) || isa<ClosureExpr>(expr));
6121
6121
}
6122
6122
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) {
6125
6126
if (auto IE = dyn_cast<IdentityExpr>(expr))
6126
- return shouldPropagateAsyncToClosure (IE->getSubExpr ());
6127
+ return closureInheritsActorContext (IE->getSubExpr ());
6127
6128
6128
6129
if (auto CLE = dyn_cast<CaptureListExpr>(expr))
6129
- return shouldPropagateAsyncToClosure (CLE->getClosureBody ());
6130
+ return closureInheritsActorContext (CLE->getClosureBody ());
6130
6131
6131
6132
if (auto CE = dyn_cast<ClosureExpr>(expr))
6132
6133
return CE->inheritsActorContext ();
@@ -7012,22 +7013,6 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
7012
7013
}
7013
7014
}
7014
7015
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
-
7031
7016
// If we have a ClosureExpr, then we can safely propagate a global actor
7032
7017
// to the closure without invalidating prior analysis.
7033
7018
fromEI = fromFunc->getExtInfo ();
@@ -7044,27 +7029,28 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
7044
7029
}
7045
7030
}
7046
7031
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 {
7049
7034
auto last = locator.last ();
7050
7035
if (!(last && last->is <LocatorPathElt::ApplyArgToParam>()))
7051
- return true ;
7036
+ return false ;
7052
7037
7053
- // The effect should not be applied if the closure is an argument
7054
- // to a function where that effect is polymorphic.
7055
7038
if (auto *call = getAsExpr<ApplyExpr>(locator.getAnchor ())) {
7056
7039
if (auto *declRef = dyn_cast<DeclRefExpr>(call->getFn ())) {
7057
7040
if (auto *fn = dyn_cast<AbstractFunctionDecl>(declRef->getDecl ()))
7058
- return ! fn->hasPolymorphicEffect (kind);
7041
+ return fn->hasPolymorphicEffect (kind);
7059
7042
}
7060
7043
}
7061
7044
7062
- return true ;
7045
+ return false ;
7063
7046
};
7064
7047
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.
7066
7050
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) {
7068
7054
auto newFromFuncType = fromFunc->withExtInfo (fromEI.withAsync ());
7069
7055
if (applyTypeToClosureExpr (cs, expr, newFromFuncType)) {
7070
7056
fromFunc = newFromFuncType->castTo <FunctionType>();
0 commit comments