@@ -6802,22 +6802,6 @@ ConstraintSystem::simplifyKeyPathConstraint(
6802
6802
// The constraint ought to have been anchored on a KeyPathExpr.
6803
6803
auto keyPath = cast<KeyPathExpr>(locator.getBaseLocator ()->getAnchor ());
6804
6804
6805
- // Gather overload choices for any key path components associated with this
6806
- // key path.
6807
- SmallVector<OverloadChoice, 4 > choices;
6808
- choices.resize (keyPath->getComponents ().size ());
6809
- for (auto resolvedItem = resolvedOverloadSets; resolvedItem;
6810
- resolvedItem = resolvedItem->Previous ) {
6811
- auto locator = resolvedItem->Locator ;
6812
- auto path = locator->getPath ();
6813
- if (locator->getAnchor () != keyPath || path.size () > 2 )
6814
- continue ;
6815
-
6816
- if (auto kpElt = path[0 ].getAs <LocatorPathElt::KeyPathComponent>()) {
6817
- choices[kpElt->getIndex ()] = resolvedItem->Choice ;
6818
- }
6819
- }
6820
-
6821
6805
keyPathTy = getFixedTypeRecursive (keyPathTy, /* want rvalue*/ true );
6822
6806
bool definitelyFunctionType = false ;
6823
6807
bool definitelyKeyPathType = false ;
@@ -6879,6 +6863,30 @@ ConstraintSystem::simplifyKeyPathConstraint(
6879
6863
return SolutionKind::Error;
6880
6864
}
6881
6865
6866
+ // First gather the callee locators for the individual components.
6867
+ SmallVector<std::pair<ConstraintLocator *, OverloadChoice>, 4 > choices;
6868
+ for (unsigned i : indices (keyPath->getComponents ())) {
6869
+ auto *componentLoc = getConstraintLocator (
6870
+ locator.withPathElement (LocatorPathElt::KeyPathComponent (i)));
6871
+ auto *calleeLoc = getCalleeLocator (componentLoc);
6872
+ choices.push_back ({calleeLoc, OverloadChoice ()});
6873
+ }
6874
+
6875
+ // Then search for the resolved overloads.
6876
+ for (auto resolvedItem = resolvedOverloadSets; resolvedItem;
6877
+ resolvedItem = resolvedItem->Previous ) {
6878
+ auto locator = resolvedItem->Locator ;
6879
+ auto kpElt = locator->getFirstElementAs <LocatorPathElt::KeyPathComponent>();
6880
+ if (!kpElt || locator->getAnchor () != keyPath)
6881
+ continue ;
6882
+
6883
+ auto &choice = choices[kpElt->getIndex ()];
6884
+ if (choice.first == locator) {
6885
+ assert (choice.second .isInvalid () && " Resolved same component twice?" );
6886
+ choice.second = resolvedItem->Choice ;
6887
+ }
6888
+ }
6889
+
6882
6890
// See if we resolved overloads for all the components involved.
6883
6891
enum {
6884
6892
ReadOnly,
@@ -6900,12 +6908,15 @@ ConstraintSystem::simplifyKeyPathConstraint(
6900
6908
case KeyPathExpr::Component::Kind::Subscript:
6901
6909
case KeyPathExpr::Component::Kind::UnresolvedProperty:
6902
6910
case KeyPathExpr::Component::Kind::UnresolvedSubscript: {
6911
+ auto *calleeLoc = choices[i].first ;
6912
+ auto choice = choices[i].second ;
6913
+
6903
6914
// If no choice was made, leave the constraint unsolved. But when
6904
6915
// generating constraints, we may already have enough information
6905
6916
// to determine whether the result will be a function type vs BGT KeyPath
6906
6917
// type, so continue through components to create new constraint at the
6907
6918
// end.
6908
- if (choices[i] .isInvalid () || anyComponentsUnresolved) {
6919
+ if (choice .isInvalid () || anyComponentsUnresolved) {
6909
6920
if (flags.contains (TMF_GenerateConstraints)) {
6910
6921
anyComponentsUnresolved = true ;
6911
6922
continue ;
@@ -6937,23 +6948,20 @@ ConstraintSystem::simplifyKeyPathConstraint(
6937
6948
}
6938
6949
6939
6950
// tuple elements do not change the capability of the key path
6940
- if (choices[i] .getKind () == OverloadChoiceKind::TupleIndex) {
6951
+ if (choice .getKind () == OverloadChoiceKind::TupleIndex) {
6941
6952
continue ;
6942
6953
}
6943
6954
6944
6955
// Discarded unsupported non-decl member lookups.
6945
- if (!choices[i] .isDecl ()) {
6956
+ if (!choice .isDecl ()) {
6946
6957
return SolutionKind::Error;
6947
6958
}
6948
6959
6949
- auto storage = dyn_cast<AbstractStorageDecl>(choices[i].getDecl ());
6950
-
6951
- auto *componentLoc = getConstraintLocator (
6952
- locator.withPathElement (LocatorPathElt::KeyPathComponent (i)));
6960
+ auto storage = dyn_cast<AbstractStorageDecl>(choice.getDecl ());
6953
6961
6954
6962
if (auto *fix = AllowInvalidRefInKeyPath::forRef (
6955
- *this , choices[i] .getDecl (), componentLoc )) {
6956
- if (!hasFixFor (componentLoc , FixKind::AllowTypeOrInstanceMember))
6963
+ *this , choice .getDecl (), calleeLoc )) {
6964
+ if (!hasFixFor (calleeLoc , FixKind::AllowTypeOrInstanceMember))
6957
6965
if (!shouldAttemptFixes () || recordFix (fix))
6958
6966
return SolutionKind::Error;
6959
6967
0 commit comments