@@ -3537,6 +3537,10 @@ static bool hasDynamicMemberLookupAttribute(Type type,
35373537 return result;
35383538}
35393539
3540+ static bool isKeyPathDynamicMemberLookup (ConstraintLocator *locator) {
3541+ auto path = locator ? locator->getPath () : None;
3542+ return !path.empty () && path.back ().isKeyPathDynamicMember ();
3543+ }
35403544
35413545// / Given a ValueMember, UnresolvedValueMember, or TypeMember constraint,
35423546// / perform a lookup into the specified base type to find a candidate list.
@@ -3568,10 +3572,15 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
35683572 // Okay, start building up the result list.
35693573 MemberLookupResult result;
35703574 result.OverallResult = MemberLookupResult::HasResults;
3571-
3575+
35723576 // If we're looking for a subscript, consider key path operations.
3577+ //
3578+ // TODO: This logic needs to be refactored to make sure that implicit
3579+ // keypath result is only introduced when it makes sense e.g. if there
3580+ // is a single argument with `keypath:` label or `\.` syntax is used.
35733581 if (memberName.isSimpleName () &&
3574- memberName.getBaseName ().getKind () == DeclBaseName::Kind::Subscript) {
3582+ memberName.getBaseName ().getKind () == DeclBaseName::Kind::Subscript &&
3583+ !isKeyPathDynamicMemberLookup (memberLocator)) {
35753584 result.ViableCandidates .push_back (
35763585 OverloadChoice (baseTy, OverloadChoiceKind::KeyPathApplication));
35773586 }
@@ -3831,20 +3840,18 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
38313840 // based dynamic member lookup. Since it's unknown upfront
38323841 // what kind of declaration lookup is going to find, let's
38333842 // double check here that given keypath is appropriate for it.
3834- if (memberLocator) {
3843+ if (isKeyPathDynamicMemberLookup ( memberLocator) ) {
38353844 auto path = memberLocator->getPath ();
3836- if (!path.empty () && path.back ().isKeyPathDynamicMember ()) {
3837- auto *keyPath = path.back ().getKeyPath ();
3838- if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
3839- // If this is an attempt to access read-only member via
3840- // writable key path, let's fail this choice early.
3841- if (isReadOnlyKeyPathComponent (storage) &&
3842- keyPath == getASTContext ().getWritableKeyPathDecl ()) {
3843- result.addUnviable (
3844- candidate,
3845- MemberLookupResult::UR_WritableKeyPathOnReadOnlyMember);
3846- return ;
3847- }
3845+ auto *keyPath = path.back ().getKeyPath ();
3846+ if (auto *storage = dyn_cast<AbstractStorageDecl>(decl)) {
3847+ // If this is an attempt to access read-only member via
3848+ // writable key path, let's fail this choice early.
3849+ if (isReadOnlyKeyPathComponent (storage) &&
3850+ keyPath == getASTContext ().getWritableKeyPathDecl ()) {
3851+ result.addUnviable (
3852+ candidate,
3853+ MemberLookupResult::UR_WritableKeyPathOnReadOnlyMember);
3854+ return ;
38483855 }
38493856 }
38503857 }
0 commit comments