Skip to content

Commit 439335d

Browse files
committed
[Diagnostics] Extend keypath subscript index missing Hashable to support dynamic member lookup
1 parent 93f9cb1 commit 439335d

File tree

4 files changed

+21
-16
lines changed

4 files changed

+21
-16
lines changed

lib/Sema/CSApply.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4661,9 +4661,9 @@ namespace {
46614661
auto fnType = overload.openedType->castTo<FunctionType>();
46624662
for (const auto &param : fnType->getParams()) {
46634663
auto indexType = simplifyType(param.getPlainType());
4664-
// index conformance to the Hashable protocol has been verified
4665-
// by the solver, we just need to get it again with all of the
4666-
// generic parameters resolved.
4664+
// Index type conformance to Hashable protocol has been
4665+
// verified by the solver, we just need to get it again
4666+
// with all of the generic parameters resolved.
46674667
auto hashableConformance =
46684668
TC.conformsToProtocol(indexType, hashable, cs.DC,
46694669
(ConformanceCheckFlags::Used |
@@ -4674,7 +4674,7 @@ namespace {
46744674
// Equatable conformance is forced into existence during type
46754675
// checking so that it's available for SILGen.
46764676
auto eqConformance =
4677-
TC.conformsToProtocol(simplifyType(indexType), equatable, cs.DC,
4677+
TC.conformsToProtocol(indexType, equatable, cs.DC,
46784678
(ConformanceCheckFlags::Used |
46794679
ConformanceCheckFlags::InExpression));
46804680
assert(eqConformance.hasValue());

lib/Sema/CSDiagnostics.cpp

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2400,13 +2400,21 @@ bool InaccessibleMemberFailure::diagnoseAsError() {
24002400
}
24012401

24022402
bool KeyPathSubscriptIndexHashableFailure::diagnoseAsError() {
2403-
auto *anchor = cast<KeyPathExpr>(getRawAnchor());
2404-
auto path = getLocator()->getPath();
2405-
const auto &componentIndex = path.back().getValue();
2403+
auto *anchor = getRawAnchor();
2404+
auto *locator = getLocator();
2405+
2406+
auto loc = anchor->getLoc();
2407+
if (locator->isKeyPathSubscriptComponent()) {
2408+
auto *KPE = cast<KeyPathExpr>(anchor);
2409+
for (auto &elt : locator->getPath()) {
2410+
if (elt.isKeyPathComponent()) {
2411+
loc = KPE->getComponents()[elt.getValue()].getLoc();
2412+
break;
2413+
}
2414+
}
2415+
}
24062416

2407-
auto *indexExpr = anchor->getComponents()[componentIndex].getIndexExpr();
2408-
emitDiagnostic(indexExpr->getLoc(),
2409-
diag::expr_keypath_subscript_index_not_hashable,
2417+
emitDiagnostic(loc, diag::expr_keypath_subscript_index_not_hashable,
24102418
resolveType(NonConformingType));
24112419
return true;
24122420
}

lib/Sema/CSDiagnostics.h

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1008,10 +1008,8 @@ class KeyPathSubscriptIndexHashableFailure final : public FailureDiagnostic {
10081008
KeyPathSubscriptIndexHashableFailure(Expr *root, ConstraintSystem &cs,
10091009
Type type, ConstraintLocator *locator)
10101010
: FailureDiagnostic(root, cs, locator), NonConformingType(type) {
1011-
#ifndef NDEBUG
1012-
auto path = locator->getPath();
1013-
assert(!path.empty() && path.back().isKeyPathComponent());
1014-
#endif
1011+
assert(locator->isResultOfKeyPathDynamicMemberLookup() ||
1012+
locator->isKeyPathSubscriptComponent());
10151013
}
10161014

10171015
bool diagnoseAsError() override;

test/attr/attr_dynamic_member_lookup.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -619,9 +619,8 @@ struct WithTrailingClosure {
619619

620620
func keypath_with_trailing_closure_subscript(_ ty: inout SubscriptLens<WithTrailingClosure>) {
621621
_ = ty[0] { 42 } // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
622-
_ = ty[0] { 42 } = 0 // FIXME(diagnostics): Once keypath related diagnostics are using fixes, "ambiguous" error would disappear
622+
_ = ty[0] { 42 } = 0
623623
// expected-error@-1 {{subscript index of type '() -> Int' in a key path must be Hashable}}
624-
// expected-error@-2 {{type of expression is ambiguous without more context}}
625624
_ = ty[] { 42 } // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
626625
_ = ty[] { 42 } = 0 // expected-error {{subscript index of type '() -> Int' in a key path must be Hashable}}
627626
}

0 commit comments

Comments
 (0)