@@ -6729,22 +6729,6 @@ ConstraintSystem::simplifyKeyPathConstraint(
6729
6729
// The constraint ought to have been anchored on a KeyPathExpr.
6730
6730
auto keyPath = cast<KeyPathExpr>(locator.getBaseLocator ()->getAnchor ());
6731
6731
6732
- // Gather overload choices for any key path components associated with this
6733
- // key path.
6734
- SmallVector<OverloadChoice, 4 > choices;
6735
- choices.resize (keyPath->getComponents ().size ());
6736
- for (auto resolvedItem = resolvedOverloadSets; resolvedItem;
6737
- resolvedItem = resolvedItem->Previous ) {
6738
- auto locator = resolvedItem->Locator ;
6739
- auto path = locator->getPath ();
6740
- if (locator->getAnchor () != keyPath || path.size () > 2 )
6741
- continue ;
6742
-
6743
- if (auto kpElt = path[0 ].getAs <LocatorPathElt::KeyPathComponent>()) {
6744
- choices[kpElt->getIndex ()] = resolvedItem->Choice ;
6745
- }
6746
- }
6747
-
6748
6732
keyPathTy = getFixedTypeRecursive (keyPathTy, /* want rvalue*/ true );
6749
6733
bool definitelyFunctionType = false ;
6750
6734
bool definitelyKeyPathType = false ;
@@ -6806,6 +6790,30 @@ ConstraintSystem::simplifyKeyPathConstraint(
6806
6790
return SolutionKind::Error;
6807
6791
}
6808
6792
6793
+ // First gather the callee locators for the individual components.
6794
+ SmallVector<std::pair<ConstraintLocator *, OverloadChoice>, 4 > choices;
6795
+ for (unsigned i : indices (keyPath->getComponents ())) {
6796
+ auto *componentLoc = getConstraintLocator (
6797
+ locator.withPathElement (LocatorPathElt::KeyPathComponent (i)));
6798
+ auto *calleeLoc = getCalleeLocator (componentLoc);
6799
+ choices.push_back ({calleeLoc, OverloadChoice ()});
6800
+ }
6801
+
6802
+ // Then search for the resolved overloads.
6803
+ for (auto resolvedItem = resolvedOverloadSets; resolvedItem;
6804
+ resolvedItem = resolvedItem->Previous ) {
6805
+ auto locator = resolvedItem->Locator ;
6806
+ auto kpElt = locator->getFirstElementAs <LocatorPathElt::KeyPathComponent>();
6807
+ if (!kpElt || locator->getAnchor () != keyPath)
6808
+ continue ;
6809
+
6810
+ auto &choice = choices[kpElt->getIndex ()];
6811
+ if (choice.first == locator) {
6812
+ assert (choice.second .isInvalid () && " Resolved same component twice?" );
6813
+ choice.second = resolvedItem->Choice ;
6814
+ }
6815
+ }
6816
+
6809
6817
// See if we resolved overloads for all the components involved.
6810
6818
enum {
6811
6819
ReadOnly,
@@ -6827,12 +6835,15 @@ ConstraintSystem::simplifyKeyPathConstraint(
6827
6835
case KeyPathExpr::Component::Kind::Subscript:
6828
6836
case KeyPathExpr::Component::Kind::UnresolvedProperty:
6829
6837
case KeyPathExpr::Component::Kind::UnresolvedSubscript: {
6838
+ auto *calleeLoc = choices[i].first ;
6839
+ auto choice = choices[i].second ;
6840
+
6830
6841
// If no choice was made, leave the constraint unsolved. But when
6831
6842
// generating constraints, we may already have enough information
6832
6843
// to determine whether the result will be a function type vs BGT KeyPath
6833
6844
// type, so continue through components to create new constraint at the
6834
6845
// end.
6835
- if (choices[i] .isInvalid () || anyComponentsUnresolved) {
6846
+ if (choice .isInvalid () || anyComponentsUnresolved) {
6836
6847
if (flags.contains (TMF_GenerateConstraints)) {
6837
6848
anyComponentsUnresolved = true ;
6838
6849
continue ;
@@ -6864,23 +6875,20 @@ ConstraintSystem::simplifyKeyPathConstraint(
6864
6875
}
6865
6876
6866
6877
// tuple elements do not change the capability of the key path
6867
- if (choices[i] .getKind () == OverloadChoiceKind::TupleIndex) {
6878
+ if (choice .getKind () == OverloadChoiceKind::TupleIndex) {
6868
6879
continue ;
6869
6880
}
6870
6881
6871
6882
// Discarded unsupported non-decl member lookups.
6872
- if (!choices[i] .isDecl ()) {
6883
+ if (!choice .isDecl ()) {
6873
6884
return SolutionKind::Error;
6874
6885
}
6875
6886
6876
- auto storage = dyn_cast<AbstractStorageDecl>(choices[i].getDecl ());
6877
-
6878
- auto *componentLoc = getConstraintLocator (
6879
- locator.withPathElement (LocatorPathElt::KeyPathComponent (i)));
6887
+ auto storage = dyn_cast<AbstractStorageDecl>(choice.getDecl ());
6880
6888
6881
6889
if (auto *fix = AllowInvalidRefInKeyPath::forRef (
6882
- *this , choices[i] .getDecl (), componentLoc )) {
6883
- if (!hasFixFor (componentLoc , FixKind::AllowTypeOrInstanceMember))
6890
+ *this , choice .getDecl (), calleeLoc )) {
6891
+ if (!hasFixFor (calleeLoc , FixKind::AllowTypeOrInstanceMember))
6884
6892
if (!shouldAttemptFixes () || recordFix (fix))
6885
6893
return SolutionKind::Error;
6886
6894
0 commit comments