mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[CS] Use callee locators for fix ambiguities
Currently we check that the fixes share the same anchor, however this doesn't account for the case where, given an ApplyExpr, one fix is anchored on its function expr, and another is anchored on the apply itself (because the former fix might be looking at the callee's requirements, and the latter fix might be looking at an argument of the call). This commit changes the logic such that we check that fixes share the same callee locator, which covers the above case. In addition, now that we have the callee locator, we can use this to find the overload directly.
This commit is contained in:
committed by
Hamish Knight
parent
894a1e50bf
commit
63df26a498
@@ -2443,9 +2443,9 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
|
||||
|
||||
// Problems related to fixes forming ambiguous solution set
|
||||
// could only be diagnosed (at the moment), if all of the fixes
|
||||
// are attached to the same anchor, which means they fix
|
||||
// different overloads of the same declaration.
|
||||
Expr *commonAnchor = nullptr;
|
||||
// have the same callee locator, which means they fix different
|
||||
// overloads of the same declaration.
|
||||
ConstraintLocator *commonCalleeLocator = nullptr;
|
||||
SmallPtrSet<ValueDecl *, 4> distinctChoices;
|
||||
SmallVector<std::pair<const Solution *, const ConstraintFix *>, 4>
|
||||
viableSolutions;
|
||||
@@ -2459,21 +2459,17 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
|
||||
return false;
|
||||
|
||||
const auto *fix = fixes.front();
|
||||
if (commonAnchor && commonAnchor != fix->getAnchor())
|
||||
auto *calleeLocator = getCalleeLocator(fix->getAnchor());
|
||||
if (commonCalleeLocator && commonCalleeLocator != calleeLocator)
|
||||
return false;
|
||||
|
||||
commonAnchor = fix->getAnchor();
|
||||
commonCalleeLocator = calleeLocator;
|
||||
|
||||
SmallVector<SelectedOverload, 2> overloads;
|
||||
solution.getOverloadChoices(commonAnchor, overloads);
|
||||
// There is unfortunately no way, at the moment, to figure out
|
||||
// what declaration the fix is attached to, so we have to make
|
||||
// sure that there is only one declaration associated with common
|
||||
// anchor to be sure that the right problem is being diagnosed.
|
||||
if (overloads.size() != 1)
|
||||
auto overload = solution.getOverloadChoiceIfAvailable(calleeLocator);
|
||||
if (!overload)
|
||||
return false;
|
||||
|
||||
auto *decl = getOverloadDecl(overloads.front());
|
||||
auto *decl = getOverloadDecl(*overload);
|
||||
if (!decl)
|
||||
return false;
|
||||
|
||||
@@ -2496,6 +2492,7 @@ bool ConstraintSystem::diagnoseAmbiguityWithFixes(
|
||||
DiagnosticTransaction transaction(TC.Diags);
|
||||
|
||||
const auto *fix = viableSolutions.front().second;
|
||||
auto *commonAnchor = commonCalleeLocator->getAnchor();
|
||||
if (fix->getKind() == FixKind::UseSubscriptOperator) {
|
||||
auto *UDE = cast<UnresolvedDotExpr>(commonAnchor);
|
||||
TC.diagnose(commonAnchor->getLoc(),
|
||||
|
||||
Reference in New Issue
Block a user