@@ -2556,18 +2556,39 @@ namespace {
2556
2556
// / Build an implicit argument for keypath based dynamic lookup,
2557
2557
// / which consists of KeyPath expression and a single component.
2558
2558
// /
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.
2560
2561
// / \param dotLoc The location of the '.' preceding member name.
2561
2562
// / \param memberLoc The locator to be associated with new argument.
2562
- Expr *buildKeyPathDynamicMemberArgExpr (Type argType , SourceLoc dotLoc,
2563
+ Expr *buildKeyPathDynamicMemberArgExpr (Type paramType , SourceLoc dotLoc,
2563
2564
ConstraintLocator *memberLoc) {
2564
2565
using Component = KeyPathExpr::Component;
2565
2566
auto *anchor = getAsExpr (memberLoc->getAnchor ());
2566
2567
2567
2568
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
+
2568
2589
auto *kp = KeyPathExpr::createImplicit (ctx, /* backslashLoc*/ dotLoc,
2569
2590
components, anchor->getEndLoc ());
2570
- kp->setType (argType );
2591
+ kp->setType (keyPathTy );
2571
2592
cs.cacheExprTypes (kp);
2572
2593
2573
2594
// See whether there's an equivalent ObjC key path string we can produce
@@ -2576,7 +2597,7 @@ namespace {
2576
2597
return kp;
2577
2598
};
2578
2599
2579
- Type keyPathTy = argType ;
2600
+ Type keyPathTy = paramType ;
2580
2601
if (auto *existential = keyPathTy->getAs <ExistentialType>()) {
2581
2602
keyPathTy = existential->getSuperclass ();
2582
2603
assert (isKnownKeyPathType (keyPathTy));
@@ -3687,6 +3708,8 @@ namespace {
3687
3708
if (!argExpr)
3688
3709
return nullptr ;
3689
3710
3711
+ solution.recordSingleArgMatchingChoice (cs.getConstraintLocator (expr));
3712
+
3690
3713
// Build an argument list.
3691
3714
auto *argList =
3692
3715
ArgumentList::forImplicitSingle (ctx, ctx.Id_dynamicMember , argExpr);
0 commit comments