@@ -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*/ 
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