Skip to content

Commit 56265a2

Browse files
authored
[CS] Resolve callees for key path dynamic members (swiftlang#28807)
[CS] Resolve callees for key path dynamic members
2 parents c89d6ad + cefc03f commit 56265a2

File tree

3 files changed

+55
-6
lines changed

3 files changed

+55
-6
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -788,9 +788,7 @@ getCalleeDeclAndArgs(ConstraintSystem &cs,
788788

789789
// Our remaining path can only be 'ApplyArgument'.
790790
auto path = callLocator->getPath();
791-
if (!path.empty() &&
792-
!(path.size() <= 2 &&
793-
path.back().getKind() == ConstraintLocator::ApplyArgument))
791+
if (!path.empty() && !path.back().is<LocatorPathElt::ApplyArgument>())
794792
return formUnknownCallee();
795793

796794
// Dig out the callee information.

lib/Sema/ConstraintSystem.cpp

Lines changed: 28 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -438,6 +438,18 @@ ConstraintSystem::getCalleeLocator(ConstraintLocator *locator,
438438
auto *anchor = locator->getAnchor();
439439
assert(anchor && "Expected an anchor!");
440440

441+
auto path = locator->getPath();
442+
{
443+
// If we have a locator for a member found through key path dynamic member
444+
// lookup, then we need to chop off the elements after the
445+
// KeyPathDynamicMember element to get the callee locator.
446+
auto iter = path.rbegin();
447+
if (locator->findLast<LocatorPathElt::KeyPathDynamicMember>(iter)) {
448+
auto newPath = path.drop_back(iter - path.rbegin());
449+
return getConstraintLocator(anchor, newPath);
450+
}
451+
}
452+
441453
// If we have a locator that starts with a key path component element, we
442454
// may have a callee given by a property or subscript component.
443455
if (auto componentElt =
@@ -2152,8 +2164,10 @@ void ConstraintSystem::bindOverloadType(
21522164
auto adjustedFnTy =
21532165
FunctionType::get(fnType->getParams(), subscriptResultTy);
21542166

2155-
addConstraint(ConstraintKind::ApplicableFunction, adjustedFnTy, memberTy,
2156-
applicableFn->getLocator());
2167+
ConstraintLocatorBuilder kpLocBuilder(keyPathLoc);
2168+
addConstraint(
2169+
ConstraintKind::ApplicableFunction, adjustedFnTy, memberTy,
2170+
kpLocBuilder.withPathElement(ConstraintLocator::ApplyFunction));
21572171

21582172
addConstraint(ConstraintKind::Bind, dynamicResultTy, fnType->getResult(),
21592173
keyPathLoc);
@@ -3424,6 +3438,18 @@ ConstraintSystem::getArgumentInfoLocator(ConstraintLocator *locator) {
34243438
if (auto *UME = dyn_cast<UnresolvedMemberExpr>(anchor))
34253439
return getConstraintLocator(UME);
34263440

3441+
auto path = locator->getPath();
3442+
{
3443+
// If this is for a dynamic member reference, the argument info is for the
3444+
// original call-site, which we can get by stripping away the
3445+
// KeyPathDynamicMember elements.
3446+
auto iter = path.begin();
3447+
if (locator->findFirst<LocatorPathElt::KeyPathDynamicMember>(iter)) {
3448+
ArrayRef<LocatorPathElt> newPath(path.begin(), iter);
3449+
return getConstraintLocator(anchor, newPath);
3450+
}
3451+
}
3452+
34273453
return getCalleeLocator(locator);
34283454
}
34293455

test/Constraints/keypath_dynamic_member_lookup.swift

Lines changed: 26 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -439,7 +439,6 @@ struct SR_11896_Immutable {
439439
}
440440
}
441441

442-
443442
// CHECK-LABEL: sil hidden @$s29keypath_dynamic_member_lookup21testKeyPathMutabilityyyF : $@convention(thin) () -> ()
444443
func testKeyPathMutability() {
445444
// CHECK: keypath $KeyPath<SR_11896_Base, Int>, (root $SR_11896_Base; stored_property #SR_11896_Base.mutable : $Int)
@@ -458,3 +457,29 @@ func testKeyPathMutability() {
458457
// CHECK: keypath $KeyPath<SR_11896_Immutable, Int>, (root $SR_11896_Immutable; gettable_property $Int
459458
_ = \SR_11896_Immutable.immutable
460459
}
460+
461+
// SR-11933: Make sure we properly handle default arguments.
462+
struct HasDefaultedSubscript {
463+
subscript(_ x: Int = 0) -> Int { x }
464+
}
465+
466+
@dynamicMemberLookup
467+
struct SR_11933 {
468+
subscript(dynamicMember kp: KeyPath<HasDefaultedSubscript, Int>) -> Int { 0 }
469+
}
470+
471+
// CHECK-LABEL: sil hidden @$s29keypath_dynamic_member_lookup28testDynamicMemberWithDefaultyyAA8SR_11933VF : $@convention(thin) (SR_11933) -> ()
472+
func testDynamicMemberWithDefault(_ x: SR_11933) {
473+
// CHECK: [[DEF_FN:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipfA_ : $@convention(thin) () -> Int
474+
// CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_FN]]()
475+
// CHECK: [[KP:%[0-9]+]] = keypath $KeyPath<HasDefaultedSubscript, Int>, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(thin) (@in_guaranteed HasDefaultedSubscript, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[DEF_ARG]])
476+
// CHECK: [[SUB_GET:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath<HasDefaultedSubscript, Int>, SR_11933) -> Int
477+
// CHECK: apply [[SUB_GET]]([[KP]], {{%[0-9]+}})
478+
_ = x[]
479+
480+
// CHECK: [[DEF_FN:%[0-9]+]] = function_ref @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipfA_ : $@convention(thin) () -> Int
481+
// CHECK: [[DEF_ARG:%[0-9]+]] = apply [[DEF_FN]]()
482+
// CHECK: [[INNER_KP:%[0-9]+]] = keypath $KeyPath<HasDefaultedSubscript, Int>, (root $HasDefaultedSubscript; gettable_property $Int, id @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icig : $@convention(method) (Int, HasDefaultedSubscript) -> Int, getter @$s29keypath_dynamic_member_lookup21HasDefaultedSubscriptVyS2icipACTK : $@convention(thin) (@in_guaranteed HasDefaultedSubscript, UnsafeRawPointer) -> @out Int, indices [%$0 : $Int : $Int], indices_equals @$sSiTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$sSiTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[DEF_ARG]])
483+
// CHECK: [[OUTER_KP:%[0-9]+]] = keypath $KeyPath<SR_11933, Int>, (root $SR_11933; gettable_property $Int, id @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcig : $@convention(method) (@guaranteed KeyPath<HasDefaultedSubscript, Int>, SR_11933) -> Int, getter @$s29keypath_dynamic_member_lookup8SR_11933V0B6MemberSis7KeyPathCyAA21HasDefaultedSubscriptVSiG_tcipACTK : $@convention(thin) (@in_guaranteed SR_11933, UnsafeRawPointer) -> @out Int, indices [%$0 : $KeyPath<HasDefaultedSubscript, Int> : $KeyPath<HasDefaultedSubscript, Int>], indices_equals @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTH : $@convention(thin) (UnsafeRawPointer, UnsafeRawPointer) -> Bool, indices_hash @$ss7KeyPathCy29keypath_dynamic_member_lookup21HasDefaultedSubscriptVSiGTh : $@convention(thin) (UnsafeRawPointer) -> Int) ([[INNER_KP]])
484+
_ = \SR_11933.[]
485+
}

0 commit comments

Comments
 (0)