Skip to content

Commit f53a9e4

Browse files
committed
[Diagnostics] Point ambiguity diagnostic to key path component instead of parent expr
1 parent 171808b commit f53a9e4

File tree

1 file changed

+22
-13
lines changed

1 file changed

+22
-13
lines changed

lib/Sema/ConstraintSystem.cpp

+22-13
Original file line numberDiff line numberDiff line change
@@ -5457,28 +5457,37 @@ bool ConstraintSystem::diagnoseAmbiguity(ArrayRef<Solution> solutions) {
54575457
// FIXME: We would prefer to emit the name as written, but that information
54585458
// is not sufficiently centralized in the AST.
54595459
DeclNameRef name(getOverloadChoiceName(overload.choices));
5460+
5461+
// A location to attach ambiguity diagnostic to.
5462+
SourceLoc diagLoc;
5463+
5464+
// Some of the locations do not simplify all the way to anchor,
5465+
// for example - key path components and dynamic member references
5466+
// are not represented via ASTNode,
54605467
auto anchor = simplifyLocatorToAnchor(overload.locator);
5461-
if (!anchor) {
5462-
// It's not clear that this is actually valid. Just use the overload's
5463-
// anchor for release builds, but assert so we can properly diagnose
5464-
// this case if it happens to be hit. Note that the overload will
5465-
// *always* be anchored, otherwise everything would be broken, ie. this
5466-
// assertion would be the least of our worries.
5467-
anchor = overload.locator->getAnchor();
5468-
assert(false && "locator could not be simplified to anchor");
5468+
if (anchor) {
5469+
diagLoc = getLoc(anchor);
5470+
} else if (auto keyPathComponent = overload.locator->getFirstElementAs<
5471+
LocatorPathElt::KeyPathComponent>()) {
5472+
auto *KPE = castToExpr<KeyPathExpr>(overload.locator->getAnchor());
5473+
diagLoc = KPE->getComponents()[keyPathComponent->getIndex()].getLoc();
5474+
} else {
5475+
diagLoc = getLoc(overload.locator->getAnchor());
54695476
}
54705477

54715478
// Emit the ambiguity diagnostic.
54725479
auto &DE = getASTContext().Diags;
5473-
DE.diagnose(getLoc(anchor),
5480+
DE.diagnose(diagLoc,
54745481
name.isOperator() ? diag::ambiguous_operator_ref
54755482
: diag::ambiguous_decl_ref,
54765483
name);
54775484

5478-
TrailingClosureAmbiguityFailure failure(solutions, anchor,
5479-
overload.choices);
5480-
if (failure.diagnoseAsNote())
5481-
return true;
5485+
if (anchor) {
5486+
TrailingClosureAmbiguityFailure failure(solutions, anchor,
5487+
overload.choices);
5488+
if (failure.diagnoseAsNote())
5489+
return true;
5490+
}
54825491

54835492
// Emit candidates. Use a SmallPtrSet to make sure only emit a particular
54845493
// candidate once. FIXME: Why is one candidate getting into the overload

0 commit comments

Comments
 (0)