|
58 | 58 | using namespace swift; |
59 | 59 | using namespace constraints; |
60 | 60 |
|
| 61 | +static bool isClosureLiteralExpr(Expr *expr) { |
| 62 | + expr = expr->getSemanticsProvidingExpr(); |
| 63 | + return (isa<CaptureListExpr>(expr) || isa<ClosureExpr>(expr)); |
| 64 | +} |
| 65 | + |
61 | 66 | bool Solution::hasFixedType(TypeVariableType *typeVar) const { |
62 | 67 | auto knownBinding = typeBindings.find(typeVar); |
63 | 68 | return knownBinding != typeBindings.end(); |
@@ -5963,24 +5968,29 @@ static bool hasCurriedSelf(ConstraintSystem &cs, ConcreteDeclRef callee, |
5963 | 5968 | /// Apply the contextually Sendable flag to the given expression, |
5964 | 5969 | static void applyContextualClosureFlags(Expr *expr, bool implicitSelfCapture, |
5965 | 5970 | bool inheritActorContext, |
5966 | | - bool isPassedToSendingParameter) { |
| 5971 | + bool isPassedToSendingParameter, |
| 5972 | + bool requiresDynamicIsolationChecking) { |
5967 | 5973 | if (auto closure = dyn_cast<ClosureExpr>(expr)) { |
5968 | 5974 | closure->setAllowsImplicitSelfCapture(implicitSelfCapture); |
5969 | 5975 | closure->setInheritsActorContext(inheritActorContext); |
5970 | 5976 | closure->setIsPassedToSendingParameter(isPassedToSendingParameter); |
| 5977 | + closure->setRequiresDynamicIsolationChecking( |
| 5978 | + requiresDynamicIsolationChecking); |
5971 | 5979 | return; |
5972 | 5980 | } |
5973 | 5981 |
|
5974 | 5982 | if (auto captureList = dyn_cast<CaptureListExpr>(expr)) { |
5975 | 5983 | applyContextualClosureFlags(captureList->getClosureBody(), |
5976 | 5984 | implicitSelfCapture, inheritActorContext, |
5977 | | - isPassedToSendingParameter); |
| 5985 | + isPassedToSendingParameter, |
| 5986 | + requiresDynamicIsolationChecking); |
5978 | 5987 | } |
5979 | 5988 |
|
5980 | 5989 | if (auto identity = dyn_cast<IdentityExpr>(expr)) { |
5981 | 5990 | applyContextualClosureFlags(identity->getSubExpr(), implicitSelfCapture, |
5982 | 5991 | inheritActorContext, |
5983 | | - isPassedToSendingParameter); |
| 5992 | + isPassedToSendingParameter, |
| 5993 | + requiresDynamicIsolationChecking); |
5984 | 5994 | } |
5985 | 5995 | } |
5986 | 5996 |
|
@@ -6084,14 +6094,40 @@ ArgumentList *ExprRewriter::coerceCallArguments( |
6084 | 6094 | return placeholder; |
6085 | 6095 | }; |
6086 | 6096 |
|
6087 | | - auto applyFlagsToArgument = [¶mInfo](unsigned paramIdx, Expr *argument) { |
| 6097 | + bool closuresRequireDynamicIsolationChecking = [&]() { |
| 6098 | + auto *decl = callee.getDecl(); |
| 6099 | + // If this is something like `{ @MainActor in ... }()`, let's consider |
| 6100 | + // callee as concurrency checked. |
| 6101 | + if (!decl) |
| 6102 | + return false; |
| 6103 | + |
| 6104 | + if (auto declaredIn = decl->findImport(dc)) |
| 6105 | + return !declaredIn->module.importedModule->isConcurrencyChecked(); |
| 6106 | + |
| 6107 | + // Both the caller and the allee are in the same module. |
| 6108 | + if (dc->getParentModule() == decl->getModuleContext()) { |
| 6109 | + return !dc->getASTContext().isSwiftVersionAtLeast(6); |
| 6110 | + } |
| 6111 | + |
| 6112 | + // If we cannot figure out where the callee came from, let's conservatively |
| 6113 | + // assume that closure arguments require dynamic isolation checks. |
| 6114 | + return true; |
| 6115 | + }(); |
| 6116 | + |
| 6117 | + auto applyFlagsToArgument = [¶mInfo, |
| 6118 | + &closuresRequireDynamicIsolationChecking]( |
| 6119 | + unsigned paramIdx, Expr *argument) { |
| 6120 | + if (!isClosureLiteralExpr(argument)) |
| 6121 | + return; |
| 6122 | + |
6088 | 6123 | bool isImplicitSelfCapture = paramInfo.isImplicitSelfCapture(paramIdx); |
6089 | 6124 | bool inheritsActorContext = paramInfo.inheritsActorContext(paramIdx); |
6090 | 6125 | bool isPassedToSendingParameter = paramInfo.isSendingParameter(paramIdx); |
6091 | 6126 |
|
6092 | 6127 | applyContextualClosureFlags(argument, isImplicitSelfCapture, |
6093 | 6128 | inheritsActorContext, |
6094 | | - isPassedToSendingParameter); |
| 6129 | + isPassedToSendingParameter, |
| 6130 | + closuresRequireDynamicIsolationChecking); |
6095 | 6131 | }; |
6096 | 6132 |
|
6097 | 6133 | // Quickly test if any further fix-ups for the argument types are necessary. |
@@ -6363,11 +6399,6 @@ ArgumentList *ExprRewriter::coerceCallArguments( |
6363 | 6399 | return ArgumentList::createTypeChecked(ctx, args, newArgs); |
6364 | 6400 | } |
6365 | 6401 |
|
6366 | | -static bool isClosureLiteralExpr(Expr *expr) { |
6367 | | - expr = expr->getSemanticsProvidingExpr(); |
6368 | | - return (isa<CaptureListExpr>(expr) || isa<ClosureExpr>(expr)); |
6369 | | -} |
6370 | | - |
6371 | 6402 | /// Whether the given expression is a closure that should inherit |
6372 | 6403 | /// the actor context from where it was formed. |
6373 | 6404 | static bool closureInheritsActorContext(Expr *expr) { |
|
0 commit comments