@@ -2556,18 +2556,39 @@ namespace {
25562556 // / Build an implicit argument for keypath based dynamic lookup,
25572557 // / which consists of KeyPath expression and a single component.
25582558 // /
2559- // / \param argType The type of the keypath subscript argument.
2559+ // / \param paramType The type of the keypath subscript parameter
2560+ // / this argument is passed to.
25602561 // / \param dotLoc The location of the '.' preceding member name.
25612562 // / \param memberLoc The locator to be associated with new argument.
2562- Expr *buildKeyPathDynamicMemberArgExpr (Type argType , SourceLoc dotLoc,
2563+ Expr *buildKeyPathDynamicMemberArgExpr (Type paramType , SourceLoc dotLoc,
25632564 ConstraintLocator *memberLoc) {
25642565 using Component = KeyPathExpr::Component;
25652566 auto *anchor = getAsExpr (memberLoc->getAnchor ());
25662567
25672568 auto makeKeyPath = [&](ArrayRef<Component> components) -> Expr * {
2569+ Type keyPathTy = paramType;
2570+
2571+ // If parameter of a dynamic member lookup is `& Sendable` type
2572+ // we need to check key path captures to determine whether the
2573+ // argument could be `& Sendable` as well or not.
2574+ if (paramType->isExistentialType () && paramType->isSendableType ()) {
2575+ auto allCapturesAreSendable = [&](const Component &component) {
2576+ auto *argList = component.getArgs ();
2577+ if (!argList)
2578+ return true ;
2579+
2580+ return llvm::all_of (*argList, [&](const auto &arg) {
2581+ return solution.getResolvedType (arg.getExpr ())->isSendableType ();
2582+ });
2583+ };
2584+
2585+ if (!llvm::all_of (components, allCapturesAreSendable))
2586+ keyPathTy = paramType->getSuperclass ();
2587+ }
2588+
25682589 auto *kp = KeyPathExpr::createImplicit (ctx, /* backslashLoc*/ dotLoc,
25692590 components, anchor->getEndLoc ());
2570- kp->setType (argType );
2591+ kp->setType (keyPathTy );
25712592 cs.cacheExprTypes (kp);
25722593
25732594 // See whether there's an equivalent ObjC key path string we can produce
@@ -2576,7 +2597,7 @@ namespace {
25762597 return kp;
25772598 };
25782599
2579- Type keyPathTy = argType ;
2600+ Type keyPathTy = paramType ;
25802601 if (auto *existential = keyPathTy->getAs <ExistentialType>()) {
25812602 keyPathTy = existential->getSuperclass ();
25822603 assert (isKnownKeyPathType (keyPathTy));
@@ -3687,6 +3708,8 @@ namespace {
36873708 if (!argExpr)
36883709 return nullptr ;
36893710
3711+ solution.recordSingleArgMatchingChoice (cs.getConstraintLocator (expr));
3712+
36903713 // Build an argument list.
36913714 auto *argList =
36923715 ArgumentList::forImplicitSingle (ctx, ctx.Id_dynamicMember , argExpr);
0 commit comments