|
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