Skip to content

Commit 93f9cb1

Browse files
committed
[ConstraintLocator] Identify whether locator is a result of keypath dynamic member lookup or belongs to keypath subscript component
1 parent c3460f8 commit 93f9cb1

File tree

4 files changed

+39
-50
lines changed

4 files changed

+39
-50
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -983,21 +983,6 @@ ConstraintSystem::TypeMatchResult constraints::matchCallArguments(
983983
const auto &param = params[paramIdx];
984984
auto paramTy = param.getOldType();
985985

986-
// Each of the index parameters has to conform to Hashable
987-
// to be viable for use as a keypath subscript component.
988-
if (keyPathSubscriptComponent) {
989-
auto *hashable =
990-
cs.getASTContext().getProtocol(KnownProtocolKind::Hashable);
991-
// Standard library might be broken.
992-
if (!hashable)
993-
return cs.getTypeMatchFailure(locator);
994-
995-
cs.addConstraint(
996-
ConstraintKind::ConformsTo, paramTy, hashable->getDeclaredType(),
997-
cs.getConstraintLocator(keyPathSubscriptComponent,
998-
LocatorPathElt::getTupleElement(paramIdx)));
999-
}
1000-
1001986
if (param.isAutoClosure())
1002987
paramTy = paramTy->castTo<FunctionType>()->getResult();
1003988

@@ -3159,11 +3144,13 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
31593144
// If this is an implicit Hashable conformance check generated for each
31603145
// index argument of the keypath subscript component, we could just treat
31613146
// it as though it conforms.
3162-
if (auto *component = getAsKeyPathSubscriptComponent(*this, anchor, path)) {
3147+
auto *loc = getConstraintLocator(locator);
3148+
if (loc->isResultOfKeyPathDynamicMemberLookup() ||
3149+
loc->isKeyPathSubscriptComponent()) {
31633150
if (protocol ==
31643151
getASTContext().getProtocol(KnownProtocolKind::Hashable)) {
3165-
auto *fix = TreatKeyPathSubscriptIndexAsHashable::create(*this, type,
3166-
component);
3152+
auto *fix =
3153+
TreatKeyPathSubscriptIndexAsHashable::create(*this, type, loc);
31673154
if (!recordFix(fix))
31683155
return SolutionKind::Solved;
31693156
}

lib/Sema/ConstraintLocator.cpp

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,30 @@ bool ConstraintLocator::isSubscriptMemberRef() const {
101101
return path.back().getKind() == ConstraintLocator::SubscriptMember;
102102
}
103103

104+
bool ConstraintLocator::isResultOfKeyPathDynamicMemberLookup() const {
105+
return llvm::any_of(getPath(), [](const LocatorPathElt &elt) {
106+
return elt.isKeyPathDynamicMember();
107+
});
108+
}
109+
110+
bool ConstraintLocator::isKeyPathSubscriptComponent() const {
111+
auto *anchor = getAnchor();
112+
auto *KPE = dyn_cast_or_null<KeyPathExpr>(anchor);
113+
if (!KPE)
114+
return false;
115+
116+
using ComponentKind = KeyPathExpr::Component::Kind;
117+
return llvm::any_of(getPath(), [&](const LocatorPathElt &elt) {
118+
if (!elt.isKeyPathComponent())
119+
return false;
120+
121+
auto index = elt.getValue();
122+
auto &component = KPE->getComponents()[index];
123+
return component.getKind() == ComponentKind::Subscript ||
124+
component.getKind() == ComponentKind::UnresolvedSubscript;
125+
});
126+
}
127+
104128
void ConstraintLocator::dump(SourceManager *sm) {
105129
dump(sm, llvm::errs());
106130
llvm::errs() << "\n";

lib/Sema/ConstraintLocator.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,14 @@ class ConstraintLocator : public llvm::FoldingSetNode {
522522
/// e.g. `foo[0]` or `\Foo.[0]`
523523
bool isSubscriptMemberRef() const;
524524

525+
/// Determine whether given locator points to the choice picked as
526+
/// as result of the key path dynamic member lookup operation.
527+
bool isResultOfKeyPathDynamicMemberLookup() const;
528+
529+
/// Determine whether given locator points to a subscript component
530+
/// of the key path at some index.
531+
bool isKeyPathSubscriptComponent() const;
532+
525533
/// Produce a profile of this locator, for use in a folding set.
526534
static void Profile(llvm::FoldingSetNodeID &id, Expr *anchor,
527535
ArrayRef<PathElement> path);

lib/Sema/ConstraintSystem.cpp

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1695,36 +1695,6 @@ isInvalidPartialApplication(ConstraintSystem &cs, const ValueDecl *member,
16951695
return {true, level};
16961696
}
16971697

1698-
static bool isResultOfKeyPathDynamicMemberLookup(ConstraintLocator *locator) {
1699-
auto path = locator->getPath();
1700-
return !path.empty() && path.back().isKeyPathDynamicMember();
1701-
}
1702-
1703-
/// If given anchor + path represents a key path with subscript
1704-
/// component at some index.
1705-
static bool isKeyPathSubscriptComponent(ConstraintLocator *locator) {
1706-
auto *anchor = locator->getAnchor();
1707-
auto *KPE = dyn_cast_or_null<KeyPathExpr>(anchor);
1708-
if (!KPE)
1709-
return false;
1710-
1711-
using ComponentKind = KeyPathExpr::Component::Kind;
1712-
auto path = locator->getPath();
1713-
while (!path.empty()) {
1714-
auto &last = path.back();
1715-
if (!last.isKeyPathComponent()) {
1716-
path = path.drop_back();
1717-
continue;
1718-
}
1719-
1720-
auto index = last.getValue();
1721-
auto &component = KPE->getComponents()[index];
1722-
return component.getKind() == ComponentKind::Subscript ||
1723-
component.getKind() == ComponentKind::UnresolvedSubscript;
1724-
}
1725-
return false;
1726-
}
1727-
17281698
void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
17291699
Type boundType,
17301700
OverloadChoice choice,
@@ -2122,8 +2092,8 @@ void ConstraintSystem::resolveOverload(ConstraintLocator *locator,
21222092
}
21232093

21242094
if (auto *SD = dyn_cast<SubscriptDecl>(decl)) {
2125-
if (isResultOfKeyPathDynamicMemberLookup(locator) ||
2126-
isKeyPathSubscriptComponent(locator)) {
2095+
if (locator->isResultOfKeyPathDynamicMemberLookup() ||
2096+
locator->isKeyPathSubscriptComponent()) {
21272097
// Subscript type has a format of (Self[.Type) -> (Arg...) -> Result
21282098
auto declTy = openedFullType->castTo<FunctionType>();
21292099
auto subscriptTy = declTy->getResult()->castTo<FunctionType>();

0 commit comments

Comments
 (0)