@@ -3537,6 +3537,10 @@ static bool hasDynamicMemberLookupAttribute(Type type,
3537
3537
return result;
3538
3538
}
3539
3539
3540
+ static bool isKeyPathDynamicMemberLookup (ConstraintLocator *locator) {
3541
+ auto path = locator ? locator->getPath () : None;
3542
+ return !path.empty () && path.back ().isKeyPathDynamicMember ();
3543
+ }
3540
3544
3541
3545
// / Given a ValueMember, UnresolvedValueMember, or TypeMember constraint,
3542
3546
// / perform a lookup into the specified base type to find a candidate list.
@@ -3568,10 +3572,15 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3568
3572
// Okay, start building up the result list.
3569
3573
MemberLookupResult result;
3570
3574
result.OverallResult = MemberLookupResult::HasResults;
3571
-
3575
+
3572
3576
// 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.
3573
3581
if (memberName.isSimpleName () &&
3574
- memberName.getBaseName ().getKind () == DeclBaseName::Kind::Subscript) {
3582
+ memberName.getBaseName ().getKind () == DeclBaseName::Kind::Subscript &&
3583
+ !isKeyPathDynamicMemberLookup (memberLocator)) {
3575
3584
result.ViableCandidates .push_back (
3576
3585
OverloadChoice (baseTy, OverloadChoiceKind::KeyPathApplication));
3577
3586
}
@@ -3831,20 +3840,18 @@ performMemberLookup(ConstraintKind constraintKind, DeclName memberName,
3831
3840
// based dynamic member lookup. Since it's unknown upfront
3832
3841
// what kind of declaration lookup is going to find, let's
3833
3842
// double check here that given keypath is appropriate for it.
3834
- if (memberLocator) {
3843
+ if (isKeyPathDynamicMemberLookup ( memberLocator) ) {
3835
3844
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 ;
3848
3855
}
3849
3856
}
3850
3857
}
0 commit comments