Skip to content

Commit 89787e2

Browse files
authored
Merge pull request swiftlang#83766 from hamishknight/fifty-thousand-ants
[CS] Use apply component locator for `verifyThatArgumentIsHashable`
2 parents 290cf83 + 4423399 commit 89787e2

File tree

8 files changed

+42
-39
lines changed

8 files changed

+42
-39
lines changed

include/swift/Sema/ConstraintLocator.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -260,6 +260,10 @@ class ConstraintLocator : public llvm::FoldingSetNode {
260260
/// of the key path at some index.
261261
bool isKeyPathMemberComponent() const;
262262

263+
/// Determine whether this locator points to an apply component of the key
264+
/// path at some index.
265+
bool isKeyPathApplyComponent() const;
266+
263267
/// Determine whether this locator points to the member found
264268
/// via key path dynamic member lookup.
265269
bool isForKeyPathDynamicMemberLookup() const;

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6405,7 +6405,8 @@ SourceLoc KeyPathSubscriptIndexHashableFailure::getLoc() const {
64056405
auto *locator = getLocator();
64066406

64076407
if (locator->isKeyPathSubscriptComponent() ||
6408-
locator->isKeyPathMemberComponent()) {
6408+
locator->isKeyPathMemberComponent() ||
6409+
locator->isKeyPathApplyComponent()) {
64096410
auto *KPE = castToExpr<KeyPathExpr>(getAnchor());
64106411
if (auto kpElt = locator->findFirst<LocatorPathElt::KeyPathComponent>())
64116412
return KPE->getComponents()[kpElt->getIndex()].getLoc();
@@ -6417,7 +6418,7 @@ SourceLoc KeyPathSubscriptIndexHashableFailure::getLoc() const {
64176418
bool KeyPathSubscriptIndexHashableFailure::diagnoseAsError() {
64186419
auto *locator = getLocator();
64196420
emitDiagnostic(diag::expr_keypath_arg_or_index_not_hashable,
6420-
!locator->isKeyPathMemberComponent(),
6421+
!locator->isKeyPathApplyComponent(),
64216422
resolveType(NonConformingType));
64226423
return true;
64236424
}

lib/Sema/CSDiagnostics.h

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1707,9 +1707,10 @@ class KeyPathSubscriptIndexHashableFailure final : public FailureDiagnostic {
17071707
KeyPathSubscriptIndexHashableFailure(const Solution &solution, Type type,
17081708
ConstraintLocator *locator)
17091709
: FailureDiagnostic(solution, locator), NonConformingType(type) {
1710-
assert((locator->isResultOfKeyPathDynamicMemberLookup() ||
1711-
locator->isKeyPathSubscriptComponent()) ||
1712-
locator->isKeyPathMemberComponent());
1710+
assert(locator->isResultOfKeyPathDynamicMemberLookup() ||
1711+
locator->isKeyPathSubscriptComponent() ||
1712+
locator->isKeyPathMemberComponent() ||
1713+
locator->isKeyPathApplyComponent());
17131714
}
17141715

17151716
SourceLoc getLoc() const override;

lib/Sema/CSGen.cpp

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,7 +1198,6 @@ namespace {
11981198
/// component kind.
11991199
Type addApplyConstraints(
12001200
Expr *anchor, Type memberTy, ArgumentList *argList,
1201-
ConstraintLocator *memberComponentLoc,
12021201
ConstraintLocator *applyComponentLoc,
12031202
SmallVectorImpl<TypeVariableType *> *addedTypeVars = nullptr) {
12041203
// Locators used in this expression.
@@ -1225,7 +1224,7 @@ namespace {
12251224
for (auto index : indices(params)) {
12261225
const auto &param = params[index];
12271226
CS.verifyThatArgumentIsHashable(index, param.getParameterType(),
1228-
memberComponentLoc, loc);
1227+
applyComponentLoc, loc);
12291228
}
12301229

12311230
// Add the constraint that the index expression's type be convertible
@@ -3895,11 +3894,8 @@ namespace {
38953894

38963895
case KeyPathExpr::Component::Kind::UnresolvedApply:
38973896
case KeyPathExpr::Component::Kind::Apply: {
3898-
auto prevMemberLocator = CS.getConstraintLocator(
3899-
locator, LocatorPathElt::KeyPathComponent(i - 1));
39003897
base = addApplyConstraints(E, base, component.getArgs(),
3901-
prevMemberLocator, memberLocator,
3902-
&componentTypeVars);
3898+
memberLocator, &componentTypeVars);
39033899
break;
39043900
}
39053901

lib/Sema/CSSimplify.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9221,9 +9221,10 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyConformsToConstraint(
92219221
// If this is an implicit Hashable conformance check generated for each
92229222
// index argument of the keypath subscript component, we could just treat
92239223
// it as though it conforms.
9224-
if ((loc->isResultOfKeyPathDynamicMemberLookup() ||
9225-
loc->isKeyPathSubscriptComponent()) ||
9226-
loc->isKeyPathMemberComponent()) {
9224+
if (loc->isResultOfKeyPathDynamicMemberLookup() ||
9225+
loc->isKeyPathSubscriptComponent() ||
9226+
loc->isKeyPathMemberComponent() ||
9227+
loc->isKeyPathApplyComponent()) {
92279228
if (protocol ==
92289229
getASTContext().getProtocol(KnownProtocolKind::Hashable)) {
92299230
auto *fix =

lib/Sema/ConstraintLocator.cpp

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -596,41 +596,41 @@ bool ConstraintLocator::isResultOfKeyPathDynamicMemberLookup() const {
596596
});
597597
}
598598

599-
bool ConstraintLocator::isKeyPathSubscriptComponent() const {
600-
auto *anchor = getAsExpr(getAnchor());
601-
auto *KPE = dyn_cast_or_null<KeyPathExpr>(anchor);
599+
static bool hasKeyPathComponent(
600+
const ConstraintLocator *loc,
601+
llvm::function_ref<bool(KeyPathExpr::Component::Kind)> predicate) {
602+
auto *KPE = getAsExpr<KeyPathExpr>(loc->getAnchor());
602603
if (!KPE)
603604
return false;
604605

605-
using ComponentKind = KeyPathExpr::Component::Kind;
606-
return llvm::any_of(getPath(), [&](const LocatorPathElt &elt) {
606+
return llvm::any_of(loc->getPath(), [&](const LocatorPathElt &elt) {
607607
auto keyPathElt = elt.getAs<LocatorPathElt::KeyPathComponent>();
608608
if (!keyPathElt)
609609
return false;
610610

611-
auto index = keyPathElt->getIndex();
612-
auto &component = KPE->getComponents()[index];
613-
return component.getKind() == ComponentKind::Subscript ||
614-
component.getKind() == ComponentKind::UnresolvedSubscript;
611+
auto &component = KPE->getComponents()[keyPathElt->getIndex()];
612+
return predicate(component.getKind());
615613
});
616614
}
617615

618-
bool ConstraintLocator::isKeyPathMemberComponent() const {
619-
auto *anchor = getAsExpr(getAnchor());
620-
auto *KPE = dyn_cast_or_null<KeyPathExpr>(anchor);
621-
if (!KPE)
622-
return false;
616+
bool ConstraintLocator::isKeyPathSubscriptComponent() const {
617+
return hasKeyPathComponent(this, [](auto kind) {
618+
return kind == KeyPathExpr::Component::Kind::Subscript ||
619+
kind == KeyPathExpr::Component::Kind::UnresolvedSubscript;
620+
});
621+
}
623622

624-
using ComponentKind = KeyPathExpr::Component::Kind;
625-
return llvm::any_of(getPath(), [&](const LocatorPathElt &elt) {
626-
auto keyPathElt = elt.getAs<LocatorPathElt::KeyPathComponent>();
627-
if (!keyPathElt)
628-
return false;
623+
bool ConstraintLocator::isKeyPathMemberComponent() const {
624+
return hasKeyPathComponent(this, [](auto kind) {
625+
return kind == KeyPathExpr::Component::Kind::Member ||
626+
kind == KeyPathExpr::Component::Kind::UnresolvedMember;
627+
});
628+
}
629629

630-
auto index = keyPathElt->getIndex();
631-
auto &component = KPE->getComponents()[index];
632-
return component.getKind() == ComponentKind::Member ||
633-
component.getKind() == ComponentKind::UnresolvedMember;
630+
bool ConstraintLocator::isKeyPathApplyComponent() const {
631+
return hasKeyPathComponent(this, [](auto kind) {
632+
return kind == KeyPathExpr::Component::Kind::Apply ||
633+
kind == KeyPathExpr::Component::Kind::UnresolvedApply;
634634
});
635635
}
636636

Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
// {"kind":"typecheck","signature":"swift::constraints::ConstraintSystem::simplifyConformsToConstraint(swift::Type, swift::ProtocolDecl*, swift::constraints::ConstraintKind, swift::constraints::ConstraintLocatorBuilder, swift::optionset::OptionSet<swift::constraints::ConstraintSystem::TypeMatchFlags, unsigned int>)","signatureAssert":"Assertion failed: (Index < Length && \"Invalid index!\"), function operator[]"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
\_(error)
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
11
// {"kind":"typecheck","signature":"swift::constraints::ConstraintSystem::getCalleeLocator(swift::constraints::ConstraintLocator*, bool, llvm::function_ref<swift::Type (swift::Expr*)>, llvm::function_ref<swift::Type (swift::Type)>, llvm::function_ref<std::__1::optional<swift::constraints::SelectedOverload> (swift::constraints::ConstraintLocator*)>)","signatureAssert":"Assertion failed: (Index < Length && \"Invalid index!\"), function operator[]"}
2-
// RUN: not --crash %target-swift-frontend -typecheck %s
2+
// RUN: not %target-swift-frontend -typecheck %s
33
struct a func b(c : [Int]) {
44
\ a(c.map{})

0 commit comments

Comments
 (0)